OLD | NEW |
---|---|
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library ddc.src.codegen.html_codegen; | 5 library ddc.src.codegen.html_codegen; |
6 | 6 |
7 import 'dart:io'; | |
8 | |
9 import 'package:html5lib/dom.dart'; | 7 import 'package:html5lib/dom.dart'; |
10 import 'package:html5lib/parser.dart' show parseFragment; | 8 import 'package:html5lib/parser.dart' show parseFragment; |
11 import 'package:path/path.dart' as path; | 9 import 'package:logging/logging.dart' show Logger; |
12 | 10 |
13 import 'package:dev_compiler/src/info.dart'; | 11 import 'package:dev_compiler/src/dependency_graph.dart'; |
14 import 'package:dev_compiler/src/options.dart'; | 12 import 'package:dev_compiler/src/options.dart'; |
13 import 'package:dev_compiler/src/utils.dart' show colorOf; | |
15 | 14 |
16 import 'js_codegen.dart' show jsLibraryName, jsOutputPath; | 15 import 'js_codegen.dart' show jsLibraryName, jsOutputPath; |
17 | 16 |
18 /// Emits an entry point HTML file corresponding to [inputFile] that can load | 17 /// Emits an entry point HTML file corresponding to [inputFile] that can load |
19 /// the code generated by the ddc compiler. | 18 /// the code generated by the ddc compiler. |
20 /// | 19 /// |
21 /// This internally transforms the given HTML [document]. When compiling to | 20 /// This internally transforms the given HTML [document]. When compiling to |
22 /// JavaScript, we remove any Dart script tags, add new script tags to load the | 21 /// JavaScript, we remove any Dart script tags, add new script tags to load the |
23 /// ddc runtime and the compiled code, and to execute the main method of the | 22 /// ddc runtime and the compiled code, and to execute the main method of the |
24 /// application. When compiling to Dart, we ensure that the document contains a | 23 /// application. When compiling to Dart, we ensure that the document contains a |
25 /// single Dart script tag, but otherwise emit the original document | 24 /// single Dart script tag, but otherwise emit the original document |
26 /// unmodified. | 25 /// unmodified. |
27 void generateEntryHtml(String inputFile, CompilerOptions options, | 26 String generateEntryHtml(HtmlSourceNode root, CompilerOptions options) { |
28 CheckerResults results, Document document) { | 27 var document = root.document.clone(true); |
29 String outputFile = path.join(options.outputDir, path.basename(inputFile)); | 28 var scripts = document.querySelectorAll('script[type="application/dart"]'); |
29 if (scripts.isEmpty) { | |
30 _log.severe('No <script type="application/dart"> found in ${root.uri}'); | |
31 return null; | |
32 } | |
33 scripts.skip(1).forEach((s) { | |
34 // TODO(sigmund): allow more than one Dart script tags? | |
35 _log.warning(s.sourceSpan.message( | |
36 'unexpected script. Only one Dart script tag allowed ' | |
37 '(see https://github.com/dart-lang/dart-dev-compiler/issues/53).', | |
38 color: options.useColors ? colorOf('warning') : false)); | |
39 s.remove(); | |
40 }); | |
30 | 41 |
31 var scripts = document.querySelectorAll('script[type="application/dart"]'); | 42 if (options.outputDart) return '${document.outerHtml}\n'; |
32 var mainScript = scripts[0]; | |
33 // TODO(sigmund): allow more than one Dart script tags? | |
34 scripts.skip(1).forEach((s) => s.remove()); | |
35 | 43 |
36 if (options.outputDart) { | 44 var libraries = []; |
37 new File(outputFile).writeAsStringSync('${document.outerHtml}\n'); | 45 visitInPostOrder(root, (n) { |
38 return; | 46 if (n is LibrarySourceNode) libraries.add(n); |
39 } | 47 }); |
40 | 48 |
41 String mainLibraryName; | 49 String mainLibraryName; |
42 var pathToDdc = path.dirname(path | 50 var fragment = _loadRuntimeScripts(); |
43 .dirname(path.relative(Platform.script.path, from: options.outputDir))); | |
44 var fragment = _loadRuntimeScripts(path.join(pathToDdc, 'lib')); | |
45 if (!options.checkSdk) fragment.nodes.add(_miniMockSdk); | 51 if (!options.checkSdk) fragment.nodes.add(_miniMockSdk); |
46 for (var lib in results.libraries) { | 52 for (var lib in libraries) { |
47 if (lib.isEntry) mainLibraryName = jsLibraryName(lib.library); | 53 var info = lib.info; |
48 fragment.nodes.add(_libraryInclude(jsOutputPath(lib))); | 54 if (info == null) continue; |
55 if (info.isEntry) mainLibraryName = jsLibraryName(info.library); | |
56 fragment.nodes.add(_libraryInclude(jsOutputPath(info))); | |
49 } | 57 } |
50 fragment.nodes.add(_invokeMain(mainLibraryName)); | 58 fragment.nodes.add(_invokeMain(mainLibraryName)); |
51 mainScript.replaceWith(fragment); | 59 scripts[0].replaceWith(fragment); |
52 new File(outputFile).writeAsStringSync('${document.outerHtml}\n'); | 60 return '${document.outerHtml}\n'; |
53 } | 61 } |
54 | 62 |
55 /// A document fragment with scripts that check for harmony features and that | 63 /// A document fragment with scripts that check for harmony features and that |
56 /// inject our runtime. | 64 /// inject our runtime. |
57 Node _loadRuntimeScripts(String ddcLibDir) => parseFragment(''' | 65 Node _loadRuntimeScripts() => parseFragment(''' |
58 <script src="$ddcLibDir/runtime/harmony_feature_check.js"></script> | 66 <script src="dev_compiler/runtime/harmony_feature_check.js"></script> |
59 <script src="$ddcLibDir/runtime/dart_runtime.js"></script> | 67 <script src="dev_compiler/runtime/dart_runtime.js"></script> |
60 '''); | 68 '''); |
61 | 69 |
62 /// A script tag that loads the .js code for a compiled library. | 70 /// A script tag that loads the .js code for a compiled library. |
63 Node _libraryInclude(String jsUrl) => | 71 Node _libraryInclude(String jsUrl) => |
64 parseFragment('<script src="$jsUrl"></script>\n'); | 72 parseFragment('<script src="$jsUrl"></script>\n'); |
65 | 73 |
66 /// A script tag that invokes the main function on the entry point library. | 74 /// A script tag that invokes the main function on the entry point library. |
67 Node _invokeMain(String mainLibraryName) => | 75 Node _invokeMain(String mainLibraryName) => |
68 parseFragment('<script>$mainLibraryName.main();</script>\n'); | 76 parseFragment('<script>$mainLibraryName.main();</script>\n'); |
69 | 77 |
70 /// A script tag with a tiny mock of the core SDK. This is just used for testing | 78 /// A script tag with a tiny mock of the core SDK. This is just used for testing |
71 /// some small samples. | 79 /// some small samples. |
72 // TODO(sigmund,jmesserly): remove. | 80 // TODO(sigmund,jmesserly): remove. |
73 Node get _miniMockSdk => parseFragment(''' | 81 Node get _miniMockSdk => parseFragment(''' |
74 <script> | 82 <script> |
75 /* placehorder for unimplemented code libraries */ | 83 /* placehorder for unimplemented code libraries */ |
76 var math = Math; | 84 var math = Math; |
77 var core = { int: { parse: Number }, print: e => console.log(e) }; | 85 var core = { int: { parse: Number }, print: e => console.log(e) }; |
78 var dom = { document: document }; | 86 var dom = { document: document }; |
79 </script>'''); | 87 </script>'''); |
88 final _log = new Logger('ddc.src.codegen.html_codegen'); | |
Jennifer Messerly
2015/03/03 02:24:21
dev_compiler?
Siggi Cherem (dart-lang)
2015/03/04 04:44:23
Good point - I'll send out a follow up CL with thi
| |
OLD | NEW |