OLD | NEW |
---|---|
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 'component/dart' instead of 'application/dart': Dartium already | |
Jennifer Messerly
2014/04/04 19:26:29
based on existing mime content types, I'm not sure
Siggi Cherem (dart-lang)
2014/04/04 21:09:11
Interesting - sounds good to me. I switched to app
| |
27 /// limits to have a single script tag per document, but it will be changing | |
28 /// semantics soon and make them even stricter. Multiple script tags are not | |
29 /// going to be running on the same isolate after this change. For polymer | |
30 /// applications we'll use a different mime-type on script tags to prevent | |
31 /// Dartium from loading them separately. Instead this bootstrap script | |
32 /// combines those special script tags and creates the application Dartium | |
33 /// 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="component/dart" 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 "component/dart" script tag that | |
50 /// contains an initializer method with the body of your old main, and make | |
51 /// sure this tag is placed above other html-imports that load the rest of the | |
52 /// application. Initialization methods are executed in the order in which | |
53 /// 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 text/javascript | |
72 // seems wrong but it hides a warning in Dartium (darbug.com/18000). | |
Jennifer Messerly
2014/04/04 19:39:50
typo in the darTbug link :)
Siggi Cherem (dart-lang)
2014/04/04 21:09:11
:). Done
| |
73 return "data:text/javascript;base64," + window.btoa(script.textContent); | |
Jennifer Messerly
2014/04/04 19:39:50
WOW. That is beyond crazy!
Does it have to be "te
Siggi Cherem (dart-lang)
2014/04/04 21:09:11
I know, it's pretty weird. I tried a bunch of thin
| |
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 == 'component/dart') { | |
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 window.addEventListener('HTMLImportsLoaded', function (e) { | |
128 // Append a new script tag that initializes everything. | |
129 var newScript = document.createElement('script'); | |
130 newScript.type = "application/dart"; | |
131 | |
132 var results = discoverScripts(document); | |
133 if (results.badTags.length > 0) { | |
134 console.warn('Dartium currently only allows a single Dart script tag ' | |
135 + 'per application, and in the future it will run them in ' | |
136 + 'separtate isolates. To prepare for this all the following ' | |
137 + 'script tags need to be updated to use a new mime-type ' | |
138 + '"components/dart" instead of "application/dart":'); | |
139 for (var i = 0; i < results.badTags.length; i++) { | |
140 console.warn(results.badTags[i]); | |
141 } | |
142 | |
143 } | |
144 newScript.textContent = createMain(results.scripts); | |
145 document.body.appendChild(newScript); | |
146 }); | |
11 })(); | 147 })(); |
OLD | NEW |