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 27 matching lines...) Expand all Loading... |
38 | 38 |
39 _HtmlInliner(this.options, Transform transform) | 39 _HtmlInliner(this.options, Transform transform) |
40 : transform = transform, | 40 : transform = transform, |
41 logger = transform.logger, | 41 logger = transform.logger, |
42 docId = transform.primaryInput.id; | 42 docId = transform.primaryInput.id; |
43 | 43 |
44 Future apply() { | 44 Future apply() { |
45 seen.add(docId); | 45 seen.add(docId); |
46 | 46 |
47 Document document; | 47 Document document; |
48 bool changed; | 48 bool changed = false; |
49 | 49 |
50 return readPrimaryAsHtml(transform).then((doc) { | 50 return readPrimaryAsHtml(transform).then((doc) { |
51 document = doc; | 51 document = doc; |
| 52 changed = new _UrlNormalizer(transform, docId).visit(document) || changed; |
| 53 |
52 experimentalBootstrap = document.querySelectorAll('link').any((link) => | 54 experimentalBootstrap = document.querySelectorAll('link').any((link) => |
53 link.attributes['rel'] == 'import' && | 55 link.attributes['rel'] == 'import' && |
54 link.attributes['href'] == POLYMER_EXPERIMENTAL_HTML); | 56 link.attributes['href'] == POLYMER_EXPERIMENTAL_HTML); |
55 changed = _extractScripts(document); | 57 changed = _extractScripts(document) || changed; |
56 return _visitImports(document); | 58 return _visitImports(document); |
57 }).then((importsFound) { | 59 }).then((importsFound) { |
58 changed = changed || importsFound; | 60 changed = changed || importsFound; |
59 return _removeScripts(document); | 61 return _removeScripts(document); |
60 }).then((scriptsRemoved) { | 62 }).then((scriptsRemoved) { |
61 changed = changed || scriptsRemoved; | 63 changed = changed || scriptsRemoved; |
62 | 64 |
63 var output = transform.primaryInput; | 65 var output = transform.primaryInput; |
64 if (changed) output = new Asset.fromString(docId, document.outerHtml); | 66 if (changed) output = new Asset.fromString(docId, document.outerHtml); |
65 transform.addOutput(output); | 67 transform.addOutput(output); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
295 /// Asset where the original content (and original url) was found. | 297 /// Asset where the original content (and original url) was found. |
296 final AssetId sourceId; | 298 final AssetId sourceId; |
297 | 299 |
298 /// Counter used to ensure that every library name we inject is unique. | 300 /// Counter used to ensure that every library name we inject is unique. |
299 int _count = 0; | 301 int _count = 0; |
300 | 302 |
301 /// Path to the top level folder relative to the transform primaryInput. | 303 /// Path to the top level folder relative to the transform primaryInput. |
302 /// This should just be some arbitrary # of ../'s. | 304 /// This should just be some arbitrary # of ../'s. |
303 final String topLevelPath; | 305 final String topLevelPath; |
304 | 306 |
| 307 /// Whether or not the normalizer has changed something in the tree. |
| 308 bool changed = false; |
| 309 |
305 _UrlNormalizer(transform, this.sourceId) | 310 _UrlNormalizer(transform, this.sourceId) |
306 : transform = transform, | 311 : transform = transform, |
307 topLevelPath = | 312 topLevelPath = |
308 '../' * (transform.primaryInput.id.path.split('/').length - 2); | 313 '../' * (transform.primaryInput.id.path.split('/').length - 2); |
309 | 314 |
| 315 visit(Element node) { |
| 316 super.visit(node); |
| 317 return changed; |
| 318 } |
| 319 |
310 visitElement(Element node) { | 320 visitElement(Element node) { |
311 // TODO(jakemac): Support custom elements that extend html elements which | 321 // TODO(jakemac): Support custom elements that extend html elements which |
312 // have url-like attributes. This probably means keeping a list of which | 322 // have url-like attributes. This probably means keeping a list of which |
313 // html elements support each url-like attribute. | 323 // html elements support each url-like attribute. |
314 if (!isCustomTagName(node.localName)) { | 324 if (!isCustomTagName(node.localName)) { |
315 node.attributes.forEach((name, value) { | 325 node.attributes.forEach((name, value) { |
316 if (_urlAttributes.contains(name)) { | 326 if (_urlAttributes.contains(name)) { |
317 if (value != '' && !value.trim().startsWith('{{')) { | 327 if (value != '' && !value.trim().startsWith('{{')) { |
318 node.attributes[name] = _newUrl(value, node.sourceSpan); | 328 node.attributes[name] = _newUrl(value, node.sourceSpan); |
| 329 changed = changed || value != node.attributes[name]; |
319 } | 330 } |
320 } | 331 } |
321 }); | 332 }); |
322 } | 333 } |
323 if (node.localName == 'style') { | 334 if (node.localName == 'style') { |
324 node.text = visitCss(node.text); | 335 node.text = visitCss(node.text); |
| 336 changed = true; |
325 } else if (node.localName == 'script' && | 337 } else if (node.localName == 'script' && |
326 node.attributes['type'] == TYPE_DART && | 338 node.attributes['type'] == TYPE_DART && |
327 !node.attributes.containsKey('src')) { | 339 !node.attributes.containsKey('src')) { |
328 // TODO(jmesserly): we might need to visit JS too to handle ES Harmony | 340 // TODO(jmesserly): we might need to visit JS too to handle ES Harmony |
329 // modules. | 341 // modules. |
330 node.text = visitInlineDart(node.text); | 342 node.text = visitInlineDart(node.text); |
| 343 changed = true; |
331 } | 344 } |
332 super.visitElement(node); | 345 return super.visitElement(node); |
333 } | 346 } |
334 | 347 |
335 static final _URL = new RegExp(r'url\(([^)]*)\)', multiLine: true); | 348 static final _URL = new RegExp(r'url\(([^)]*)\)', multiLine: true); |
336 static final _QUOTE = new RegExp('["\']', multiLine: true); | 349 static final _QUOTE = new RegExp('["\']', multiLine: true); |
337 | 350 |
338 /// Visit the CSS text and replace any relative URLs so we can inline it. | 351 /// Visit the CSS text and replace any relative URLs so we can inline it. |
339 // Ported from: | 352 // Ported from: |
340 // https://github.com/Polymer/vulcanize/blob/c14f63696797cda18dc3d372b78aa3378
acc691f/lib/vulcan.js#L149 | 353 // https://github.com/Polymer/vulcanize/blob/c14f63696797cda18dc3d372b78aa3378
acc691f/lib/vulcan.js#L149 |
341 // TODO(jmesserly): use csslib here instead? Parsing with RegEx is sadness. | 354 // TODO(jmesserly): use csslib here instead? Parsing with RegEx is sadness. |
342 // Maybe it's reliable enough for finding URLs in CSS? I'm not sure. | 355 // Maybe it's reliable enough for finding URLs in CSS? I'm not sure. |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 /// When inlining <link rel="stylesheet"> tags copy over all attributes to the | 457 /// When inlining <link rel="stylesheet"> tags copy over all attributes to the |
445 /// style tag except these ones. | 458 /// style tag except these ones. |
446 const IGNORED_LINKED_STYLE_ATTRS = | 459 const IGNORED_LINKED_STYLE_ATTRS = |
447 const ['charset', 'href', 'href-lang', 'rel', 'rev']; | 460 const ['charset', 'href', 'href-lang', 'rel', 'rev']; |
448 | 461 |
449 /// Global RegExp objects for validating generated library names. | 462 /// Global RegExp objects for validating generated library names. |
450 final INVALID_LIB_CHARS_REGEX = new RegExp('[^a-z0-9_]'); | 463 final INVALID_LIB_CHARS_REGEX = new RegExp('[^a-z0-9_]'); |
451 final NUM_REGEX = new RegExp('[0-9]'); | 464 final NUM_REGEX = new RegExp('[0-9]'); |
452 | 465 |
453 _getSpan(SourceFile file, AstNode node) => file.span(node.offset, node.end); | 466 _getSpan(SourceFile file, AstNode node) => file.span(node.offset, node.end); |
OLD | NEW |