/* * 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); } }); }; }); })();