| 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 10 matching lines...) Expand all Loading... |
| 21 import 'common.dart'; | 21 import 'common.dart'; |
| 22 | 22 |
| 23 // TODO(sigmund): move to web_components package (dartbug.com/18037). | 23 // TODO(sigmund): move to web_components package (dartbug.com/18037). |
| 24 class _HtmlInliner extends PolymerTransformer { | 24 class _HtmlInliner extends PolymerTransformer { |
| 25 final TransformOptions options; | 25 final TransformOptions options; |
| 26 final Transform transform; | 26 final Transform transform; |
| 27 final TransformLogger logger; | 27 final TransformLogger logger; |
| 28 final AssetId docId; | 28 final AssetId docId; |
| 29 final seen = new Set<AssetId>(); | 29 final seen = new Set<AssetId>(); |
| 30 final scriptIds = <AssetId>[]; | 30 final scriptIds = <AssetId>[]; |
| 31 final extractedFiles = new Set<AssetId>(); |
| 31 | 32 |
| 32 /// The number of extracted inline Dart scripts. Used as a counter to give | 33 /// The number of extracted inline Dart scripts. Used as a counter to give |
| 33 /// unique-ish filenames. | 34 /// unique-ish filenames. |
| 34 int inlineScriptCounter = 0; | 35 int inlineScriptCounter = 0; |
| 35 | 36 |
| 36 _HtmlInliner(this.options, Transform transform) | 37 _HtmlInliner(this.options, Transform transform) |
| 37 : transform = transform, | 38 : transform = transform, |
| 38 logger = transform.logger, | 39 logger = transform.logger, |
| 39 docId = transform.primaryInput.id; | 40 docId = transform.primaryInput.id; |
| 40 | 41 |
| 41 Future apply() { | 42 Future apply() { |
| 42 seen.add(docId); | 43 seen.add(docId); |
| 43 | 44 |
| 44 Document document; | 45 Document document; |
| 45 bool changed; | 46 bool changed; |
| 46 | 47 |
| 47 return readPrimaryAsHtml(transform).then((doc) { | 48 return readPrimaryAsHtml(transform).then((doc) { |
| 48 document = doc; | 49 document = doc; |
| 49 // Add the main script's ID, or null if none is present. | 50 // Add the main script's ID, or null if none is present. |
| 50 // This will be used by ScriptCompactor. | 51 // This will be used by ScriptCompactor. |
| 51 changed = _extractScripts(document, docId); | 52 changed = _extractScripts(document, docId); |
| 52 return _visitImports(document); | 53 return _visitImports(document); |
| 53 }).then((importsFound) { | 54 }).then((importsFound) { |
| 54 bool scriptsRemoved = _removeScripts(document); | 55 changed = changed || importsFound; |
| 55 changed = changed || importsFound || scriptsRemoved; | 56 return _removeScripts(document); |
| 57 }).then((scriptsRemoved) { |
| 58 changed = changed || scriptsRemoved; |
| 56 | 59 |
| 57 var output = transform.primaryInput; | 60 var output = transform.primaryInput; |
| 58 if (changed) output = new Asset.fromString(docId, document.outerHtml); | 61 if (changed) output = new Asset.fromString(docId, document.outerHtml); |
| 59 transform.addOutput(output); | 62 transform.addOutput(output); |
| 60 | 63 |
| 61 // We produce a secondary asset with extra information for later phases. | 64 // We produce a secondary asset with extra information for later phases. |
| 62 transform.addOutput(new Asset.fromString( | 65 transform.addOutput(new Asset.fromString( |
| 63 docId.addExtension('.scriptUrls'), | 66 docId.addExtension('.scriptUrls'), |
| 64 JSON.encode(scriptIds, toEncodable: (id) => id.serialize()))); | 67 JSON.encode(scriptIds, toEncodable: (id) => id.serialize()))); |
| 65 }); | 68 }); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 css = new _UrlNormalizer(transform, id).visitCss(css); | 156 css = new _UrlNormalizer(transform, id).visitCss(css); |
| 154 link.replaceWith(new Element.tag('style')..text = css); | 157 link.replaceWith(new Element.tag('style')..text = css); |
| 155 }); | 158 }); |
| 156 } | 159 } |
| 157 | 160 |
| 158 /// Remove "application/dart;component=1" scripts and remember their | 161 /// Remove "application/dart;component=1" scripts and remember their |
| 159 /// [AssetId]s for later use. | 162 /// [AssetId]s for later use. |
| 160 /// | 163 /// |
| 161 /// Dartium only allows a single script tag per page, so we can't inline | 164 /// Dartium only allows a single script tag per page, so we can't inline |
| 162 /// the script tags. Instead we remove them entirely. | 165 /// the script tags. Instead we remove them entirely. |
| 163 bool _removeScripts(Document doc) { | 166 Future<bool> _removeScripts(Document doc) { |
| 164 bool changed = false; | 167 bool changed = false; |
| 165 for (var script in doc.querySelectorAll('script')) { | 168 return Future.forEach(doc.querySelectorAll('script'), (script) { |
| 166 if (script.attributes['type'] == TYPE_DART_COMPONENT) { | 169 if (script.attributes['type'] == TYPE_DART_COMPONENT) { |
| 167 changed = true; | 170 changed = true; |
| 168 script.remove(); | 171 script.remove(); |
| 169 var src = script.attributes['src']; | 172 var src = script.attributes['src']; |
| 170 scriptIds.add(uriToAssetId(docId, src, logger, script.sourceSpan)); | 173 var srcId = uriToAssetId(docId, src, logger, script.sourceSpan); |
| 174 |
| 175 // We check for extractedFiles because 'hasInput' below is only true for |
| 176 // assets that existed before this transformer runs (hasInput is false |
| 177 // for files created by [_extractScripts]). |
| 178 if (extractedFiles.contains(srcId)) { |
| 179 scriptIds.add(srcId); |
| 180 return true; |
| 181 } |
| 182 return transform.hasInput(srcId).then((exists) { |
| 183 if (!exists) { |
| 184 logger.warning('Script file at "$src" not found.', |
| 185 span: script.sourceSpan); |
| 186 } else { |
| 187 scriptIds.add(srcId); |
| 188 } |
| 189 }); |
| 171 } | 190 } |
| 172 } | 191 }).then((_) => changed); |
| 173 return changed; | |
| 174 } | 192 } |
| 175 | 193 |
| 176 /// Split inline scripts into their own files. We need to do this for dart2js | 194 /// Split inline scripts into their own files. We need to do this for dart2js |
| 177 /// to be able to compile them. | 195 /// to be able to compile them. |
| 178 /// | 196 /// |
| 179 /// This also validates that there weren't any duplicate scripts. | 197 /// This also validates that there weren't any duplicate scripts. |
| 180 bool _extractScripts(Document doc, AssetId sourceId) { | 198 bool _extractScripts(Document doc, AssetId sourceId) { |
| 181 bool changed = false; | 199 bool changed = false; |
| 182 bool first = true; | 200 bool first = true; |
| 183 for (var script in doc.querySelectorAll('script')) { | 201 for (var script in doc.querySelectorAll('script')) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 212 // myPkgName|web/foo/bar.html -> myPkgName.web.foo.bar_html | 230 // myPkgName|web/foo/bar.html -> myPkgName.web.foo.bar_html |
| 213 // This should roughly match the recommended library name conventions. | 231 // This should roughly match the recommended library name conventions. |
| 214 var libName = '${path.withoutExtension(sourceId.path)}_' | 232 var libName = '${path.withoutExtension(sourceId.path)}_' |
| 215 '${path.extension(sourceId.path).substring(1)}'; | 233 '${path.extension(sourceId.path).substring(1)}'; |
| 216 if (libName.startsWith('lib/')) libName = libName.substring(4); | 234 if (libName.startsWith('lib/')) libName = libName.substring(4); |
| 217 libName = libName.replaceAll('/', '.').replaceAll('-', '_'); | 235 libName = libName.replaceAll('/', '.').replaceAll('-', '_'); |
| 218 libName = '${sourceId.package}.${libName}_$count'; | 236 libName = '${sourceId.package}.${libName}_$count'; |
| 219 | 237 |
| 220 code = "library $libName;\n$code"; | 238 code = "library $libName;\n$code"; |
| 221 } | 239 } |
| 240 extractedFiles.add(newId); |
| 222 transform.addOutput(new Asset.fromString(newId, code)); | 241 transform.addOutput(new Asset.fromString(newId, code)); |
| 223 } | 242 } |
| 224 return changed; | 243 return changed; |
| 225 } | 244 } |
| 226 } | 245 } |
| 227 | 246 |
| 228 /// Parse [code] and determine whether it has a library directive. | 247 /// Parse [code] and determine whether it has a library directive. |
| 229 bool _hasLibraryDirective(String code) => | 248 bool _hasLibraryDirective(String code) => |
| 230 parseCompilationUnit(code).directives.any((d) => d is LibraryDirective); | 249 parseCompilationUnit(code).directives.any((d) => d is LibraryDirective); |
| 231 | 250 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 ]; | 410 ]; |
| 392 | 411 |
| 393 _getSpan(SourceFile file, AstNode node) => file.span(node.offset, node.end); | 412 _getSpan(SourceFile file, AstNode node) => file.span(node.offset, node.end); |
| 394 | 413 |
| 395 const COMPONENT_WARNING = | 414 const COMPONENT_WARNING = |
| 396 'More than one Dart script per HTML document is not supported, but in the ' | 415 'More than one Dart script per HTML document is not supported, but in the ' |
| 397 'near future Dartium will execute each tag as a separate isolate. If this ' | 416 'near future Dartium will execute each tag as a separate isolate. If this ' |
| 398 'code is meant to load definitions that are part of the same application ' | 417 'code is meant to load definitions that are part of the same application ' |
| 399 'you should switch it to use the "application/dart;component=1" mime-type ' | 418 'you should switch it to use the "application/dart;component=1" mime-type ' |
| 400 'instead.'; | 419 'instead.'; |
| OLD | NEW |