OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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 library html_css_fixup; | 5 library html_css_fixup; |
6 | 6 |
7 import 'dart:json' as json; | 7 import 'dart:json' as json; |
8 | 8 |
9 import 'package:html5lib/dom.dart'; | 9 import 'package:html5lib/dom.dart'; |
10 import 'package:html5lib/dom_parsing.dart'; | 10 import 'package:html5lib/dom_parsing.dart'; |
11 import 'package:csslib/visitor.dart'; | 11 import 'package:csslib/visitor.dart'; |
12 | 12 |
13 import 'file_system/path.dart'; | |
13 import 'info.dart'; | 14 import 'info.dart'; |
14 import 'messages.dart'; | 15 import 'messages.dart'; |
15 import 'options.dart'; | 16 import 'options.dart'; |
16 | 17 |
17 /** | 18 /** |
18 * If processCss is enabled, prefix any component's HTML attributes for id or | 19 * If processCss is enabled, prefix any component's HTML attributes for id or |
19 * class to reference the mangled CSS class name or id. | 20 * class to reference the mangled CSS class name or id. |
20 * | 21 * |
21 * Adds prefix error/warning messages to [messages], if [messages] is | 22 * Adds prefix error/warning messages to [messages], if [messages] is |
22 * supplied. | 23 * supplied. |
23 */ | 24 */ |
24 void fixupHtmlCss(FileInfo fileInfo, CompilerOptions opts) { | 25 void fixupHtmlCss(FileInfo fileInfo, CompilerOptions opts) { |
25 // Walk the HTML tree looking for class names or id that are in our parsed | 26 // Walk the HTML tree looking for class names or id that are in our parsed |
26 // stylesheet selectors and making those CSS classes and ids unique to that | 27 // stylesheet selectors and making those CSS classes and ids unique to that |
27 // component. | 28 // component. |
28 if (opts.verbose) print(" CSS fixup ${fileInfo.path.filename}"); | 29 if (opts.verbose) print(" CSS fixup ${fileInfo.path.filename}"); |
29 for (var component in fileInfo.declaredComponents) { | 30 for (var component in fileInfo.declaredComponents) { |
30 if (component.styleSheet != null) { | 31 // TODO(terry): Consider allowing more than one style sheet per component. |
32 // For components only 1 stylesheet allowed. | |
33 if (!component.styleSheets.isEmpty && component.styleSheets.length == 1) { | |
34 var styleSheet = component.styleSheets[0]; | |
31 // If polyfill is on prefix component name to all CSS classes and ids | 35 // If polyfill is on prefix component name to all CSS classes and ids |
32 // referenced in the scoped style. | 36 // referenced in the scoped style. |
33 var prefix = opts.processCss ? component.tagName : null; | 37 var prefix = opts.processCss ? component.tagName : null; |
34 // List of referenced #id and .class in CSS. | 38 // List of referenced #id and .class in CSS. |
35 var knownCss = new IdClassVisitor()..visitTree(component.styleSheet); | 39 var knownCss = new IdClassVisitor()..visitTree(styleSheet); |
36 // Prefix all id and class refs in CSS selectors and HTML attributes. | 40 // Prefix all id and class refs in CSS selectors and HTML attributes. |
37 new _ScopedStyleRenamer(knownCss, prefix, opts.debugCss).visit(component); | 41 new _ScopedStyleRenamer(knownCss, prefix, opts.debugCss).visit(component); |
38 } | 42 } |
39 } | 43 } |
40 } | 44 } |
41 | 45 |
42 /** Build list of every CSS class name and id selector in a stylesheet. */ | 46 /** Build list of every CSS class name and id selector in a stylesheet. */ |
43 class IdClassVisitor extends Visitor { | 47 class IdClassVisitor extends Visitor { |
44 final Set<String> classes = new Set(); | 48 final Set<String> classes = new Set(); |
45 final Set<String> ids = new Set(); | 49 final Set<String> ids = new Set(); |
(...skipping 22 matching lines...) Expand all Loading... | |
68 } | 72 } |
69 return selectors; | 73 return selectors; |
70 } | 74 } |
71 | 75 |
72 /** | 76 /** |
73 * Return a map of simple CSS selectors (class and id selectors) as a Dart map | 77 * Return a map of simple CSS selectors (class and id selectors) as a Dart map |
74 * definition. | 78 * definition. |
75 */ | 79 */ |
76 String createCssSelectorsDefinition(ComponentInfo info, bool cssPolyfill) { | 80 String createCssSelectorsDefinition(ComponentInfo info, bool cssPolyfill) { |
77 var cssVisited = new IdClassVisitor(); | 81 var cssVisited = new IdClassVisitor(); |
78 if (info.styleSheet != null) cssVisited..visitTree(info.styleSheet); | 82 |
83 // For components only 1 stylesheet allowed. | |
84 if (!info.styleSheets.isEmpty && info.styleSheets.length == 1) { | |
85 var styleSheet = info.styleSheets[0]; | |
86 cssVisited..visitTree(styleSheet); | |
87 } | |
88 | |
79 var css = json.stringify(createCssSimpleSelectors(cssVisited, info, | 89 var css = json.stringify(createCssSimpleSelectors(cssVisited, info, |
80 scopedStyles: cssPolyfill)); | 90 scopedStyles: cssPolyfill)); |
81 | |
82 return 'static Map<String, String> _css = $css;'; | 91 return 'static Map<String, String> _css = $css;'; |
83 } | 92 } |
84 | 93 |
85 // TODO(terry): Do we need to handle other selectors than IDs/classes? | 94 // TODO(terry): Do we need to handle other selectors than IDs/classes? |
86 // TODO(terry): Would be nice if we didn't need to mangle names; requires users | 95 // TODO(terry): Would be nice if we didn't need to mangle names; requires users |
87 // to be careful in their code and makes it more than a "polyfill". | 96 // to be careful in their code and makes it more than a "polyfill". |
88 // Maybe mechanism that generates CSS class name for scoping. | 97 // Maybe mechanism that generates CSS class name for scoping. |
89 /** | 98 /** |
90 * Fix a component's HTML to implement scoped stylesheets. | 99 * Fix a component's HTML to implement scoped stylesheets. |
91 * | 100 * |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
159 if (id != null && ids.contains(id)) { | 168 if (id != null && ids.contains(id)) { |
160 var mangledName = "${prefix}_$id"; | 169 var mangledName = "${prefix}_$id"; |
161 if (_debugCss) { | 170 if (_debugCss) { |
162 print(" id = ${node.attributes['id'].toString()} => $mangledName"); | 171 print(" id = ${node.attributes['id'].toString()} => $mangledName"); |
163 } | 172 } |
164 node.attributes['id'] = mangledName; | 173 node.attributes['id'] = mangledName; |
165 } | 174 } |
166 } | 175 } |
167 } | 176 } |
168 } | 177 } |
178 | |
179 /** Compute each CSS URI resource relative from the generated CSS file. */ | |
180 class UriVisitor extends Visitor { | |
181 final Path _relativePath; | |
182 | |
183 UriVisitor(PathInfo pathInfo, Path mainFile, Path cssFile, bool rewriteUrl) | |
184 : _relativePath = cssFile.relativeTo( | |
185 rewriteUrl ? pathInfo.outputDirPath(mainFile) : mainFile.directoryPath | |
186 ).directoryPath; | |
Siggi Cherem (dart-lang)
2013/03/11 21:13:11
oops - this was my fault. Can you fix the indentat
terry
2013/03/11 22:09:13
Done.
| |
187 | |
188 | |
189 void visitUriTerm(UriTerm node) { | |
190 // TODO(terry): Needs to use pathos. | |
191 node.text = _relativePath.join(new Path(node.text)).toString(); | |
192 } | |
193 } | |
OLD | NEW |