Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Unified Diff: pkg/polymer/lib/src/build/import_inliner.dart

Issue 159353005: code refactoring in import_inliner (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: moar refactoring Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 a66d1bbc84176faefcc440d0c9f6772617128ed3..126dc1ec0f88dd383b2f30f3c0f924966b42f907 100644
--- a/pkg/polymer/lib/src/build/import_inliner.dart
+++ b/pkg/polymer/lib/src/build/import_inliner.dart
@@ -18,81 +18,96 @@ import 'package:source_maps/span.dart' show Span;
import 'code_extractor.dart'; // import just for documentation.
import 'common.dart';
-/**
- * Recursively inlines the contents of HTML imports. Produces as output a single
- * HTML file that inlines the polymer-element definitions, and a text file that
- * contains, in order, the URIs to each library that sourced in a script tag.
- *
- * This transformer assumes that all script tags point to external files. To
- * support script tags with inlined code, use this transformer after running
- * [InlineCodeExtractor] on an earlier phase.
- */
-class ImportInliner extends Transformer with PolymerTransformer {
+class _HtmlInliner extends PolymerTransformer {
final TransformOptions options;
+ final Transform transform;
+ final TransformLogger logger;
+ final AssetId docId;
+ final seen = new Set<AssetId>();
+ final imported = new DocumentFragment();
+ final scriptIds = <AssetId>[];
+
+ _HtmlInliner(this.options, Transform transform)
+ : transform = transform,
+ logger = transform.logger,
+ docId = transform.primaryInput.id;
+
+ Future apply() {
+ seen.add(docId);
+
+ Document document;
+
+ return readPrimaryAsHtml(transform).then((document) =>
+ _visitImports(document, docId).then((importsFound) {
+
+ if (importsFound) {
+ document.body.insertBefore(imported, document.body.firstChild);
+ transform.addOutput(new Asset.fromString(docId, document.outerHtml));
+ } else {
+ transform.addOutput(transform.primaryInput);
+ }
- ImportInliner(this.options);
+ // We produce a secondary asset with extra information for later phases.
+ transform.addOutput(new Asset.fromString(
+ docId.addExtension('.scriptUrls'),
+ JSON.encode(scriptIds, toEncodable: (id) => id.serialize())));
+ }));
+ }
- /** Only run on entry point .html files. */
- Future<bool> isPrimary(Asset input) =>
- new Future.value(options.isHtmlEntryPoint(input.id));
+ /**
+ * Visits imports in [document] and add the imported documents to [documents].
+ * Documents are added in the order they appear, transitive imports are added
+ * first.
+ */
+ Future<bool> _visitImports(Document document, AssetId sourceId) {
+ bool hasImports = false;
- Future apply(Transform transform) {
- var logger = transform.logger;
- var seen = new Set<AssetId>();
- var documents = [];
- var id = transform.primaryInput.id;
- seen.add(id);
- return readPrimaryAsHtml(transform).then((document) {
- var future = _visitImports(document, id, transform, seen, documents);
- return future.then((importsFound) {
- // We produce a secondary asset with extra information for later phases.
- var secondaryId = id.addExtension('.scriptUrls');
- if (!importsFound) {
- transform.addOutput(transform.primaryInput);
- transform.addOutput(new Asset.fromString(secondaryId, '[]'));
- return;
- }
+ // 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 href = tag.attributes['href'];
+ var id = resolve(sourceId, href, transform.logger, tag.sourceSpan);
+ hasImports = true;
- // 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
- // tags. Instead, we collect the urls of each script tag so we import
- // them directly from the Dart bootstrap code.
- var scripts = [];
-
- var fragment = new DocumentFragment();
- for (var importedDoc in documents) {
- bool first = true;
- for (var e in importedDoc.queryAll('script')) {
- if (e.attributes['type'] == 'application/dart') {
- e.remove();
-
- // only one Dart script per document is supported in Dartium.
- if (first) {
- first = false;
- scripts.add(e);
- } else {
- // TODO(jmesserly): remove this when we are running linter.
- logger.warning('more than one Dart script per HTML document is '
- 'not supported. Script will be ignored.',
- span: e.sourceSpan);
- }
- }
- }
+ tag.remove();
+ if (id == null || !seen.add(id) ||
+ (id.package == 'polymer' && id.path == 'lib/init.html')) return null;
- // TODO(jmesserly): should we merge the head too?
- fragment.nodes.addAll(importedDoc.body.nodes);
- }
+ return _inlineImport(id);
+ }).then((_) => hasImports);
+ }
- document.body.insertBefore(fragment, document.body.firstChild);
+ // Loads an asset identified by [id], visits its imports and collects its
+ // html imports. Then inlines it into the main document.
+ Future _inlineImport(AssetId id) =>
+ readAsHtml(id, transform).then((doc) => _visitImports(doc, id).then((_) {
- for (var tag in document.queryAll('link')) {
- if (tag.attributes['rel'] == 'import') tag.remove();
- }
+ new _UrlNormalizer(transform, id).visit(doc);
+ _extractScripts(doc);
+
+ // 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);
+ }));
+
+ /**
+ * 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
+ * tags. Instead, we collect the urls of each script tag so we import
+ * them directly from the Dart bootstrap code.
+ */
+ void _extractScripts(Document document) {
+ bool first = true;
+ for (var script in document.querySelectorAll('script')) {
+ if (script.attributes['type'] == 'application/dart') {
+ script.remove();
- transform.addOutput(new Asset.fromString(id, document.outerHtml));
+ // only one Dart script per document is supported in Dartium.
+ if (first) {
+ first = false;
- var scriptIds = [];
- for (var script in scripts) {
var src = script.attributes['src'];
if (src == null) {
logger.warning('unexpected script without a src url. The '
@@ -100,58 +115,42 @@ class ImportInliner extends Transformer with PolymerTransformer {
'InlineCodeExtractor', span: script.sourceSpan);
continue;
}
- scriptIds.add(resolve(id, src, logger, script.sourceSpan));
+ scriptIds.add(resolve(docId, src, logger, script.sourceSpan));
+
+ } else {
+ // TODO(jmesserly): remove this when we are running linter.
+ logger.warning('more than one Dart script per HTML '
+ 'document is not supported. Script will be ignored.',
+ span: script.sourceSpan);
}
- transform.addOutput(new Asset.fromString(secondaryId,
- JSON.encode(scriptIds, toEncodable: (id) => id.serialize())));
- });
- });
+ }
+ }
}
+}
- /**
- * Visits imports in [document] and add their polymer-element and script tags
- * to [elements], unless they have already been [seen]. Elements are added in
- * the order they appear, transitive imports are added first.
- */
- Future<bool> _visitImports(Document document, AssetId sourceId,
- Transform transform, Set<AssetId> seen, List<Document> documents) {
- var importIds = [];
- bool hasImports = false;
- for (var tag in document.queryAll('link')) {
- if (tag.attributes['rel'] != 'import') continue;
- var href = tag.attributes['href'];
- var id = resolve(sourceId, href, transform.logger, tag.sourceSpan);
- hasImports = true;
- if (id == null || seen.contains(id) ||
- (id.package == 'polymer' && id.path == 'lib/init.html')) continue;
- importIds.add(id);
- }
+/**
+ * Recursively inlines the contents of HTML imports. Produces as output a single
+ * HTML file that inlines the polymer-element definitions, and a text file that
+ * contains, in order, the URIs to each library that sourced in a script tag.
+ *
+ * This transformer assumes that all script tags point to external files. To
+ * support script tags with inlined code, use this transformer after running
+ * [InlineCodeExtractor] on an earlier phase.
+ */
+class ImportInliner extends Transformer {
+ final TransformOptions options;
- if (importIds.isEmpty) return new Future.value(hasImports);
+ ImportInliner(this.options);
- // Note: we need to preserve the import order in the generated output.
- return Future.forEach(importIds, (id) {
- if (seen.contains(id)) return new Future.value(null);
- seen.add(id);
- return _collectImportedDocuments(id, transform, seen, documents);
- }).then((_) => true);
- }
+ /** Only run on entry point .html files. */
+ Future<bool> isPrimary(Asset input) =>
+ new Future.value(options.isHtmlEntryPoint(input.id));
- /**
- * Loads an asset identified by [id], visits its imports and collects it's
- * polymer-element definitions and script tags.
- */
- Future _collectImportedDocuments(AssetId id, Transform transform,
- Set<AssetId> seen, List documents) {
- return readAsHtml(id, transform).then((document) {
- return _visitImports(document, id, transform, seen, documents).then((_) {
- new _UrlNormalizer(transform, id).visit(document);
- documents.add(document);
- });
- });
- }
+ Future apply(Transform transform) =>
+ new _HtmlInliner(options, transform).apply();
}
+
/** Internally adjusts urls in the html that we are about to inline. */
class _UrlNormalizer extends TreeVisitor {
final Transform transform;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698