| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /// Experimental bootstrap to initialize polymer applications. This library is | |
| 6 /// not used by default, and may be replaced by Dart code in the near future. | |
| 7 /// | |
| 8 /// This script contains logic to bootstrap polymer apps during development. It | |
| 9 /// internally discovers Dart script tags through HTML imports, and constructs | |
| 10 /// a new entrypoint for the application that is then launched in an isolate. | |
| 11 /// | |
| 12 /// For each script tag found, we will load the corresponding Dart library and | |
| 13 /// execute all methods annotated with `@initMethod` and register all classes | |
| 14 /// labeled with `@CustomTag`. We keep track of the order of imports and execute | |
| 15 /// initializers in the same order. | |
| 16 /// | |
| 17 /// You can this experimental bootstrap logic by including the | |
| 18 /// polymer_experimental.html import, instead of polymer.html: | |
| 19 /// | |
| 20 /// <link rel="import" href="packages/polymer/polymer_experimental.html"> | |
| 21 /// | |
| 22 /// This bootstrap replaces `initPolymer` so Dart code might need to be changed | |
| 23 /// too. If you loaded init.dart directly, you can remove it. But if you invoke | |
| 24 /// initPolymer in your main, you should remove that call and change to use | |
| 25 /// `@initMethod` instead. The current bootstrap doesn't support having Dart | |
| 26 /// script tags in the main page, so you may need to move some code into an HTML | |
| 27 /// import. For example, If you need to run some initialization code before any | |
| 28 /// other code is executed, include an HTML import to an html file with a | |
| 29 /// "application/dart" script tag that contains an initializer | |
| 30 /// method with the body of your old main, and make sure this tag is placed | |
| 31 /// above other html-imports that load the rest of the application. | |
| 32 /// Initialization methods are executed in the order in which they are | |
| 33 /// discovered in the HTML document. | |
| 34 (function() { | |
| 35 // Only run in Dartium. | |
| 36 if (!navigator.dartEnabled && | |
| 37 // TODO(sigmund): remove userAgent check once 1.6 rolls as stable. | |
| 38 // See: dartbug.com/18463 | |
| 39 (navigator.userAgent.indexOf('(Dart)') === -1)) { | |
| 40 return; | |
| 41 } | |
| 42 | |
| 43 // Extract a Dart import URL from a script tag, which is the 'src' attribute | |
| 44 // of the script tag, or a data-url with the script contents for inlined code. | |
| 45 function getScriptUrl(script) { | |
| 46 var url = script.src; | |
| 47 if (url) { | |
| 48 // Normalize package: urls | |
| 49 var index = url.indexOf('packages/'); | |
| 50 if (index == 0 || (index > 0 && url[index - 1] == '/')) { | |
| 51 url = "package:" + url.slice(index + 9); | |
| 52 } | |
| 53 return url; | |
| 54 } | |
| 55 | |
| 56 // TODO(sigmund): change back to application/dart: using application/json is | |
| 57 // wrong but it hides a warning in Dartium (dartbug.com/18000). | |
| 58 return "data:application/json;base64," + window.btoa(script.textContent); | |
| 59 } | |
| 60 | |
| 61 // Creates a Dart program that imports [urls] and passes them to | |
| 62 // startPolymerInDevelopment, which in turn will invoke methods marked with | |
| 63 // @initMethod, and register any custom tag labeled with @CustomTag in those | |
| 64 // libraries. | |
| 65 function createMain(urls, mainUrl) { | |
| 66 var imports = Array(urls.length + 1); | |
| 67 for (var i = 0; i < urls.length; ++i) { | |
| 68 imports[i] = 'import "' + urls[i] + '" as i' + i + ';'; | |
| 69 } | |
| 70 imports[urls.length] = 'import "package:polymer/src/mirror_loader.dart";'; | |
| 71 var arg = urls.length == 0 ? '[]' : | |
| 72 ('[\n "' + urls.join('",\n "') + '"\n ]'); | |
| 73 return (imports.join('\n') + | |
| 74 '\n\nmain() {\n' + | |
| 75 ' startPolymerInDevelopment(' + arg + ');\n' + | |
| 76 '}\n'); | |
| 77 } | |
| 78 | |
| 79 function discoverScripts(content, state, importedDoc) { | |
| 80 if (!state) { | |
| 81 // internal state tracking documents we've visited, the resulting list of | |
| 82 // scripts, and any tags with the incorrect mime-type. | |
| 83 state = {seen: {}, scripts: [], badTags: []}; | |
| 84 } | |
| 85 if (!content) return state; | |
| 86 | |
| 87 // Note: we visit both script and link-imports together to ensure we | |
| 88 // preserve the order of the script tags as they are discovered. | |
| 89 var nodes = content.querySelectorAll('script,link[rel="import"]'); | |
| 90 for (var i = 0; i < nodes.length; i++) { | |
| 91 var node = nodes[i]; | |
| 92 if (node instanceof HTMLLinkElement) { | |
| 93 // TODO(jmesserly): figure out why ".import" fails in content_shell but | |
| 94 // works in Dartium. | |
| 95 if (node.import && node.import.href) node = node.import; | |
| 96 | |
| 97 if (state.seen[node.href]) continue; | |
| 98 state.seen[node.href] = node; | |
| 99 discoverScripts(node.import, state, true); | |
| 100 } else if (node instanceof HTMLScriptElement) { | |
| 101 if (node.type != 'application/dart') continue; | |
| 102 if (importedDoc) { | |
| 103 state.scripts.push(getScriptUrl(node)); | |
| 104 } else { | |
| 105 state.badTags.push(node); | |
| 106 } | |
| 107 } | |
| 108 } | |
| 109 return state; | |
| 110 } | |
| 111 | |
| 112 // TODO(jmesserly): we're using this function because DOMContentLoaded can | |
| 113 // be fired too soon: https://www.w3.org/Bugs/Public/show_bug.cgi?id=23526 | |
| 114 HTMLImports.whenReady(function() { | |
| 115 // Append a new script tag that initializes everything. | |
| 116 var newScript = document.createElement('script'); | |
| 117 newScript.type = "application/dart"; | |
| 118 | |
| 119 var results = discoverScripts(document); | |
| 120 if (results.badTags.length > 0) { | |
| 121 console.warn('The experimental polymer boostrap does not support ' | |
| 122 + 'having script tags in the main document. You can move the script ' | |
| 123 + 'tag to an HTML import instead. Also make sure your script tag ' | |
| 124 + 'doesn\'t have a main, but a top-level method marked with ' | |
| 125 + '@initMethod instead'); | |
| 126 for (var i = 0; i < results.badTags.length; i++) { | |
| 127 console.warn(results.badTags[i]); | |
| 128 } | |
| 129 } | |
| 130 newScript.textContent = createMain(results.scripts); | |
| 131 document.body.appendChild(newScript); | |
| 132 }); | |
| 133 })(); | |
| OLD | NEW |