diff --git a/client/tools/htmlconverter.py b/client/tools/htmlconverter.py
index 8da432898dc..37c7feddbeb 100644
--- a/client/tools/htmlconverter.py
+++ b/client/tools/htmlconverter.py
@@ -12,7 +12,8 @@ into JavaScript sections. It also can optimize the HTML to inline code.
"""
from HTMLParser import HTMLParser
-from os.path import abspath, basename, dirname, exists, isabs, join, split
+import os.path
+from os.path import abspath, basename, dirname, exists, isabs, join
import base64, re, optparse, os, shutil, subprocess, sys, tempfile, codecs
import urllib2
@@ -199,20 +200,6 @@ def encodeImage(rootDir, filename):
filetype,
base64.b64encode(f.read()))
-def encodeImageUrl(filename):
- """ Downloads an image and returns a base64 url encoding for it """
- filetype = filename[-3:]
- if filetype == 'svg': filetype = 'svg+xml'
- print 'Downloading ' + filename
- try:
- f = urllib2.urlopen(filename)
- except:
- return filename
-
- return 'data:image/%s;charset=utf-8;base64,%s' % (
- filetype,
- base64.b64encode(f.read()))
-
def processCss(filename):
""" Reads and converts a css file by replacing all image refernces into
base64 encoded images.
@@ -262,7 +249,7 @@ class DartHTMLConverter(HTMLParser):
self.dart_inline_code = []
return True
- def inlineImage(self, attrDic):
+ def convertImage(self, attrDic):
pass
def starttagHelper(self, tag, attrs, isEnd):
@@ -283,7 +270,7 @@ class DartHTMLConverter(HTMLParser):
return
elif tag == 'img' and 'src' in attrDic:
- self.inlineImage(attrDic)
+ self.convertImage(attrDic)
# emit everything else as in the input
self.output.append('<%s%s%s>' % (
@@ -364,20 +351,71 @@ class DartToDartHTMLConverter(DartHTMLConverter):
self.output.append(DARTIUM_TO_JS_SCRIPT)
DartHTMLConverter.handle_endtag(self, tag)
+# A data URL for a blank 1x1 PNG. The PNG's data is from
+# convert -size 1x1 +set date:create +set date:modify \
+# xc:'rgba(0,0,0,0)' 1x1.png
+# base64.b64encode(open('1x1.png').read())
+# (The +set stuff is because just doing "-strip" apparently doesn't work;
+# it leaves several info chunks resulting in a 224-byte PNG.)
+BLANK_IMAGE_BASE64_URL = 'data:image/png;charset=utf-8;base64,%s' % (
+ ('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABEAQAAADljNBBAAAAAmJLR0T//xSrMc0AAAAJc'
+ 'EhZcwAAAEgAAABIAEbJaz4AAAAJdnBBZwAAAAEAAAABAMeVX+0AAAANSURBVAjXY2BgYG'
+ 'AAAAAFAAFe8yo6AAAAAElFTkSuQmCC'))
+
class OfflineHTMLConverter(DartHTMLConverter):
- def __init__(self, prefix_path, outdir, verbose):
+ def __init__(self, prefix_path, outdir, verbose, inline_images):
# Note: can't use super calls because HTMLParser is not a subclass of object
DartHTMLConverter.__init__(self, None, prefix_path)
self.outdir = outdir
self.verbose = verbose
+ self.inline_images = inline_images # Inline as data://, vs. use local file.
def compileScript(self, attrDic):
# do not rewrite the script tag
return False
- def inlineImage(self, attrDic):
- attrDic['src'] = encodeImageUrl(attrDic['src'])
+ def downloadImageUrlToEncode(self, url):
+ """ Downloads an image and returns a base64 url encoding for it.
+ May throw if the download fails.
+ """
+ # Don't try to re-encode an image that's already data://.
+ if url.startswith('data:image/'):
+ return url
+ filetype = url[-3:]
+ if filetype == 'svg': filetype = 'svg+xml'
+ if self.verbose:
+ print 'Downloading ' + url
+ f = urllib2.urlopen(url)
+ return 'data:image/%s;charset=utf-8;base64,%s' % (
+ filetype,
+ base64.b64encode(f.read()))
+
+ def downloadImageUrlToFile(self, url):
+ """Downloads an image and returns the filename. May throw if the
+ download fails.
+ """
+ extension = os.path.splitext(url)[1]
+ # mkstemp() happens to work to create a non-temporary, so we use it.
+ filename = tempfile.mkstemp(extension, 'img_', self.prefix_path)[1]
+ if self.verbose:
+ print 'Downloading %s to %s' % (url, filename)
+ writeOut(urllib2.urlopen(url).read(), filename)
+ return os.path.join(self.prefix_path, os.path.basename(filename))
+
+ def downloadImage(self, url):
+ """Downloads an image either to file or to data://, and return the URL."""
+ try:
+ if self.inline_images:
+ return self.downloadImageUrlToEncode(url)
+ else:
+ return self.downloadImageUrlToFile(url)
+ except:
+ print '*** Image download failed: %s' % url
+ return BLANK_IMAGE_BASE64_URL
+
+ def convertImage(self, attrDic):
+ attrDic['src'] = self.downloadImage(attrDic['src'])
def safeMakeDirs(dirname):
""" Creates a directory and, if necessary its parent directories.
@@ -398,7 +436,7 @@ class ConverterException(Exception):
pass
def Flags():
- """ Consturcts a parser for extracting flags from the command line. """
+ """ Constructs a parser for extracting flags from the command line. """
result = optparse.OptionParser()
result.add_option("--optimize",
help="Use optimizer in dartc",
@@ -447,11 +485,14 @@ def convertForChromium(filename, optimize, outfile, verbose):
converter.close()
writeOut(converter.getResult(), outfile)
-def convertForOffline(filename, outfile, verbose):
+def convertForOffline(filename, outfile, verbose, encode_images):
""" Converts a file for offline use. """
with codecs.open(filename, 'r', 'utf-8') as f:
contents = f.read()
- converter = OfflineHTMLConverter(dirname(filename), dirname(outfile), verbose)
+ converter = OfflineHTMLConverter(dirname(filename),
+ dirname(outfile),
+ verbose,
+ encode_images)
converter.feed(contents)
converter.close()