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

Side by Side Diff: pkg/polymer/lib/boot.js

Issue 225043004: Replace bootstrap logic with 'boot.js', use 'component/dart' mime-type and add (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 /// Bootstrap to initialize polymer applications. This library is will be
6 /// replaced by boot.dart in the near future (see dartbug.com/18007).
7 ///
8 /// This script contains logic to bootstrap polymer apps during development. It
9 /// internally discovers special Dart script tags through HTML imports, and
10 /// constructs a new entrypoint for the application that is then launched in an
11 /// isolate.
12 ///
13 /// For each script tag found, we will load the corresponding Dart library and
14 /// execute all methods annotated with `@initMethod` and register all classes
15 /// labeled with `@CustomTag`. We keep track of the order of imports and execute
16 /// initializers in the same order.
17 ///
18 /// All polymer applications use this bootstrap logic. It is included
19 /// automatically when you include the polymer.html import:
20 ///
21 /// <link rel="import" href="packages/polymer/polymer.html">
22 ///
23 /// There are two important changes compared to previous versions of polymer
24 /// (0.10.0-pre.6 and older):
25 ///
26 /// * Use 'application/dart;component=1' instead of 'application/dart':
27 /// Dartium already limits to have a single script tag per document, but it
28 /// will be changing semantics soon and make them even stricter. Multiple
29 /// script tags are not going to be running on the same isolate after this
30 /// change. For polymer applications we'll use a parameter on the script tags
31 /// mime-type to prevent Dartium from loading them separately. Instead this
32 /// bootstrap script combines those special script tags and creates the
33 /// application Dartium needs to run.
34 ///
35 // If you had:
36 ///
37 /// <polymer-element name="x-foo"> ...
38 /// <script type="application/dart" src="x_foo.dart'></script>
39 ///
40 /// Now you need to write:
41 ///
42 /// <polymer-element name="x-foo"> ...
43 /// <script type="application/dart;component=1" src="x_foo.dart'></script>
44 ///
45 /// * `initPolymer` is gone: we used to initialize applications in two
46 /// possible ways: using `init.dart` or invoking initPolymer in your main. Any
47 /// of these initialization patterns can be replaced to use an `@initMethod`
48 /// instead. For example, If you need to run some initialization code before
49 /// any other code is executed, include a "application/dart;component=1"
50 /// script tag that contains an initializer method with the body of your old
51 /// main, and make sure this tag is placed above other html-imports that load
52 /// the rest of the application. Initialization methods are executed in the
53 /// order in which they are discovered in the HTML document.
5 (function() { 54 (function() {
6 console.error('"boot.js" is now deprecated. Instead, you can initialize ' 55 // Only run in Dartium.
7 + 'your polymer application by adding the following tags: \'' + 56 if (navigator.userAgent.indexOf('(Dart)') === -1) return;
8 + '<script type="application/dart">export "package:polymer/init.dart";' 57
9 + '</script><script src="packages/browser/dart.js"></script>\'. ' 58 // Extract a Dart import URL from a script tag, which is the 'src' attribute
10 + 'Make sure these script tags come after all HTML imports.'); 59 // of the script tag, or a data-url with the script contents for inlined code.
60 function getScriptUrl(script) {
61 var url = script.src;
62 if (url) {
63 // Normalize package: urls
64 var index = url.indexOf('packages/');
65 if (index == 0 || (index > 0 && url[index - 1] == '/')) {
66 url = "package:" + url.slice(index + 9);
67 }
68 return url;
69 }
70
71 // TODO(sigmund): change back to application/dart: using application/json is
72 // wrong but it hides a warning in Dartium (dartbug.com/18000).
73 return "data:application/json;base64," + window.btoa(script.textContent);
74 }
75
76 // Creates a Dart program that imports [urls] and passes them to
77 // startPolymerInDevelopment, which in turn will invoke methods marked with
78 // @initMethod, and register any custom tag labeled with @CustomTag in those
79 // libraries.
80 function createMain(urls, mainUrl) {
81 var imports = Array(urls.length + 1);
82 for (var i = 0; i < urls.length; ++i) {
83 imports[i] = 'import "' + urls[i] + '" as i' + i + ';';
84 }
85 imports[urls.length] = 'import "package:polymer/src/mirror_loader.dart";';
86 var arg = urls.length == 0 ? '[]' :
87 ('[\n "' + urls.join('",\n "') + '"\n ]');
88 return (imports.join('\n') +
89 '\n\nmain() {\n' +
90 ' startPolymerInDevelopment(' + arg + ');\n' +
91 '}\n');
92 }
93
94 function discoverScripts(content, state) {
95 if (!state) {
96 // internal state tracking documents we've visited, the resulting list of
97 // scripts, and any tags with the incorrect mime-type.
98 state = {seen: {}, scripts: [], badTags: []};
99 }
100 if (!content) return state;
101
102 // Note: we visit both script and link-imports together to ensure we
103 // preserve the order of the script tags as they are discovered.
104 var nodes = content.querySelectorAll('script,link[rel="import"]');
105 for (var i = 0; i < nodes.length; i++) {
106 var node = nodes[i];
107 if (node instanceof HTMLLinkElement) {
108 // TODO(jmesserly): figure out why ".import" fails in content_shell but
109 // works in Dartium.
110 if (node.import && node.import.href) node = node.import;
111
112 if (state.seen[node.href]) continue;
113 state.seen[node.href] = node;
114 discoverScripts(node.import, state);
115 } else if (node instanceof HTMLScriptElement) {
116 if (node.type == 'application/dart;component=1') {
117 state.scripts.push(getScriptUrl(node));
118 }
119 if (node.type == 'application/dart') {
120 state.badTags.push(node);
121 }
122 }
123 }
124 return state;
125 }
126
127 // Waits for all imports to be loaded, then calls [callback].
128 function onImportsReady(callback) {
129 // Note: we only need to check the main document because an import is loaded
130 // only when all it's transitive imports are loaded too.
131 var nodes = document.querySelectorAll('link[rel="import"]');
132 var total = nodes.length;
133 var loaded = 0;
134 function incrementLoaded() {
135 loaded++;
136 if (loaded == total) callback();
137 }
138
139 for (var i = 0; i < total; i++) {
140 if (nodes[i].import) {
141 incrementLoaded();
142 } else {
143 nodes[i].addEventListener('load', incrementLoaded);
144 }
145 }
146 }
147
148 onImportsReady(function () {
149 // Append a new script tag that initializes everything.
150 var newScript = document.createElement('script');
151 newScript.type = "application/dart";
152
153 var results = discoverScripts(document);
154 if (results.badTags.length > 0) {
155 console.warn('Dartium currently only allows a single Dart script tag '
156 + 'per application, and in the future it will run them in '
157 + 'separtate isolates. To prepare for this all the following '
158 + 'script tags need to be updated to use the mime-type '
159 + '"application/dart;component=1" instead of "application/dart":');
160 for (var i = 0; i < results.badTags.length; i++) {
161 console.warn(results.badTags[i]);
162 }
163
164 }
165 newScript.textContent = createMain(results.scripts);
166 document.body.appendChild(newScript);
167 });
11 })(); 168 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698