Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 library web_components.build.html_import_annotation_inliner; | |
| 5 | |
| 6 import 'dart:async'; | |
| 7 import 'package:barback/barback.dart'; | |
| 8 import 'package:html5lib/dom.dart' as dom; | |
| 9 import 'package:html5lib/parser.dart'; | |
| 10 import '../src/normalize_path.dart'; | |
| 11 | |
| 12 /// Given an html entry point with a single dart bootstrap file created by the | |
| 13 /// `initialize` transformer, this will open that dart file and remove all | |
| 14 /// `HtmlImport` initializers from it. Then it appends those imports to the head | |
| 15 /// of the html entry point. | |
| 16 /// Note: Does not inline the import, it just puts the <link rel="import"> tag. | |
| 17 class HtmlImportAnnotationInliner extends AggregateTransformer { | |
| 18 final String _bootstrapFile; | |
| 19 final String _htmlEntryPoint; | |
| 20 TransformLogger _logger; | |
| 21 | |
| 22 HtmlImportAnnotationInliner(this._bootstrapFile, this._htmlEntryPoint); | |
| 23 | |
| 24 factory HtmlImportAnnotationInliner.asPlugin(BarbackSettings settings) { | |
| 25 var bootstrapFile = settings.configuration['bootstrap_file']; | |
| 26 if (bootstrapFile is! String || !bootstrapFile.endsWith('.dart')) { | |
| 27 throw new ArgumentError( | |
| 28 '`bootstrap_file` should be a string path to a dart file'); | |
| 29 } | |
| 30 var htmlEntryPoint = settings.configuration['html_entry_point']; | |
| 31 if (htmlEntryPoint is! String || !htmlEntryPoint.endsWith('.html')) { | |
| 32 throw new ArgumentError( | |
| 33 '`html_entry_point` should be a string path to an html file'); | |
| 34 } | |
| 35 return new HtmlImportAnnotationInliner(bootstrapFile, htmlEntryPoint); | |
| 36 } | |
| 37 | |
| 38 classifyPrimary(AssetId id) { | |
| 39 if (_bootstrapFile == id.path || _htmlEntryPoint == id.path) return ' '; | |
| 40 return null; | |
| 41 } | |
| 42 | |
| 43 Future apply(AggregateTransform transform) { | |
| 44 _logger = transform.logger; | |
| 45 Asset dartEntryPoint; | |
| 46 Asset htmlEntryPoint; | |
| 47 return transform.primaryInputs.take(2).listen((Asset asset) { | |
| 48 if (asset.id.path == _bootstrapFile) dartEntryPoint = asset; | |
| 49 if (asset.id.path == _htmlEntryPoint) htmlEntryPoint = asset; | |
| 50 }).asFuture().then((_) { | |
| 51 // Will be populated with all import paths found in HtmlImport | |
| 52 // constructors. | |
| 53 var importPaths; | |
| 54 return dartEntryPoint.readAsString().then((dartCode) { | |
| 55 var matches = _htmlImportWithRawString.allMatches(dartCode); | |
| 56 importPaths = new Set.from(matches.map((match) => | |
| 57 normalizeHtmlImportPath( | |
| 58 match.group(1), | |
| 59 match.group(2) == 'null' ? null : match.group(2), | |
| 60 match.group(3)))); | |
| 61 | |
| 62 var newDartCode = dartCode.replaceAll(_htmlImportWithRawString, ''); | |
| 63 var leftoverMatches = _htmlImportGeneral.allMatches(newDartCode); | |
| 64 for (var match in leftoverMatches) { | |
| 65 _logger.warning('Found HtmlImport constructor which was supplied an ' | |
| 66 'expression. Only raw strings are currently supported for the ' | |
| 67 'transformer, so ${match.group(1)} will be injected dynamically'); | |
| 68 } | |
| 69 transform.addOutput( | |
| 70 new Asset.fromString(dartEntryPoint.id, newDartCode)); | |
| 71 }).then((_) => htmlEntryPoint.readAsString()).then((html) { | |
| 72 var doc = parse(html); | |
| 73 for (var importPath in importPaths) { | |
| 74 var import = new dom.Element.tag('link')..attributes = { | |
| 75 'rel': 'import', | |
| 76 'href': importPath, | |
| 77 }; | |
| 78 doc.head.append(import); | |
| 79 } | |
| 80 transform.addOutput( | |
| 81 new Asset.fromString(htmlEntryPoint.id, doc.outerHtml)); | |
| 82 }); | |
| 83 }); | |
| 84 } | |
| 85 | |
| 86 // Matches HtmlImport constructors which are supplied a raw string. These are | |
| 87 // the only ones currently supported for inlining. | |
| 88 final RegExp _htmlImportWithRawString = new RegExp( | |
|
Jennifer Messerly
2015/01/29 21:32:37
this is vaguely terrifying :)
although it gives m
jakemac
2015/02/02 20:55:57
Done, now using InitializerPluginTransformer which
| |
| 89 r"\n\s*new InitEntry\(const i[\d]*\.HtmlImport\('([\w\d\/\.:]*\.html)'\)," | |
| 90 r"\sconst\sLibraryIdentifier\(#[\w\.]*, '?([\w_]*)'?, '([\w\d\/\.]*)'\)\)" | |
| 91 r","); | |
| 92 | |
| 93 // Matches HtmlImport initializers which are supplied any arguments. This | |
| 94 // is used to detect if any were left over and not inlined. | |
| 95 final RegExp _htmlImportGeneral = new RegExp( | |
| 96 r"\n\s*new InitEntry\(const i[\d]*\.HtmlImport\(([\w\d\.]*)\),\s.*\),"); | |
| 97 } | |
| OLD | NEW |