914 lines
26 KiB
JavaScript
914 lines
26 KiB
JavaScript
|
(function(__global) {
|
||
|
|
||
|
var isWorker = typeof window == 'undefined' && typeof self != 'undefined' && typeof importScripts != 'undefined';
|
||
|
var isBrowser = typeof window != 'undefined' && typeof document != 'undefined';
|
||
|
var isWindows = typeof process != 'undefined' && typeof process.platform != 'undefined' && !!process.platform.match(/^win/);
|
||
|
|
||
|
if (!__global.console)
|
||
|
__global.console = { assert: function() {} };
|
||
|
|
||
|
// IE8 support
|
||
|
var indexOf = Array.prototype.indexOf || function(item) {
|
||
|
for (var i = 0, thisLen = this.length; i < thisLen; i++) {
|
||
|
if (this[i] === item) {
|
||
|
return i;
|
||
|
}
|
||
|
}
|
||
|
return -1;
|
||
|
};
|
||
|
|
||
|
var defineProperty;
|
||
|
(function () {
|
||
|
try {
|
||
|
if (!!Object.defineProperty({}, 'a', {}))
|
||
|
defineProperty = Object.defineProperty;
|
||
|
}
|
||
|
catch (e) {
|
||
|
defineProperty = function(obj, prop, opt) {
|
||
|
try {
|
||
|
obj[prop] = opt.value || opt.get.call(obj);
|
||
|
}
|
||
|
catch(e) {}
|
||
|
}
|
||
|
}
|
||
|
})();
|
||
|
|
||
|
var errArgs = new Error(0, '_').fileName == '_';
|
||
|
|
||
|
function addToError(err, msg) {
|
||
|
// parse the stack removing loader code lines for simplification
|
||
|
if (!err.originalErr) {
|
||
|
var stack = ((err.message || err) + (err.stack ? '\n' + err.stack : '')).toString().split('\n');
|
||
|
var newStack = [];
|
||
|
for (var i = 0; i < stack.length; i++) {
|
||
|
if (typeof $__curScript == 'undefined' || stack[i].indexOf($__curScript.src) == -1)
|
||
|
newStack.push(stack[i]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var newMsg = '(SystemJS) ' + (newStack ? newStack.join('\n\t') : err.message.substr(11)) + '\n\t' + msg;
|
||
|
|
||
|
// Convert file:/// URLs to paths in Node
|
||
|
if (!isBrowser)
|
||
|
newMsg = newMsg.replace(isWindows ? /file:\/\/\//g : /file:\/\//g, '');
|
||
|
|
||
|
var newErr = errArgs ? new Error(newMsg, err.fileName, err.lineNumber) : new Error(newMsg);
|
||
|
|
||
|
newErr.stack = newMsg;
|
||
|
|
||
|
// track the original error
|
||
|
newErr.originalErr = err.originalErr || err;
|
||
|
|
||
|
return newErr;
|
||
|
}
|
||
|
|
||
|
function __eval(source, debugName, context) {
|
||
|
try {
|
||
|
new Function(source).call(context);
|
||
|
}
|
||
|
catch(e) {
|
||
|
throw addToError(e, 'Evaluating ' + debugName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var baseURI;
|
||
|
|
||
|
// environent baseURI detection
|
||
|
if (typeof document != 'undefined' && document.getElementsByTagName) {
|
||
|
baseURI = document.baseURI;
|
||
|
|
||
|
if (!baseURI) {
|
||
|
var bases = document.getElementsByTagName('base');
|
||
|
baseURI = bases[0] && bases[0].href || window.location.href;
|
||
|
}
|
||
|
}
|
||
|
else if (typeof location != 'undefined') {
|
||
|
baseURI = __global.location.href;
|
||
|
}
|
||
|
|
||
|
// sanitize out the hash and querystring
|
||
|
if (baseURI) {
|
||
|
baseURI = baseURI.split('#')[0].split('?')[0];
|
||
|
baseURI = baseURI.substr(0, baseURI.lastIndexOf('/') + 1);
|
||
|
}
|
||
|
else if (typeof process != 'undefined' && process.cwd) {
|
||
|
baseURI = 'file://' + (isWindows ? '/' : '') + process.cwd() + '/';
|
||
|
if (isWindows)
|
||
|
baseURI = baseURI.replace(/\\/g, '/');
|
||
|
}
|
||
|
else {
|
||
|
throw new TypeError('No environment baseURI');
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
var nativeURL = new __global.URL('test:///').protocol == 'test:';
|
||
|
}
|
||
|
catch(e) {}
|
||
|
|
||
|
var URL = nativeURL ? __global.URL : __global.URLPolyfill;
|
||
|
|
||
|
/*
|
||
|
*********************************************************************************************
|
||
|
|
||
|
Dynamic Module Loader Polyfill
|
||
|
|
||
|
- Implemented exactly to the former 2014-08-24 ES6 Specification Draft Rev 27, Section 15
|
||
|
http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts#august_24_2014_draft_rev_27
|
||
|
|
||
|
- Functions are commented with their spec numbers, with spec differences commented.
|
||
|
|
||
|
- Spec bugs are commented in this code with links.
|
||
|
|
||
|
- Abstract functions have been combined where possible, and their associated functions
|
||
|
commented.
|
||
|
|
||
|
- Realm implementation is entirely omitted.
|
||
|
|
||
|
*********************************************************************************************
|
||
|
*/
|
||
|
|
||
|
function Module() {}
|
||
|
// http://www.ecma-international.org/ecma-262/6.0/#sec-@@tostringtag
|
||
|
defineProperty(Module.prototype, 'toString', {
|
||
|
value: function() {
|
||
|
return 'Module';
|
||
|
}
|
||
|
});
|
||
|
function Loader(options) {
|
||
|
this._loader = {
|
||
|
loaderObj: this,
|
||
|
loads: [],
|
||
|
modules: {},
|
||
|
importPromises: {},
|
||
|
moduleRecords: {}
|
||
|
};
|
||
|
|
||
|
// 26.3.3.6
|
||
|
defineProperty(this, 'global', {
|
||
|
get: function() {
|
||
|
return __global;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 26.3.3.13 realm not implemented
|
||
|
}
|
||
|
|
||
|
(function() {
|
||
|
|
||
|
// Some Helpers
|
||
|
|
||
|
// logs a linkset snapshot for debugging
|
||
|
/* function snapshot(loader) {
|
||
|
console.log('---Snapshot---');
|
||
|
for (var i = 0; i < loader.loads.length; i++) {
|
||
|
var load = loader.loads[i];
|
||
|
var linkSetLog = ' ' + load.name + ' (' + load.status + '): ';
|
||
|
|
||
|
for (var j = 0; j < load.linkSets.length; j++) {
|
||
|
linkSetLog += '{' + logloads(load.linkSets[j].loads) + '} ';
|
||
|
}
|
||
|
console.log(linkSetLog);
|
||
|
}
|
||
|
console.log('');
|
||
|
}
|
||
|
function logloads(loads) {
|
||
|
var log = '';
|
||
|
for (var k = 0; k < loads.length; k++)
|
||
|
log += loads[k].name + (k != loads.length - 1 ? ' ' : '');
|
||
|
return log;
|
||
|
} */
|
||
|
|
||
|
|
||
|
/* function checkInvariants() {
|
||
|
// see https://bugs.ecmascript.org/show_bug.cgi?id=2603#c1
|
||
|
|
||
|
var loads = System._loader.loads;
|
||
|
var linkSets = [];
|
||
|
|
||
|
for (var i = 0; i < loads.length; i++) {
|
||
|
var load = loads[i];
|
||
|
console.assert(load.status == 'loading' || load.status == 'loaded', 'Each load is loading or loaded');
|
||
|
|
||
|
for (var j = 0; j < load.linkSets.length; j++) {
|
||
|
var linkSet = load.linkSets[j];
|
||
|
|
||
|
for (var k = 0; k < linkSet.loads.length; k++)
|
||
|
console.assert(loads.indexOf(linkSet.loads[k]) != -1, 'linkSet loads are a subset of loader loads');
|
||
|
|
||
|
if (linkSets.indexOf(linkSet) == -1)
|
||
|
linkSets.push(linkSet);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (var i = 0; i < loads.length; i++) {
|
||
|
var load = loads[i];
|
||
|
for (var j = 0; j < linkSets.length; j++) {
|
||
|
var linkSet = linkSets[j];
|
||
|
|
||
|
if (linkSet.loads.indexOf(load) != -1)
|
||
|
console.assert(load.linkSets.indexOf(linkSet) != -1, 'linkSet contains load -> load contains linkSet');
|
||
|
|
||
|
if (load.linkSets.indexOf(linkSet) != -1)
|
||
|
console.assert(linkSet.loads.indexOf(load) != -1, 'load contains linkSet -> linkSet contains load');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (var i = 0; i < linkSets.length; i++) {
|
||
|
var linkSet = linkSets[i];
|
||
|
for (var j = 0; j < linkSet.loads.length; j++) {
|
||
|
var load = linkSet.loads[j];
|
||
|
|
||
|
for (var k = 0; k < load.dependencies.length; k++) {
|
||
|
var depName = load.dependencies[k].value;
|
||
|
var depLoad;
|
||
|
for (var l = 0; l < loads.length; l++) {
|
||
|
if (loads[l].name != depName)
|
||
|
continue;
|
||
|
depLoad = loads[l];
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// loading records are allowed not to have their dependencies yet
|
||
|
// if (load.status != 'loading')
|
||
|
// console.assert(depLoad, 'depLoad found');
|
||
|
|
||
|
// console.assert(linkSet.loads.indexOf(depLoad) != -1, 'linkset contains all dependencies');
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} */
|
||
|
|
||
|
// 15.2.3 - Runtime Semantics: Loader State
|
||
|
|
||
|
// 15.2.3.11
|
||
|
function createLoaderLoad(object) {
|
||
|
return {
|
||
|
// modules is an object for ES5 implementation
|
||
|
modules: {},
|
||
|
loads: [],
|
||
|
loaderObj: object
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// 15.2.3.2 Load Records and LoadRequest Objects
|
||
|
|
||
|
var anonCnt = 0;
|
||
|
|
||
|
// 15.2.3.2.1
|
||
|
function createLoad(name) {
|
||
|
return {
|
||
|
status: 'loading',
|
||
|
name: name || '<Anonymous' + ++anonCnt + '>',
|
||
|
linkSets: [],
|
||
|
dependencies: [],
|
||
|
metadata: {}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
// 15.2.3.2.2 createLoadRequestObject, absorbed into calling functions
|
||
|
|
||
|
// 15.2.4
|
||
|
|
||
|
// 15.2.4.1
|
||
|
function loadModule(loader, name, options) {
|
||
|
return new Promise(asyncStartLoadPartwayThrough({
|
||
|
step: options.address ? 'fetch' : 'locate',
|
||
|
loader: loader,
|
||
|
moduleName: name,
|
||
|
// allow metadata for import https://bugs.ecmascript.org/show_bug.cgi?id=3091
|
||
|
moduleMetadata: options && options.metadata || {},
|
||
|
moduleSource: options.source,
|
||
|
moduleAddress: options.address
|
||
|
}));
|
||
|
}
|
||
|
|
||
|
// 15.2.4.2
|
||
|
function requestLoad(loader, request, refererName, refererAddress) {
|
||
|
// 15.2.4.2.1 CallNormalize
|
||
|
return new Promise(function(resolve, reject) {
|
||
|
resolve(loader.loaderObj.normalize(request, refererName, refererAddress));
|
||
|
})
|
||
|
// 15.2.4.2.2 GetOrCreateLoad
|
||
|
.then(function(name) {
|
||
|
var load;
|
||
|
if (loader.modules[name]) {
|
||
|
load = createLoad(name);
|
||
|
load.status = 'linked';
|
||
|
// https://bugs.ecmascript.org/show_bug.cgi?id=2795
|
||
|
load.module = loader.modules[name];
|
||
|
return load;
|
||
|
}
|
||
|
|
||
|
for (var i = 0, l = loader.loads.length; i < l; i++) {
|
||
|
load = loader.loads[i];
|
||
|
if (load.name != name)
|
||
|
continue;
|
||
|
return load;
|
||
|
}
|
||
|
|
||
|
load = createLoad(name);
|
||
|
loader.loads.push(load);
|
||
|
|
||
|
proceedToLocate(loader, load);
|
||
|
|
||
|
return load;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// 15.2.4.3
|
||
|
function proceedToLocate(loader, load) {
|
||
|
proceedToFetch(loader, load,
|
||
|
Promise.resolve()
|
||
|
// 15.2.4.3.1 CallLocate
|
||
|
.then(function() {
|
||
|
return loader.loaderObj.locate({ name: load.name, metadata: load.metadata });
|
||
|
})
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// 15.2.4.4
|
||
|
function proceedToFetch(loader, load, p) {
|
||
|
proceedToTranslate(loader, load,
|
||
|
p
|
||
|
// 15.2.4.4.1 CallFetch
|
||
|
.then(function(address) {
|
||
|
// adjusted, see https://bugs.ecmascript.org/show_bug.cgi?id=2602
|
||
|
if (load.status != 'loading')
|
||
|
return;
|
||
|
load.address = address;
|
||
|
|
||
|
return loader.loaderObj.fetch({ name: load.name, metadata: load.metadata, address: address });
|
||
|
})
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// 15.2.4.5
|
||
|
function proceedToTranslate(loader, load, p) {
|
||
|
p
|
||
|
// 15.2.4.5.1 CallTranslate
|
||
|
.then(function(source) {
|
||
|
if (load.status != 'loading')
|
||
|
return;
|
||
|
|
||
|
load.address = load.address || load.name;
|
||
|
|
||
|
return Promise.resolve(loader.loaderObj.translate({ name: load.name, metadata: load.metadata, address: load.address, source: source }))
|
||
|
|
||
|
// 15.2.4.5.2 CallInstantiate
|
||
|
.then(function(source) {
|
||
|
load.source = source;
|
||
|
return loader.loaderObj.instantiate({ name: load.name, metadata: load.metadata, address: load.address, source: source });
|
||
|
})
|
||
|
|
||
|
// 15.2.4.5.3 InstantiateSucceeded
|
||
|
.then(function(instantiateResult) {
|
||
|
if (instantiateResult === undefined)
|
||
|
throw new TypeError('Declarative modules unsupported in the polyfill.');
|
||
|
|
||
|
if (typeof instantiateResult != 'object')
|
||
|
throw new TypeError('Invalid instantiate return value');
|
||
|
|
||
|
load.depsList = instantiateResult.deps || [];
|
||
|
load.execute = instantiateResult.execute;
|
||
|
})
|
||
|
// 15.2.4.6 ProcessLoadDependencies
|
||
|
.then(function() {
|
||
|
load.dependencies = [];
|
||
|
var depsList = load.depsList;
|
||
|
|
||
|
var loadPromises = [];
|
||
|
for (var i = 0, l = depsList.length; i < l; i++) (function(request, index) {
|
||
|
loadPromises.push(
|
||
|
requestLoad(loader, request, load.name, load.address)
|
||
|
|
||
|
// 15.2.4.6.1 AddDependencyLoad (load is parentLoad)
|
||
|
.then(function(depLoad) {
|
||
|
|
||
|
// adjusted from spec to maintain dependency order
|
||
|
// this is due to the System.register internal implementation needs
|
||
|
load.dependencies[index] = {
|
||
|
key: request,
|
||
|
value: depLoad.name
|
||
|
};
|
||
|
|
||
|
if (depLoad.status != 'linked') {
|
||
|
var linkSets = load.linkSets.concat([]);
|
||
|
for (var i = 0, l = linkSets.length; i < l; i++)
|
||
|
addLoadToLinkSet(linkSets[i], depLoad);
|
||
|
}
|
||
|
|
||
|
// console.log('AddDependencyLoad ' + depLoad.name + ' for ' + load.name);
|
||
|
// snapshot(loader);
|
||
|
})
|
||
|
);
|
||
|
})(depsList[i], i);
|
||
|
|
||
|
return Promise.all(loadPromises);
|
||
|
})
|
||
|
|
||
|
// 15.2.4.6.2 LoadSucceeded
|
||
|
.then(function() {
|
||
|
// console.log('LoadSucceeded ' + load.name);
|
||
|
// snapshot(loader);
|
||
|
|
||
|
load.status = 'loaded';
|
||
|
|
||
|
var linkSets = load.linkSets.concat([]);
|
||
|
for (var i = 0, l = linkSets.length; i < l; i++)
|
||
|
updateLinkSetOnLoad(linkSets[i], load);
|
||
|
});
|
||
|
})
|
||
|
// 15.2.4.5.4 LoadFailed
|
||
|
['catch'](function(exc) {
|
||
|
load.status = 'failed';
|
||
|
load.exception = exc;
|
||
|
|
||
|
var linkSets = load.linkSets.concat([]);
|
||
|
for (var i = 0, l = linkSets.length; i < l; i++) {
|
||
|
linkSetFailed(linkSets[i], load, exc);
|
||
|
}
|
||
|
|
||
|
console.assert(load.linkSets.length == 0, 'linkSets not removed');
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// 15.2.4.7 PromiseOfStartLoadPartwayThrough absorbed into calling functions
|
||
|
|
||
|
// 15.2.4.7.1
|
||
|
function asyncStartLoadPartwayThrough(stepState) {
|
||
|
return function(resolve, reject) {
|
||
|
var loader = stepState.loader;
|
||
|
var name = stepState.moduleName;
|
||
|
var step = stepState.step;
|
||
|
|
||
|
if (loader.modules[name])
|
||
|
throw new TypeError('"' + name + '" already exists in the module table');
|
||
|
|
||
|
// adjusted to pick up existing loads
|
||
|
var existingLoad;
|
||
|
for (var i = 0, l = loader.loads.length; i < l; i++) {
|
||
|
if (loader.loads[i].name == name) {
|
||
|
existingLoad = loader.loads[i];
|
||
|
|
||
|
if (step == 'translate' && !existingLoad.source) {
|
||
|
existingLoad.address = stepState.moduleAddress;
|
||
|
proceedToTranslate(loader, existingLoad, Promise.resolve(stepState.moduleSource));
|
||
|
}
|
||
|
|
||
|
// a primary load -> use that existing linkset if it is for the direct load here
|
||
|
// otherwise create a new linkset unit
|
||
|
if (existingLoad.linkSets.length && existingLoad.linkSets[0].loads[0].name == existingLoad.name)
|
||
|
return existingLoad.linkSets[0].done.then(function() {
|
||
|
resolve(existingLoad);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var load = existingLoad || createLoad(name);
|
||
|
|
||
|
load.metadata = stepState.moduleMetadata;
|
||
|
|
||
|
var linkSet = createLinkSet(loader, load);
|
||
|
|
||
|
loader.loads.push(load);
|
||
|
|
||
|
resolve(linkSet.done);
|
||
|
|
||
|
if (step == 'locate')
|
||
|
proceedToLocate(loader, load);
|
||
|
|
||
|
else if (step == 'fetch')
|
||
|
proceedToFetch(loader, load, Promise.resolve(stepState.moduleAddress));
|
||
|
|
||
|
else {
|
||
|
console.assert(step == 'translate', 'translate step');
|
||
|
load.address = stepState.moduleAddress;
|
||
|
proceedToTranslate(loader, load, Promise.resolve(stepState.moduleSource));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Declarative linking functions run through alternative implementation:
|
||
|
// 15.2.5.1.1 CreateModuleLinkageRecord not implemented
|
||
|
// 15.2.5.1.2 LookupExport not implemented
|
||
|
// 15.2.5.1.3 LookupModuleDependency not implemented
|
||
|
|
||
|
// 15.2.5.2.1
|
||
|
function createLinkSet(loader, startingLoad) {
|
||
|
var linkSet = {
|
||
|
loader: loader,
|
||
|
loads: [],
|
||
|
startingLoad: startingLoad, // added see spec bug https://bugs.ecmascript.org/show_bug.cgi?id=2995
|
||
|
loadingCount: 0
|
||
|
};
|
||
|
linkSet.done = new Promise(function(resolve, reject) {
|
||
|
linkSet.resolve = resolve;
|
||
|
linkSet.reject = reject;
|
||
|
});
|
||
|
addLoadToLinkSet(linkSet, startingLoad);
|
||
|
return linkSet;
|
||
|
}
|
||
|
// 15.2.5.2.2
|
||
|
function addLoadToLinkSet(linkSet, load) {
|
||
|
if (load.status == 'failed')
|
||
|
return;
|
||
|
|
||
|
for (var i = 0, l = linkSet.loads.length; i < l; i++)
|
||
|
if (linkSet.loads[i] == load)
|
||
|
return;
|
||
|
|
||
|
linkSet.loads.push(load);
|
||
|
load.linkSets.push(linkSet);
|
||
|
|
||
|
// adjustment, see https://bugs.ecmascript.org/show_bug.cgi?id=2603
|
||
|
if (load.status != 'loaded') {
|
||
|
linkSet.loadingCount++;
|
||
|
}
|
||
|
|
||
|
var loader = linkSet.loader;
|
||
|
|
||
|
for (var i = 0, l = load.dependencies.length; i < l; i++) {
|
||
|
if (!load.dependencies[i])
|
||
|
continue;
|
||
|
|
||
|
var name = load.dependencies[i].value;
|
||
|
|
||
|
if (loader.modules[name])
|
||
|
continue;
|
||
|
|
||
|
for (var j = 0, d = loader.loads.length; j < d; j++) {
|
||
|
if (loader.loads[j].name != name)
|
||
|
continue;
|
||
|
|
||
|
addLoadToLinkSet(linkSet, loader.loads[j]);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// console.log('add to linkset ' + load.name);
|
||
|
// snapshot(linkSet.loader);
|
||
|
}
|
||
|
|
||
|
// linking errors can be generic or load-specific
|
||
|
// this is necessary for debugging info
|
||
|
function doLink(linkSet) {
|
||
|
var error = false;
|
||
|
try {
|
||
|
link(linkSet, function(load, exc) {
|
||
|
linkSetFailed(linkSet, load, exc);
|
||
|
error = true;
|
||
|
});
|
||
|
}
|
||
|
catch(e) {
|
||
|
linkSetFailed(linkSet, null, e);
|
||
|
error = true;
|
||
|
}
|
||
|
return error;
|
||
|
}
|
||
|
|
||
|
// 15.2.5.2.3
|
||
|
function updateLinkSetOnLoad(linkSet, load) {
|
||
|
// console.log('update linkset on load ' + load.name);
|
||
|
// snapshot(linkSet.loader);
|
||
|
|
||
|
console.assert(load.status == 'loaded' || load.status == 'linked', 'loaded or linked');
|
||
|
|
||
|
linkSet.loadingCount--;
|
||
|
|
||
|
if (linkSet.loadingCount > 0)
|
||
|
return;
|
||
|
|
||
|
// adjusted for spec bug https://bugs.ecmascript.org/show_bug.cgi?id=2995
|
||
|
var startingLoad = linkSet.startingLoad;
|
||
|
|
||
|
// non-executing link variation for loader tracing
|
||
|
// on the server. Not in spec.
|
||
|
/***/
|
||
|
if (linkSet.loader.loaderObj.execute === false) {
|
||
|
var loads = [].concat(linkSet.loads);
|
||
|
for (var i = 0, l = loads.length; i < l; i++) {
|
||
|
var load = loads[i];
|
||
|
load.module = {
|
||
|
name: load.name,
|
||
|
module: _newModule({}),
|
||
|
evaluated: true
|
||
|
};
|
||
|
load.status = 'linked';
|
||
|
finishLoad(linkSet.loader, load);
|
||
|
}
|
||
|
return linkSet.resolve(startingLoad);
|
||
|
}
|
||
|
/***/
|
||
|
|
||
|
var abrupt = doLink(linkSet);
|
||
|
|
||
|
if (abrupt)
|
||
|
return;
|
||
|
|
||
|
console.assert(linkSet.loads.length == 0, 'loads cleared');
|
||
|
|
||
|
linkSet.resolve(startingLoad);
|
||
|
}
|
||
|
|
||
|
// 15.2.5.2.4
|
||
|
function linkSetFailed(linkSet, load, exc) {
|
||
|
var loader = linkSet.loader;
|
||
|
var requests;
|
||
|
|
||
|
checkError:
|
||
|
if (load) {
|
||
|
if (linkSet.loads[0].name == load.name) {
|
||
|
exc = addToError(exc, 'Error loading ' + load.name);
|
||
|
}
|
||
|
else {
|
||
|
for (var i = 0; i < linkSet.loads.length; i++) {
|
||
|
var pLoad = linkSet.loads[i];
|
||
|
for (var j = 0; j < pLoad.dependencies.length; j++) {
|
||
|
var dep = pLoad.dependencies[j];
|
||
|
if (dep.value == load.name) {
|
||
|
exc = addToError(exc, 'Error loading ' + load.name + ' as "' + dep.key + '" from ' + pLoad.name);
|
||
|
break checkError;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
exc = addToError(exc, 'Error loading ' + load.name + ' from ' + linkSet.loads[0].name);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
exc = addToError(exc, 'Error linking ' + linkSet.loads[0].name);
|
||
|
}
|
||
|
|
||
|
|
||
|
var loads = linkSet.loads.concat([]);
|
||
|
for (var i = 0, l = loads.length; i < l; i++) {
|
||
|
var load = loads[i];
|
||
|
|
||
|
// store all failed load records
|
||
|
loader.loaderObj.failed = loader.loaderObj.failed || [];
|
||
|
if (indexOf.call(loader.loaderObj.failed, load) == -1)
|
||
|
loader.loaderObj.failed.push(load);
|
||
|
|
||
|
var linkIndex = indexOf.call(load.linkSets, linkSet);
|
||
|
console.assert(linkIndex != -1, 'link not present');
|
||
|
load.linkSets.splice(linkIndex, 1);
|
||
|
if (load.linkSets.length == 0) {
|
||
|
var globalLoadsIndex = indexOf.call(linkSet.loader.loads, load);
|
||
|
if (globalLoadsIndex != -1)
|
||
|
linkSet.loader.loads.splice(globalLoadsIndex, 1);
|
||
|
}
|
||
|
}
|
||
|
linkSet.reject(exc);
|
||
|
}
|
||
|
|
||
|
// 15.2.5.2.5
|
||
|
function finishLoad(loader, load) {
|
||
|
// add to global trace if tracing
|
||
|
if (loader.loaderObj.trace) {
|
||
|
if (!loader.loaderObj.loads)
|
||
|
loader.loaderObj.loads = {};
|
||
|
var depMap = {};
|
||
|
load.dependencies.forEach(function(dep) {
|
||
|
depMap[dep.key] = dep.value;
|
||
|
});
|
||
|
loader.loaderObj.loads[load.name] = {
|
||
|
name: load.name,
|
||
|
deps: load.dependencies.map(function(dep){ return dep.key }),
|
||
|
depMap: depMap,
|
||
|
address: load.address,
|
||
|
metadata: load.metadata,
|
||
|
source: load.source
|
||
|
};
|
||
|
}
|
||
|
// if not anonymous, add to the module table
|
||
|
if (load.name) {
|
||
|
console.assert(!loader.modules[load.name] || loader.modules[load.name].module === load.module.module, 'load not in module table');
|
||
|
loader.modules[load.name] = load.module;
|
||
|
}
|
||
|
var loadIndex = indexOf.call(loader.loads, load);
|
||
|
if (loadIndex != -1)
|
||
|
loader.loads.splice(loadIndex, 1);
|
||
|
for (var i = 0, l = load.linkSets.length; i < l; i++) {
|
||
|
loadIndex = indexOf.call(load.linkSets[i].loads, load);
|
||
|
if (loadIndex != -1)
|
||
|
load.linkSets[i].loads.splice(loadIndex, 1);
|
||
|
}
|
||
|
load.linkSets.splice(0, load.linkSets.length);
|
||
|
}
|
||
|
|
||
|
function doDynamicExecute(linkSet, load, linkError) {
|
||
|
try {
|
||
|
var module = load.execute();
|
||
|
}
|
||
|
catch(e) {
|
||
|
linkError(load, e);
|
||
|
return;
|
||
|
}
|
||
|
if (!module || !(module instanceof Module))
|
||
|
linkError(load, new TypeError('Execution must define a Module instance'));
|
||
|
else
|
||
|
return module;
|
||
|
}
|
||
|
|
||
|
// 26.3 Loader
|
||
|
|
||
|
// 26.3.1.1
|
||
|
// defined at top
|
||
|
|
||
|
// importPromises adds ability to import a module twice without error - https://bugs.ecmascript.org/show_bug.cgi?id=2601
|
||
|
function createImportPromise(loader, name, promise) {
|
||
|
var importPromises = loader._loader.importPromises;
|
||
|
return importPromises[name] = promise.then(function(m) {
|
||
|
importPromises[name] = undefined;
|
||
|
return m;
|
||
|
}, function(e) {
|
||
|
importPromises[name] = undefined;
|
||
|
throw e;
|
||
|
});
|
||
|
}
|
||
|
|
||
|
Loader.prototype = {
|
||
|
// 26.3.3.1
|
||
|
constructor: Loader,
|
||
|
// 26.3.3.2
|
||
|
define: function(name, source, options) {
|
||
|
// check if already defined
|
||
|
if (this._loader.importPromises[name])
|
||
|
throw new TypeError('Module is already loading.');
|
||
|
return createImportPromise(this, name, new Promise(asyncStartLoadPartwayThrough({
|
||
|
step: 'translate',
|
||
|
loader: this._loader,
|
||
|
moduleName: name,
|
||
|
moduleMetadata: options && options.metadata || {},
|
||
|
moduleSource: source,
|
||
|
moduleAddress: options && options.address
|
||
|
})));
|
||
|
},
|
||
|
// 26.3.3.3
|
||
|
'delete': function(name) {
|
||
|
var loader = this._loader;
|
||
|
delete loader.importPromises[name];
|
||
|
delete loader.moduleRecords[name];
|
||
|
return loader.modules[name] ? delete loader.modules[name] : false;
|
||
|
},
|
||
|
// 26.3.3.4 entries not implemented
|
||
|
// 26.3.3.5
|
||
|
get: function(key) {
|
||
|
if (!this._loader.modules[key])
|
||
|
return;
|
||
|
return this._loader.modules[key].module;
|
||
|
},
|
||
|
// 26.3.3.7
|
||
|
has: function(name) {
|
||
|
return !!this._loader.modules[name];
|
||
|
},
|
||
|
// 26.3.3.8
|
||
|
'import': function(name, parentName, parentAddress) {
|
||
|
if (typeof parentName == 'object')
|
||
|
parentName = parentName.name;
|
||
|
|
||
|
// run normalize first
|
||
|
var loaderObj = this;
|
||
|
|
||
|
// added, see https://bugs.ecmascript.org/show_bug.cgi?id=2659
|
||
|
return Promise.resolve(loaderObj.normalize(name, parentName))
|
||
|
.then(function(name) {
|
||
|
var loader = loaderObj._loader;
|
||
|
|
||
|
if (loader.modules[name])
|
||
|
return loader.modules[name].module;
|
||
|
|
||
|
return loader.importPromises[name] || createImportPromise(loaderObj, name,
|
||
|
loadModule(loader, name, {})
|
||
|
.then(function(load) {
|
||
|
delete loader.importPromises[name];
|
||
|
return load.module.module;
|
||
|
}));
|
||
|
});
|
||
|
},
|
||
|
// 26.3.3.9 keys not implemented
|
||
|
// 26.3.3.10
|
||
|
load: function(name) {
|
||
|
var loader = this._loader;
|
||
|
if (loader.modules[name])
|
||
|
return Promise.resolve();
|
||
|
return loader.importPromises[name] || createImportPromise(this, name, new Promise(asyncStartLoadPartwayThrough({
|
||
|
step: 'locate',
|
||
|
loader: loader,
|
||
|
moduleName: name,
|
||
|
moduleMetadata: {},
|
||
|
moduleSource: undefined,
|
||
|
moduleAddress: undefined
|
||
|
}))
|
||
|
.then(function() {
|
||
|
delete loader.importPromises[name];
|
||
|
}));
|
||
|
},
|
||
|
// 26.3.3.11
|
||
|
module: function(source, options) {
|
||
|
var load = createLoad();
|
||
|
load.address = options && options.address;
|
||
|
var linkSet = createLinkSet(this._loader, load);
|
||
|
var sourcePromise = Promise.resolve(source);
|
||
|
var loader = this._loader;
|
||
|
var p = linkSet.done.then(function() {
|
||
|
return load.module.module;
|
||
|
});
|
||
|
proceedToTranslate(loader, load, sourcePromise);
|
||
|
return p;
|
||
|
},
|
||
|
// 26.3.3.12
|
||
|
newModule: function (obj) {
|
||
|
if (typeof obj != 'object')
|
||
|
throw new TypeError('Expected object');
|
||
|
|
||
|
var m = new Module();
|
||
|
|
||
|
var pNames = [];
|
||
|
if (Object.getOwnPropertyNames && obj != null)
|
||
|
pNames = Object.getOwnPropertyNames(obj);
|
||
|
else
|
||
|
for (var key in obj)
|
||
|
pNames.push(key);
|
||
|
|
||
|
for (var i = 0; i < pNames.length; i++) (function(key) {
|
||
|
defineProperty(m, key, {
|
||
|
configurable: false,
|
||
|
enumerable: true,
|
||
|
get: function () {
|
||
|
return obj[key];
|
||
|
},
|
||
|
set: function() {
|
||
|
throw new Error('Module exports cannot be changed externally.');
|
||
|
}
|
||
|
});
|
||
|
})(pNames[i]);
|
||
|
|
||
|
if (Object.freeze)
|
||
|
Object.freeze(m);
|
||
|
|
||
|
return m;
|
||
|
},
|
||
|
// 26.3.3.14
|
||
|
set: function(name, module) {
|
||
|
if (!(module instanceof Module))
|
||
|
throw new TypeError('Loader.set(' + name + ', module) must be a module');
|
||
|
this._loader.modules[name] = {
|
||
|
module: module
|
||
|
};
|
||
|
},
|
||
|
// 26.3.3.15 values not implemented
|
||
|
// 26.3.3.16 @@iterator not implemented
|
||
|
// 26.3.3.17 @@toStringTag not implemented
|
||
|
|
||
|
// 26.3.3.18.1
|
||
|
normalize: function(name, referrerName, referrerAddress) {},
|
||
|
// 26.3.3.18.2
|
||
|
locate: function(load) {
|
||
|
return load.name;
|
||
|
},
|
||
|
// 26.3.3.18.3
|
||
|
fetch: function(load) {
|
||
|
},
|
||
|
// 26.3.3.18.4
|
||
|
translate: function(load) {
|
||
|
return load.source;
|
||
|
},
|
||
|
// 26.3.3.18.5
|
||
|
instantiate: function(load) {
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var _newModule = Loader.prototype.newModule;
|
||
|
|
||
|
/*
|
||
|
* ES6 Module Declarative Linking Code
|
||
|
*/
|
||
|
function link(linkSet, linkError) {
|
||
|
|
||
|
var loader = linkSet.loader;
|
||
|
|
||
|
if (!linkSet.loads.length)
|
||
|
return;
|
||
|
|
||
|
var loads = linkSet.loads.concat([]);
|
||
|
|
||
|
for (var i = 0; i < loads.length; i++) {
|
||
|
var load = loads[i];
|
||
|
|
||
|
var module = doDynamicExecute(linkSet, load, linkError);
|
||
|
if (!module)
|
||
|
return;
|
||
|
load.module = {
|
||
|
name: load.name,
|
||
|
module: module
|
||
|
};
|
||
|
load.status = 'linked';
|
||
|
|
||
|
finishLoad(loader, load);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
})();
|
||
|
|
||
|
var System;
|
||
|
|