OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2014 Google Inc. All rights reserved. | 2 * Copyright (C) 2014 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 10 matching lines...) Expand all Loading... | |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 var allDescriptors = []; | |
31 var _importedScripts = {}; | 32 var _importedScripts = {}; |
eustas
2014/08/15 13:22:26
Is it still "imported" scripts?
apavlov
2014/08/15 13:31:44
Can be renamed _loadedScripts
| |
32 | 33 |
33 /** | 34 /** |
34 * @param {string} url | 35 * @param {string} url |
35 * @return {string} | 36 * @return {string} |
36 */ | 37 */ |
37 function loadResource(url) | 38 function loadResource(url) |
38 { | 39 { |
39 var xhr = new XMLHttpRequest(); | 40 var xhr = new XMLHttpRequest(); |
40 xhr.open("GET", url, false); | 41 xhr.open("GET", url, false); |
41 try { | 42 try { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
74 return normalizedPath; | 75 return normalizedPath; |
75 if (path[0] === "/" && normalizedPath) | 76 if (path[0] === "/" && normalizedPath) |
76 normalizedPath = "/" + normalizedPath; | 77 normalizedPath = "/" + normalizedPath; |
77 if ((path[path.length - 1] === "/") || (segments[segments.length - 1] === ". ") || (segments[segments.length - 1] === "..")) | 78 if ((path[path.length - 1] === "/") || (segments[segments.length - 1] === ". ") || (segments[segments.length - 1] === "..")) |
78 normalizedPath = normalizedPath + "/"; | 79 normalizedPath = normalizedPath + "/"; |
79 | 80 |
80 return normalizedPath; | 81 return normalizedPath; |
81 } | 82 } |
82 | 83 |
83 /** | 84 /** |
84 * This function behavior depends on the "debug_devtools" flag value. | |
85 * - In debug mode it loads scripts synchronously via xhr request. | |
86 * - In release mode every occurrence of "importScript" in the js files | |
87 * that have been whitelisted in the build system gets replaced with | |
88 * the script source code on the compilation phase. | |
89 * The build system will throw an exception if it finds an importScript() call | |
90 * in other files. | |
91 * | |
92 * To load scripts lazily in release mode call "loadScript" function. | |
93 * @param {string} scriptName | 85 * @param {string} scriptName |
94 */ | 86 */ |
95 function importScript(scriptName) | 87 function loadScript(scriptName) |
96 { | 88 { |
97 var sourceURL = self._importScriptPathPrefix + scriptName; | 89 var sourceURL = self._importScriptPathPrefix + scriptName; |
98 var schemaIndex = sourceURL.indexOf("://") + 3; | 90 var schemaIndex = sourceURL.indexOf("://") + 3; |
99 sourceURL = sourceURL.substring(0, schemaIndex) + normalizePath(sourceURL.su bstring(schemaIndex)); | 91 sourceURL = sourceURL.substring(0, schemaIndex) + normalizePath(sourceURL.su bstring(schemaIndex)); |
100 if (_importedScripts[sourceURL]) | 92 if (_importedScripts[sourceURL]) |
101 return; | 93 return; |
102 _importedScripts[sourceURL] = true; | 94 _importedScripts[sourceURL] = true; |
103 var scriptSource = loadResource(sourceURL); | 95 var scriptSource = loadResource(sourceURL); |
104 if (!scriptSource) | 96 if (!scriptSource) |
105 throw "empty response arrived for script '" + sourceURL + "'"; | 97 throw "empty response arrived for script '" + sourceURL + "'"; |
106 var oldPrefix = self._importScriptPathPrefix; | 98 var oldPrefix = self._importScriptPathPrefix; |
107 self._importScriptPathPrefix += scriptName.substring(0, scriptName.lastIndex Of("/") + 1); | 99 self._importScriptPathPrefix += scriptName.substring(0, scriptName.lastIndex Of("/") + 1); |
108 try { | 100 try { |
109 self.eval(scriptSource + "\n//# sourceURL=" + sourceURL); | 101 self.eval(scriptSource + "\n//# sourceURL=" + sourceURL); |
110 } finally { | 102 } finally { |
111 self._importScriptPathPrefix = oldPrefix; | 103 self._importScriptPathPrefix = oldPrefix; |
112 } | 104 } |
113 } | 105 } |
114 | 106 |
115 (function() { | 107 (function() { |
116 var baseUrl = location.origin + location.pathname; | 108 var baseUrl = location.origin + location.pathname; |
117 self._importScriptPathPrefix = baseUrl.substring(0, baseUrl.lastIndexOf("/") + 1); | 109 self._importScriptPathPrefix = baseUrl.substring(0, baseUrl.lastIndexOf("/") + 1); |
118 })(); | 110 })(); |
119 | 111 |
120 var loadScript = importScript; | |
121 | |
122 /** | 112 /** |
123 * @constructor | 113 * @constructor |
124 * @param {!Array.<!Runtime.ModuleDescriptor>} descriptors | |
125 */ | 114 */ |
126 var Runtime = function(descriptors) | 115 var Runtime = function() |
127 { | 116 { |
128 /** | 117 /** |
129 * @type {!Array.<!Runtime.Module>} | 118 * @type {!Array.<!Runtime.Module>} |
130 */ | 119 */ |
131 this._modules = []; | 120 this._modules = []; |
132 /** | 121 /** |
133 * @type {!Object.<string, !Runtime.Module>} | 122 * @type {!Object.<string, !Runtime.Module>} |
134 */ | 123 */ |
135 this._modulesMap = {}; | 124 this._modulesMap = {}; |
136 /** | 125 /** |
137 * @type {!Array.<!Runtime.Extension>} | 126 * @type {!Array.<!Runtime.Extension>} |
138 */ | 127 */ |
139 this._extensions = []; | 128 this._extensions = []; |
140 | 129 |
141 /** | 130 /** |
142 * @type {!Object.<string, !function(new:Object)>} | 131 * @type {!Object.<string, !function(new:Object)>} |
143 */ | 132 */ |
144 this._cachedTypeClasses = {}; | 133 this._cachedTypeClasses = {}; |
145 | 134 |
146 /** | 135 /** |
147 * @type {!Object.<string, !Runtime.ModuleDescriptor>} | 136 * @type {!Object.<string, !Runtime.ModuleDescriptor>} |
148 */ | 137 */ |
149 this._descriptorsMap = {}; | 138 this._descriptorsMap = {}; |
150 for (var i = 0; i < descriptors.length; ++i) | 139 for (var i = 0; i < allDescriptors.length; ++i) |
151 this._descriptorsMap[descriptors[i]["name"]] = descriptors[i]; | 140 this._descriptorsMap[allDescriptors[i]["name"]] = allDescriptors[i]; |
152 } | 141 } |
153 | 142 |
154 /** | 143 /** |
155 * @param {string} moduleName | 144 * @param {string} moduleName |
156 * @return {!Worker} | 145 * @return {!Worker} |
157 */ | 146 */ |
158 Runtime.startWorker = function(moduleName) | 147 Runtime.startWorker = function(moduleName) |
159 { | 148 { |
160 return new Worker(moduleName + "/_module.js"); | 149 if (allDescriptors.length) |
150 return new Worker(moduleName + ".js"); | |
151 | |
152 /** | |
153 * @suppress {checkTypes} | |
154 */ | |
155 var loader = function() { | |
156 self.onmessage = function(event) { | |
157 self.onmessage = null; | |
158 var scripts = event.data; | |
159 for (var i = 0; i < scripts.length; ++i) { | |
160 var source = scripts[i]["source"]; | |
161 self.eval(source + "\n//# sourceURL=" + scripts[i]["url"]); | |
162 } | |
163 }; | |
164 }; | |
165 | |
166 var content = loadResource(moduleName + "/module.json"); | |
167 if (!content) | |
168 throw new Error("Worker is not defined: " + moduleName + " " + new Error ().stack); | |
169 var workerJSON = JSON.parse(content); | |
170 var message = []; | |
171 var scripts = workerJSON["scripts"]; | |
172 for (var i = 0; i < scripts.length; ++i) { | |
173 message.push({ | |
174 source: loadResource(moduleName + "/" + scripts[i]), | |
175 url: self._importScriptPathPrefix + moduleName + "/" + scripts[i] | |
176 }); | |
177 } | |
178 var blob = new Blob(["(" + loader.toString() + ")()\n//# sourceURL=" + modul eName], { type: "text/javascript" }); | |
179 var workerURL = window.URL.createObjectURL(blob); | |
180 var worker = new Worker(workerURL); | |
181 worker.postMessage(message); | |
182 window.URL.revokeObjectURL(workerURL); | |
183 return worker; | |
161 } | 184 } |
162 | 185 |
163 Runtime.prototype = { | 186 Runtime.prototype = { |
164 /** | 187 /** |
165 * @param {!Array.<string>} configuration | 188 * @param {!Array.<string>} configuration |
166 */ | 189 */ |
167 registerModules: function(configuration) | 190 registerModules: function(configuration) |
168 { | 191 { |
169 for (var i = 0; i < configuration.length; ++i) | 192 for (var i = 0; i < configuration.length; ++i) |
170 this._registerModule(configuration[i]); | 193 this._registerModule(configuration[i]); |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
471 Error.stackTraceLimit = 50; | 494 Error.stackTraceLimit = 50; |
472 console.assert(false, "Module " + this._name + " is loaded from itse lf: " + new Error().stack); | 495 console.assert(false, "Module " + this._name + " is loaded from itse lf: " + new Error().stack); |
473 Error.stackTraceLimit = oldStackTraceLimit; | 496 Error.stackTraceLimit = oldStackTraceLimit; |
474 return; | 497 return; |
475 } | 498 } |
476 | 499 |
477 this._isLoading = true; | 500 this._isLoading = true; |
478 var dependencies = this._descriptor.dependencies; | 501 var dependencies = this._descriptor.dependencies; |
479 for (var i = 0; dependencies && i < dependencies.length; ++i) | 502 for (var i = 0; dependencies && i < dependencies.length; ++i) |
480 this._manager.loadModule(dependencies[i]); | 503 this._manager.loadModule(dependencies[i]); |
481 if (this._descriptor.scripts) | 504 if (this._descriptor.scripts) { |
482 loadScript(this._name + "/_module.js"); | 505 if (allDescriptors.length) { |
506 loadScript(this._name + ".js"); | |
507 } else { | |
508 var scripts = this._descriptor.scripts; | |
509 for (var i = 0; i < scripts.length; ++i) | |
510 loadScript(this._name + "/" + scripts[i]); | |
511 } | |
512 } | |
483 this._isLoading = false; | 513 this._isLoading = false; |
484 this._loaded = true; | 514 this._loaded = true; |
485 } | 515 } |
486 } | 516 } |
487 | 517 |
488 /** | 518 /** |
489 * @constructor | 519 * @constructor |
490 * @param {!Runtime.Module} module | 520 * @param {!Runtime.Module} module |
491 * @param {!Runtime.ExtensionDescriptor} descriptor | 521 * @param {!Runtime.ExtensionDescriptor} descriptor |
492 */ | 522 */ |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
558 this._instance = new constructorFunction(); | 588 this._instance = new constructorFunction(); |
559 } | 589 } |
560 return this._instance; | 590 return this._instance; |
561 } | 591 } |
562 } | 592 } |
563 | 593 |
564 /** | 594 /** |
565 * @type {!Runtime} | 595 * @type {!Runtime} |
566 */ | 596 */ |
567 var runtime; | 597 var runtime; |
OLD | NEW |