aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/systemjs/lib/scriptLoader.js
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/systemjs/lib/scriptLoader.js')
-rw-r--r--thirdparty/systemjs/lib/scriptLoader.js196
1 files changed, 196 insertions, 0 deletions
diff --git a/thirdparty/systemjs/lib/scriptLoader.js b/thirdparty/systemjs/lib/scriptLoader.js
new file mode 100644
index 000000000..8bd1d4b3e
--- /dev/null
+++ b/thirdparty/systemjs/lib/scriptLoader.js
@@ -0,0 +1,196 @@
+/*
+ * Script tag fetch
+ *
+ * When load.metadata.scriptLoad is true, we load via script tag injection.
+ */
+(function() {
+
+ if (typeof document != 'undefined')
+ var head = document.getElementsByTagName('head')[0];
+
+ var curSystem;
+ var curRequire;
+
+ // if doing worker executing, this is set to the load record being executed
+ var workerLoad = null;
+
+ // interactive mode handling method courtesy RequireJS
+ var ieEvents = head && (function() {
+ var s = document.createElement('script');
+ var isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]';
+ return s.attachEvent && !(s.attachEvent.toString && s.attachEvent.toString().indexOf('[native code') < 0) && !isOpera;
+ })();
+
+ // IE interactive-only part
+ // we store loading scripts array as { script: <script>, load: {...} }
+ var interactiveLoadingScripts = [];
+ var interactiveScript;
+ function getInteractiveScriptLoad() {
+ if (interactiveScript && interactiveScript.script.readyState === 'interactive')
+ return interactiveScript.load;
+
+ for (var i = 0; i < interactiveLoadingScripts.length; i++)
+ if (interactiveLoadingScripts[i].script.readyState == 'interactive') {
+ interactiveScript = interactiveLoadingScripts[i];
+ return interactiveScript.load;
+ }
+ }
+
+ // System.register, System.registerDynamic, AMD define pipeline
+ // this is called by the above methods when they execute
+ // we then run the reduceRegister_ collection function either immediately
+ // if we are in IE and know the currently executing script (interactive)
+ // or later if we need to wait for the synchronous load callback to know the script
+ var loadingCnt = 0;
+ var registerQueue = [];
+ hook('pushRegister_', function(pushRegister) {
+ return function(register) {
+ // if using eval-execution then skip
+ if (pushRegister.call(this, register))
+ return false;
+
+ // if using worker execution, then we're done
+ if (workerLoad)
+ this.reduceRegister_(workerLoad, register);
+
+ // detect if we know the currently executing load (IE)
+ // if so, immediately call reduceRegister
+ else if (ieEvents)
+ this.reduceRegister_(getInteractiveScriptLoad(), register);
+
+ // otherwise, add to our execution queue
+ // to call reduceRegister on sync script load event
+ else if (loadingCnt)
+ registerQueue.push(register);
+
+ // if we're not currently loading anything though
+ // then do the reduction against a null load
+ // (out of band named define or named register)
+ // note even in non-script environments, this catch is used
+ else
+ this.reduceRegister_(null, register);
+
+ return true;
+ };
+ });
+
+ function webWorkerImport(loader, load) {
+ return new Promise(function(resolve, reject) {
+ if (load.metadata.integrity)
+ reject(new Error('Subresource integrity checking is not supported in web workers.'));
+
+ workerLoad = load;
+ try {
+ importScripts(load.address);
+ }
+ catch(e) {
+ workerLoad = null;
+ reject(e);
+ }
+ workerLoad = null;
+
+ // if nothing registered, then something went wrong
+ if (!load.metadata.entry)
+ reject(new Error(load.address + ' did not call System.register or AMD define. If loading a global, ensure the meta format is set to global.'));
+
+ resolve('');
+ });
+ }
+
+ // override fetch to use script injection
+ hook('fetch', function(fetch) {
+ return function(load) {
+ var loader = this;
+
+ if (load.metadata.format == 'json' || !load.metadata.scriptLoad || (!isBrowser && !isWorker))
+ return fetch.call(this, load);
+
+ if (isWorker)
+ return webWorkerImport(loader, load);
+
+ return new Promise(function(resolve, reject) {
+ var s = document.createElement('script');
+
+ s.async = true;
+
+ if (load.metadata.crossOrigin)
+ s.crossOrigin = load.metadata.crossOrigin;
+
+ if (load.metadata.integrity)
+ s.setAttribute('integrity', load.metadata.integrity);
+
+ if (ieEvents) {
+ s.attachEvent('onreadystatechange', complete);
+ interactiveLoadingScripts.push({
+ script: s,
+ load: load
+ });
+ }
+ else {
+ s.addEventListener('load', complete, false);
+ s.addEventListener('error', error, false);
+ }
+
+ loadingCnt++;
+
+ curSystem = __global.System;
+ curRequire = __global.require;
+
+ s.src = load.address;
+ head.appendChild(s);
+
+ function complete(evt) {
+ if (s.readyState && s.readyState != 'loaded' && s.readyState != 'complete')
+ return;
+
+ loadingCnt--;
+
+ // complete call is sync on execution finish
+ // (in ie already done reductions)
+ if (!load.metadata.entry && !registerQueue.length) {
+ loader.reduceRegister_(load);
+ }
+ else if (!ieEvents) {
+ for (var i = 0; i < registerQueue.length; i++)
+ loader.reduceRegister_(load, registerQueue[i]);
+ registerQueue = [];
+ }
+
+ cleanup();
+
+ // if nothing registered, then something went wrong
+ if (!load.metadata.entry && !load.metadata.bundle)
+ reject(new Error(load.name + ' did not call System.register or AMD define. If loading a global module configure the global name via the meta exports property for script injection support.'));
+
+ resolve('');
+ }
+
+ function error(evt) {
+ cleanup();
+ reject(new Error('Unable to load script ' + load.address));
+ }
+
+ function cleanup() {
+ __global.System = curSystem;
+ __global.require = curRequire;
+
+ if (s.detachEvent) {
+ s.detachEvent('onreadystatechange', complete);
+ for (var i = 0; i < interactiveLoadingScripts.length; i++)
+ if (interactiveLoadingScripts[i].script == s) {
+ if (interactiveScript && interactiveScript.script == s)
+ interactiveScript = null;
+ interactiveLoadingScripts.splice(i, 1);
+ }
+ }
+ else {
+ s.removeEventListener('load', complete, false);
+ s.removeEventListener('error', error, false);
+ }
+
+ head.removeChild(s);
+ }
+ });
+ };
+ });
+})();