OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * Part of the template compilation that concerns with extracting information | 6 * Part of the template compilation that concerns with extracting information |
7 * from the HTML parse tree. | 7 * from the HTML parse tree. |
8 */ | 8 */ |
9 library analyzer; | 9 library analyzer; |
10 | 10 |
| 11 import 'dart:uri'; |
11 import 'package:html5lib/dom.dart'; | 12 import 'package:html5lib/dom.dart'; |
12 import 'package:html5lib/dom_parsing.dart'; | 13 import 'package:html5lib/dom_parsing.dart'; |
13 import 'package:source_maps/span.dart'; | 14 import 'package:source_maps/span.dart'; |
14 | 15 |
15 import 'dart_parser.dart'; | 16 import 'dart_parser.dart'; |
16 import 'file_system/path.dart'; | 17 import 'file_system/path.dart'; |
17 import 'files.dart'; | 18 import 'files.dart'; |
18 import 'html5_utils.dart'; | 19 import 'html5_utils.dart'; |
19 import 'info.dart'; | 20 import 'info.dart'; |
20 import 'messages.dart'; | 21 import 'messages.dart'; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 // child nodes and get their infos, and if any of them need data binding, | 113 // child nodes and get their infos, and if any of them need data binding, |
113 // we create an ElementInfo for ourselves and return it, otherwise we just | 114 // we create an ElementInfo for ourselves and return it, otherwise we just |
114 // return null. | 115 // return null. |
115 if (info == null) { | 116 if (info == null) { |
116 // <element> tags are tracked in the file's declared components, so they | 117 // <element> tags are tracked in the file's declared components, so they |
117 // don't need a parent. | 118 // don't need a parent. |
118 var parent = node.tagName == 'element' ? null : _parent; | 119 var parent = node.tagName == 'element' ? null : _parent; |
119 info = new ElementInfo(node, parent); | 120 info = new ElementInfo(node, parent); |
120 } | 121 } |
121 | 122 |
122 // TODO(terry): How to handle <link rel="stylesheet" href="..."> | |
123 // - What if multiple stylesheet links for a component? | |
124 // - What if a stylesheet link for all component and particular | |
125 // stylesheet links for each component? | |
126 // - What if multiple <style> tags for the same component? | |
127 if (node.tagName == 'style' && node.attributes.containsKey("scoped")) { | |
128 // TODO(terry): Faster to parse the CSS tags separately instead of | |
129 // concatenating all styles. | |
130 // Get contents of style tag. | |
131 _currentInfo.cssSource.write(node.nodes.single.value); | |
132 } | |
133 | |
134 visitElementInfo(info); | 123 visitElementInfo(info); |
135 | 124 |
136 if (_parent == null) { | 125 if (_parent == null) { |
137 _fileInfo.bodyInfo = info; | 126 _fileInfo.bodyInfo = info; |
138 } | 127 } |
139 } | 128 } |
140 | 129 |
141 void visitElementInfo(ElementInfo info) { | 130 void visitElementInfo(ElementInfo info) { |
142 var node = info.node; | 131 var node = info.node; |
143 | 132 |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 } | 742 } |
754 } | 743 } |
755 | 744 |
756 /** | 745 /** |
757 * Process `link rel="component"` as specified in: | 746 * Process `link rel="component"` as specified in: |
758 * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/components/index.ht
ml#link-type-component> | 747 * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/components/index.ht
ml#link-type-component> |
759 */ | 748 */ |
760 void visitLinkElement(Element node) { | 749 void visitLinkElement(Element node) { |
761 // TODO(jmesserly): deprecate the plural form, it is singular in the spec. | 750 // TODO(jmesserly): deprecate the plural form, it is singular in the spec. |
762 var rel = node.attributes['rel']; | 751 var rel = node.attributes['rel']; |
763 if (rel != 'component' && rel != 'components') return; | 752 if (rel != 'component' && rel != 'components' && |
| 753 rel != 'stylesheet') return; |
764 | 754 |
765 if (!_inHead) { | 755 if (!_inHead) { |
766 _messages.warning('link rel="$rel" only valid in ' | 756 _messages.warning('link rel="$rel" only valid in ' |
767 'head.', node.sourceSpan, file: _fileInfo.path); | 757 'head.', node.sourceSpan, file: _fileInfo.path); |
768 return; | 758 return; |
769 } | 759 } |
770 | 760 |
771 var href = node.attributes['href']; | 761 var href = node.attributes['href']; |
772 if (href == null || href == '') { | 762 if (href == null || href == '') { |
773 _messages.warning('link rel="$rel" missing href.', | 763 _messages.warning('link rel="$rel" missing href.', |
774 node.sourceSpan, file: _fileInfo.path); | 764 node.sourceSpan, file: _fileInfo.path); |
775 return; | 765 return; |
776 } | 766 } |
777 | 767 |
778 var path; | 768 var path; |
779 if (href.startsWith('package:')) { | 769 if (href.startsWith('package:')) { |
780 path = _packageRoot.join(new Path(href.substring(8))); | 770 path = _packageRoot.join(new Path(href.substring(8))); |
781 } else { | 771 } else { |
782 path = _fileInfo.path.directoryPath.join(new Path(href)); | 772 path = _fileInfo.path.directoryPath.join(new Path(href)); |
783 } | 773 } |
784 | 774 |
785 _fileInfo.componentLinks.add(path); | 775 if (rel == 'component' || rel == 'components') { |
| 776 _fileInfo.componentLinks.add(path); |
| 777 } else { |
| 778 assert(rel == 'stylesheet'); |
| 779 // Local stylesheets only are handled. |
| 780 var scheme = Uri.parse(href).scheme; |
| 781 if (scheme != 'http' && scheme != 'https') { |
| 782 _fileInfo.styleSheetHref.add(path); |
| 783 } |
| 784 } |
786 } | 785 } |
787 | 786 |
788 void visitElementElement(Element node) { | 787 void visitElementElement(Element node) { |
789 // TODO(jmesserly): what do we do in this case? It seems like an <element> | 788 // TODO(jmesserly): what do we do in this case? It seems like an <element> |
790 // inside a Shadow DOM should be scoped to that <template> tag, and not | 789 // inside a Shadow DOM should be scoped to that <template> tag, and not |
791 // visible from the outside. | 790 // visible from the outside. |
792 if (_currentInfo is ComponentInfo) { | 791 if (_currentInfo is ComponentInfo) { |
793 _messages.error('Nested component definitions are not yet supported.', | 792 _messages.error('Nested component definitions are not yet supported.', |
794 node.sourceSpan, file: _fileInfo.path); | 793 node.sourceSpan, file: _fileInfo.path); |
795 return; | 794 return; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 if (start == null) moveNext(); | 995 if (start == null) moveNext(); |
997 if (start < length) { | 996 if (start < length) { |
998 do { | 997 do { |
999 bindings.add(binding); | 998 bindings.add(binding); |
1000 content.add(textContent); | 999 content.add(textContent); |
1001 } while (moveNext()); | 1000 } while (moveNext()); |
1002 } | 1001 } |
1003 content.add(textContent); | 1002 content.add(textContent); |
1004 } | 1003 } |
1005 } | 1004 } |
OLD | NEW |