| 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 // This script dynamically prepares a set of files to run polymer.dart. It uses | 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 | 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 | 7 // it inlines all <polymer-element> definitions on the top-level page (needed by |
| 8 // registerPolymerElement), and it removes script tags that appear inside | 8 // registerPolymerElement), and it removes script tags that appear inside |
| 9 // those tags. It finally rewrites the main entrypoint to call an initialization | 9 // those tags. It finally rewrites the main entrypoint to call an initialization |
| 10 // function on each of the declared <polymer-elements>. | 10 // function on each of the declared <polymer-elements>. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 if (!navigator.webkitStartDart) { | 52 if (!navigator.webkitStartDart) { |
| 53 // TODO(sigmund): rephrase when we split build.dart in two: analysis vs | 53 // TODO(sigmund): rephrase when we split build.dart in two: analysis vs |
| 54 // deploy pieces. | 54 // deploy pieces. |
| 55 console.warn('boot.js only works in Dartium. Run the build.dart' + | 55 console.warn('boot.js only works in Dartium. Run the build.dart' + |
| 56 ' tool to compile a depolyable JavaScript version') | 56 ' tool to compile a depolyable JavaScript version') |
| 57 return; | 57 return; |
| 58 } | 58 } |
| 59 document.write( | 59 document.write( |
| 60 '<script src="packages/html_import/html_import.min.js"></script>'); | 60 '<script src="packages/html_import/html_import.min.js"></script>'); |
| 61 | 61 |
| 62 // Whether [node] is under `<body>` or `<head>` and not nested in an | |
| 63 // `<element>` or `<polymer-element>` tag. | |
| 64 function isTopLevel(node) { | |
| 65 var parent = node.parentNode; | |
| 66 if (parent == null || parent == document.body || parent == document.head) { | |
| 67 return true; | |
| 68 } | |
| 69 if (parent.localName && ( | |
| 70 parent.localName == 'element' || | |
| 71 parent.localName == 'polymer-element')) { | |
| 72 return false; | |
| 73 } | |
| 74 return isTopLevel(parent); | |
| 75 } | |
| 76 | |
| 77 // Extract a Dart import URL from a script tag, which is the 'src' attribute | 62 // Extract a Dart import URL from a script tag, which is the 'src' attribute |
| 78 // of the script tag, or a data-url with the script contents for inlined code. | 63 // of the script tag, or a data-url with the script contents for inlined code. |
| 79 function getScriptUrl(script) { | 64 function getScriptUrl(script) { |
| 80 var url = script.src; | 65 var url = script.src; |
| 81 if (url) { | 66 if (url) { |
| 82 // Normalize package: urls | 67 // Normalize package: urls |
| 83 var index = url.indexOf('packages/'); | 68 var index = url.indexOf('packages/'); |
| 84 if (index == 0 || (index > 0 && url[index - 1] == '/')) { | 69 if (index == 0 || (index > 0 && url[index - 1] == '/')) { |
| 85 url = "package:" + url.slice(index + 9); | 70 url = "package:" + url.slice(index + 9); |
| 86 } | 71 } |
| 87 | 72 return url; |
| 88 // TODO(sigmund): remove the timestamp. We added this to work around | |
| 89 // a caching bug in dartium (see http://dartbug.com/12074). Note this | |
| 90 // doesn't fix caching problems with other libraries imported further in, | |
| 91 // and it can also introduce canonicalization problems if the files under | |
| 92 // these urls are being imported from other libraries. | |
| 93 var time = new Date().getTime(); | |
| 94 return url + '?' + time; | |
| 95 } else { | 73 } else { |
| 96 // TODO(sigmund): investigate how to eliminate the warning in Dartium | 74 // TODO(sigmund): investigate how to eliminate the warning in Dartium |
| 97 // (changing to text/javascript hides the warning, but seems wrong). | 75 // (changing to text/javascript hides the warning, but seems wrong). |
| 98 return "data:application/dart;base64," + window.btoa(script.textContent); | 76 return "data:application/dart;base64," + window.btoa(script.textContent); |
| 99 } | 77 } |
| 100 } | 78 } |
| 101 | 79 |
| 102 // Moves <polymer-elements> from imported documents into the top-level page. | 80 // Moves <polymer-elements> from imported documents into the top-level page. |
| 103 function inlinePolymerElements(content, ref, seen) { | 81 function inlinePolymerElements(content, ref, seen) { |
| 104 if (!seen) seen = {}; | 82 if (!seen) seen = {}; |
| 105 var links = content.querySelectorAll('link[rel="import"]'); | 83 var links = content.querySelectorAll('link[rel="import"]'); |
| 106 for (var i = 0; i < links.length; i++) { | 84 for (var i = 0; i < links.length; i++) { |
| 107 var link = links[i].import; | 85 var link = links[i].import; |
| 108 if (seen[link.href]) continue; | 86 if (seen[link.href]) continue; |
| 109 seen[link.href] = link; | 87 seen[link.href] = link; |
| 110 inlinePolymerElements(link.content, ref, seen); | 88 inlinePolymerElements(link.content, ref, seen); |
| 111 } | 89 } |
| 112 | 90 |
| 113 if (content != document) { // no need to do anything for the top-level page | 91 if (content != document) { // no need to do anything for the top-level page |
| 114 var elements = content.querySelectorAll('polymer-element'); | 92 var elements = content.querySelectorAll('polymer-element'); |
| 115 for (var i = 0; i < elements.length; i++) { | 93 for (var i = 0; i < elements.length; i++) { |
| 116 document.body.insertBefore(elements[i], ref); | 94 document.body.insertBefore(elements[i], ref); |
| 117 } | 95 } |
| 118 } | 96 } |
| 119 } | 97 } |
| 120 | 98 |
| 121 // Creates a Dart program that imports [urls] and [mainUrl] and invokes the | 99 // Creates a Dart program that imports [urls] and passes them to initPolymer |
| 122 // _init methods of each library in urls (if present) followed by the main | 100 // (which in turn will invoke their main function, their methods marked with |
| 123 // method of [mainUrl]. | 101 // @initMethod, and register any custom tag labeled with @CustomTag). |
| 124 function createMain(urls, mainUrl) { | 102 function createMain(urls, mainUrl) { |
| 125 var imports = Array(urls.length + 2); | 103 var imports = Array(urls.length + 1); |
| 126 for (var i = 0; i < urls.length; ++i) { | 104 for (var i = 0; i < urls.length; ++i) { |
| 127 imports[i] = 'import "' + urls[i] + '" as i' + i + ';'; | 105 imports[i] = 'import "' + urls[i] + '" as i' + i + ';'; |
| 128 } | 106 } |
| 129 imports[urls.length] = 'import "package:polymer/polymer.dart" as polymer;'; | 107 imports[urls.length] = 'import "package:polymer/polymer.dart" as polymer;'; |
| 130 imports[urls.length + 1 ] = 'import "' + mainUrl + '" as userMain;'; | 108 var arg = urls.length == 0 ? '[]' : |
| 131 var firstArg = urls.length == 0 ? '[]' : | |
| 132 ('[\n "' + urls.join('",\n "') + '"\n ]'); | 109 ('[\n "' + urls.join('",\n "') + '"\n ]'); |
| 133 return (imports.join('\n') + | 110 return (imports.join('\n') + |
| 134 '\n\nmain() {\n' + | 111 '\n\nmain() {\n' + |
| 135 ' polymer.initPolymer(' + firstArg + ', userMain.main);\n' + | 112 ' polymer.initPolymer(' + arg + ');\n' + |
| 136 '}\n'); | 113 '}\n'); |
| 137 } | 114 } |
| 138 | 115 |
| 139 // Finds all top-level <script> tags, and <script> tags in custom elements | 116 // Finds all top-level <script> tags, and <script> tags in custom elements |
| 140 // and merges them into a single entrypoint. | 117 // and merges them into a single entrypoint. |
| 141 function mergeScripts() { | 118 function mergeScripts() { |
| 142 var scripts = document.getElementsByTagName("script"); | 119 var scripts = document.getElementsByTagName("script"); |
| 143 var length = scripts.length; | 120 var length = scripts.length; |
| 144 | 121 |
| 145 var dartScripts = [] | |
| 146 var urls = []; | 122 var urls = []; |
| 123 var toRemove = []; |
| 147 | 124 |
| 148 // Collect the information we need to replace the script tags | 125 // Collect the information we need to replace the script tags |
| 149 for (var i = 0; i < length; ++i) { | 126 for (var i = 0; i < length; ++i) { |
| 150 var script = scripts[i]; | 127 var script = scripts[i]; |
| 151 if (script.type == "application/dart") { | 128 if (script.type == "application/dart") { |
| 152 dartScripts.push(script); | |
| 153 if (isTopLevel(script)) continue; | |
| 154 urls.push(getScriptUrl(script)); | 129 urls.push(getScriptUrl(script)); |
| 130 toRemove.push(script); |
| 155 } | 131 } |
| 156 } | 132 } |
| 157 | 133 |
| 158 // Removes all the original script tags under elements, and replace | 134 toRemove.forEach(function (s) { s.parentNode.removeChild(s); }); |
| 159 // top-level script tags so we first call each element's _init. | 135 |
| 160 for (var i = 0; i < dartScripts.length; ++i) { | 136 // Append a new script tag that initializes everything. |
| 161 var script = dartScripts[i]; | 137 var newScript = document.createElement('script'); |
| 162 if (isTopLevel(script)) { | 138 newScript.type = "application/dart"; |
| 163 var newScript = document.createElement('script'); | 139 newScript.textContent = createMain(urls); |
| 164 newScript.type = "application/dart"; | 140 document.body.appendChild(newScript); |
| 165 newScript.textContent = createMain(urls, getScriptUrl(script)); | |
| 166 script.parentNode.replaceChild(newScript, script); | |
| 167 } else { | |
| 168 script.parentNode.removeChild(script); | |
| 169 } | |
| 170 } | |
| 171 } | 141 } |
| 172 | 142 |
| 173 var alreadyRan = false; | 143 var alreadyRan = false; |
| 174 window.addEventListener('HTMLImportsLoaded', function (e) { | 144 window.addEventListener('HTMLImportsLoaded', function (e) { |
| 175 if (alreadyRan) { | 145 if (alreadyRan) { |
| 176 console.warn('HTMLImportsLoaded fired again.'); | 146 console.warn('HTMLImportsLoaded fired again.'); |
| 177 return; | 147 return; |
| 178 } | 148 } |
| 179 alreadyRan = true; | 149 alreadyRan = true; |
| 180 var ref = document.body.children[0]; | 150 var ref = document.body.children[0]; |
| 181 inlinePolymerElements(document, ref); | 151 inlinePolymerElements(document, ref); |
| 182 mergeScripts(); | 152 mergeScripts(); |
| 183 if (!navigator.webkitStartDart()) { | 153 if (!navigator.webkitStartDart()) { |
| 184 document.body.innerHTML = 'This build has expired. Please download a ' + | 154 document.body.innerHTML = 'This build has expired. Please download a ' + |
| 185 'new Dartium at http://www.dartlang.org/dartium/index.html'; | 155 'new Dartium at http://www.dartlang.org/dartium/index.html'; |
| 186 } | 156 } |
| 187 }); | 157 }); |
| 188 })(); | 158 })(); |
| OLD | NEW |