Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /** Transfomer that inlines polymer-element definitions from html imports. */ | 5 /** Transfomer that inlines polymer-element definitions from html imports. */ |
| 6 library polymer.src.build.import_inliner; | 6 library polymer.src.build.import_inliner; |
| 7 | 7 |
| 8 import 'dart:async'; | 8 import 'dart:async'; |
| 9 import 'dart:convert'; | |
| 9 | 10 |
| 10 import 'package:barback/barback.dart'; | 11 import 'package:barback/barback.dart'; |
| 11 import 'package:path/path.dart' as path; | 12 import 'package:path/path.dart' as path; |
| 12 import 'package:html5lib/dom.dart' show Document, Node, DocumentFragment; | 13 import 'package:html5lib/dom.dart' show Document, Node, DocumentFragment; |
| 13 import 'package:html5lib/dom_parsing.dart' show TreeVisitor; | 14 import 'package:html5lib/dom_parsing.dart' show TreeVisitor; |
| 15 | |
| 16 import 'code_extractor.dart'; // import just for documentation. | |
| 14 import 'common.dart'; | 17 import 'common.dart'; |
| 15 | 18 |
| 16 /** Recursively inlines the contents of HTML imports. */ | 19 /** |
| 20 * Recursively inlines the contents of HTML imports. Produces as output a single | |
| 21 * HTML file that inlines the polymer-element definitions, and a text file that | |
| 22 * contains, in order, the URIs to each library that sourced in a script tag. | |
| 23 * | |
| 24 * This transformer assumes that all script tags point to external files. To | |
| 25 * support script tags with inlined code, use this transformer after running | |
| 26 * [InlineCodeExtractor] on an earlier phase. | |
| 27 */ | |
| 17 // TODO(sigmund): currently we just inline polymer-element and script tags, we | 28 // TODO(sigmund): currently we just inline polymer-element and script tags, we |
| 18 // need to make sure we match semantics of html-imports for other tags too. | 29 // need to make sure we match semantics of html-imports for other tags too. |
| 19 // (see dartbug.com/12613). | 30 // (see dartbug.com/12613). |
| 20 class ImportInliner extends Transformer with PolymerTransformer { | 31 class ImportInliner extends Transformer with PolymerTransformer { |
| 21 final TransformOptions options; | 32 final TransformOptions options; |
| 22 | 33 |
| 23 ImportInliner(this.options); | 34 ImportInliner(this.options); |
| 24 | 35 |
| 25 /** Only run on entry point .html files. */ | 36 /** Only run on entry point .html files. */ |
| 26 Future<bool> isPrimary(Asset input) => | 37 Future<bool> isPrimary(Asset input) => |
| 27 new Future.value(options.isHtmlEntryPoint(input.id)); | 38 new Future.value(options.isHtmlEntryPoint(input.id)); |
| 28 | 39 |
| 29 Future apply(Transform transform) { | 40 Future apply(Transform transform) { |
| 41 var logger = transform.logger; | |
| 30 var seen = new Set<AssetId>(); | 42 var seen = new Set<AssetId>(); |
| 31 var elements = []; | 43 var elements = []; |
| 32 var id = transform.primaryInput.id; | 44 var id = transform.primaryInput.id; |
| 33 seen.add(id); | 45 seen.add(id); |
| 34 return readPrimaryAsHtml(transform).then((document) { | 46 return readPrimaryAsHtml(transform).then((document) { |
| 35 var future = _visitImports(document, id, transform, seen, elements); | 47 var future = _visitImports(document, id, transform, seen, elements); |
| 36 return future.then((importsFound) { | 48 return future.then((importsFound) { |
| 49 // We produce a secondary asset with extra information for later phases. | |
| 50 var secondaryId = id.addExtension('.scriptUrls'); | |
| 37 if (!importsFound) { | 51 if (!importsFound) { |
| 38 transform.addOutput(transform.primaryInput); | 52 transform.addOutput(transform.primaryInput); |
| 53 transform.addOutput(new Asset.fromString(secondaryId, '[]')); | |
| 39 return; | 54 return; |
| 40 } | 55 } |
| 41 | 56 |
| 42 for (var tag in document.queryAll('link')) { | 57 for (var tag in document.queryAll('link')) { |
| 43 if (tag.attributes['rel'] == 'import') { | 58 if (tag.attributes['rel'] == 'import') { |
| 44 tag.remove(); | 59 tag.remove(); |
| 45 } | 60 } |
| 46 } | 61 } |
| 47 var fragment = new DocumentFragment()..nodes.addAll(elements); | 62 |
| 63 // Split Dart script tags from all the other elements | |
|
Jennifer Messerly
2013/10/19 00:15:47
maybe expand on the comment here about why we're d
Siggi Cherem (dart-lang)
2013/10/21 20:43:14
Done.
| |
| 64 var scripts = []; | |
| 65 var rest = []; | |
| 66 for (var e in elements) { | |
| 67 if (e.tagName == 'script' && | |
| 68 e.attributes['type'] == 'application/dart') { | |
| 69 scripts.add(e); | |
| 70 } else if (e.tagName == 'polymer-element') { | |
| 71 rest.add(e); | |
| 72 var script = e.query('script'); | |
| 73 if (script != null && | |
| 74 script.attributes['type'] == 'application/dart') { | |
| 75 script.remove(); | |
| 76 scripts.add(script); | |
| 77 } | |
| 78 } else { | |
| 79 rest.add(e); | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 var fragment = new DocumentFragment()..nodes.addAll(rest); | |
| 48 document.body.insertBefore(fragment, | 84 document.body.insertBefore(fragment, |
| 49 //TODO(jmesserly): add Node.firstChild to html5lib | 85 //TODO(jmesserly): add Node.firstChild to html5lib |
| 50 document.body.nodes.length == 0 ? null : document.body.nodes[0]); | 86 document.body.nodes.length == 0 ? null : document.body.nodes[0]); |
| 51 transform.addOutput(new Asset.fromString(id, document.outerHtml)); | 87 transform.addOutput(new Asset.fromString(id, document.outerHtml)); |
| 88 | |
| 89 var scriptIds = []; | |
| 90 for (var script in scripts) { | |
| 91 var src = script.attributes['src']; | |
| 92 if (src == null) { | |
| 93 logger.warning('unexpected script without a src url. The ' | |
| 94 'ImportInliner transformer should run after running the ' | |
| 95 'InlineCodeExtractor', script.sourceSpan); | |
| 96 continue; | |
| 97 } | |
| 98 scriptIds.add(resolve(id, src, logger, script.sourceSpan)); | |
| 99 } | |
| 100 transform.addOutput(new Asset.fromString(secondaryId, | |
| 101 JSON.encode(scriptIds, toEncodable: (id) => id.serialize()))); | |
| 52 }); | 102 }); |
| 53 }); | 103 }); |
| 54 } | 104 } |
| 55 | 105 |
| 56 /** | 106 /** |
| 57 * Visits imports in [document] and add their polymer-element and script tags | 107 * Visits imports in [document] and add their polymer-element and script tags |
| 58 * to [elements], unless they have already been [seen]. Elements are added in | 108 * to [elements], unless they have already been [seen]. Elements are added in |
| 59 * the order they appear, transitive imports are added first. | 109 * the order they appear, transitive imports are added first. |
| 60 */ | 110 */ |
| 61 Future<bool> _visitImports(Document document, AssetId sourceId, | 111 Future<bool> _visitImports(Document document, AssetId sourceId, |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 'cite', // in blockquote, del, ins, q | 227 'cite', // in blockquote, del, ins, q |
| 178 'data', // in object | 228 'data', // in object |
| 179 'formaction', // in button, input | 229 'formaction', // in button, input |
| 180 'href', // in a, area, link, base, command | 230 'href', // in a, area, link, base, command |
| 181 'icon', // in command | 231 'icon', // in command |
| 182 'manifest', // in html | 232 'manifest', // in html |
| 183 'poster', // in video | 233 'poster', // in video |
| 184 'src', // in audio, embed, iframe, img, input, script, source, track, | 234 'src', // in audio, embed, iframe, img, input, script, source, track, |
| 185 // video | 235 // video |
| 186 ]; | 236 ]; |
| OLD | NEW |