| 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 import 'dart:convert'; |
| 10 | 10 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 : transform = transform, | 33 : transform = transform, |
| 34 logger = transform.logger, | 34 logger = transform.logger, |
| 35 docId = transform.primaryInput.id; | 35 docId = transform.primaryInput.id; |
| 36 | 36 |
| 37 Future apply() { | 37 Future apply() { |
| 38 seen.add(docId); | 38 seen.add(docId); |
| 39 | 39 |
| 40 Document document; | 40 Document document; |
| 41 | 41 |
| 42 return readPrimaryAsHtml(transform).then((document) => | 42 return readPrimaryAsHtml(transform).then((document) => |
| 43 _visitImports(document, docId).then((importsFound) { | 43 _visitImports(document).then((importsFound) { |
| 44 | 44 |
| 45 var output = transform.primaryInput; | 45 var output = transform.primaryInput; |
| 46 if (importsFound) { | 46 if (importsFound) { |
| 47 output = new Asset.fromString(docId, document.outerHtml); | 47 output = new Asset.fromString(docId, document.outerHtml); |
| 48 } | 48 } |
| 49 transform.addOutput(output); | 49 transform.addOutput(output); |
| 50 | 50 |
| 51 // We produce a secondary asset with extra information for later phases. | 51 // We produce a secondary asset with extra information for later phases. |
| 52 transform.addOutput(new Asset.fromString( | 52 transform.addOutput(new Asset.fromString( |
| 53 docId.addExtension('.scriptUrls'), | 53 docId.addExtension('.scriptUrls'), |
| 54 JSON.encode(scriptIds, toEncodable: (id) => id.serialize()))); | 54 JSON.encode(scriptIds, toEncodable: (id) => id.serialize()))); |
| 55 })); | 55 })); |
| 56 } | 56 } |
| 57 | 57 |
| 58 /// Visits imports in [document] and add the imported documents to documents. | 58 /// Visits imports in [document] and add the imported documents to documents. |
| 59 /// Documents are added in the order they appear, transitive imports are added | 59 /// Documents are added in the order they appear, transitive imports are added |
| 60 /// first. | 60 /// first. |
| 61 /// | 61 /// |
| 62 /// Returns `true` if and only if the document was changed and should be | 62 /// Returns `true` if and only if the document was changed and should be |
| 63 /// written out. | 63 /// written out. |
| 64 Future<bool> _visitImports(Document document, AssetId sourceId) { | 64 Future<bool> _visitImports(Document document) { |
| 65 bool changed = false; | 65 bool changed = false; |
| 66 | 66 |
| 67 _moveHeadToBody(document); | 67 _moveHeadToBody(document); |
| 68 | 68 |
| 69 // Note: we need to preserve the import order in the generated output. | 69 // Note: we need to preserve the import order in the generated output. |
| 70 return Future.forEach(document.querySelectorAll('link'), (Element tag) { | 70 return Future.forEach(document.querySelectorAll('link'), (Element tag) { |
| 71 var rel = tag.attributes['rel']; | 71 var rel = tag.attributes['rel']; |
| 72 if (rel != 'import' && rel != 'stylesheet') return null; | 72 if (rel != 'import' && rel != 'stylesheet') return null; |
| 73 | 73 |
| 74 // Note: URL has already been normalized so use docId. |
| 74 var href = tag.attributes['href']; | 75 var href = tag.attributes['href']; |
| 75 var id = resolve(sourceId, href, transform.logger, tag.sourceSpan, | 76 var id = resolve(docId, href, transform.logger, tag.sourceSpan, |
| 76 allowAbsolute: rel == 'stylesheet'); | 77 allowAbsolute: rel == 'stylesheet'); |
| 77 | 78 |
| 78 if (rel == 'import') { | 79 if (rel == 'import') { |
| 79 changed = true; | 80 changed = true; |
| 80 if (id == null || !seen.add(id)) { | 81 if (id == null || !seen.add(id)) { |
| 81 tag.remove(); | 82 tag.remove(); |
| 82 return null; | 83 return null; |
| 83 } | 84 } |
| 84 return _inlineImport(id, tag); | 85 return _inlineImport(id, tag); |
| 85 | 86 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 100 /// respect to eachother, because stylesheets can be pulled in transitively | 101 /// respect to eachother, because stylesheets can be pulled in transitively |
| 101 /// from imports. | 102 /// from imports. |
| 102 // TODO(jmesserly): vulcanizer doesn't need this because they inline JS | 103 // TODO(jmesserly): vulcanizer doesn't need this because they inline JS |
| 103 // scripts, causing them to be naturally moved as part of the inlining. | 104 // scripts, causing them to be naturally moved as part of the inlining. |
| 104 // Should we do the same? Alternatively could we inline head into head and | 105 // Should we do the same? Alternatively could we inline head into head and |
| 105 // body into body and avoid this whole thing? | 106 // body into body and avoid this whole thing? |
| 106 void _moveHeadToBody(Document doc) { | 107 void _moveHeadToBody(Document doc) { |
| 107 var insertionPoint = doc.body.firstChild; | 108 var insertionPoint = doc.body.firstChild; |
| 108 for (var node in doc.head.nodes.toList(growable: false)) { | 109 for (var node in doc.head.nodes.toList(growable: false)) { |
| 109 if (node is! Element) continue; | 110 if (node is! Element) continue; |
| 110 var tag = node.tagName; | 111 var tag = node.localName; |
| 111 var type = node.attributes['type']; | 112 var type = node.attributes['type']; |
| 112 var rel = node.attributes['rel']; | 113 var rel = node.attributes['rel']; |
| 113 if (tag == 'style' || tag == 'script' && | 114 if (tag == 'style' || tag == 'script' && |
| 114 (type == null || type == TYPE_JS || type == TYPE_DART) || | 115 (type == null || type == TYPE_JS || type == TYPE_DART) || |
| 115 tag == 'link' && (rel == 'stylesheet' || rel == 'import')) { | 116 tag == 'link' && (rel == 'stylesheet' || rel == 'import')) { |
| 116 // Move the node into the body, where its contents will be placed. | 117 // Move the node into the body, where its contents will be placed. |
| 117 doc.body.insertBefore(node, insertionPoint); | 118 doc.body.insertBefore(node, insertionPoint); |
| 118 } | 119 } |
| 119 } | 120 } |
| 120 } | 121 } |
| 121 | 122 |
| 122 // Loads an asset identified by [id], visits its imports and collects its | 123 // Loads an asset identified by [id], visits its imports and collects its |
| 123 // html imports. Then inlines it into the main document. | 124 // html imports. Then inlines it into the main document. |
| 124 Future _inlineImport(AssetId id, Element link) => | 125 Future _inlineImport(AssetId id, Element link) { |
| 125 readAsHtml(id, transform).then((doc) => _visitImports(doc, id).then((_) { | 126 return readAsHtml(id, transform).then((doc) { |
| 127 new _UrlNormalizer(transform, id).visit(doc); |
| 128 return _visitImports(doc).then((_) { |
| 129 _extractScripts(doc); |
| 126 | 130 |
| 127 new _UrlNormalizer(transform, id).visit(doc); | 131 // TODO(jmesserly): figure out how this is working in vulcanizer. |
| 128 _extractScripts(doc); | 132 // Do they produce a <body> tag with a <head> and <body> inside? |
| 129 | 133 var imported = new DocumentFragment(); |
| 130 // TODO(jmesserly): figure out how this is working in vulcanizer. | 134 imported.nodes..addAll(doc.head.nodes)..addAll(doc.body.nodes); |
| 131 // Do they produce a <body> tag with a <head> and <body> inside? | 135 link.replaceWith(imported); |
| 132 var imported = new DocumentFragment(); | 136 }); |
| 133 imported.nodes..addAll(doc.head.nodes)..addAll(doc.body.nodes); | 137 }); |
| 134 link.replaceWith(imported); | 138 } |
| 135 })); | |
| 136 | 139 |
| 137 Future _inlineStylesheet(AssetId id, Element link) { | 140 Future _inlineStylesheet(AssetId id, Element link) { |
| 138 return transform.readInputAsString(id).then((css) { | 141 return transform.readInputAsString(id).then((css) { |
| 139 var url = spanUrlFor(id, transform); | 142 var url = spanUrlFor(id, transform); |
| 140 css = new _UrlNormalizer(transform, id).visitCss(css, url); | 143 css = new _UrlNormalizer(transform, id).visitCss(css, url); |
| 141 link.replaceWith(new Element.tag('style')..text = css); | 144 link.replaceWith(new Element.tag('style')..text = css); |
| 142 }); | 145 }); |
| 143 } | 146 } |
| 144 | 147 |
| 145 /// Split Dart script tags from all the other elements. Now that Dartium | 148 /// Split Dart script tags from all the other elements. Now that Dartium |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 'cite', // in blockquote, del, ins, q | 285 'cite', // in blockquote, del, ins, q |
| 283 'data', // in object | 286 'data', // in object |
| 284 'formaction', // in button, input | 287 'formaction', // in button, input |
| 285 'href', // in a, area, link, base, command | 288 'href', // in a, area, link, base, command |
| 286 'icon', // in command | 289 'icon', // in command |
| 287 'manifest', // in html | 290 'manifest', // in html |
| 288 'poster', // in video | 291 'poster', // in video |
| 289 'src', // in audio, embed, iframe, img, input, script, source, track, | 292 'src', // in audio, embed, iframe, img, input, script, source, track, |
| 290 // video | 293 // video |
| 291 ]; | 294 ]; |
| OLD | NEW |