mirror of
https://github.com/dart-lang/sdk
synced 2024-09-04 16:03:44 +00:00
htmlconverter: support DOMContentLoaded and more:
- adds support for running code on DOMContentLoaded, but only for chromium - fix errors in tests after rename to List - fix test due to bug in dartium importing dart:json - add flag to htmlconverter_test to keep temporary files (for debugging) - adds a test that relies on DOMCOntentLoaded (this will fail in dartium) - make htmlconverter.py use the dartc build in the top-level directory Review URL: https://chromereviews.googleplex.com/3512025 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@69 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
9236cc458b
commit
b4be3ca2fe
|
@ -89,6 +89,9 @@ def main(outdir = None, *inputs):
|
|||
|
||||
seen.add(lib)
|
||||
|
||||
if lib.startswith('dart:'):
|
||||
continue
|
||||
|
||||
if (dirname(dirname(lib)).endswith('dom/generated/src')
|
||||
or dirname(lib).endswith('dom/src')):
|
||||
continue
|
||||
|
|
|
@ -24,12 +24,29 @@ sys.path.append(TOOLS_PATH)
|
|||
import utils
|
||||
|
||||
DART_MIME_TYPE = "application/dart"
|
||||
IMPORT_SOURCE_PATTERN = "(#import|#source)(\(['\"])([^'\"]*)(['\"]\);)"
|
||||
|
||||
DARTC_INPUT_IMPORTS = """
|
||||
DARTC_INLINE_CODE_ADDITIONAL_IMPORTS = """
|
||||
#library('inlinedcode');
|
||||
#import('dart:dom');
|
||||
#import('dart:json');
|
||||
"""
|
||||
|
||||
ENTRY_POINT = """
|
||||
#library('entry');
|
||||
#import('dart:dom');
|
||||
#import('%s', prefix: 'original');
|
||||
main() {
|
||||
// Ensure the code starts on DOM content loaded.
|
||||
if (document.readyState == "interactive" ||
|
||||
document.readyState == "complete") {
|
||||
original.main();
|
||||
} else {
|
||||
window.addEventListener('DOMContentLoaded', (e) => original.main(), false);
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
CSS_TEMPLATE = '<style type="text/css">%s</style>'
|
||||
CHROMIUM_SCRIPT_TEMPLATE = '<script type="application/javascript">%s</script>'
|
||||
|
||||
|
@ -76,7 +93,25 @@ class DartCompiler(object):
|
|||
"The script body should be empty if src is specified")
|
||||
elif src.endswith('.dart'):
|
||||
indir = tempfile.mkdtemp()
|
||||
inputfile = src
|
||||
inputfile = abspath(src)
|
||||
with open(inputfile, 'r') as f:
|
||||
contents = f.read();
|
||||
|
||||
# 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 '#library' in contents:
|
||||
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)
|
||||
|
||||
else:
|
||||
raise ConverterException("invalid file type:" + src)
|
||||
else:
|
||||
|
@ -86,18 +121,23 @@ class DartCompiler(object):
|
|||
return ''
|
||||
|
||||
indir = tempfile.mkdtemp()
|
||||
|
||||
inputfile = join(indir, 'code.dart')
|
||||
with open(inputfile, 'w') as f:
|
||||
f.write(DARTC_INPUT_IMPORTS)
|
||||
f.write(DARTC_INLINE_CODE_ADDITIONAL_IMPORTS)
|
||||
f.write(body)
|
||||
|
||||
status, out, err = execute(self.compileCommand(inputfile, outdir),
|
||||
wrappedfile = join(indir, 'entry.dart')
|
||||
with open(wrappedfile, 'w') as f:
|
||||
f.write(ENTRY_POINT % inputfile)
|
||||
|
||||
status, out, err = execute(self.compileCommand(wrappedfile, outdir),
|
||||
self.verbose)
|
||||
if status:
|
||||
raise ConverterException()
|
||||
|
||||
# Inline the compiled code in the page
|
||||
with open(self.outputFileName(inputfile, outdir), 'r') as f:
|
||||
with open(self.outputFileName(wrappedfile, outdir), 'r') as f:
|
||||
res = f.read()
|
||||
|
||||
# Cleanup
|
||||
|
@ -107,9 +147,9 @@ class DartCompiler(object):
|
|||
return CHROMIUM_SCRIPT_TEMPLATE % res
|
||||
|
||||
def compileCommand(self, inputfile, outdir):
|
||||
cmd = [abspath(join(CLIENT_PATH,
|
||||
cmd = [abspath(join(DART_PATH,
|
||||
# TODO(sigmund): support also mode = release
|
||||
utils.GetBuildRoot(utils.GuessOS(), 'debug', 'dartc'),
|
||||
utils.GetBuildRoot(utils.GuessOS(), 'debug', 'ia32'),
|
||||
'dartc')), '-noincremental', '-out', outdir]
|
||||
if self.optimize:
|
||||
cmd.append('-optimize')
|
||||
|
@ -125,14 +165,20 @@ class DartCompiler(object):
|
|||
def execute(cmd, verbose=False):
|
||||
"""Execute a command in a subprocess. """
|
||||
if verbose: print 'Executing: ' + ' '.join(cmd)
|
||||
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output, err = pipe.communicate()
|
||||
if pipe.returncode != 0:
|
||||
print 'Execution failed: ' + output + '\n' + err
|
||||
if verbose or pipe.returncode != 0:
|
||||
print output
|
||||
print err
|
||||
return pipe.returncode, output, err
|
||||
try:
|
||||
pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output, err = pipe.communicate()
|
||||
if pipe.returncode != 0:
|
||||
print 'Execution failed: ' + output + '\n' + err
|
||||
if verbose or pipe.returncode != 0:
|
||||
print output
|
||||
print err
|
||||
return pipe.returncode, output, err
|
||||
except Exception as e:
|
||||
print 'Exception when executing: ' + ' '.join(cmd)
|
||||
print e
|
||||
return 1, None, None
|
||||
|
||||
|
||||
def convertPath(project_path, prefix_path):
|
||||
""" Convert a project path (whose root corresponds to the current working
|
||||
|
@ -311,6 +357,7 @@ class DartToDartHTMLConverter(DartHTMLConverter):
|
|||
self.outdir,
|
||||
convertPath(attrDic['src'], self.prefix_path)],
|
||||
self.verbose)
|
||||
|
||||
if status:
|
||||
raise ConverterException('calling copy_dart.py')
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ TEST2_HTML = """
|
|||
"""
|
||||
|
||||
TEST2_DART = """
|
||||
#library('test2');
|
||||
#import('dart:dom');
|
||||
main() {
|
||||
window.alert('test2!');
|
||||
|
@ -132,12 +133,11 @@ TEST4_HTML = """
|
|||
|
||||
TEST4_DART = """
|
||||
#import('dart:dom');
|
||||
#import('dart:json');
|
||||
#import('observable/observable.dart');
|
||||
|
||||
main() {
|
||||
// use imported code
|
||||
var arr = new ObservableArray();
|
||||
var arr = new ObservableList();
|
||||
arr.addChangeListener((EventSummary events) {
|
||||
var t = ['update', 'add ',
|
||||
'remove', 'global'][events.events[0].type];
|
||||
|
@ -171,6 +171,40 @@ Content-Type: text/plain
|
|||
#EOF
|
||||
"""
|
||||
|
||||
TEST5_HTML = """
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<script type="application/javascript">
|
||||
if (window.layoutTestController) {
|
||||
window.layoutTestController.dumpAsText();
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- embed source code -->
|
||||
<script type="application/dart">
|
||||
main() {
|
||||
var element = document.getElementById("test5div");
|
||||
if (element == null) {
|
||||
window.alert("this script shoulnd't be run synchronously");
|
||||
} else {
|
||||
window.alert(element.innerHTML);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<div id="test5div">this is visible on DOMContentLoaded</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
TEST5_OUTPUT = """
|
||||
ALERT: this is visible on DOMContentLoaded
|
||||
Content-Type: text/plain
|
||||
this is visible on DOMContentLoaded
|
||||
#EOF
|
||||
"""
|
||||
|
||||
|
||||
FILES = {
|
||||
'test_1.html': TEST1_HTML,
|
||||
|
||||
|
@ -184,11 +218,23 @@ FILES = {
|
|||
|
||||
'test_4.html': TEST4_HTML,
|
||||
'test_4.dart': TEST4_DART,
|
||||
|
||||
'test_5.html': TEST5_HTML,
|
||||
}
|
||||
|
||||
INPUTS = ['test_1.html', 'test_2.html', 'test_3.html', 'test_4.html']
|
||||
OUTPUTS = [TEST1_OUTPUT, TEST2_OUTPUT, TEST3_OUTPUT, TEST4_OUTPUT]
|
||||
INPUTS = [
|
||||
'test_1.html',
|
||||
'test_2.html',
|
||||
'test_3.html',
|
||||
'test_4.html',
|
||||
'test_5.html']
|
||||
|
||||
OUTPUTS = [
|
||||
TEST1_OUTPUT,
|
||||
TEST2_OUTPUT,
|
||||
TEST3_OUTPUT,
|
||||
TEST4_OUTPUT,
|
||||
TEST5_OUTPUT]
|
||||
|
||||
CLIENT_PATH = dirname(dirname(abspath(__file__)))
|
||||
RED_COLOR = "\033[31m"
|
||||
|
@ -252,7 +298,7 @@ def deleteInputFiles():
|
|||
for filename in FILES:
|
||||
os.remove(filename)
|
||||
|
||||
def runTest(test, target, verbose):
|
||||
def runTest(test, target, verbose, keep_temporary_files):
|
||||
inputfile = INPUTS[test]
|
||||
suffix = '-js.html' if target == 'chromium' else '-dartium.html'
|
||||
outfile = abspath(join('out', inputfile.replace(".html", suffix)))
|
||||
|
@ -273,12 +319,17 @@ def runTest(test, target, verbose):
|
|||
|
||||
status = browserRun(
|
||||
"... running compiled html in %s" % target, outfile, test, verbose)
|
||||
os.remove(outfile)
|
||||
if not keep_temporary_files:
|
||||
os.remove(outfile)
|
||||
return status
|
||||
|
||||
def Flags():
|
||||
""" Consturcts a parser for extracting flags from the command line. """
|
||||
result = optparse.OptionParser()
|
||||
result.add_option("--keep_temporary_files",
|
||||
help="Keep temporary files created for each test",
|
||||
default=False,
|
||||
action="store_true")
|
||||
result.add_option("-v", "--verbose",
|
||||
help="Print verbose output",
|
||||
default=False,
|
||||
|
@ -290,23 +341,38 @@ def Flags():
|
|||
result.set_usage("htmlconverter_test.py [--verbose -t chromium,dartium]")
|
||||
return result
|
||||
|
||||
def shouldRunTest(test, prefixes):
|
||||
if len(prefixes) == 0:
|
||||
return True
|
||||
for a in prefixes:
|
||||
if INPUTS[test].startswith(a):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
os.chdir(CLIENT_PATH)
|
||||
parser = Flags()
|
||||
options, args = parser.parse_args()
|
||||
verbose = options.verbose
|
||||
keep_temporary_files = options.keep_temporary_files
|
||||
|
||||
createInputFiles()
|
||||
for test in range(len(INPUTS)):
|
||||
if 'chromium' in options.target:
|
||||
if runTest(test, 'chromium', options.verbose) != 0:
|
||||
deleteInputFiles()
|
||||
return 1
|
||||
if 'dartium' in options.target:
|
||||
if runTest(test, 'dartium', options.verbose) != 0:
|
||||
deleteInputFiles()
|
||||
return 1
|
||||
if shouldRunTest(test, args):
|
||||
if 'chromium' in options.target:
|
||||
if runTest(test, 'chromium', verbose, keep_temporary_files) != 0:
|
||||
if not keep_temporary_files:
|
||||
deleteInputFiles()
|
||||
return 1
|
||||
if 'dartium' in options.target:
|
||||
if runTest(test, 'dartium', verbose, keep_temporary_files) != 0:
|
||||
if not keep_temporary_files:
|
||||
deleteInputFiles()
|
||||
return 1
|
||||
|
||||
deleteInputFiles()
|
||||
if not keep_temporary_files:
|
||||
deleteInputFiles()
|
||||
return 0
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue