Chromium Code Reviews| Index: pkg/polymer/lib/src/build/import_inliner.dart | 
| diff --git a/pkg/polymer/lib/src/build/import_inliner.dart b/pkg/polymer/lib/src/build/import_inliner.dart | 
| index 126dc1ec0f88dd383b2f30f3c0f924966b42f907..8d55760b3bf31835fd20349a8fce846e7e2586e2 100644 | 
| --- a/pkg/polymer/lib/src/build/import_inliner.dart | 
| +++ b/pkg/polymer/lib/src/build/import_inliner.dart | 
| @@ -13,7 +13,7 @@ import 'package:path/path.dart' as path; | 
| import 'package:html5lib/dom.dart' show | 
| Document, DocumentFragment, Element, Node; | 
| import 'package:html5lib/dom_parsing.dart' show TreeVisitor; | 
| -import 'package:source_maps/span.dart' show Span; | 
| +import 'package:source_maps/span.dart'; | 
| import 'code_extractor.dart'; // import just for documentation. | 
| import 'common.dart'; | 
| @@ -55,26 +55,39 @@ class _HtmlInliner extends PolymerTransformer { | 
| } | 
| /** | 
| - * Visits imports in [document] and add the imported documents to [documents]. | 
| + * Visits imports in [document] and add the imported documents to documents. | 
| * Documents are added in the order they appear, transitive imports are added | 
| * first. | 
| + * | 
| + * Returns `true` if and only if the document was changed and should be | 
| + * written out. | 
| */ | 
| Future<bool> _visitImports(Document document, AssetId sourceId) { | 
| - bool hasImports = false; | 
| + bool changed = false; | 
| // Note: we need to preserve the import order in the generated output. | 
| return Future.forEach(document.querySelectorAll('link'), (Element tag) { | 
| - if (tag.attributes['rel'] != 'import') return null; | 
| + var rel = tag.attributes['rel']; | 
| + if (rel != 'import' && rel != 'stylesheet') return null; | 
| + | 
| var href = tag.attributes['href']; | 
| - var id = resolve(sourceId, href, transform.logger, tag.sourceSpan); | 
| - hasImports = true; | 
| + var id = resolve(sourceId, href, transform.logger, tag.sourceSpan, | 
| + allowAbsolute: rel == 'stylesheet'); | 
| + | 
| + if (rel == 'import') { | 
| + changed = true; | 
| + tag.remove(); | 
| + if (id == null || !seen.add(id) || | 
| + (id.package == 'polymer' && id.path == 'lib/init.html')) return null; | 
| 
 
Siggi Cherem (dart-lang)
2014/02/13 00:08:18
80 :-(
 
Jennifer Messerly
2014/02/13 06:12:52
oops, missed this. fixed.
out of curiosity, why t
 
Siggi Cherem (dart-lang)
2014/02/13 17:46:33
Oh, this was from some old bootstrap we used to ha
 
Jennifer Messerly
2014/02/13 20:43:45
awesome. done!
 
 | 
| - tag.remove(); | 
| - if (id == null || !seen.add(id) || | 
| - (id.package == 'polymer' && id.path == 'lib/init.html')) return null; | 
| + return _inlineImport(id); | 
| - return _inlineImport(id); | 
| - }).then((_) => hasImports); | 
| + } else if (rel == 'stylesheet') { | 
| + if (id == null) return null; | 
| + changed = true; | 
| + return _inlineStylesheet(id, tag); | 
| + } | 
| + }).then((_) => changed); | 
| } | 
| // Loads an asset identified by [id], visits its imports and collects its | 
| @@ -87,11 +100,16 @@ class _HtmlInliner extends PolymerTransformer { | 
| // TODO(jmesserly): figure out how this is working in vulcanizer. | 
| // Do they produce a <body> tag with a <head> and <body> inside? | 
| - imported.nodes | 
| - ..addAll(doc.head.nodes) | 
| - ..addAll(doc.body.nodes); | 
| + imported.nodes..addAll(doc.head.nodes)..addAll(doc.body.nodes); | 
| })); | 
| + Future _inlineStylesheet(AssetId id, Element link) => | 
| 
 
Siggi Cherem (dart-lang)
2014/02/13 00:08:18
the formatting mixing => + then below is a bit odd
 
Jennifer Messerly
2014/02/13 06:11:22
okay, I'll change this one. But, I'm think we shou
 
 | 
| + readAsString(id, transform).then((css) { | 
| + | 
| + css = new _UrlNormalizer(transform, id).visitCss(css); | 
| + link.replaceWith(new Element.tag('style')..text = css); | 
| + }); | 
| + | 
| /** | 
| * Split Dart script tags from all the other elements. Now that Dartium | 
| * only allows a single script tag per page, we can't inline script | 
| @@ -172,6 +190,25 @@ class _UrlNormalizer extends TreeVisitor { | 
| super.visitElement(node); | 
| } | 
| + static final _URL = new RegExp(r'url\(([^)]*)\)', multiLine: true); | 
| + static final _QUOTE = new RegExp('["\']', multiLine: true); | 
| + | 
| + /** Visit the CSS text and replace any relative URLs so we can inline it. */ | 
| + // Ported from: | 
| + // https://github.com/Polymer/vulcanize/blob/c14f63696797cda18dc3d372b78aa3378acc691f/lib/vulcan.js#L149 | 
| + // TODO(jmesserly): use csslib here instead? Parsing with RegEx is sadness. | 
| + // Maybe it's reliable enough for finding URLs in CSS? I'm not sure. | 
| + String visitCss(String cssText) { | 
| + var src = new SourceFile.text(sourceId.path, cssText); | 
| + return cssText.replaceAllMapped(_URL, (match) { | 
| + // Extract the URL, without any surrounding quotes. | 
| + var span = src.span(match.start, match.end); | 
| + var href = match[1].replaceAll(_QUOTE, ''); | 
| + href = _newUrl(href, span); | 
| + return 'url($href)'; | 
| + }); | 
| + } | 
| + | 
| _newUrl(String href, Span span) { | 
| var uri = Uri.parse(href); | 
| if (uri.isAbsolute) return href; |