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 17 matching lines...) Expand all Loading... | |
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 // This gets all concatenated module descriptors in the release mode. | 31 // This gets all concatenated module descriptors in the release mode. |
32 var allDescriptors = []; | 32 var allDescriptors = []; |
33 var applicationDescriptor; | 33 var applicationDescriptor; |
34 var _loadedScripts = {}; | 34 var _loadedScripts = {}; |
35 | 35 |
36 /** | 36 /** |
37 * @param {string} url | 37 * @param {string} url |
38 * @return {string} | |
39 */ | |
40 function loadResource(url) | |
41 { | |
42 var xhr = new XMLHttpRequest(); | |
43 xhr.open("GET", url, false); | |
44 try { | |
45 xhr.send(null); | |
46 } catch (e) { | |
47 console.error(url + " -> " + new Error().stack); | |
48 throw e; | |
49 } | |
50 // xhr.status === 0 if loading from bundle. | |
51 return xhr.status < 400 ? xhr.responseText : ""; | |
52 } | |
53 | |
54 /** | |
55 * @param {string} url | |
56 * @return {!Promise.<string>} | 38 * @return {!Promise.<string>} |
57 */ | 39 */ |
58 function loadResourcePromise(url) | 40 function loadResourcePromise(url) |
59 { | 41 { |
60 return new Promise(load); | 42 return new Promise(load); |
61 | 43 |
62 /** | 44 /** |
63 * @param {function(?)} fulfill | 45 * @param {function(?)} fulfill |
64 * @param {function(*)} reject | 46 * @param {function(*)} reject |
65 */ | 47 */ |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 * @return {boolean} | 209 * @return {boolean} |
228 */ | 210 */ |
229 Runtime.isReleaseMode = function() | 211 Runtime.isReleaseMode = function() |
230 { | 212 { |
231 return !!allDescriptors.length; | 213 return !!allDescriptors.length; |
232 } | 214 } |
233 | 215 |
234 /** | 216 /** |
235 * @param {string} moduleName | 217 * @param {string} moduleName |
236 * @param {string} workerName | 218 * @param {string} workerName |
237 * @return {!SharedWorker} | 219 * @return {!Promise.<!SharedWorker>} |
238 */ | 220 */ |
239 Runtime.startSharedWorker = function(moduleName, workerName) | 221 Runtime.startSharedWorker = function(moduleName, workerName) |
240 { | 222 { |
241 if (Runtime.isReleaseMode()) | 223 if (Runtime.isReleaseMode()) |
242 return new SharedWorker(moduleName + "_module.js", workerName); | 224 return Promise.resolve(new SharedWorker(moduleName + "_module.js", worke rName)); |
243 | 225 |
244 var content = loadResource(moduleName + "/module.json"); | 226 return loadResourcePromise(moduleName + "/module.json").then(start, start.bi nd(null, undefined)); |
245 if (!content) | 227 |
246 throw new Error("Worker is not defined: " + moduleName + " " + new Error ().stack); | 228 /** |
247 var scripts = JSON.parse(content)["scripts"]; | 229 * @param {string=} content |
248 if (scripts.length !== 1) | 230 */ |
249 throw Error("Runtime.startSharedWorker supports modules with only one sc ript!"); | 231 function start(content) |
250 return new SharedWorker(moduleName + "/" + scripts[0], workerName); | 232 { |
233 if (!content) | |
234 throw new Error("Worker is not defined: " + moduleName + " " + new E rror().stack); | |
235 var scripts = JSON.parse(content)["scripts"]; | |
236 if (scripts.length !== 1) | |
237 throw new Error("Runtime.startSharedWorker supports modules with onl y one script!"); | |
238 return new SharedWorker(moduleName + "/" + scripts[0], workerName); | |
239 } | |
251 } | 240 } |
252 | 241 |
253 /** | 242 /** |
254 * @param {string} moduleName | 243 * @param {string} moduleName |
255 * @return {!Worker} | 244 * @return {!Promise.<!Worker>} |
256 */ | 245 */ |
257 Runtime.startWorker = function(moduleName) | 246 Runtime.startWorker = function(moduleName) |
pfeldman
2014/11/07 14:51:17
Lets extract WorkerRuntime.
apavlov
2014/11/10 07:44:11
Done.
| |
258 { | 247 { |
259 if (Runtime.isReleaseMode()) | 248 if (Runtime.isReleaseMode()) |
260 return new Worker(moduleName + "_module.js"); | 249 return Promise.resolve(new Worker(moduleName + "_module.js")); |
261 | |
262 var content = loadResource(moduleName + "/module.json"); | |
263 if (!content) | |
264 throw new Error("Worker is not defined: " + moduleName + " " + new Error ().stack); | |
265 var message = []; | |
266 var scripts = JSON.parse(content)["scripts"]; | |
267 for (var i = 0; i < scripts.length; ++i) { | |
268 var url = self._importScriptPathPrefix + moduleName + "/" + scripts[i]; | |
269 var parts = url.split("://"); | |
270 url = parts.length === 1 ? url : parts[0] + "://" + normalizePath(parts[ 1]); | |
271 message.push({ | |
272 source: loadResource(moduleName + "/" + scripts[i]), | |
273 url: url | |
274 }); | |
275 } | |
276 | 250 |
277 /** | 251 /** |
278 * @suppress {checkTypes} | 252 * @suppress {checkTypes} |
279 */ | 253 */ |
280 var loader = function() { | 254 var loader = function() { |
281 self.onmessage = function(event) { | 255 self.onmessage = function(event) { |
282 self.onmessage = null; | 256 self.onmessage = null; |
283 var scripts = event.data; | 257 var scripts = event.data; |
284 for (var i = 0; i < scripts.length; ++i) { | 258 for (var i = 0; i < scripts.length; ++i) { |
285 var source = scripts[i]["source"]; | 259 var source = scripts[i]["source"]; |
286 self.eval(source + "\n//# sourceURL=" + scripts[i]["url"]); | 260 self.eval(source + "\n//# sourceURL=" + scripts[i]["url"]); |
287 } | 261 } |
288 }; | 262 }; |
289 }; | 263 }; |
290 | 264 |
291 var blob = new Blob(["(" + loader.toString() + ")()\n//# sourceURL=" + modul eName], { type: "text/javascript" }); | 265 return loadResourcePromise(moduleName + "/module.json").then(start, start.bi nd(null, undefined)); |
292 var workerURL = window.URL.createObjectURL(blob); | 266 |
293 try { | 267 /** |
294 var worker = new Worker(workerURL); | 268 * @param {string=} content |
295 worker.postMessage(message); | 269 */ |
296 return worker; | 270 function start(content) |
297 } finally { | 271 { |
298 window.URL.revokeObjectURL(workerURL); | 272 if (!content) |
273 throw new Error("Worker is not defined: " + moduleName + " " + new E rror().stack); | |
274 var message = []; | |
275 var scripts = JSON.parse(content)["scripts"]; | |
276 var promise = Promise.resolve(); | |
277 for (var i = 0; i < scripts.length; ++i) { | |
278 var url = self._importScriptPathPrefix + moduleName + "/" + scripts[ i]; | |
279 var parts = url.split("://"); | |
280 url = parts.length === 1 ? url : parts[0] + "://" + normalizePath(pa rts[1]); | |
281 promise = promise.then(promiseGetter(loadResourcePromise(moduleName + "/" + scripts[i]))).then(pushSource.bind(null, url), pushSource.bind(null, nul l, null)); | |
282 } | |
283 | |
284 return promise.then(createWorker); | |
285 | |
286 function promiseGetter(promise) | |
287 { | |
288 return function() { | |
289 return promise; | |
290 }; | |
291 } | |
292 | |
293 /** | |
294 * @param {?string} url | |
295 * @param {?string} source | |
296 */ | |
297 function pushSource(url, source) | |
298 { | |
299 if (!url) { | |
300 console.error("Failed to load " + url); | |
301 return; | |
302 } | |
303 message.push({ source: source, url: url }); | |
304 } | |
305 | |
306 /** | |
307 * @return {!Worker} | |
308 */ | |
309 function createWorker() | |
310 { | |
311 var blob = new Blob(["(" + loader.toString() + ")()\n//# sourceURL=" + moduleName], { type: "text/javascript" }); | |
312 var workerURL = window.URL.createObjectURL(blob); | |
313 try { | |
314 var worker = new Worker(workerURL); | |
315 worker.postMessage(message); | |
316 return worker; | |
317 } finally { | |
318 window.URL.revokeObjectURL(workerURL); | |
319 } | |
320 } | |
299 } | 321 } |
300 } | 322 } |
301 | 323 |
302 /** | 324 /** |
303 * @param {string} appName | 325 * @param {string} appName |
304 */ | 326 */ |
305 Runtime.startApplication = function(appName) | 327 Runtime.startApplication = function(appName) |
306 { | 328 { |
307 console.timeStamp("Runtime.startApplication"); | 329 console.timeStamp("Runtime.startApplication"); |
308 | 330 |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
718 | 740 |
719 if (this._pendingLoadPromise) | 741 if (this._pendingLoadPromise) |
720 return this._pendingLoadPromise; | 742 return this._pendingLoadPromise; |
721 | 743 |
722 var dependencies = this._descriptor.dependencies; | 744 var dependencies = this._descriptor.dependencies; |
723 var dependencyPromises = []; | 745 var dependencyPromises = []; |
724 for (var i = 0; dependencies && i < dependencies.length; ++i) | 746 for (var i = 0; dependencies && i < dependencies.length; ++i) |
725 dependencyPromises.push(this._manager._modulesMap[dependencies[i]]._ loadPromise()); | 747 dependencyPromises.push(this._manager._modulesMap[dependencies[i]]._ loadPromise()); |
726 | 748 |
727 this._pendingLoadPromise = Promise.all(dependencyPromises) | 749 this._pendingLoadPromise = Promise.all(dependencyPromises) |
750 .then(loadStylesheetsPromise.bind(this)) | |
pfeldman
2014/11/07 14:51:17
make a prototype method? _loadStyleSheets (similar
apavlov
2014/11/10 07:44:11
Done.
| |
728 .then(this._loadScripts.bind(this)) | 751 .then(this._loadScripts.bind(this)) |
729 .then(markAsLoaded.bind(this)); | 752 .then(markAsLoaded.bind(this)); |
730 | 753 |
731 return this._pendingLoadPromise; | 754 return this._pendingLoadPromise; |
732 | 755 |
733 /** | 756 /** |
757 * @return {!Promise.<undefined>} | |
758 * @this {Runtime.Module} | |
759 */ | |
760 function loadStylesheetsPromise() | |
761 { | |
762 var stylesheets = this._descriptor["stylesheets"]; | |
763 if (!stylesheets) | |
764 return Promise.resolve(); | |
765 var promises = []; | |
766 for (var i = 0; i < stylesheets.length; ++i) { | |
767 var url = this._modularizeURL(stylesheets[i]); | |
768 promises.push(loadResourcePromise(url).then(cacheStylesheet.bind (this, url), cacheStylesheet.bind(this, url, undefined))); | |
769 } | |
770 return Promise.all(promises).then(undefined); | |
771 } | |
772 | |
773 /** | |
774 * @param {string} path | |
775 * @param {string=} content | |
776 */ | |
777 function cacheStylesheet(path, content) | |
778 { | |
779 if (!content) { | |
780 console.error("Failed to load stylesheet: " + path); | |
781 return; | |
782 } | |
783 Runtime.cachedResources[path] = content; | |
784 } | |
785 | |
786 /** | |
734 * @this {Runtime.Module} | 787 * @this {Runtime.Module} |
735 */ | 788 */ |
736 function markAsLoaded() | 789 function markAsLoaded() |
737 { | 790 { |
738 delete this._pendingLoadPromise; | 791 delete this._pendingLoadPromise; |
739 this._loaded = true; | 792 this._loaded = true; |
740 } | 793 } |
741 }, | 794 }, |
742 | 795 |
743 /** | 796 /** |
744 * @return {!Promise.<undefined>} | 797 * @return {!Promise.<undefined>} |
745 */ | 798 */ |
746 _loadScripts: function() | 799 _loadScripts: function() |
747 { | 800 { |
748 if (!this._descriptor.scripts) | 801 if (!this._descriptor.scripts) |
749 return Promise.resolve(undefined); | 802 return Promise.resolve(undefined); |
750 | 803 |
751 if (Runtime.isReleaseMode()) | 804 if (Runtime.isReleaseMode()) |
752 return loadScriptsPromise([this._name + "_module.js"]); | 805 return loadScriptsPromise([this._name + "_module.js"]); |
753 | 806 |
754 return loadScriptsPromise(this._descriptor.scripts.map(modularizeURL, th is)).catch(Runtime._reportError); | 807 return loadScriptsPromise(this._descriptor.scripts.map(this._modularizeU RL, this)).catch(Runtime._reportError); |
755 | |
756 /** | |
757 * @param {string} scriptName | |
758 * @this {Runtime.Module} | |
759 */ | |
760 function modularizeURL(scriptName) | |
761 { | |
762 return this._name + "/" + scriptName; | |
763 } | |
764 }, | 808 }, |
765 | 809 |
766 /** | 810 /** |
811 * @param {string} scriptName | |
812 */ | |
813 _modularizeURL: function(scriptName) | |
814 { | |
815 return normalizePath(this._name + "/" + scriptName); | |
816 }, | |
817 | |
818 /** | |
767 * @param {string} className | 819 * @param {string} className |
768 * @return {?Object} | 820 * @return {?Object} |
769 */ | 821 */ |
770 _instance: function(className) | 822 _instance: function(className) |
771 { | 823 { |
772 if (className in this._instanceMap) | 824 if (className in this._instanceMap) |
773 return this._instanceMap[className]; | 825 return this._instanceMap[className]; |
774 | 826 |
775 var constructorFunction = window.eval(className); | 827 var constructorFunction = window.eval(className); |
776 if (!(constructorFunction instanceof Function)) { | 828 if (!(constructorFunction instanceof Function)) { |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1047 } | 1099 } |
1048 } | 1100 } |
1049 })();} | 1101 })();} |
1050 | 1102 |
1051 | 1103 |
1052 // This must be constructed after the query parameters have been parsed. | 1104 // This must be constructed after the query parameters have been parsed. |
1053 Runtime.experiments = new Runtime.ExperimentsSupport(); | 1105 Runtime.experiments = new Runtime.ExperimentsSupport(); |
1054 | 1106 |
1055 /** @type {!Runtime} */ | 1107 /** @type {!Runtime} */ |
1056 var runtime; | 1108 var runtime; |
OLD | NEW |