Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: pkg/polymer/lib/src/emitters.dart

Issue 23224003: move polymer.dart into dart svn (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: add --deploy to todomvc sample Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/polymer/lib/src/dart_parser.dart ('k') | pkg/polymer/lib/src/file_system.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /** Collects several code emitters for the template tool. */
6 library emitters;
7
8 import 'package:html5lib/dom.dart';
9 import 'package:html5lib/dom_parsing.dart' show TreeVisitor;
10 import 'package:html5lib/parser.dart' show parseFragment;
11 import 'package:source_maps/printer.dart';
12 import 'package:source_maps/refactor.dart';
13
14 import 'compiler_options.dart';
15 import 'css_emitters.dart' show emitStyleSheet, emitOriginalCss;
16 import 'html5_utils.dart';
17 import 'info.dart' show ComponentInfo, FileInfo, GlobalInfo;
18 import 'messages.dart';
19 import 'paths.dart' show PathMapper;
20 import 'utils.dart' show escapeDartString, path;
21
22 /** Generates the class corresponding to a single web component. */
23 NestedPrinter emitPolymerElement(ComponentInfo info, PathMapper pathMapper,
24 TextEditTransaction transaction, CompilerOptions options) {
25 if (info.classDeclaration == null) return null;
26
27 var codeInfo = info.userCode;
28 if (transaction == null) {
29 // TODO(sigmund): avoid emitting this file if we don't need to do any
30 // modifications (e.g. no @observable and not adding the libraryName).
31 transaction = new TextEditTransaction(codeInfo.code, codeInfo.sourceFile);
32 }
33 if (codeInfo.libraryName == null) {
34 // For deploy, we need to import the library associated with the component,
35 // so we need to ensure there is a library directive.
36 var libraryName = info.tagName.replaceAll(new RegExp('[-./]'), '_');
37 transaction.edit(0, 0, 'library $libraryName;');
38 }
39 return transaction.commit();
40 }
41
42 /** The code that will be used to bootstrap the application. */
43 NestedPrinter generateBootstrapCode(
44 FileInfo info, FileInfo userMainInfo, GlobalInfo global,
45 PathMapper pathMapper, CompilerOptions options) {
46
47 var printer = new NestedPrinter(0)
48 ..addLine('library app_bootstrap;')
49 ..addLine('')
50 ..addLine("import 'package:polymer/polymer.dart';")
51 ..addLine("import 'dart:mirrors' show currentMirrorSystem;");
52 if (userMainInfo.userCode != null) {
53 printer..addLine("import '${pathMapper.importUrlFor(info, userMainInfo)}' "
54 "as userMain;\n");
55 }
56
57 int i = 0;
58 for (var c in global.components.values) {
59 if (c.hasConflict) continue;
60 printer.addLine("import '${pathMapper.importUrlFor(info, c)}' as i$i;");
61 i++;
62 }
63
64 printer..addLine('')
65 ..addLine('void main() {')
66 ..indent += 1
67 ..addLine("initPolymer([")
68 ..indent += 2;
69
70 for (var c in global.components.values) {
71 if (c.hasConflict) continue;
72 printer.addLine("'${pathMapper.importUrlFor(info, c)}',");
73 }
74
75 return printer
76 ..indent -= 1
77 ..addLine('],')
78 ..addLine(userMainInfo.userCode != null ? 'userMain.main,' : '() {},')
79 ..addLine(
80 "currentMirrorSystem().findLibrary(const Symbol('app_bootstrap'))")
81 ..indent += 2
82 ..addLine(".first.uri.toString());")
83 ..indent -= 4
84 ..addLine('}');
85 }
86
87
88 /**
89 * Rewrites attributes that contain relative URL (excluding src urls in script
90 * and link tags which are already rewritten by other parts of the compiler).
91 */
92 class _AttributeUrlTransform extends TreeVisitor {
93 final String filePath;
94 final PathMapper pathMapper;
95
96 _AttributeUrlTransform(this.filePath, this.pathMapper);
97
98 visitElement(Element node) {
99 if (node.tagName == 'script') return;
100 if (node.tagName == 'link') return;
101
102 for (var key in node.attributes.keys) {
103 if (urlAttributes.contains(key)) {
104 node.attributes[key] =
105 pathMapper.transformUrl(filePath, node.attributes[key]);
106 }
107 }
108 super.visitElement(node);
109 }
110 }
111
112 final _shadowDomJS = new RegExp(r'shadowdom\..*\.js', caseSensitive: false);
113 final _bootJS = new RegExp(r'.*/polymer/boot.js', caseSensitive: false);
114
115 /** Trim down the html for the main html page. */
116 void transformMainHtml(Document document, FileInfo fileInfo,
117 PathMapper pathMapper, bool hasCss, bool rewriteUrls,
118 Messages messages, GlobalInfo global, String bootstrapOutName) {
119 var filePath = fileInfo.inputUrl.resolvedPath;
120
121 var dartLoaderTag = null;
122 bool shadowDomFound = false;
123 for (var tag in document.queryAll('script')) {
124 var src = tag.attributes['src'];
125 if (src != null) {
126 var last = src.split('/').last;
127 if (last == 'dart.js' || last == 'testing.js') {
128 dartLoaderTag = tag;
129 } else if (_shadowDomJS.hasMatch(last)) {
130 shadowDomFound = true;
131 }
132 }
133 if (tag.attributes['type'] == 'application/dart') {
134 tag.remove();
135 } else if (src != null) {
136 if (_bootJS.hasMatch(src)) {
137 tag.remove();
138 } else if (rewriteUrls) {
139 tag.attributes["src"] = pathMapper.transformUrl(filePath, src);
140 }
141 }
142 }
143
144 for (var tag in document.queryAll('link')) {
145 var href = tag.attributes['href'];
146 var rel = tag.attributes['rel'];
147 if (rel == 'component' || rel == 'components' || rel == 'import') {
148 tag.remove();
149 } else if (href != null && rewriteUrls && !hasCss) {
150 // Only rewrite URL if rewrite on and we're not CSS polyfilling.
151 tag.attributes['href'] = pathMapper.transformUrl(filePath, href);
152 }
153 }
154
155 if (rewriteUrls) {
156 // Transform any element's attribute which is a relative URL.
157 new _AttributeUrlTransform(filePath, pathMapper).visit(document);
158 }
159
160 if (hasCss) {
161 var newCss = pathMapper.mangle(path.basename(filePath), '.css', true);
162 var linkElem = new Element.html(
163 '<link rel="stylesheet" type="text/css" href="$newCss">');
164 document.head.insertBefore(linkElem, null);
165 }
166
167 var styles = document.queryAll('style');
168 if (styles.length > 0) {
169 var allCss = new StringBuffer();
170 fileInfo.styleSheets.forEach((styleSheet) =>
171 allCss.write(emitStyleSheet(styleSheet, fileInfo)));
172 styles[0].nodes.clear();
173 styles[0].nodes.add(new Text(allCss.toString()));
174 for (var i = styles.length - 1; i > 0 ; i--) {
175 styles[i].remove();
176 }
177 }
178
179 // TODO(jmesserly): put this in the global CSS file?
180 // http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html# css-additions
181 document.head.nodes.insert(0, parseFragment(
182 '<style>template { display: none; }</style>'));
183
184 // Move all <element> declarations to the main HTML file
185 // TODO(sigmund): remove this once we have HTMLImports implemented.
186 for (var c in global.components.values) {
187 document.body.nodes.insert(0, new Text('\n'));
188 var fragment = c.element;
189 for (var tag in fragment.queryAll('script')) {
190 // TODO(sigmund): leave script tags around when we start using "boot.js"
191 if (tag.attributes['type'] == 'application/dart') {
192 tag.remove();
193 }
194 }
195 document.body.nodes.insert(0, fragment);
196 }
197
198 if (!shadowDomFound) {
199 // TODO(jmesserly): we probably shouldn't add this automatically.
200 document.body.nodes.add(parseFragment('<script type="text/javascript" '
201 'src="packages/shadow_dom/shadow_dom.debug.js"></script>\n'));
202
203 // JS interop code required for Polymer CSS shimming.
204 document.body.nodes.add(parseFragment('<script type="text/javascript" '
205 'src="packages/browser/interop.js"></script>\n'));
206 }
207
208 var bootstrapScript = parseFragment(
209 '<script type="application/dart" src="$bootstrapOutName"></script>');
210 if (dartLoaderTag == null) {
211 document.body.nodes.add(bootstrapScript);
212 // TODO(jmesserly): turn this warning on.
213 //messages.warning('Missing script to load Dart. '
214 // 'Please add this line to your HTML file: $dartLoader',
215 // document.body.sourceSpan);
216 // TODO(sigmund): switch to 'boot.js'
217 document.body.nodes.add(parseFragment('<script type="text/javascript" '
218 'src="packages/browser/dart.js"></script>\n'));
219 } else if (dartLoaderTag.parent != document.body) {
220 document.body.nodes.add(bootstrapScript);
221 } else {
222 document.body.insertBefore(bootstrapScript, dartLoaderTag);
223 }
224
225 // Insert the "auto-generated" comment after the doctype, otherwise IE will
226 // go into quirks mode.
227 int commentIndex = 0;
228 DocumentType doctype =
229 document.nodes.firstWhere((n) => n is DocumentType, orElse: () => null);
230 if (doctype != null) {
231 commentIndex = document.nodes.indexOf(doctype) + 1;
232 // TODO(jmesserly): the html5lib parser emits a warning for missing
233 // doctype, but it allows you to put it after comments. Presumably they do
234 // this because some comments won't force IE into quirks mode (sigh). See
235 // this link for more info:
236 // http://bugzilla.validator.nu/show_bug.cgi?id=836
237 // For simplicity we emit the warning always, like validator.nu does.
238 if (doctype.tagName != 'html' || commentIndex != 1) {
239 messages.warning('file should start with <!DOCTYPE html> '
240 'to avoid the possibility of it being parsed in quirks mode in IE. '
241 'See http://www.w3.org/TR/html5-diff/#doctype', doctype.sourceSpan);
242 }
243 }
244 document.nodes.insert(commentIndex, parseFragment(
245 '\n<!-- This file was auto-generated from $filePath. -->\n'));
246 }
OLDNEW
« no previous file with comments | « pkg/polymer/lib/src/dart_parser.dart ('k') | pkg/polymer/lib/src/file_system.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698