OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013, 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 | |
5 /** Transfomer that inlines polymer-element definitions from html imports. */ | |
6 library polymer.src.transform.import_inliner; | |
7 | |
8 import 'dart:async'; | |
9 | |
10 import 'package:barback/barback.dart'; | |
11 import 'package:html5lib/dom.dart' show Document, DocumentFragment; | |
12 import 'common.dart'; | |
13 | |
14 /** Recursively inlines polymer-element definitions from html imports. */ | |
15 // TODO(sigmund): what about other things in html-imports, like scripts? | |
Jennifer Messerly
2013/08/19 22:57:26
inline *all the things* \o/
Siggi Cherem (dart-lang)
2013/08/21 20:35:42
:-) filed a bug and updated the TODO with more det
| |
16 class ImportedElementInliner extends Transformer { | |
17 Future<bool> isPrimary(Asset input) => | |
18 new Future.value(input.id.extension == ".html"); | |
19 | |
20 Future apply(Transform transform) { | |
21 var seen = new Set<AssetId>(); | |
22 var elements = []; | |
23 var id = transform.primaryId; | |
24 seen.add(id); | |
25 return getPrimaryContent(transform).then((content) { | |
26 var document = parseHtml(content, id.path, transform.logger); | |
27 var future = _visitImports(document, id, transform, seen, elements); | |
28 return future.then((importsFound) { | |
29 if (!importsFound) { | |
30 transform.addOutput(new Asset.fromString(id, content)); | |
31 return; | |
32 } | |
33 | |
34 for (var tag in document.queryAll('link')) { | |
35 if (tag.attributes['rel'] == 'import') { | |
36 tag.remove(); | |
37 } | |
38 } | |
39 var fragment = new DocumentFragment()..nodes.addAll(elements); | |
40 document.body.insertBefore(fragment, | |
41 document.body.nodes.length == 0 ? null : document.body.nodes[0]); | |
Jennifer Messerly
2013/08/19 22:57:26
TODO(jmesserly): add Node.firstChild to html5lib
h
Siggi Cherem (dart-lang)
2013/08/21 20:35:42
Done.
| |
42 transform.addOutput(new Asset.fromString(id, document.outerHtml)); | |
43 }); | |
44 }); | |
45 } | |
46 | |
47 /** | |
48 * Visits imports in [document] and add their polymer-element definitions to | |
49 * [element], unless they have already been [seen]. Elements are added in the | |
Bob Nystrom
2013/08/19 22:28:59
"[element]" -> "[elements]".
Siggi Cherem (dart-lang)
2013/08/21 20:35:42
Done.
| |
50 * order they appear, transitive imports are added first. | |
51 */ | |
52 Future<bool> _visitImports(Document document, AssetId sourceId, | |
53 Transform transform, Set<AssetId> seen, List<Node> elements) { | |
54 var importIds = []; | |
55 bool hasImports = false; | |
56 for (var tag in document.queryAll('link')) { | |
57 if (tag.attributes['rel'] != 'import') continue; | |
58 var href = tag.attributes['href']; | |
59 var id = resolve(sourceId, href, transform.logger, tag.sourceSpan); | |
60 hasImports = true; | |
61 if (id == null || seen.contains(id)) continue; | |
62 importIds.add(id); | |
63 } | |
64 | |
65 if (importIds.isEmpty) return new Future.value(hasImports); | |
66 | |
67 // Note: we need to preserve the import order in the generated output. | |
68 return Future.forEach(importIds, (id) { | |
69 if (seen.contains(id)) return new Future.value(null); | |
70 seen.add(id); | |
71 return _collectPolymerElements(id, transform, seen, elements); | |
72 }).then((_) => true); | |
73 } | |
74 | |
75 /** | |
76 * Loads an asset identified by [id], visits its imports and collects it's | |
77 * polymer-element definitions. | |
78 */ | |
79 Future _collectPolymerElements( | |
80 AssetId id, Transform transform, Set<AssetId> seen, List elements) { | |
81 return getContent(transform, id) | |
82 .then((content) => parseHtml(content, id.path, transform.logger)) | |
83 .then((document) { | |
84 return _visitImports(document, id, transform, seen, elements) | |
Jennifer Messerly
2013/08/19 22:57:26
this might look better with =>
Siggi Cherem (dart-lang)
2013/08/21 20:35:42
unfortunatelly I need the 'document' argument both
| |
85 .then((_) => elements.addAll(document.queryAll('polymer-element'))); | |
86 }); | |
87 } | |
88 } | |
OLD | NEW |