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

Side by Side Diff: lib/boot.js

Issue 20863002: Introduce boot.js: this finally makes it possible to load and run Todomvc (Closed) Base URL: git@github.com:dart-lang/web-ui.git@master
Patch Set: 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 // This script dynamically prepares a set of files to run polymer.dart. It uses
6 // the html_import polyfill to search for all imported files, then
7 // it inlines all <polymer-element> definitions on the top-level page (needed by
8 // registerPolymerElement), and it removes script tags that appear inside
9 // those tags. It finally rewrites the main entrypoint to call an initialization
10 // function on each of the declared <polymer-elements>.
11 //
12 // This script is needed only when running polymer.dart in Dartium. It should be
13 // removed by the polymer deployment commands.
14
15 // As an example, given an input of this form:
16 // <polymer-element name="c1">
17 // <template></template>
18 // <script type="application/dart" src="url0.dart"></script>
19 // </polymer-element>
20 // <element name="c2">
21 // <template></template>
22 // <script type="application/dart">main() => { print('body2'); }</script>
23 // </element>
24 // <c1></c1>
25 // <c2></c2>
26 // <script type="application/dart" src="url2.dart"></script>
27 // <script src="packages/polymer/boot.js"></script>
28 //
29 // This script will simplifies the page as follows:
30 // <polymer-element name="c1">
31 // <template></template>
32 // </polymer-element>
33 // <polymer-element name="c2">
34 // <template></template>
35 // </polymer-element>
36 // <c1></c1>
37 // <c2></c2>
38 // <script type="application/dart">
39 // import 'url0.dart' as i0;
40 // import "data:application/dart;base64,CiAgICBtYWluKCkgewogICAgICBwcmludCgn Ym9keTInKTsKICAgIH0KICAgIA==" as i1;
41 // import 'url2.dart' as i2;
42 // ...
43 // main() {
44 // // code that checks which libraries have a 'main' and invokes them.
45 // // practically equivalent to: i0._init(); i1._init(); i2.main();
46 // }
47 // </script>
48
49
50 (function() {
51 // Only run in Dartium.
52 if (!navigator.webkitStartDart) return;
Jennifer Messerly 2013/07/27 02:18:44 should we print a console message? "boot.js only
Siggi Cherem (dart-lang) 2013/07/30 00:10:29 Done.
53
54 // Whether [node] is under `<body>` or `<head>` and not nested in an
55 // `<element>` or `<polymer-element>` tag.
56 function isTopLevel(node) {
57 var parent = node.parentNode;
58 if (parent == null || parent == document.body || parent == document.head) {
59 return true;
60 }
61 if (parent.localName && (
62 parent.localName == 'element' ||
63 parent.localName == 'polymer-element')) {
64 return false;
65 }
66 return isTopLevel(parent);
67 }
68
69 // Extract a Dart import URL from a script tag, which is the 'src' attribute
70 // of the script tag, or a data-url with the script contents for inlined code.
71 function getScriptUrl(script) {
72 var url = script.src;
73 if (url && url != '') {
Jennifer Messerly 2013/07/27 02:18:44 second check is unnecessary, empty string is false
Siggi Cherem (dart-lang) 2013/07/30 00:10:29 Done.
74 // Normalize package: urls
75 var index = url.indexOf('packages/');
76 if (index == 0 || (index > 0 && url[index - 1] == '/')) {
77 url = "package:" + url.slice(index + 9);
78 }
79
80 // TODO(sigmund): remove the timestamp. We added this to work around
Jennifer Messerly 2013/07/27 02:18:44 awesome workaround, btw!
81 // a caching bug in dartium (see http://dartbug.com/12074). Note this
82 // doesn't fix caching problems with other libraries imported further in,
83 // and it can also introduce canonicalization problems if the files under
84 // these urls are being imported from other libraries.
85 var time = new Date().getTime();
86 return url + '?' + time;
87 } else {
88 // TODO(sigmund): investigate how to eliminate the warning in Dartium
Jennifer Messerly 2013/07/27 02:18:44 curious, what is the warning?
Siggi Cherem (dart-lang) 2013/07/30 00:10:29 In the console you'd see a message of this form:
89 // (changing to text/javascript hides the warning, but seems wrong).
90 return "data:application/dart;base64," + window.btoa(script.textContent);
91 }
92 }
93
94 // Moves <polymer-elements> from imported documents into the top-level page.
Jennifer Messerly 2013/07/27 02:18:44 does html_imports/polymer do this too? instead of
Siggi Cherem (dart-lang) 2013/07/30 00:10:29 Exactly =), I was planning to do so as a next step
95 function inlinePolymerElements(content, seen) {
96 if (!seen) seen = {};
97 var links = content.querySelectorAll('link[rel="import"]');
98
99 if (content != document) { // no need to do anything for the top-level page
100 var elements = content.querySelectorAll('polymer-element');
101 var ref = document.body.firstChild;
102 for (var i = 0; i < elements.length; ++i) {
103 document.body.insertBefore(elements[i], ref);
104 }
105 }
106
107 for (var i = 0; i < links.length; i++) {
108 var link = links[i].import;
109 if (seen[link.href]) continue;
110 seen[link.href] = link;
111 inlinePolymerElements(link.content, seen);
112 }
113 }
114
115 // Creates a Dart program that imports [urls] and [mainUrl] and invokes the
116 // _init methods of each library in urls (if present) followed by the main
117 // method of [mainUrl].
118 function createMain(urls, mainUrl) {
119 var imports = Array(urls.length + 2);
120 for (var i = 0; i < urls.length; ++i) {
121 imports[i] = 'import "' + urls[i] + '" as i' + i + ';';
122 }
123 imports[urls.length] = 'import "package:polymer/polymer.dart" as polymer;';
124 imports[urls.length + 1 ] = 'import "' + mainUrl + '" as userMain;';
125 return (imports.join('\n') +
126 '\n\nmain() {\n' +
127 ' polymer.initializePolymer([\n' +
128 ' "' + urls.join('",\n "') + '"\n ], userMain.main);\n' +
129 '}\n');
130 }
131
132 // Finds all top-level <script> tags, and <script> tags in custom elements
133 // and merges them into a single entrypoint.
134 function mergeScripts() {
135 var scripts = document.getElementsByTagName("script");
136 var length = scripts.length;
137
138 var dartScripts = []
139 var urls = [];
140
141 // Collect the information we need to replace the script tags
142 for (var i = 0; i < length; ++i) {
143 var script = scripts[i];
144 if (script.type == "application/dart") {
145 dartScripts.push(script);
146 if (isTopLevel(script)) continue;
147 urls.push(getScriptUrl(script));
148 }
149 }
150
151 if (urls.length > 0) {
152 // Removes all the original script tags under elements, and replace
153 // top-level script tags so we first call each element's _init.
154 for (var i = 0; i < dartScripts.length; ++i) {
155 var script = dartScripts[i];
156 if (isTopLevel(script)) {
157 var newScript = document.createElement('script');
158 newScript.type = "application/dart";
159 newScript.textContent = createMain(urls, getScriptUrl(script));
160 script.parentNode.replaceChild(newScript, script);
161 } else {
162 script.parentNode.removeChild(script);
163 }
164 }
165 }
166 }
167
168 window.addEventListener('HTMLImportsLoaded', function (e) {
169 inlinePolymerElements(document);
170 mergeScripts();
171 if (!navigator.webkitStartDart()) {
172 document.body.innerHTML = 'This build has expired. Please download a new Dartium at http://www.dartlang.org/dartium/index.html';
173 }
174 });
175 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698