Chromium Code Reviews| 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 _importedScripts = {}; | 31 var allDescriptors = []; |
|
lushnikov
2014/08/15 14:23:13
let's clarify how/when it gets some values
apavlov
2014/08/15 14:54:45
Done.
| |
| 32 var _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 (_loadedScripts[sourceURL]) |
| 101 return; | 93 return; |
| 102 _importedScripts[sourceURL] = true; | 94 _loadedScripts[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); | |
|
lushnikov
2014/08/15 14:23:13
lets inline
apavlov
2014/08/15 14:54:45
Done.
| |
| 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] | |
|
lushnikov
2014/08/15 14:23:13
lets normalize path here
apavlov
2014/08/15 14:54:45
Done.
| |
| 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); | |
|
lushnikov
2014/08/15 14:23:13
lets do this in finally to not leak memory
apavlov
2014/08/15 14:54:45
Done.
| |
| 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) { |
|
lushnikov
2014/08/15 14:23:13
lets introduce isRelease() on Runtime
apavlov
2014/08/15 14:54:46
Done.
| |
| 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 |