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

Unified Diff: lib/build/html_import_annotation_inliner.dart

Issue 882823003: Adds @HtmlImport with both dynamic and transformer based implementations. Still need an HtmlInliner… (Closed) Base URL: git@github.com:dart-lang/web-components.git@master
Patch Set: assign logger Created 5 years, 11 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
Index: lib/build/html_import_annotation_inliner.dart
diff --git a/lib/build/html_import_annotation_inliner.dart b/lib/build/html_import_annotation_inliner.dart
new file mode 100644
index 0000000000000000000000000000000000000000..f8ffaa273b8be8d577b04b39598f04cebee59c7f
--- /dev/null
+++ b/lib/build/html_import_annotation_inliner.dart
@@ -0,0 +1,124 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+library web_components.build.html_import_annotation_inliner;
+
+import 'dart:async';
+import 'package:analyzer/analyzer.dart';
+import 'package:barback/barback.dart';
+import 'package:html5lib/dom.dart' as dom;
+import 'package:html5lib/parser.dart';
+import 'package:initialize/plugin_transformer.dart';
+import 'package:source_maps/refactor.dart';
+import '../src/normalize_path.dart';
+
+/// Given an html entry point with a single dart bootstrap file created by the
+/// `initialize` transformer, this will open that dart file and remove all
+/// `HtmlImport` initializers from it. Then it appends those imports to the head
+/// of the html entry point.
+/// Notes: Does not inline the import, it just puts the <link rel="import"> tag.
+/// This also has a few limitations, it only supports string literals (to avoid
+/// using the analyzer to resolve references) and doesn't support const
+/// references to HtmlImport annotations (for the same reason).
+class HtmlImportAnnotationInliner extends InitializePluginTransformer {
+ final String _bootstrapFile;
+ final String _htmlEntryPoint;
+ TransformLogger _logger;
+ final Set<String> importPaths = new Set();
+
+ HtmlImportAnnotationInliner(String bootstrapFile, this._htmlEntryPoint)
+ : super(bootstrapFile),
+ _bootstrapFile = bootstrapFile;
+
+ factory HtmlImportAnnotationInliner.asPlugin(BarbackSettings settings) {
+ var bootstrapFile = settings.configuration['bootstrap_file'];
+ if (bootstrapFile is! String || !bootstrapFile.endsWith('.dart')) {
+ throw new ArgumentError(
+ '`bootstrap_file` should be a string path to a dart file');
+ }
+ var htmlEntryPoint = settings.configuration['html_entry_point'];
+ if (htmlEntryPoint is! String || !htmlEntryPoint.endsWith('.html')) {
+ throw new ArgumentError(
+ '`html_entry_point` should be a string path to an html file');
+ }
+ return new HtmlImportAnnotationInliner(bootstrapFile, htmlEntryPoint);
+ }
+
+ classifyPrimary(AssetId id) {
+ var superValue = super.classifyPrimary(id);
+ if (superValue != null) return superValue;
+ // Group it with the bootstrap file.
+ if (_htmlEntryPoint == id.path) return _bootstrapFile;
+ return null;
+ }
+
+ apply(AggregateTransform transform) {
+ _logger = transform.logger;
+ return super.apply(transform).then((_) {
+ var htmlEntryPoint =
+ allAssets.firstWhere((asset) => asset.id.path == _htmlEntryPoint);
+ return htmlEntryPoint.readAsString().then((html) {
+ var doc = parse(html);
+ for (var importPath in importPaths) {
+ var import = new dom.Element.tag('link')
+ ..attributes = {'rel': 'import', 'href': importPath,};
Siggi Cherem (dart-lang) 2015/02/12 16:49:44 nit: remove trailing comma `,`?
jakemac 2015/02/12 17:04:09 oh I probably had these on separate lines in which
+ doc.head.append(import);
+ }
+ transform
+ .addOutput(new Asset.fromString(htmlEntryPoint.id, doc.outerHtml));
+ });
+ });
+ }
+
+ // Executed for each initializer constructor in the bootstrap file. We filter
+ // out the HtmlImport ones and inline them.
+ initEntry(
+ InstanceCreationExpression expression, TextEditTransaction transaction) {
+ // Filter out extraneous values.
+ if (expression is! InstanceCreationExpression) return;
+ var args = expression.argumentList.arguments;
+ // Only support InstanceCreationExpressions. Const references to HtmlImport
+ // annotations can't be cheaply discovered.
+ if (args[0] is! InstanceCreationExpression) return;
+ if (!'${args[0].constructorName.type.name}'.contains('.HtmlImport')) return;
+
+ // Grab the raw path supplied to the HtmlImport. Only string literals are
+ // supported for the transformer.
Siggi Cherem (dart-lang) 2015/02/12 16:49:44 FYI - I opened https://github.com/dart-lang/initia
jakemac 2015/02/12 17:04:09 I replied there, but basically in the new plugin a
+ var originalPath = args[0].argumentList.arguments[0];
+ if (originalPath is SimpleStringLiteral) {
+ originalPath = originalPath.value;
+ } else {
+ _logger.warning('Found HtmlImport constructor which was supplied an '
+ 'expression. Only raw strings are currently supported for the '
+ 'transformer, so $originalPath will be injected dynamically');
+ return;
+ }
+
+ // Now grab the package from the LibraryIdentifier, we know its either a
+ // string or null literal.
+ var package = args[1].argumentList.arguments[1];
+ if (package is SimpleStringLiteral) {
+ package = package.value;
+ } else if (package is NullLiteral) {
+ package = null;
+ } else {
+ _logger.error('Invalid LibraryIdentifier declaration. The 2nd argument '
+ 'be a literal string or null. `${args[1]}`');
+ }
+
+ // And finally get the original dart file path, this is always a string
+ // literal.
+ var dartPath = args[1].argumentList.arguments[2];
+ if (dartPath is SimpleStringLiteral) {
+ dartPath = dartPath.value;
+ } else {
+ _logger.error('Invalid LibraryIdentifier declaration. The 3rd argument '
+ 'be a literal string. `${args[1]}`');
+ }
+
+ // Add the normalized path to our list and remove the expression from the
+ // bootstrap file.
+ importPaths.add(normalizeHtmlImportPath(originalPath, package, dartPath));
+ removeInitializer(expression, transaction);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698