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 |