mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 21:20:36 +00:00
htmlconverter: allow imports in inlined code, including imports to dom/html
Review URL: https://chromereviews.googleplex.com/3530016 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@174 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
83337cd637
commit
6c03d06c5d
|
@ -26,13 +26,19 @@ import utils
|
|||
|
||||
DART_MIME_TYPE = "application/dart"
|
||||
LIBRARY_PATTERN = "^#library\(.*\);"
|
||||
IMPORT_SOURCE_PATTERN = "(#import|#source)(\(['\"])([^'\"]*)(['\"]\);)"
|
||||
IMPORT_SOURCE_MATCHER = re.compile(
|
||||
r"^ *(#import|#source)(\(['\"])([^'\"]*)(.*\);)", re.MULTILINE)
|
||||
DOM_IMPORT_MATCHER = re.compile(
|
||||
r"^#import\(['\"]dart\:dom['\"].*\);", re.MULTILINE)
|
||||
HTML_NO_PREFIX_IMPORT_MATCHER = re.compile(
|
||||
r"^#import.*(dart:html|html.dart)['\"]\);", re.MULTILINE)
|
||||
JSON_IMPORT_MATCHER = re.compile(
|
||||
r"^#import\(['\"]dart:json['\"].*\);", re.MULTILINE)
|
||||
|
||||
DARTC_INLINE_CODE_ADDITIONAL_IMPORTS = """
|
||||
#library('inlinedcode');
|
||||
#import('dart:dom');
|
||||
#import('dart:json');
|
||||
"""
|
||||
COMPILER_NOT_FOUND_ERROR = (
|
||||
"""Couldn't find compiler: please run the following commands:
|
||||
$ cd %s
|
||||
$ ./tools/build.py --arch=ia32""")
|
||||
|
||||
ENTRY_POINT = """
|
||||
#library('entry');
|
||||
|
@ -56,13 +62,21 @@ DARTIUM_TO_JS_SCRIPT = """
|
|||
"that doesn't support Dart. Do you want to redirect to " +
|
||||
"a version compiled to JavaScript instead?")) {
|
||||
var addr = window.location;
|
||||
window.location = addr.toString().replace('-dartium.html', '-js.html');
|
||||
window.location = addr.toString().replace('-dart.html', '-js.html');
|
||||
}
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
"""
|
||||
|
||||
def adjustImports(contents):
|
||||
def repl(matchobj):
|
||||
path = matchobj.group(3)
|
||||
if not path.startswith('dart:'):
|
||||
path = abspath(path)
|
||||
return (matchobj.group(1) + matchobj.group(2) + path + matchobj.group(4))
|
||||
return IMPORT_SOURCE_MATCHER.sub(repl, contents)
|
||||
|
||||
class DartCompiler(object):
|
||||
""" Common code for compiling Dart script tags in an HTML file. """
|
||||
|
||||
|
@ -96,17 +110,10 @@ class DartCompiler(object):
|
|||
# We will import the source file to emulate in JS that code is run after
|
||||
# DOMContentLoaded. We need a #library to ensure #import won't fail:
|
||||
if not re.search(LIBRARY_PATTERN, contents, re.MULTILINE):
|
||||
def repl(matchobj):
|
||||
path = matchobj.group(3)
|
||||
if path.startswith('dart:'):
|
||||
return matchobj.group(0)
|
||||
return (matchobj.group(1) + matchobj.group(2)
|
||||
+ abspath(path) + matchobj.group(4))
|
||||
contents = re.sub(IMPORT_SOURCE_PATTERN, repl, contents)
|
||||
inputfile = join(indir, 'code.dart')
|
||||
with open(inputfile, 'w') as f:
|
||||
f.write("#library('code');")
|
||||
f.write(contents)
|
||||
f.write(adjustImports(contents))
|
||||
|
||||
else:
|
||||
raise ConverterException("invalid file type:" + src)
|
||||
|
@ -117,10 +124,23 @@ class DartCompiler(object):
|
|||
return ''
|
||||
|
||||
indir = tempfile.mkdtemp()
|
||||
# eliminate leading spaces in front of directives
|
||||
body = adjustImports(body)
|
||||
|
||||
inputfile = join(indir, 'code.dart')
|
||||
with open(inputfile, 'w') as f:
|
||||
f.write(DARTC_INLINE_CODE_ADDITIONAL_IMPORTS)
|
||||
f.write("#library('inlinedcode');\n")
|
||||
# dom and json are added by default
|
||||
if not DOM_IMPORT_MATCHER.search(body):
|
||||
f.write("#import('dart:dom');\n")
|
||||
if not JSON_IMPORT_MATCHER.search(body):
|
||||
f.write("#import('dart:json');\n")
|
||||
# html import will conflict with DOM import
|
||||
if HTML_NO_PREFIX_IMPORT_MATCHER.search(body):
|
||||
raise ConverterException(
|
||||
'Can\'t import "dom:html" or "html.dart" from scripts inlined ' +
|
||||
'in the page without a prefix. This import conflicts with an ' +
|
||||
' import of "dart:dom" that is injected automatically.')
|
||||
f.write(body)
|
||||
|
||||
wrappedfile = join(indir, 'entry.dart')
|
||||
|
@ -130,7 +150,7 @@ class DartCompiler(object):
|
|||
status, out, err = execute(self.compileCommand(wrappedfile, outdir),
|
||||
self.verbose)
|
||||
if status:
|
||||
raise ConverterException()
|
||||
raise ConverterException('compilation errors found by dartc')
|
||||
|
||||
# Inline the compiled code in the page
|
||||
with open(self.outputFileName(wrappedfile, outdir), 'r') as f:
|
||||
|
@ -143,10 +163,13 @@ class DartCompiler(object):
|
|||
return CHROMIUM_SCRIPT_TEMPLATE % res
|
||||
|
||||
def compileCommand(self, inputfile, outdir):
|
||||
cmd = [abspath(join(DART_PATH,
|
||||
binary = abspath(join(DART_PATH,
|
||||
# TODO(sigmund): support also mode = release
|
||||
utils.GetBuildRoot(utils.GuessOS(), 'debug', 'ia32'),
|
||||
'dartc')), '-noincremental', '-out', outdir]
|
||||
'dartc'))
|
||||
if not exists(binary):
|
||||
raise ConverterException(COMPILER_NOT_FOUND_ERROR % DART_PATH)
|
||||
cmd = [binary, '-noincremental', '-out', outdir]
|
||||
if self.optimize:
|
||||
cmd.append('-optimize')
|
||||
cmd.append('--disable-type-optimizations')
|
||||
|
@ -185,6 +208,7 @@ def convertPath(project_path, prefix_path):
|
|||
- prefix_path: prefix for relative paths.
|
||||
"""
|
||||
if isabs(project_path):
|
||||
# TODO(sigmund): add a flag to pass in the root-level for absolute paths.
|
||||
return project_path[1:]
|
||||
elif not (project_path.startswith('http://') or
|
||||
project_path.startswith('https://')):
|
||||
|
@ -342,7 +366,7 @@ class DartToDartHTMLConverter(DartHTMLConverter):
|
|||
self.verbose)
|
||||
|
||||
if status:
|
||||
raise ConverterException('calling copy_dart.py')
|
||||
raise ConverterException('exception calling copy_dart.py')
|
||||
|
||||
# do not rewrite the script tag
|
||||
return False
|
||||
|
@ -455,8 +479,8 @@ def Flags():
|
|||
result.add_option("-t", "--target",
|
||||
help="The target html to generate",
|
||||
metavar="[chromium,dartium]",
|
||||
default='chromium,dartium')
|
||||
result.set_usage("htmlconverter.py input.html -o OUTDIR -t chromium,dartium")
|
||||
default='chromium')
|
||||
result.set_usage("htmlconverter.py input.html -o OUTDIR")
|
||||
return result
|
||||
|
||||
def writeOut(contents, filepath):
|
||||
|
@ -503,6 +527,8 @@ def convertForOffline(filename, outfile, verbose, encode_images):
|
|||
f.write(contents)
|
||||
print "Generated output in: " + abspath(outfile)
|
||||
|
||||
RED_COLOR = "\033[31m"
|
||||
NO_COLOR = "\033[0m"
|
||||
|
||||
def main():
|
||||
parser = Flags()
|
||||
|
@ -511,15 +537,19 @@ def main():
|
|||
parser.print_help()
|
||||
return 1
|
||||
|
||||
filename = args[0]
|
||||
outfile = join(options.out, filename)
|
||||
if 'chromium' in options.target:
|
||||
convertForChromium(
|
||||
filename, options.optimize, outfile.replace('.html', '-js.html'),
|
||||
options.verbose)
|
||||
if 'dartium' in options.target:
|
||||
convertForDartium(filename, outfile.replace('.html', '-dartium.html'),
|
||||
options.verbose)
|
||||
try:
|
||||
filename = args[0]
|
||||
outfile = join(options.out, filename)
|
||||
if 'chromium' in options.target:
|
||||
convertForChromium(
|
||||
filename, options.optimize, outfile.replace('.html', '-js.html'),
|
||||
options.verbose)
|
||||
if 'dartium' in options.target:
|
||||
convertForDartium(filename, outfile.replace('.html', '-dart.html'),
|
||||
options.verbose)
|
||||
except Exception as e:
|
||||
print "%sERROR%s: %s" % (RED_COLOR, NO_COLOR, str(e))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -96,7 +96,7 @@ TEST3_DART = """
|
|||
"""
|
||||
|
||||
TEST3_DART_A = """
|
||||
class MyClass {
|
||||
class MyClass {
|
||||
static myprint() {
|
||||
window.alert('test3!');
|
||||
}
|
||||
|
@ -204,6 +204,37 @@ this is visible on DOMContentLoaded
|
|||
#EOF
|
||||
"""
|
||||
|
||||
# TODO(sigmund): integrate with testing infrastructure and mark negative tests.
|
||||
# removing the prefix on test6 should purposely fail.
|
||||
|
||||
TEST6_HTML = """
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<script type="application/javascript">
|
||||
if (window.layoutTestController) {
|
||||
window.layoutTestController.dumpAsText();
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- embed source code -->
|
||||
<script type="application/dart">
|
||||
#import('html/html.dart', prefix: 'html');
|
||||
main() {
|
||||
html.window.alert('hi');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
TEST6_OUTPUT = """
|
||||
ALERT: hi
|
||||
Content-Type: text/plain
|
||||
|
||||
#EOF
|
||||
"""
|
||||
|
||||
|
||||
FILES = {
|
||||
'test_1.html': TEST1_HTML,
|
||||
|
@ -220,6 +251,7 @@ FILES = {
|
|||
'test_4.dart': TEST4_DART,
|
||||
|
||||
'test_5.html': TEST5_HTML,
|
||||
'test_6.html': TEST6_HTML,
|
||||
}
|
||||
|
||||
INPUTS = [
|
||||
|
@ -227,14 +259,18 @@ INPUTS = [
|
|||
'test_2.html',
|
||||
'test_3.html',
|
||||
'test_4.html',
|
||||
'test_5.html']
|
||||
'test_5.html',
|
||||
'test_6.html'
|
||||
]
|
||||
|
||||
OUTPUTS = [
|
||||
TEST1_OUTPUT,
|
||||
TEST2_OUTPUT,
|
||||
TEST3_OUTPUT,
|
||||
TEST4_OUTPUT,
|
||||
TEST5_OUTPUT]
|
||||
TEST5_OUTPUT,
|
||||
TEST6_OUTPUT
|
||||
]
|
||||
|
||||
CLIENT_PATH = dirname(dirname(abspath(__file__)))
|
||||
RED_COLOR = "\033[31m"
|
||||
|
@ -300,7 +336,7 @@ def deleteInputFiles():
|
|||
|
||||
def runTest(test, target, verbose, keep_temporary_files):
|
||||
inputfile = INPUTS[test]
|
||||
suffix = '-js.html' if target == 'chromium' else '-dartium.html'
|
||||
suffix = '-js.html' if target == 'chromium' else '-dart.html'
|
||||
outfile = abspath(join('out', inputfile.replace(".html", suffix)))
|
||||
|
||||
# TODO(sigmund): tests should also run in dartium before converting them
|
||||
|
|
Loading…
Reference in a new issue