82f2b76e25
We now use webpack instead of SystemJS, effectively bundling modules into one file (plus commons chunks) for every entry point. This results in a much smaller extension size (almost half). Furthermore we use yarn/npm even for extension run-time dependencies. This relieves us from manually vendoring and building dependencies. It's also easier to understand for new developers familiar with node.
5170 lines
165 KiB
JavaScript
5170 lines
165 KiB
JavaScript
/*
|
|
* SystemJS v0.19.47
|
|
*/
|
|
(function() {
|
|
function bootstrap() {// from https://gist.github.com/Yaffle/1088850
|
|
(function(global) {
|
|
function URLPolyfill(url, baseURL) {
|
|
if (typeof url != 'string')
|
|
throw new TypeError('URL must be a string');
|
|
var m = String(url).replace(/^\s+|\s+$/g, "").replace(/\\/g, '/').match(/^([^:\/?#]+:)?(?:\/\/(?:([^:@\/?#]*)(?::([^:@\/?#]*))?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
|
|
if (!m)
|
|
throw new RangeError('Invalid URL format');
|
|
var protocol = m[1] || "";
|
|
var username = m[2] || "";
|
|
var password = m[3] || "";
|
|
var host = m[4] || "";
|
|
var hostname = m[5] || "";
|
|
var port = m[6] || "";
|
|
var pathname = m[7] || "";
|
|
var search = m[8] || "";
|
|
var hash = m[9] || "";
|
|
if (baseURL !== undefined) {
|
|
var base = baseURL instanceof URLPolyfill ? baseURL : new URLPolyfill(baseURL);
|
|
var flag = !protocol && !host && !username;
|
|
if (flag && !pathname && !search)
|
|
search = base.search;
|
|
if (flag && pathname[0] !== "/")
|
|
pathname = (pathname ? (((base.host || base.username) && !base.pathname ? "/" : "") + base.pathname.slice(0, base.pathname.lastIndexOf("/") + 1) + pathname) : base.pathname);
|
|
// dot segments removal
|
|
var output = [];
|
|
pathname.replace(/^(\.\.?(\/|$))+/, "")
|
|
.replace(/\/(\.(\/|$))+/g, "/")
|
|
.replace(/\/\.\.$/, "/../")
|
|
.replace(/\/?[^\/]*/g, function (p) {
|
|
if (p === "/..")
|
|
output.pop();
|
|
else
|
|
output.push(p);
|
|
});
|
|
pathname = output.join("").replace(/^\//, pathname[0] === "/" ? "/" : "");
|
|
if (flag) {
|
|
port = base.port;
|
|
hostname = base.hostname;
|
|
host = base.host;
|
|
password = base.password;
|
|
username = base.username;
|
|
}
|
|
if (!protocol)
|
|
protocol = base.protocol;
|
|
}
|
|
|
|
// convert URLs to use / always
|
|
pathname = pathname.replace(/\\/g, '/');
|
|
|
|
this.origin = host ? protocol + (protocol !== "" || host !== "" ? "//" : "") + host : "";
|
|
this.href = protocol + (protocol && host || protocol == "file:" ? "//" : "") + (username !== "" ? username + (password !== "" ? ":" + password : "") + "@" : "") + host + pathname + search + hash;
|
|
this.protocol = protocol;
|
|
this.username = username;
|
|
this.password = password;
|
|
this.host = host;
|
|
this.hostname = hostname;
|
|
this.port = port;
|
|
this.pathname = pathname;
|
|
this.search = search;
|
|
this.hash = hash;
|
|
}
|
|
global.URLPolyfill = URLPolyfill;
|
|
})(typeof self != 'undefined' ? self : global);
|
|
(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);
|
|
}
|
|
});
|
|
}
|
|
|
|
// 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 {
|
|
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);
|
|
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;
|
|
|
|
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);
|
|
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) {
|
|
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(load) {
|
|
delete loader.importPromises[name];
|
|
return load.module.module;
|
|
})))
|
|
.then(function () {});
|
|
},
|
|
// 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;
|
|
var fetchTextFromURL;
|
|
if (typeof XMLHttpRequest != 'undefined') {
|
|
fetchTextFromURL = function(url, authorization, fulfill, reject) {
|
|
var xhr = new XMLHttpRequest();
|
|
var sameDomain = true;
|
|
var doTimeout = false;
|
|
if (!('withCredentials' in xhr)) {
|
|
// check if same domain
|
|
var domainCheck = /^(\w+:)?\/\/([^\/]+)/.exec(url);
|
|
if (domainCheck) {
|
|
sameDomain = domainCheck[2] === window.location.host;
|
|
if (domainCheck[1])
|
|
sameDomain &= domainCheck[1] === window.location.protocol;
|
|
}
|
|
}
|
|
if (!sameDomain && typeof XDomainRequest != 'undefined') {
|
|
xhr = new XDomainRequest();
|
|
xhr.onload = load;
|
|
xhr.onerror = error;
|
|
xhr.ontimeout = error;
|
|
xhr.onprogress = function() {};
|
|
xhr.timeout = 0;
|
|
doTimeout = true;
|
|
}
|
|
function load() {
|
|
fulfill(xhr.responseText);
|
|
}
|
|
function error() {
|
|
reject(new Error('XHR error' + (xhr.status ? ' (' + xhr.status + (xhr.statusText ? ' ' + xhr.statusText : '') + ')' : '') + ' loading ' + url));
|
|
}
|
|
|
|
xhr.onreadystatechange = function () {
|
|
if (xhr.readyState === 4) {
|
|
// in Chrome on file:/// URLs, status is 0
|
|
if (xhr.status == 0) {
|
|
if (xhr.responseText) {
|
|
load();
|
|
}
|
|
else {
|
|
// when responseText is empty, wait for load or error event
|
|
// to inform if it is a 404 or empty file
|
|
xhr.addEventListener('error', error);
|
|
xhr.addEventListener('load', load);
|
|
}
|
|
}
|
|
else if (xhr.status === 200) {
|
|
load();
|
|
}
|
|
else {
|
|
error();
|
|
}
|
|
}
|
|
};
|
|
xhr.open("GET", url, true);
|
|
|
|
if (xhr.setRequestHeader) {
|
|
xhr.setRequestHeader('Accept', 'application/x-es-module, */*');
|
|
// can set "authorization: true" to enable withCredentials only
|
|
if (authorization) {
|
|
if (typeof authorization == 'string')
|
|
xhr.setRequestHeader('Authorization', authorization);
|
|
xhr.withCredentials = true;
|
|
}
|
|
}
|
|
|
|
if (doTimeout) {
|
|
setTimeout(function() {
|
|
xhr.send();
|
|
}, 0);
|
|
} else {
|
|
xhr.send(null);
|
|
}
|
|
};
|
|
}
|
|
else if (typeof require != 'undefined' && typeof process != 'undefined') {
|
|
var fs;
|
|
fetchTextFromURL = function(url, authorization, fulfill, reject) {
|
|
if (url.substr(0, 8) != 'file:///')
|
|
throw new Error('Unable to fetch "' + url + '". Only file URLs of the form file:/// allowed running in Node.');
|
|
fs = fs || require('fs');
|
|
if (isWindows)
|
|
url = url.replace(/\//g, '\\').substr(8);
|
|
else
|
|
url = url.substr(7);
|
|
return fs.readFile(url, function(err, data) {
|
|
if (err) {
|
|
return reject(err);
|
|
}
|
|
else {
|
|
// Strip Byte Order Mark out if it's the leading char
|
|
var dataString = data + '';
|
|
if (dataString[0] === '\ufeff')
|
|
dataString = dataString.substr(1);
|
|
|
|
fulfill(dataString);
|
|
}
|
|
});
|
|
};
|
|
}
|
|
else if (typeof self != 'undefined' && typeof self.fetch != 'undefined') {
|
|
fetchTextFromURL = function(url, authorization, fulfill, reject) {
|
|
var opts = {
|
|
headers: {'Accept': 'application/x-es-module, */*'}
|
|
};
|
|
|
|
if (authorization) {
|
|
if (typeof authorization == 'string')
|
|
opts.headers['Authorization'] = authorization;
|
|
opts.credentials = 'include';
|
|
}
|
|
|
|
fetch(url, opts)
|
|
.then(function (r) {
|
|
if (r.ok) {
|
|
return r.text();
|
|
} else {
|
|
throw new Error('Fetch error: ' + r.status + ' ' + r.statusText);
|
|
}
|
|
})
|
|
.then(fulfill, reject);
|
|
}
|
|
}
|
|
else {
|
|
throw new TypeError('No environment fetch API available.');
|
|
}
|
|
/*
|
|
* Traceur, Babel and TypeScript transpile hook for Loader
|
|
*/
|
|
var transpile = (function() {
|
|
|
|
// use Traceur by default
|
|
Loader.prototype.transpiler = 'traceur';
|
|
|
|
function transpile(load) {
|
|
var self = this;
|
|
|
|
return Promise.resolve(__global[self.transpiler == 'typescript' ? 'ts' : self.transpiler]
|
|
|| (self.pluginLoader || self)['import'](self.transpiler))
|
|
.then(function(transpiler) {
|
|
if (transpiler.__useDefault)
|
|
transpiler = transpiler['default'];
|
|
|
|
var transpileFunction;
|
|
if (transpiler.Compiler)
|
|
transpileFunction = traceurTranspile;
|
|
else if (transpiler.createLanguageService)
|
|
transpileFunction = typescriptTranspile;
|
|
else
|
|
transpileFunction = babelTranspile;
|
|
|
|
// note __moduleName will be part of the transformer meta in future when we have the spec for this
|
|
return '(function(__moduleName){' + transpileFunction.call(self, load, transpiler) + '\n})("' + load.name + '");\n//# sourceURL=' + load.address + '!transpiled';
|
|
});
|
|
};
|
|
|
|
function traceurTranspile(load, traceur) {
|
|
var options = this.traceurOptions || {};
|
|
options.modules = 'instantiate';
|
|
options.script = false;
|
|
if (options.sourceMaps === undefined)
|
|
options.sourceMaps = 'inline';
|
|
options.filename = load.address;
|
|
options.inputSourceMap = load.metadata.sourceMap;
|
|
options.moduleName = false;
|
|
|
|
var compiler = new traceur.Compiler(options);
|
|
|
|
return doTraceurCompile(load.source, compiler, options.filename);
|
|
}
|
|
function doTraceurCompile(source, compiler, filename) {
|
|
try {
|
|
return compiler.compile(source, filename);
|
|
}
|
|
catch(e) {
|
|
// on older versions of traceur (<0.9.3), an array of errors is thrown
|
|
// rather than a single error.
|
|
if (e.length) {
|
|
throw e[0];
|
|
}
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
function babelTranspile(load, babel) {
|
|
var options = this.babelOptions || {};
|
|
options.modules = 'system';
|
|
if (options.sourceMap === undefined)
|
|
options.sourceMap = 'inline';
|
|
options.inputSourceMap = load.metadata.sourceMap;
|
|
options.filename = load.address;
|
|
options.code = true;
|
|
options.ast = false;
|
|
|
|
return babel.transform(load.source, options).code;
|
|
}
|
|
|
|
function typescriptTranspile(load, ts) {
|
|
var options = this.typescriptOptions || {};
|
|
options.target = options.target || ts.ScriptTarget.ES5;
|
|
if (options.sourceMap === undefined)
|
|
options.sourceMap = true;
|
|
if (options.sourceMap && options.inlineSourceMap !== false)
|
|
options.inlineSourceMap = true;
|
|
|
|
options.module = ts.ModuleKind.System;
|
|
|
|
return ts.transpile(load.source, options, load.address);
|
|
}
|
|
|
|
return transpile;
|
|
})();
|
|
// SystemJS Loader Class and Extension helpers
|
|
function SystemJSLoader() {
|
|
Loader.call(this);
|
|
|
|
this.paths = {};
|
|
this._loader.paths = {};
|
|
|
|
systemJSConstructor.call(this);
|
|
}
|
|
|
|
// inline Object.create-style class extension
|
|
function SystemProto() {};
|
|
SystemProto.prototype = Loader.prototype;
|
|
SystemJSLoader.prototype = new SystemProto();
|
|
SystemJSLoader.prototype.constructor = SystemJSLoader;
|
|
|
|
var systemJSConstructor;
|
|
|
|
function hook(name, hook) {
|
|
SystemJSLoader.prototype[name] = hook(SystemJSLoader.prototype[name] || function() {});
|
|
}
|
|
function hookConstructor(hook) {
|
|
systemJSConstructor = hook(systemJSConstructor || function() {});
|
|
}
|
|
|
|
|
|
var absURLRegEx = /^[^\/]+:\/\//;
|
|
function isAbsolute(name) {
|
|
return name.match(absURLRegEx);
|
|
}
|
|
function isRel(name) {
|
|
return (name[0] == '.' && (!name[1] || name[1] == '/' || name[1] == '.')) || name[0] == '/';
|
|
}
|
|
function isPlain(name) {
|
|
return !isRel(name) && !isAbsolute(name);
|
|
}
|
|
|
|
var baseURIObj = new URL(baseURI);
|
|
|
|
function urlResolve(name, parent) {
|
|
// url resolution shortpaths
|
|
if (name[0] == '.') {
|
|
// dot-relative url normalization
|
|
if (name[1] == '/' && name[2] != '.')
|
|
return (parent && parent.substr(0, parent.lastIndexOf('/') + 1) || baseURI) + name.substr(2);
|
|
}
|
|
else if (name[0] != '/' && name.indexOf(':') == -1) {
|
|
// plain parent normalization
|
|
return (parent && parent.substr(0, parent.lastIndexOf('/') + 1) || baseURI) + name;
|
|
}
|
|
|
|
return new URL(name, parent && parent.replace(/#/g, '%05') || baseURIObj).href.replace(/%05/g, '#');
|
|
}
|
|
|
|
// NB no specification provided for System.paths, used ideas discussed in https://github.com/jorendorff/js-loaders/issues/25
|
|
function applyPaths(loader, name) {
|
|
// most specific (most number of slashes in path) match wins
|
|
var pathMatch = '', wildcard, maxWildcardPrefixLen = 0;
|
|
|
|
var paths = loader.paths;
|
|
var pathsCache = loader._loader.paths;
|
|
|
|
// check to see if we have a paths entry
|
|
for (var p in paths) {
|
|
if (paths.hasOwnProperty && !paths.hasOwnProperty(p))
|
|
continue;
|
|
|
|
// paths sanitization
|
|
var path = paths[p];
|
|
if (path !== pathsCache[p])
|
|
path = paths[p] = pathsCache[p] = urlResolve(paths[p], isRel(paths[p]) ? baseURI : loader.baseURL);
|
|
|
|
// exact path match
|
|
if (p.indexOf('*') === -1) {
|
|
if (name == p)
|
|
return paths[p];
|
|
|
|
// support trailing / in paths rules
|
|
else if (name.substr(0, p.length - 1) == p.substr(0, p.length - 1) && (name.length < p.length || name[p.length - 1] == p[p.length - 1]) && (paths[p][paths[p].length - 1] == '/' || paths[p] == '')) {
|
|
return paths[p].substr(0, paths[p].length - 1) + (name.length > p.length ? (paths[p] && '/' || '') + name.substr(p.length) : '');
|
|
}
|
|
}
|
|
// wildcard path match
|
|
else {
|
|
var pathParts = p.split('*');
|
|
if (pathParts.length > 2)
|
|
throw new TypeError('Only one wildcard in a path is permitted');
|
|
|
|
var wildcardPrefixLen = pathParts[0].length;
|
|
if (wildcardPrefixLen >= maxWildcardPrefixLen &&
|
|
name.substr(0, pathParts[0].length) == pathParts[0] &&
|
|
name.substr(name.length - pathParts[1].length) == pathParts[1]) {
|
|
maxWildcardPrefixLen = wildcardPrefixLen;
|
|
pathMatch = p;
|
|
wildcard = name.substr(pathParts[0].length, name.length - pathParts[1].length - pathParts[0].length);
|
|
}
|
|
}
|
|
}
|
|
|
|
var outPath = paths[pathMatch];
|
|
if (typeof wildcard == 'string')
|
|
outPath = outPath.replace('*', wildcard);
|
|
|
|
return outPath;
|
|
}
|
|
|
|
function dedupe(deps) {
|
|
var newDeps = [];
|
|
for (var i = 0, l = deps.length; i < l; i++)
|
|
if (indexOf.call(newDeps, deps[i]) == -1)
|
|
newDeps.push(deps[i])
|
|
return newDeps;
|
|
}
|
|
|
|
function group(deps) {
|
|
var names = [];
|
|
var indices = [];
|
|
for (var i = 0, l = deps.length; i < l; i++) {
|
|
var index = indexOf.call(names, deps[i]);
|
|
if (index === -1) {
|
|
names.push(deps[i]);
|
|
indices.push([i]);
|
|
}
|
|
else {
|
|
indices[index].push(i);
|
|
}
|
|
}
|
|
return { names: names, indices: indices };
|
|
}
|
|
|
|
var getOwnPropertyDescriptor = true;
|
|
try {
|
|
Object.getOwnPropertyDescriptor({ a: 0 }, 'a');
|
|
}
|
|
catch(e) {
|
|
getOwnPropertyDescriptor = false;
|
|
}
|
|
|
|
// converts any module.exports object into an object ready for SystemJS.newModule
|
|
function getESModule(exports) {
|
|
var esModule = {};
|
|
// don't trigger getters/setters in environments that support them
|
|
if ((typeof exports == 'object' || typeof exports == 'function') && exports !== __global) {
|
|
if (getOwnPropertyDescriptor) {
|
|
for (var p in exports) {
|
|
// The default property is copied to esModule later on
|
|
if (p === 'default')
|
|
continue;
|
|
defineOrCopyProperty(esModule, exports, p);
|
|
}
|
|
}
|
|
else {
|
|
extend(esModule, exports);
|
|
}
|
|
}
|
|
esModule['default'] = exports;
|
|
defineProperty(esModule, '__useDefault', {
|
|
value: true
|
|
});
|
|
return esModule;
|
|
}
|
|
|
|
function defineOrCopyProperty(targetObj, sourceObj, propName) {
|
|
try {
|
|
var d;
|
|
if (d = Object.getOwnPropertyDescriptor(sourceObj, propName))
|
|
defineProperty(targetObj, propName, d);
|
|
}
|
|
catch (ex) {
|
|
// Object.getOwnPropertyDescriptor threw an exception, fall back to normal set property
|
|
// we dont need hasOwnProperty here because getOwnPropertyDescriptor would have returned undefined above
|
|
targetObj[propName] = sourceObj[propName];
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function extend(a, b, prepend) {
|
|
var hasOwnProperty = b && b.hasOwnProperty;
|
|
for (var p in b) {
|
|
if (hasOwnProperty && !b.hasOwnProperty(p))
|
|
continue;
|
|
if (!prepend || !(p in a))
|
|
a[p] = b[p];
|
|
}
|
|
return a;
|
|
}
|
|
|
|
// meta first-level extends where:
|
|
// array + array appends
|
|
// object + object extends
|
|
// other properties replace
|
|
function extendMeta(a, b, prepend) {
|
|
var hasOwnProperty = b && b.hasOwnProperty;
|
|
for (var p in b) {
|
|
if (hasOwnProperty && !b.hasOwnProperty(p))
|
|
continue;
|
|
var val = b[p];
|
|
if (!(p in a))
|
|
a[p] = val;
|
|
else if (val instanceof Array && a[p] instanceof Array)
|
|
a[p] = [].concat(prepend ? val : a[p]).concat(prepend ? a[p] : val);
|
|
else if (typeof val == 'object' && val !== null && typeof a[p] == 'object')
|
|
a[p] = extend(extend({}, a[p]), val, prepend);
|
|
else if (!prepend)
|
|
a[p] = val;
|
|
}
|
|
}
|
|
|
|
function extendPkgConfig(pkgCfgA, pkgCfgB, pkgName, loader, warnInvalidProperties) {
|
|
for (var prop in pkgCfgB) {
|
|
if (indexOf.call(['main', 'format', 'defaultExtension', 'basePath'], prop) != -1) {
|
|
pkgCfgA[prop] = pkgCfgB[prop];
|
|
}
|
|
else if (prop == 'map') {
|
|
extend(pkgCfgA.map = pkgCfgA.map || {}, pkgCfgB.map);
|
|
}
|
|
else if (prop == 'meta') {
|
|
extend(pkgCfgA.meta = pkgCfgA.meta || {}, pkgCfgB.meta);
|
|
}
|
|
else if (prop == 'depCache') {
|
|
for (var d in pkgCfgB.depCache) {
|
|
var dNormalized;
|
|
|
|
if (d.substr(0, 2) == './')
|
|
dNormalized = pkgName + '/' + d.substr(2);
|
|
else
|
|
dNormalized = coreResolve.call(loader, d);
|
|
loader.depCache[dNormalized] = (loader.depCache[dNormalized] || []).concat(pkgCfgB.depCache[d]);
|
|
}
|
|
}
|
|
else if (warnInvalidProperties && indexOf.call(['browserConfig', 'nodeConfig', 'devConfig', 'productionConfig'], prop) == -1 &&
|
|
(!pkgCfgB.hasOwnProperty || pkgCfgB.hasOwnProperty(prop))) {
|
|
warn.call(loader, '"' + prop + '" is not a valid package configuration option in package ' + pkgName);
|
|
}
|
|
}
|
|
}
|
|
|
|
// deeply-merge (to first level) config with any existing package config
|
|
function setPkgConfig(loader, pkgName, cfg, prependConfig) {
|
|
var pkg;
|
|
|
|
// first package is config by reference for fast path, cloned after that
|
|
if (!loader.packages[pkgName]) {
|
|
pkg = loader.packages[pkgName] = cfg;
|
|
}
|
|
else {
|
|
var basePkg = loader.packages[pkgName];
|
|
pkg = loader.packages[pkgName] = {};
|
|
|
|
extendPkgConfig(pkg, prependConfig ? cfg : basePkg, pkgName, loader, prependConfig);
|
|
extendPkgConfig(pkg, prependConfig ? basePkg : cfg, pkgName, loader, !prependConfig);
|
|
}
|
|
|
|
// main object becomes main map
|
|
if (typeof pkg.main == 'object') {
|
|
pkg.map = pkg.map || {};
|
|
pkg.map['./@main'] = pkg.main;
|
|
pkg.main['default'] = pkg.main['default'] || './';
|
|
pkg.main = '@main';
|
|
}
|
|
|
|
return pkg;
|
|
}
|
|
|
|
function warn(msg) {
|
|
if (this.warnings && typeof console != 'undefined' && console.warn)
|
|
console.warn(msg);
|
|
}
|
|
|
|
function createInstantiate (load, result) {
|
|
load.metadata.entry = createEntry();
|
|
load.metadata.entry.execute = function() {
|
|
return result;
|
|
}
|
|
load.metadata.entry.deps = [];
|
|
load.metadata.format = 'defined';
|
|
}
|
|
// we define a __exec for globally-scoped execution
|
|
// used by module format implementations
|
|
var __exec;
|
|
|
|
(function() {
|
|
|
|
var hasBuffer = typeof Buffer != 'undefined';
|
|
try {
|
|
if (hasBuffer && new Buffer('a').toString('base64') != 'YQ==')
|
|
hasBuffer = false;
|
|
}
|
|
catch(e) {
|
|
hasBuffer = false;
|
|
}
|
|
|
|
var sourceMapPrefix = '\n//# sourceMappingURL=data:application/json;base64,';
|
|
function inlineSourceMap(sourceMapString) {
|
|
if (hasBuffer)
|
|
return sourceMapPrefix + new Buffer(sourceMapString).toString('base64');
|
|
else if (typeof btoa != 'undefined')
|
|
return sourceMapPrefix + btoa(unescape(encodeURIComponent(sourceMapString)));
|
|
else
|
|
return '';
|
|
}
|
|
|
|
function getSource(load, wrap) {
|
|
var lastLineIndex = load.source.lastIndexOf('\n');
|
|
|
|
// wrap ES formats with a System closure for System global encapsulation
|
|
if (load.metadata.format == 'global')
|
|
wrap = false;
|
|
|
|
var sourceMap = load.metadata.sourceMap;
|
|
if (sourceMap) {
|
|
if (typeof sourceMap != 'object')
|
|
throw new TypeError('load.metadata.sourceMap must be set to an object.');
|
|
|
|
sourceMap = JSON.stringify(sourceMap);
|
|
}
|
|
|
|
return (wrap ? '(function(System, SystemJS) {' : '') + load.source + (wrap ? '\n})(System, System);' : '')
|
|
// adds the sourceURL comment if not already present
|
|
+ (load.source.substr(lastLineIndex, 15) != '\n//# sourceURL='
|
|
? '\n//# sourceURL=' + load.address + (sourceMap ? '!transpiled' : '') : '')
|
|
// add sourceMappingURL if load.metadata.sourceMap is set
|
|
+ (sourceMap && inlineSourceMap(sourceMap) || '');
|
|
}
|
|
|
|
var curLoad;
|
|
|
|
// System.register, System.registerDynamic, AMD define pipeline
|
|
// if currently evalling code here, immediately reduce the registered entry against the load record
|
|
hook('pushRegister_', function() {
|
|
return function(register) {
|
|
if (!curLoad)
|
|
return false;
|
|
|
|
this.reduceRegister_(curLoad, register);
|
|
return true;
|
|
};
|
|
});
|
|
|
|
// System clobbering protection (mostly for Traceur)
|
|
var curSystem;
|
|
var callCounter = 0;
|
|
function preExec(loader, load) {
|
|
curLoad = load;
|
|
if (callCounter++ == 0)
|
|
curSystem = __global.System;
|
|
__global.System = __global.SystemJS = loader;
|
|
}
|
|
function postExec() {
|
|
if (--callCounter == 0)
|
|
__global.System = __global.SystemJS = curSystem;
|
|
curLoad = undefined;
|
|
}
|
|
|
|
var useVm;
|
|
var vm;
|
|
__exec = function(load) {
|
|
if (!load.source)
|
|
return;
|
|
if ((load.metadata.integrity || load.metadata.nonce) && supportsScriptExec)
|
|
return scriptExec.call(this, load);
|
|
try {
|
|
preExec(this, load);
|
|
curLoad = load;
|
|
// global scoped eval for node (avoids require scope leak)
|
|
if (!vm && this._nodeRequire) {
|
|
vm = this._nodeRequire('vm');
|
|
useVm = vm.runInThisContext("typeof System !== 'undefined' && System") === this;
|
|
}
|
|
if (useVm)
|
|
vm.runInThisContext(getSource(load, true), { filename: load.address + (load.metadata.sourceMap ? '!transpiled' : '') });
|
|
else
|
|
(0, eval)(getSource(load, true));
|
|
postExec();
|
|
}
|
|
catch(e) {
|
|
postExec();
|
|
throw addToError(e, 'Evaluating ' + load.address);
|
|
}
|
|
};
|
|
|
|
var supportsScriptExec = false;
|
|
if (isBrowser && typeof document != 'undefined' && document.getElementsByTagName) {
|
|
if (!(window.chrome && window.chrome.extension || navigator.userAgent.match(/^Node\.js/)))
|
|
supportsScriptExec = true;
|
|
}
|
|
|
|
// script execution via injecting a script tag into the page
|
|
// this allows CSP integrity and nonce to be set for CSP environments
|
|
var head;
|
|
function scriptExec(load) {
|
|
if (!head)
|
|
head = document.head || document.body || document.documentElement;
|
|
|
|
var script = document.createElement('script');
|
|
script.text = getSource(load, false);
|
|
var onerror = window.onerror;
|
|
var e;
|
|
window.onerror = function(_e) {
|
|
e = addToError(_e, 'Evaluating ' + load.address);
|
|
if (onerror)
|
|
onerror.apply(this, arguments);
|
|
}
|
|
preExec(this, load);
|
|
|
|
if (load.metadata.integrity)
|
|
script.setAttribute('integrity', load.metadata.integrity);
|
|
if (load.metadata.nonce)
|
|
script.setAttribute('nonce', load.metadata.nonce);
|
|
|
|
head.appendChild(script);
|
|
head.removeChild(script);
|
|
postExec();
|
|
window.onerror = onerror;
|
|
if (e)
|
|
throw e;
|
|
}
|
|
|
|
})();
|
|
function readMemberExpression(p, value) {
|
|
var pParts = p.split('.');
|
|
while (pParts.length)
|
|
value = value[pParts.shift()];
|
|
return value;
|
|
}
|
|
|
|
function getMapMatch(map, name) {
|
|
var bestMatch, bestMatchLength = 0;
|
|
|
|
for (var p in map) {
|
|
if (name.substr(0, p.length) == p && (name.length == p.length || name[p.length] == '/')) {
|
|
var curMatchLength = p.split('/').length;
|
|
if (curMatchLength <= bestMatchLength)
|
|
continue;
|
|
bestMatch = p;
|
|
bestMatchLength = curMatchLength;
|
|
}
|
|
}
|
|
|
|
return bestMatch;
|
|
}
|
|
|
|
function prepareBaseURL(loader) {
|
|
// ensure baseURl is fully normalized
|
|
if (this._loader.baseURL !== this.baseURL) {
|
|
if (this.baseURL[this.baseURL.length - 1] != '/')
|
|
this.baseURL += '/';
|
|
|
|
this._loader.baseURL = this.baseURL = new URL(this.baseURL, baseURIObj).href;
|
|
}
|
|
}
|
|
|
|
var envModule;
|
|
function setProduction(isProduction, isBuilder) {
|
|
this.set('@system-env', envModule = this.newModule({
|
|
browser: isBrowser,
|
|
node: !!this._nodeRequire,
|
|
production: !isBuilder && isProduction,
|
|
dev: isBuilder || !isProduction,
|
|
build: isBuilder,
|
|
'default': true
|
|
}));
|
|
}
|
|
|
|
hookConstructor(function(constructor) {
|
|
return function() {
|
|
constructor.call(this);
|
|
|
|
// support baseURL
|
|
this.baseURL = baseURI;
|
|
|
|
// support map and paths
|
|
this.map = {};
|
|
|
|
// make the location of the system.js script accessible
|
|
if (typeof $__curScript != 'undefined')
|
|
this.scriptSrc = $__curScript.src;
|
|
|
|
// global behaviour flags
|
|
this.warnings = false;
|
|
this.defaultJSExtensions = false;
|
|
this.pluginFirst = false;
|
|
this.loaderErrorStack = false;
|
|
|
|
// by default load ".json" files as json
|
|
// leading * meta doesn't need normalization
|
|
// NB add this in next breaking release
|
|
// this.meta['*.json'] = { format: 'json' };
|
|
|
|
// support the empty module, as a concept
|
|
this.set('@empty', this.newModule({}));
|
|
|
|
setProduction.call(this, false, false);
|
|
};
|
|
});
|
|
|
|
// include the node require since we're overriding it
|
|
if (typeof require != 'undefined' && typeof process != 'undefined' && !process.browser)
|
|
SystemJSLoader.prototype._nodeRequire = require;
|
|
|
|
/*
|
|
Core SystemJS Normalization
|
|
|
|
If a name is relative, we apply URL normalization to the page
|
|
If a name is an absolute URL, we leave it as-is
|
|
|
|
Plain names (neither of the above) run through the map and paths
|
|
normalization phases.
|
|
|
|
The paths normalization phase applies last (paths extension), which
|
|
defines the `decanonicalize` function and normalizes everything into
|
|
a URL.
|
|
*/
|
|
|
|
var parentModuleContext;
|
|
function getNodeModule(name, baseURL) {
|
|
if (!isPlain(name))
|
|
throw new Error('Node module ' + name + ' can\'t be loaded as it is not a package require.');
|
|
|
|
if (!parentModuleContext) {
|
|
var Module = this._nodeRequire('module');
|
|
var base = baseURL.substr(isWindows ? 8 : 7);
|
|
parentModuleContext = new Module(base);
|
|
parentModuleContext.paths = Module._nodeModulePaths(base);
|
|
}
|
|
return parentModuleContext.require(name);
|
|
}
|
|
|
|
function coreResolve(name, parentName) {
|
|
// standard URL resolution
|
|
if (isRel(name))
|
|
return urlResolve(name, parentName);
|
|
else if (isAbsolute(name))
|
|
return name;
|
|
|
|
// plain names not starting with './', '://' and '/' go through custom resolution
|
|
var mapMatch = getMapMatch(this.map, name);
|
|
|
|
if (mapMatch) {
|
|
name = this.map[mapMatch] + name.substr(mapMatch.length);
|
|
|
|
if (isRel(name))
|
|
return urlResolve(name);
|
|
else if (isAbsolute(name))
|
|
return name;
|
|
}
|
|
|
|
if (this.has(name))
|
|
return name;
|
|
|
|
// dynamically load node-core modules when requiring `@node/fs` for example
|
|
if (name.substr(0, 6) == '@node/') {
|
|
if (!this._nodeRequire)
|
|
throw new TypeError('Error loading ' + name + '. Can only load node core modules in Node.');
|
|
if (this.builder)
|
|
this.set(name, this.newModule({}));
|
|
else
|
|
this.set(name, this.newModule(getESModule(getNodeModule.call(this, name.substr(6), this.baseURL))));
|
|
return name;
|
|
}
|
|
|
|
// prepare the baseURL to ensure it is normalized
|
|
prepareBaseURL.call(this);
|
|
|
|
return applyPaths(this, name) || this.baseURL + name;
|
|
}
|
|
|
|
hook('normalize', function(normalize) {
|
|
return function(name, parentName, skipExt) {
|
|
var resolved = coreResolve.call(this, name, parentName);
|
|
if (this.defaultJSExtensions && !skipExt && resolved.substr(resolved.length - 3, 3) != '.js' && !isPlain(resolved))
|
|
resolved += '.js';
|
|
return resolved;
|
|
};
|
|
});
|
|
|
|
// percent encode just '#' in urls if using HTTP requests
|
|
var httpRequest = typeof XMLHttpRequest != 'undefined';
|
|
hook('locate', function(locate) {
|
|
return function(load) {
|
|
return Promise.resolve(locate.call(this, load))
|
|
.then(function(address) {
|
|
if (httpRequest)
|
|
return address.replace(/#/g, '%23');
|
|
return address;
|
|
});
|
|
};
|
|
});
|
|
|
|
/*
|
|
* Fetch with authorization
|
|
*/
|
|
hook('fetch', function() {
|
|
return function(load) {
|
|
return new Promise(function(resolve, reject) {
|
|
fetchTextFromURL(load.address, load.metadata.authorization, resolve, reject);
|
|
});
|
|
};
|
|
});
|
|
|
|
/*
|
|
__useDefault
|
|
|
|
When a module object looks like:
|
|
newModule(
|
|
__useDefault: true,
|
|
default: 'some-module'
|
|
})
|
|
|
|
Then importing that module provides the 'some-module'
|
|
result directly instead of the full module.
|
|
|
|
Useful for eg module.exports = function() {}
|
|
*/
|
|
hook('import', function(systemImport) {
|
|
return function(name, parentName, parentAddress) {
|
|
if (parentName && parentName.name)
|
|
warn.call(this, 'SystemJS.import(name, { name: parentName }) is deprecated for SystemJS.import(name, parentName), while importing ' + name + ' from ' + parentName.name);
|
|
return systemImport.call(this, name, parentName, parentAddress).then(function(module) {
|
|
return module.__useDefault ? module['default'] : module;
|
|
});
|
|
};
|
|
});
|
|
|
|
/*
|
|
* Allow format: 'detect' meta to enable format detection
|
|
*/
|
|
hook('translate', function(systemTranslate) {
|
|
return function(load) {
|
|
if (load.metadata.format == 'detect')
|
|
load.metadata.format = undefined;
|
|
return systemTranslate.apply(this, arguments);
|
|
};
|
|
});
|
|
|
|
|
|
/*
|
|
* JSON format support
|
|
*
|
|
* Supports loading JSON files as a module format itself
|
|
*
|
|
* Usage:
|
|
*
|
|
* SystemJS.config({
|
|
* meta: {
|
|
* '*.json': { format: 'json' }
|
|
* }
|
|
* });
|
|
*
|
|
* Module is returned as if written:
|
|
*
|
|
* export default {JSON}
|
|
*
|
|
* No named exports are provided
|
|
*
|
|
* Files ending in ".json" are treated as json automatically by SystemJS
|
|
*/
|
|
hook('instantiate', function(instantiate) {
|
|
return function(load) {
|
|
if (load.metadata.format == 'json' && !this.builder) {
|
|
var entry = load.metadata.entry = createEntry();
|
|
entry.deps = [];
|
|
entry.execute = function() {
|
|
try {
|
|
return JSON.parse(load.source);
|
|
}
|
|
catch(e) {
|
|
throw new Error("Invalid JSON file " + load.name);
|
|
}
|
|
};
|
|
}
|
|
};
|
|
})
|
|
|
|
/*
|
|
Extend config merging one deep only
|
|
|
|
loader.config({
|
|
some: 'random',
|
|
config: 'here',
|
|
deep: {
|
|
config: { too: 'too' }
|
|
}
|
|
});
|
|
|
|
<=>
|
|
|
|
loader.some = 'random';
|
|
loader.config = 'here'
|
|
loader.deep = loader.deep || {};
|
|
loader.deep.config = { too: 'too' };
|
|
|
|
|
|
Normalizes meta and package configs allowing for:
|
|
|
|
SystemJS.config({
|
|
meta: {
|
|
'./index.js': {}
|
|
}
|
|
});
|
|
|
|
To become
|
|
|
|
SystemJS.meta['https://thissite.com/index.js'] = {};
|
|
|
|
For easy normalization canonicalization with latest URL support.
|
|
|
|
*/
|
|
function envSet(loader, cfg, envCallback) {
|
|
if (envModule.browser && cfg.browserConfig)
|
|
envCallback(cfg.browserConfig);
|
|
if (envModule.node && cfg.nodeConfig)
|
|
envCallback(cfg.nodeConfig);
|
|
if (envModule.dev && cfg.devConfig)
|
|
envCallback(cfg.devConfig);
|
|
if (envModule.build && cfg.buildConfig)
|
|
envCallback(cfg.buildConfig);
|
|
if (envModule.production && cfg.productionConfig)
|
|
envCallback(cfg.productionConfig);
|
|
}
|
|
|
|
SystemJSLoader.prototype.getConfig = function(name) {
|
|
var cfg = {};
|
|
var loader = this;
|
|
for (var p in loader) {
|
|
if (loader.hasOwnProperty && !loader.hasOwnProperty(p) || p in SystemJSLoader.prototype && p != 'transpiler')
|
|
continue;
|
|
if (indexOf.call(['_loader', 'amdDefine', 'amdRequire', 'defined', 'failed', 'version', 'loads'], p) == -1)
|
|
cfg[p] = loader[p];
|
|
}
|
|
cfg.production = envModule.production;
|
|
return cfg;
|
|
};
|
|
|
|
var curCurScript;
|
|
SystemJSLoader.prototype.config = function(cfg, isEnvConfig) {
|
|
var loader = this;
|
|
|
|
if ('loaderErrorStack' in cfg) {
|
|
curCurScript = $__curScript;
|
|
if (cfg.loaderErrorStack)
|
|
$__curScript = undefined;
|
|
else
|
|
$__curScript = curCurScript;
|
|
}
|
|
|
|
if ('warnings' in cfg)
|
|
loader.warnings = cfg.warnings;
|
|
|
|
// transpiler deprecation path
|
|
if (cfg.transpilerRuntime === false)
|
|
loader._loader.loadedTranspilerRuntime = true;
|
|
|
|
if ('production' in cfg || 'build' in cfg)
|
|
setProduction.call(loader, !!cfg.production, !!(cfg.build || envModule && envModule.build));
|
|
|
|
if (!isEnvConfig) {
|
|
// if using nodeConfig / browserConfig / productionConfig, take baseURL from there
|
|
// these exceptions will be unnecessary when we can properly implement config queuings
|
|
var baseURL;
|
|
envSet(loader, cfg, function(cfg) {
|
|
baseURL = baseURL || cfg.baseURL;
|
|
});
|
|
baseURL = baseURL || cfg.baseURL;
|
|
|
|
// always configure baseURL first
|
|
if (baseURL) {
|
|
var hasConfig = false;
|
|
function checkHasConfig(obj) {
|
|
for (var p in obj)
|
|
if (obj.hasOwnProperty(p))
|
|
return true;
|
|
}
|
|
if (checkHasConfig(loader.packages) || checkHasConfig(loader.meta) || checkHasConfig(loader.depCache) || checkHasConfig(loader.bundles) || checkHasConfig(loader.packageConfigPaths))
|
|
throw new TypeError('Incorrect configuration order. The baseURL must be configured with the first SystemJS.config call.');
|
|
|
|
this.baseURL = baseURL;
|
|
prepareBaseURL.call(this);
|
|
}
|
|
|
|
if (cfg.paths)
|
|
extend(loader.paths, cfg.paths);
|
|
|
|
envSet(loader, cfg, function(cfg) {
|
|
if (cfg.paths)
|
|
extend(loader.paths, cfg.paths);
|
|
});
|
|
|
|
// warn on wildcard path deprecations
|
|
if (this.warnings) {
|
|
for (var p in loader.paths)
|
|
if (p.indexOf('*') != -1)
|
|
warn.call(loader, 'Paths configuration "' + p + '" -> "' + loader.paths[p] + '" uses wildcards which are being deprecated for just leaving a trailing "/" to indicate folder paths.');
|
|
}
|
|
}
|
|
|
|
if (cfg.defaultJSExtensions) {
|
|
loader.defaultJSExtensions = cfg.defaultJSExtensions;
|
|
warn.call(loader, 'The defaultJSExtensions configuration option is deprecated, use packages configuration instead.');
|
|
}
|
|
|
|
if (cfg.pluginFirst)
|
|
loader.pluginFirst = cfg.pluginFirst;
|
|
|
|
if (cfg.map) {
|
|
for (var p in cfg.map) {
|
|
var v = cfg.map[p];
|
|
|
|
// object map backwards-compat into packages configuration
|
|
if (typeof v !== 'string') {
|
|
var defaultJSExtension = loader.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js';
|
|
var prop = loader.decanonicalize(p);
|
|
if (defaultJSExtension && prop.substr(prop.length - 3, 3) == '.js')
|
|
prop = prop.substr(0, prop.length - 3);
|
|
|
|
// if a package main, revert it
|
|
var pkgMatch = '';
|
|
for (var pkg in loader.packages) {
|
|
if (prop.substr(0, pkg.length) == pkg
|
|
&& (!prop[pkg.length] || prop[pkg.length] == '/')
|
|
&& pkgMatch.split('/').length < pkg.split('/').length)
|
|
pkgMatch = pkg;
|
|
}
|
|
if (pkgMatch && loader.packages[pkgMatch].main)
|
|
prop = prop.substr(0, prop.length - loader.packages[pkgMatch].main.length - 1);
|
|
|
|
var pkg = loader.packages[prop] = loader.packages[prop] || {};
|
|
pkg.map = v;
|
|
}
|
|
else {
|
|
loader.map[p] = v;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cfg.packageConfigPaths) {
|
|
var packageConfigPaths = [];
|
|
for (var i = 0; i < cfg.packageConfigPaths.length; i++) {
|
|
var path = cfg.packageConfigPaths[i];
|
|
var packageLength = Math.max(path.lastIndexOf('*') + 1, path.lastIndexOf('/'));
|
|
var normalized = coreResolve.call(loader, path.substr(0, packageLength));
|
|
packageConfigPaths[i] = normalized + path.substr(packageLength);
|
|
}
|
|
loader.packageConfigPaths = packageConfigPaths;
|
|
}
|
|
|
|
if (cfg.bundles) {
|
|
for (var p in cfg.bundles) {
|
|
var bundle = [];
|
|
for (var i = 0; i < cfg.bundles[p].length; i++) {
|
|
var defaultJSExtension = loader.defaultJSExtensions && cfg.bundles[p][i].substr(cfg.bundles[p][i].length - 3, 3) != '.js';
|
|
var normalizedBundleDep = loader.decanonicalize(cfg.bundles[p][i]);
|
|
if (defaultJSExtension && normalizedBundleDep.substr(normalizedBundleDep.length - 3, 3) == '.js')
|
|
normalizedBundleDep = normalizedBundleDep.substr(0, normalizedBundleDep.length - 3);
|
|
bundle.push(normalizedBundleDep);
|
|
}
|
|
loader.bundles[p] = bundle;
|
|
}
|
|
}
|
|
|
|
if (cfg.packages) {
|
|
for (var p in cfg.packages) {
|
|
if (p.match(/^([^\/]+:)?\/\/$/))
|
|
throw new TypeError('"' + p + '" is not a valid package name.');
|
|
|
|
var prop = coreResolve.call(loader, p);
|
|
|
|
// allow trailing slash in packages
|
|
if (prop[prop.length - 1] == '/')
|
|
prop = prop.substr(0, prop.length - 1);
|
|
|
|
setPkgConfig(loader, prop, cfg.packages[p], false);
|
|
}
|
|
}
|
|
|
|
for (var c in cfg) {
|
|
var v = cfg[c];
|
|
|
|
if (indexOf.call(['baseURL', 'map', 'packages', 'bundles', 'paths', 'warnings', 'packageConfigPaths',
|
|
'loaderErrorStack', 'browserConfig', 'nodeConfig', 'devConfig', 'buildConfig', 'productionConfig'], c) != -1)
|
|
continue;
|
|
|
|
if (typeof v != 'object' || v instanceof Array) {
|
|
loader[c] = v;
|
|
}
|
|
else {
|
|
loader[c] = loader[c] || {};
|
|
|
|
for (var p in v) {
|
|
// base-level wildcard meta does not normalize to retain catch-all quality
|
|
if (c == 'meta' && p[0] == '*') {
|
|
extend(loader[c][p] = loader[c][p] || {}, v[p]);
|
|
}
|
|
else if (c == 'meta') {
|
|
// meta can go through global map, with defaultJSExtensions adding
|
|
var resolved = coreResolve.call(loader, p);
|
|
if (loader.defaultJSExtensions && resolved.substr(resolved.length - 3, 3) != '.js' && !isPlain(resolved))
|
|
resolved += '.js';
|
|
extend(loader[c][resolved] = loader[c][resolved] || {}, v[p]);
|
|
}
|
|
else if (c == 'depCache') {
|
|
var defaultJSExtension = loader.defaultJSExtensions && p.substr(p.length - 3, 3) != '.js';
|
|
var prop = loader.decanonicalize(p);
|
|
if (defaultJSExtension && prop.substr(prop.length - 3, 3) == '.js')
|
|
prop = prop.substr(0, prop.length - 3);
|
|
loader[c][prop] = [].concat(v[p]);
|
|
}
|
|
else {
|
|
loader[c][p] = v[p];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
envSet(loader, cfg, function(cfg) {
|
|
loader.config(cfg, true);
|
|
});
|
|
};
|
|
/*
|
|
* Package Configuration Extension
|
|
*
|
|
* Example:
|
|
*
|
|
* SystemJS.packages = {
|
|
* jquery: {
|
|
* main: 'index.js', // when not set, package name is requested directly
|
|
* format: 'amd',
|
|
* defaultExtension: 'ts', // defaults to 'js', can be set to false
|
|
* modules: {
|
|
* '*.ts': {
|
|
* loader: 'typescript'
|
|
* },
|
|
* 'vendor/sizzle.js': {
|
|
* format: 'global'
|
|
* }
|
|
* },
|
|
* map: {
|
|
* // map internal require('sizzle') to local require('./vendor/sizzle')
|
|
* sizzle: './vendor/sizzle.js',
|
|
* // map any internal or external require of 'jquery/vendor/another' to 'another/index.js'
|
|
* './vendor/another.js': './another/index.js',
|
|
* // test.js / test -> lib/test.js
|
|
* './test.js': './lib/test.js',
|
|
*
|
|
* // environment-specific map configurations
|
|
* './index.js': {
|
|
* '~browser': './index-node.js',
|
|
* './custom-condition.js|~export': './index-custom.js'
|
|
* }
|
|
* },
|
|
* // allows for setting package-prefixed depCache
|
|
* // keys are normalized module names relative to the package itself
|
|
* depCache: {
|
|
* // import 'package/index.js' loads in parallel package/lib/test.js,package/vendor/sizzle.js
|
|
* './index.js': ['./test'],
|
|
* './test.js': ['external-dep'],
|
|
* 'external-dep/path.js': ['./another.js']
|
|
* }
|
|
* }
|
|
* };
|
|
*
|
|
* Then:
|
|
* import 'jquery' -> jquery/index.js
|
|
* import 'jquery/submodule' -> jquery/submodule.js
|
|
* import 'jquery/submodule.ts' -> jquery/submodule.ts loaded as typescript
|
|
* import 'jquery/vendor/another' -> another/index.js
|
|
*
|
|
* Detailed Behaviours
|
|
* - main can have a leading "./" can be added optionally
|
|
* - map and defaultExtension are applied to the main
|
|
* - defaultExtension adds the extension only if the exact extension is not present
|
|
* - defaultJSExtensions applies after map when defaultExtension is not set
|
|
* - if a meta value is available for a module, map and defaultExtension are skipped
|
|
* - like global map, package map also applies to subpaths (sizzle/x, ./vendor/another/sub)
|
|
* - condition module map is '@env' module in package or '@system-env' globally
|
|
* - map targets support conditional interpolation ('./x': './x.#{|env}.js')
|
|
* - internal package map targets cannot use boolean conditionals
|
|
*
|
|
* Package Configuration Loading
|
|
*
|
|
* Not all packages may already have their configuration present in the System config
|
|
* For these cases, a list of packageConfigPaths can be provided, which when matched against
|
|
* a request, will first request a ".json" file by the package name to derive the package
|
|
* configuration from. This allows dynamic loading of non-predetermined code, a key use
|
|
* case in SystemJS.
|
|
*
|
|
* Example:
|
|
*
|
|
* SystemJS.packageConfigPaths = ['packages/test/package.json', 'packages/*.json'];
|
|
*
|
|
* // will first request 'packages/new-package/package.json' for the package config
|
|
* // before completing the package request to 'packages/new-package/path'
|
|
* SystemJS.import('packages/new-package/path');
|
|
*
|
|
* // will first request 'packages/test/package.json' before the main
|
|
* SystemJS.import('packages/test');
|
|
*
|
|
* When a package matches packageConfigPaths, it will always send a config request for
|
|
* the package configuration.
|
|
* The package name itself is taken to be the match up to and including the last wildcard
|
|
* or trailing slash.
|
|
* The most specific package config path will be used.
|
|
* Any existing package configurations for the package will deeply merge with the
|
|
* package config, with the existing package configurations taking preference.
|
|
* To opt-out of the package configuration request for a package that matches
|
|
* packageConfigPaths, use the { configured: true } package config option.
|
|
*
|
|
*/
|
|
(function() {
|
|
|
|
hookConstructor(function(constructor) {
|
|
return function() {
|
|
constructor.call(this);
|
|
this.packages = {};
|
|
this.packageConfigPaths = [];
|
|
};
|
|
});
|
|
|
|
function getPackage(loader, normalized) {
|
|
// use most specific package
|
|
var curPkg, curPkgLen = 0, pkgLen;
|
|
for (var p in loader.packages) {
|
|
if (normalized.substr(0, p.length) === p && (normalized.length === p.length || normalized[p.length] === '/')) {
|
|
pkgLen = p.split('/').length;
|
|
if (pkgLen > curPkgLen) {
|
|
curPkg = p;
|
|
curPkgLen = pkgLen;
|
|
}
|
|
}
|
|
}
|
|
return curPkg;
|
|
}
|
|
|
|
function addDefaultExtension(loader, pkg, pkgName, subPath, skipExtensions) {
|
|
// don't apply extensions to folders or if defaultExtension = false
|
|
if (!subPath || subPath[subPath.length - 1] == '/' || skipExtensions || pkg.defaultExtension === false)
|
|
return subPath;
|
|
|
|
var metaMatch = false;
|
|
|
|
// exact meta or meta with any content after the last wildcard skips extension
|
|
if (pkg.meta)
|
|
getMetaMatches(pkg.meta, subPath, function(metaPattern, matchMeta, matchDepth) {
|
|
if (matchDepth == 0 || metaPattern.lastIndexOf('*') != metaPattern.length - 1)
|
|
return metaMatch = true;
|
|
});
|
|
|
|
// exact global meta or meta with any content after the last wildcard skips extension
|
|
if (!metaMatch && loader.meta)
|
|
getMetaMatches(loader.meta, pkgName + '/' + subPath, function(metaPattern, matchMeta, matchDepth) {
|
|
if (matchDepth == 0 || metaPattern.lastIndexOf('*') != metaPattern.length - 1)
|
|
return metaMatch = true;
|
|
});
|
|
|
|
if (metaMatch)
|
|
return subPath;
|
|
|
|
// work out what the defaultExtension is and add if not there already
|
|
// NB reconsider if default should really be ".js"?
|
|
var defaultExtension = '.' + (pkg.defaultExtension || 'js');
|
|
if (subPath.substr(subPath.length - defaultExtension.length) != defaultExtension)
|
|
return subPath + defaultExtension;
|
|
else
|
|
return subPath;
|
|
}
|
|
|
|
function applyPackageConfigSync(loader, pkg, pkgName, subPath, skipExtensions) {
|
|
// main
|
|
if (!subPath) {
|
|
if (pkg.main)
|
|
subPath = pkg.main.substr(0, 2) == './' ? pkg.main.substr(2) : pkg.main;
|
|
// also no submap if name is package itself (import 'pkg' -> 'path/to/pkg.js')
|
|
else
|
|
// NB can add a default package main convention here when defaultJSExtensions is deprecated
|
|
// if it becomes internal to the package then it would no longer be an exit path
|
|
return pkgName + (loader.defaultJSExtensions ? '.js' : '');
|
|
}
|
|
|
|
// map config checking without then with extensions
|
|
if (pkg.map) {
|
|
var mapPath = './' + subPath;
|
|
|
|
var mapMatch = getMapMatch(pkg.map, mapPath);
|
|
|
|
// we then check map with the default extension adding
|
|
if (!mapMatch) {
|
|
mapPath = './' + addDefaultExtension(loader, pkg, pkgName, subPath, skipExtensions);
|
|
if (mapPath != './' + subPath)
|
|
mapMatch = getMapMatch(pkg.map, mapPath);
|
|
}
|
|
if (mapMatch) {
|
|
var mapped = doMapSync(loader, pkg, pkgName, mapMatch, mapPath, skipExtensions);
|
|
if (mapped)
|
|
return mapped;
|
|
}
|
|
}
|
|
|
|
// normal package resolution
|
|
return pkgName + '/' + addDefaultExtension(loader, pkg, pkgName, subPath, skipExtensions);
|
|
}
|
|
|
|
function validMapping(mapMatch, mapped, pkgName, path) {
|
|
// disallow internal to subpath maps
|
|
if (mapMatch == '.')
|
|
throw new Error('Package ' + pkgName + ' has a map entry for "." which is not permitted.');
|
|
|
|
// allow internal ./x -> ./x/y or ./x/ -> ./x/y recursive maps
|
|
// but only if the path is exactly ./x and not ./x/z
|
|
if (mapped.substr(0, mapMatch.length) == mapMatch && path.length > mapMatch.length)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
function doMapSync(loader, pkg, pkgName, mapMatch, path, skipExtensions) {
|
|
if (path[path.length - 1] == '/')
|
|
path = path.substr(0, path.length - 1);
|
|
var mapped = pkg.map[mapMatch];
|
|
|
|
if (typeof mapped == 'object')
|
|
throw new Error('Synchronous conditional normalization not supported sync normalizing ' + mapMatch + ' in ' + pkgName);
|
|
|
|
if (!validMapping(mapMatch, mapped, pkgName, path) || typeof mapped != 'string')
|
|
return;
|
|
|
|
// package map to main / base-level
|
|
if (mapped == '.')
|
|
mapped = pkgName;
|
|
|
|
// internal package map
|
|
else if (mapped.substr(0, 2) == './')
|
|
return pkgName + '/' + addDefaultExtension(loader, pkg, pkgName, mapped.substr(2) + path.substr(mapMatch.length), skipExtensions);
|
|
|
|
// external map reference
|
|
return loader.normalizeSync(mapped + path.substr(mapMatch.length), pkgName + '/');
|
|
}
|
|
|
|
function applyPackageConfig(loader, pkg, pkgName, subPath, skipExtensions) {
|
|
// main
|
|
if (!subPath) {
|
|
if (pkg.main)
|
|
subPath = pkg.main.substr(0, 2) == './' ? pkg.main.substr(2) : pkg.main;
|
|
// also no submap if name is package itself (import 'pkg' -> 'path/to/pkg.js')
|
|
else
|
|
// NB can add a default package main convention here when defaultJSExtensions is deprecated
|
|
// if it becomes internal to the package then it would no longer be an exit path
|
|
return Promise.resolve(pkgName + (loader.defaultJSExtensions ? '.js' : ''));
|
|
}
|
|
|
|
// map config checking without then with extensions
|
|
var mapPath, mapMatch;
|
|
|
|
if (pkg.map) {
|
|
mapPath = './' + subPath;
|
|
mapMatch = getMapMatch(pkg.map, mapPath);
|
|
|
|
// we then check map with the default extension adding
|
|
if (!mapMatch) {
|
|
mapPath = './' + addDefaultExtension(loader, pkg, pkgName, subPath, skipExtensions);
|
|
if (mapPath != './' + subPath)
|
|
mapMatch = getMapMatch(pkg.map, mapPath);
|
|
}
|
|
}
|
|
|
|
return (mapMatch ? doMap(loader, pkg, pkgName, mapMatch, mapPath, skipExtensions) : Promise.resolve())
|
|
.then(function(mapped) {
|
|
if (mapped)
|
|
return Promise.resolve(mapped);
|
|
|
|
// normal package resolution / fallback resolution for no conditional match
|
|
return Promise.resolve(pkgName + '/' + addDefaultExtension(loader, pkg, pkgName, subPath, skipExtensions));
|
|
});
|
|
}
|
|
|
|
function doStringMap(loader, pkg, pkgName, mapMatch, mapped, path, skipExtensions) {
|
|
// NB the interpolation cases should strictly skip subsequent interpolation
|
|
// package map to main / base-level
|
|
if (mapped == '.')
|
|
mapped = pkgName;
|
|
|
|
// internal package map
|
|
else if (mapped.substr(0, 2) == './')
|
|
return Promise.resolve(pkgName + '/' + addDefaultExtension(loader, pkg, pkgName, mapped.substr(2) + path.substr(mapMatch.length), skipExtensions))
|
|
.then(function(name) {
|
|
return interpolateConditional.call(loader, name, pkgName + '/');
|
|
});
|
|
|
|
// external map reference
|
|
return loader.normalize(mapped + path.substr(mapMatch.length), pkgName + '/');
|
|
}
|
|
|
|
function doMap(loader, pkg, pkgName, mapMatch, path, skipExtensions) {
|
|
if (path[path.length - 1] == '/')
|
|
path = path.substr(0, path.length - 1);
|
|
|
|
var mapped = pkg.map[mapMatch];
|
|
|
|
if (typeof mapped == 'string') {
|
|
if (!validMapping(mapMatch, mapped, pkgName, path))
|
|
return Promise.resolve();
|
|
return doStringMap(loader, pkg, pkgName, mapMatch, mapped, path, skipExtensions);
|
|
}
|
|
|
|
// we use a special conditional syntax to allow the builder to handle conditional branch points further
|
|
if (loader.builder)
|
|
return Promise.resolve(pkgName + '/#:' + path);
|
|
|
|
// we load all conditions upfront
|
|
var conditionPromises = [];
|
|
var conditions = [];
|
|
for (var e in mapped) {
|
|
var c = parseCondition(e);
|
|
conditions.push({
|
|
condition: c,
|
|
map: mapped[e]
|
|
});
|
|
conditionPromises.push(loader['import'](c.module, pkgName));
|
|
}
|
|
|
|
// map object -> conditional map
|
|
return Promise.all(conditionPromises)
|
|
.then(function(conditionValues) {
|
|
// first map condition to match is used
|
|
for (var i = 0; i < conditions.length; i++) {
|
|
var c = conditions[i].condition;
|
|
var value = readMemberExpression(c.prop, conditionValues[i]);
|
|
if (!c.negate && value || c.negate && !value)
|
|
return conditions[i].map;
|
|
}
|
|
})
|
|
.then(function(mapped) {
|
|
if (mapped) {
|
|
if (!validMapping(mapMatch, mapped, pkgName, path))
|
|
return;
|
|
return doStringMap(loader, pkg, pkgName, mapMatch, mapped, path, skipExtensions);
|
|
}
|
|
|
|
// no environment match -> fallback to original subPath by returning undefined
|
|
});
|
|
}
|
|
|
|
// normalizeSync = decanonicalize + package resolution
|
|
SystemJSLoader.prototype.normalizeSync = SystemJSLoader.prototype.decanonicalize = SystemJSLoader.prototype.normalize;
|
|
|
|
// decanonicalize must JUST handle package defaultExtension: false case when defaultJSExtensions is set
|
|
// to be deprecated!
|
|
hook('decanonicalize', function(decanonicalize) {
|
|
return function(name, parentName) {
|
|
if (this.builder)
|
|
return decanonicalize.call(this, name, parentName, true);
|
|
|
|
var decanonicalized = decanonicalize.call(this, name, parentName, false);
|
|
|
|
if (!this.defaultJSExtensions)
|
|
return decanonicalized;
|
|
|
|
var pkgName = getPackage(this, decanonicalized);
|
|
|
|
var pkg = this.packages[pkgName];
|
|
var defaultExtension = pkg && pkg.defaultExtension;
|
|
|
|
if (defaultExtension == undefined && pkg && pkg.meta)
|
|
getMetaMatches(pkg.meta, decanonicalized.substr(pkgName), function(metaPattern, matchMeta, matchDepth) {
|
|
if (matchDepth == 0 || metaPattern.lastIndexOf('*') != metaPattern.length - 1) {
|
|
defaultExtension = false;
|
|
return true;
|
|
}
|
|
});
|
|
|
|
if ((defaultExtension === false || defaultExtension && defaultExtension != '.js') && name.substr(name.length - 3, 3) != '.js' && decanonicalized.substr(decanonicalized.length - 3, 3) == '.js')
|
|
decanonicalized = decanonicalized.substr(0, decanonicalized.length - 3);
|
|
|
|
return decanonicalized;
|
|
};
|
|
});
|
|
|
|
hook('normalizeSync', function(normalizeSync) {
|
|
return function(name, parentName, isPlugin) {
|
|
var loader = this;
|
|
isPlugin = isPlugin === true;
|
|
|
|
// apply contextual package map first
|
|
// (we assume the parent package config has already been loaded)
|
|
if (parentName)
|
|
var parentPackageName = getPackage(loader, parentName) ||
|
|
loader.defaultJSExtensions && parentName.substr(parentName.length - 3, 3) == '.js' &&
|
|
getPackage(loader, parentName.substr(0, parentName.length - 3));
|
|
|
|
var parentPackage = parentPackageName && loader.packages[parentPackageName];
|
|
|
|
// ignore . since internal maps handled by standard package resolution
|
|
if (parentPackage && name[0] != '.') {
|
|
var parentMap = parentPackage.map;
|
|
var parentMapMatch = parentMap && getMapMatch(parentMap, name);
|
|
|
|
if (parentMapMatch && typeof parentMap[parentMapMatch] == 'string') {
|
|
var mapped = doMapSync(loader, parentPackage, parentPackageName, parentMapMatch, name, isPlugin);
|
|
if (mapped)
|
|
return mapped;
|
|
}
|
|
}
|
|
|
|
var defaultJSExtension = loader.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js';
|
|
|
|
// apply map, core, paths, contextual package map
|
|
var normalized = normalizeSync.call(loader, name, parentName, false);
|
|
|
|
// undo defaultJSExtension
|
|
if (defaultJSExtension && normalized.substr(normalized.length - 3, 3) != '.js')
|
|
defaultJSExtension = false;
|
|
if (defaultJSExtension)
|
|
normalized = normalized.substr(0, normalized.length - 3);
|
|
|
|
var pkgConfigMatch = getPackageConfigMatch(loader, normalized);
|
|
var pkgName = pkgConfigMatch && pkgConfigMatch.packageName || getPackage(loader, normalized);
|
|
|
|
if (!pkgName)
|
|
return normalized + (defaultJSExtension ? '.js' : '');
|
|
|
|
var subPath = normalized.substr(pkgName.length + 1);
|
|
|
|
return applyPackageConfigSync(loader, loader.packages[pkgName] || {}, pkgName, subPath, isPlugin);
|
|
};
|
|
});
|
|
|
|
hook('normalize', function(normalize) {
|
|
return function(name, parentName, isPlugin) {
|
|
var loader = this;
|
|
isPlugin = isPlugin === true;
|
|
|
|
return Promise.resolve()
|
|
.then(function() {
|
|
// apply contextual package map first
|
|
// (we assume the parent package config has already been loaded)
|
|
if (parentName)
|
|
var parentPackageName = getPackage(loader, parentName) ||
|
|
loader.defaultJSExtensions && parentName.substr(parentName.length - 3, 3) == '.js' &&
|
|
getPackage(loader, parentName.substr(0, parentName.length - 3));
|
|
|
|
var parentPackage = parentPackageName && loader.packages[parentPackageName];
|
|
|
|
// ignore . since internal maps handled by standard package resolution
|
|
if (parentPackage && name.substr(0, 2) != './') {
|
|
var parentMap = parentPackage.map;
|
|
var parentMapMatch = parentMap && getMapMatch(parentMap, name);
|
|
|
|
if (parentMapMatch)
|
|
return doMap(loader, parentPackage, parentPackageName, parentMapMatch, name, isPlugin);
|
|
}
|
|
|
|
return Promise.resolve();
|
|
})
|
|
.then(function(mapped) {
|
|
if (mapped)
|
|
return mapped;
|
|
|
|
var defaultJSExtension = loader.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js';
|
|
|
|
// apply map, core, paths, contextual package map
|
|
var normalized = normalize.call(loader, name, parentName, false);
|
|
|
|
// undo defaultJSExtension
|
|
if (defaultJSExtension && normalized.substr(normalized.length - 3, 3) != '.js')
|
|
defaultJSExtension = false;
|
|
if (defaultJSExtension)
|
|
normalized = normalized.substr(0, normalized.length - 3);
|
|
|
|
var pkgConfigMatch = getPackageConfigMatch(loader, normalized);
|
|
var pkgName = pkgConfigMatch && pkgConfigMatch.packageName || getPackage(loader, normalized);
|
|
|
|
if (!pkgName)
|
|
return Promise.resolve(normalized + (defaultJSExtension ? '.js' : ''));
|
|
|
|
var pkg = loader.packages[pkgName];
|
|
|
|
// if package is already configured or not a dynamic config package, use existing package config
|
|
var isConfigured = pkg && (pkg.configured || !pkgConfigMatch);
|
|
return (isConfigured ? Promise.resolve(pkg) : loadPackageConfigPath(loader, pkgName, pkgConfigMatch.configPath))
|
|
.then(function(pkg) {
|
|
var subPath = normalized.substr(pkgName.length + 1);
|
|
|
|
return applyPackageConfig(loader, pkg, pkgName, subPath, isPlugin);
|
|
});
|
|
});
|
|
};
|
|
});
|
|
|
|
// check if the given normalized name matches a packageConfigPath
|
|
// if so, loads the config
|
|
var packageConfigPaths = {};
|
|
|
|
// data object for quick checks against package paths
|
|
function createPkgConfigPathObj(path) {
|
|
var lastWildcard = path.lastIndexOf('*');
|
|
var length = Math.max(lastWildcard + 1, path.lastIndexOf('/'));
|
|
return {
|
|
length: length,
|
|
regEx: new RegExp('^(' + path.substr(0, length).replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '[^\\/]+') + ')(\\/|$)'),
|
|
wildcard: lastWildcard != -1
|
|
};
|
|
}
|
|
|
|
// most specific match wins
|
|
function getPackageConfigMatch(loader, normalized) {
|
|
var pkgName, exactMatch = false, configPath;
|
|
for (var i = 0; i < loader.packageConfigPaths.length; i++) {
|
|
var packageConfigPath = loader.packageConfigPaths[i];
|
|
var p = packageConfigPaths[packageConfigPath] || (packageConfigPaths[packageConfigPath] = createPkgConfigPathObj(packageConfigPath));
|
|
if (normalized.length < p.length)
|
|
continue;
|
|
var match = normalized.match(p.regEx);
|
|
if (match && (!pkgName || (!(exactMatch && p.wildcard) && pkgName.length < match[1].length))) {
|
|
pkgName = match[1];
|
|
exactMatch = !p.wildcard;
|
|
configPath = pkgName + packageConfigPath.substr(p.length);
|
|
}
|
|
}
|
|
|
|
if (!pkgName)
|
|
return;
|
|
|
|
return {
|
|
packageName: pkgName,
|
|
configPath: configPath
|
|
};
|
|
}
|
|
|
|
function loadPackageConfigPath(loader, pkgName, pkgConfigPath) {
|
|
var configLoader = loader.pluginLoader || loader;
|
|
|
|
// NB remove this when json is default
|
|
(configLoader.meta[pkgConfigPath] = configLoader.meta[pkgConfigPath] || {}).format = 'json';
|
|
configLoader.meta[pkgConfigPath].loader = null;
|
|
|
|
return configLoader.load(pkgConfigPath)
|
|
.then(function() {
|
|
var cfg = configLoader.get(pkgConfigPath)['default'];
|
|
|
|
// support "systemjs" prefixing
|
|
if (cfg.systemjs)
|
|
cfg = cfg.systemjs;
|
|
|
|
// modules backwards compatibility
|
|
if (cfg.modules) {
|
|
cfg.meta = cfg.modules;
|
|
warn.call(loader, 'Package config file ' + pkgConfigPath + ' is configured with "modules", which is deprecated as it has been renamed to "meta".');
|
|
}
|
|
|
|
return setPkgConfig(loader, pkgName, cfg, true);
|
|
});
|
|
}
|
|
|
|
function getMetaMatches(pkgMeta, subPath, matchFn) {
|
|
// wildcard meta
|
|
var meta = {};
|
|
var wildcardIndex;
|
|
for (var module in pkgMeta) {
|
|
// allow meta to start with ./ for flexibility
|
|
var dotRel = module.substr(0, 2) == './' ? './' : '';
|
|
if (dotRel)
|
|
module = module.substr(2);
|
|
|
|
wildcardIndex = module.indexOf('*');
|
|
if (wildcardIndex === -1)
|
|
continue;
|
|
|
|
if (module.substr(0, wildcardIndex) == subPath.substr(0, wildcardIndex)
|
|
&& module.substr(wildcardIndex + 1) == subPath.substr(subPath.length - module.length + wildcardIndex + 1)) {
|
|
// alow match function to return true for an exit path
|
|
if (matchFn(module, pkgMeta[dotRel + module], module.split('/').length))
|
|
return;
|
|
}
|
|
}
|
|
// exact meta
|
|
var exactMeta = pkgMeta[subPath] && pkgMeta.hasOwnProperty && pkgMeta.hasOwnProperty(subPath) ? pkgMeta[subPath] : pkgMeta['./' + subPath];
|
|
if (exactMeta)
|
|
matchFn(exactMeta, exactMeta, 0);
|
|
}
|
|
|
|
hook('locate', function(locate) {
|
|
return function(load) {
|
|
var loader = this;
|
|
return Promise.resolve(locate.call(this, load))
|
|
.then(function(address) {
|
|
var pkgName = getPackage(loader, load.name);
|
|
if (pkgName) {
|
|
var pkg = loader.packages[pkgName];
|
|
var subPath = load.name.substr(pkgName.length + 1);
|
|
|
|
var meta = {};
|
|
if (pkg.meta) {
|
|
var bestDepth = 0;
|
|
|
|
// NB support a main shorthand in meta here?
|
|
getMetaMatches(pkg.meta, subPath, function(metaPattern, matchMeta, matchDepth) {
|
|
if (matchDepth > bestDepth)
|
|
bestDepth = matchDepth;
|
|
extendMeta(meta, matchMeta, matchDepth && bestDepth > matchDepth);
|
|
});
|
|
|
|
extendMeta(load.metadata, meta);
|
|
}
|
|
|
|
// format
|
|
if (pkg.format && !load.metadata.loader)
|
|
load.metadata.format = load.metadata.format || pkg.format;
|
|
}
|
|
|
|
return address;
|
|
});
|
|
};
|
|
});
|
|
|
|
})();
|
|
/*
|
|
* 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);
|
|
}
|
|
});
|
|
};
|
|
});
|
|
})();
|
|
/*
|
|
* Instantiate registry extension
|
|
*
|
|
* Supports Traceur System.register 'instantiate' output for loading ES6 as ES5.
|
|
*
|
|
* - Creates the loader.register function
|
|
* - Also supports metadata.format = 'register' in instantiate for anonymous register modules
|
|
* - Also supports metadata.deps, metadata.execute and metadata.executingRequire
|
|
* for handling dynamic modules alongside register-transformed ES6 modules
|
|
*
|
|
*
|
|
* The code here replicates the ES6 linking groups algorithm to ensure that
|
|
* circular ES6 compiled into System.register can work alongside circular AMD
|
|
* and CommonJS, identically to the actual ES6 loader.
|
|
*
|
|
*/
|
|
|
|
|
|
/*
|
|
* Registry side table entries in loader.defined
|
|
* Registry Entry Contains:
|
|
* - name
|
|
* - deps
|
|
* - declare for declarative modules
|
|
* - execute for dynamic modules, different to declarative execute on module
|
|
* - executingRequire indicates require drives execution for circularity of dynamic modules
|
|
* - declarative optional boolean indicating which of the above
|
|
*
|
|
* Can preload modules directly on SystemJS.defined['my/module'] = { deps, execute, executingRequire }
|
|
*
|
|
* Then the entry gets populated with derived information during processing:
|
|
* - normalizedDeps derived from deps, created in instantiate
|
|
* - groupIndex used by group linking algorithm
|
|
* - evaluated indicating whether evaluation has happend
|
|
* - module the module record object, containing:
|
|
* - exports actual module exports
|
|
*
|
|
* For dynamic we track the es module with:
|
|
* - esModule actual es module value
|
|
* - esmExports whether to extend the esModule with named exports
|
|
*
|
|
* Then for declarative only we track dynamic bindings with the 'module' records:
|
|
* - name
|
|
* - exports
|
|
* - setters declarative setter functions
|
|
* - dependencies, module records of dependencies
|
|
* - importers, module records of dependents
|
|
*
|
|
* After linked and evaluated, entries are removed, declarative module records remain in separate
|
|
* module binding table
|
|
*
|
|
*/
|
|
|
|
var leadingCommentAndMetaRegEx = /^(\s*\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)*\s*/;
|
|
function detectRegisterFormat(source) {
|
|
var leadingCommentAndMeta = source.match(leadingCommentAndMetaRegEx);
|
|
return leadingCommentAndMeta && source.substr(leadingCommentAndMeta[0].length, 15) == 'System.register';
|
|
}
|
|
|
|
function createEntry() {
|
|
return {
|
|
name: null,
|
|
deps: null,
|
|
originalIndices: null,
|
|
declare: null,
|
|
execute: null,
|
|
executingRequire: false,
|
|
declarative: false,
|
|
normalizedDeps: null,
|
|
groupIndex: null,
|
|
evaluated: false,
|
|
module: null,
|
|
esModule: null,
|
|
esmExports: false
|
|
};
|
|
}
|
|
|
|
(function() {
|
|
|
|
/*
|
|
* There are two variations of System.register:
|
|
* 1. System.register for ES6 conversion (2-3 params) - System.register([name, ]deps, declare)
|
|
* see https://github.com/ModuleLoader/es6-module-loader/wiki/System.register-Explained
|
|
*
|
|
* 2. System.registerDynamic for dynamic modules (3-4 params) - System.registerDynamic([name, ]deps, executingRequire, execute)
|
|
* the true or false statement
|
|
*
|
|
* this extension implements the linking algorithm for the two variations identical to the spec
|
|
* allowing compiled ES6 circular references to work alongside AMD and CJS circular references.
|
|
*
|
|
*/
|
|
SystemJSLoader.prototype.register = function(name, deps, declare) {
|
|
if (typeof name != 'string') {
|
|
declare = deps;
|
|
deps = name;
|
|
name = null;
|
|
}
|
|
|
|
// dynamic backwards-compatibility
|
|
// can be deprecated eventually
|
|
if (typeof declare == 'boolean')
|
|
return this.registerDynamic.apply(this, arguments);
|
|
|
|
var entry = createEntry();
|
|
// ideally wouldn't apply map config to bundle names but
|
|
// dependencies go through map regardless so we can't restrict
|
|
// could reconsider in shift to new spec
|
|
entry.name = name && (this.decanonicalize || this.normalize).call(this, name);
|
|
entry.declarative = true;
|
|
entry.deps = deps;
|
|
entry.declare = declare;
|
|
|
|
this.pushRegister_({
|
|
amd: false,
|
|
entry: entry
|
|
});
|
|
};
|
|
SystemJSLoader.prototype.registerDynamic = function(name, deps, declare, execute) {
|
|
if (typeof name != 'string') {
|
|
execute = declare;
|
|
declare = deps;
|
|
deps = name;
|
|
name = null;
|
|
}
|
|
|
|
// dynamic
|
|
var entry = createEntry();
|
|
entry.name = name && (this.decanonicalize || this.normalize).call(this, name);
|
|
entry.deps = deps;
|
|
entry.execute = execute;
|
|
entry.executingRequire = declare;
|
|
|
|
this.pushRegister_({
|
|
amd: false,
|
|
entry: entry
|
|
});
|
|
};
|
|
hook('reduceRegister_', function() {
|
|
return function(load, register) {
|
|
if (!register)
|
|
return;
|
|
|
|
var entry = register.entry;
|
|
var curMeta = load && load.metadata;
|
|
|
|
// named register
|
|
if (entry.name) {
|
|
if (!(entry.name in this.defined))
|
|
this.defined[entry.name] = entry;
|
|
|
|
if (curMeta)
|
|
curMeta.bundle = true;
|
|
}
|
|
// anonymous register
|
|
if (!entry.name || load && !curMeta.entry && entry.name == load.name) {
|
|
if (!curMeta)
|
|
throw new TypeError('Invalid System.register call. Anonymous System.register calls can only be made by modules loaded by SystemJS.import and not via script tags.');
|
|
if (curMeta.entry) {
|
|
if (curMeta.format == 'register')
|
|
throw new Error('Multiple anonymous System.register calls in module ' + load.name + '. If loading a bundle, ensure all the System.register calls are named.');
|
|
else
|
|
throw new Error('Module ' + load.name + ' interpreted as ' + curMeta.format + ' module format, but called System.register.');
|
|
}
|
|
if (!curMeta.format)
|
|
curMeta.format = 'register';
|
|
curMeta.entry = entry;
|
|
}
|
|
};
|
|
});
|
|
|
|
hookConstructor(function(constructor) {
|
|
return function() {
|
|
constructor.call(this);
|
|
|
|
this.defined = {};
|
|
this._loader.moduleRecords = {};
|
|
};
|
|
});
|
|
|
|
function buildGroups(entry, loader, groups) {
|
|
groups[entry.groupIndex] = groups[entry.groupIndex] || [];
|
|
|
|
if (indexOf.call(groups[entry.groupIndex], entry) != -1)
|
|
return;
|
|
|
|
groups[entry.groupIndex].push(entry);
|
|
|
|
for (var i = 0, l = entry.normalizedDeps.length; i < l; i++) {
|
|
var depName = entry.normalizedDeps[i];
|
|
var depEntry = loader.defined[depName];
|
|
|
|
// not in the registry means already linked / ES6
|
|
if (!depEntry || depEntry.evaluated)
|
|
continue;
|
|
|
|
// now we know the entry is in our unlinked linkage group
|
|
var depGroupIndex = entry.groupIndex + (depEntry.declarative != entry.declarative);
|
|
|
|
// the group index of an entry is always the maximum
|
|
if (depEntry.groupIndex === null || depEntry.groupIndex < depGroupIndex) {
|
|
|
|
// if already in a group, remove from the old group
|
|
if (depEntry.groupIndex !== null) {
|
|
groups[depEntry.groupIndex].splice(indexOf.call(groups[depEntry.groupIndex], depEntry), 1);
|
|
|
|
// if the old group is empty, then we have a mixed depndency cycle
|
|
if (groups[depEntry.groupIndex].length == 0)
|
|
throw new Error("Mixed dependency cycle detected");
|
|
}
|
|
|
|
depEntry.groupIndex = depGroupIndex;
|
|
}
|
|
|
|
buildGroups(depEntry, loader, groups);
|
|
}
|
|
}
|
|
|
|
function link(name, startEntry, loader) {
|
|
// skip if already linked
|
|
if (startEntry.module)
|
|
return;
|
|
|
|
startEntry.groupIndex = 0;
|
|
|
|
var groups = [];
|
|
|
|
buildGroups(startEntry, loader, groups);
|
|
|
|
var curGroupDeclarative = !!startEntry.declarative == groups.length % 2;
|
|
for (var i = groups.length - 1; i >= 0; i--) {
|
|
var group = groups[i];
|
|
for (var j = 0; j < group.length; j++) {
|
|
var entry = group[j];
|
|
|
|
// link each group
|
|
if (curGroupDeclarative)
|
|
linkDeclarativeModule(entry, loader);
|
|
else
|
|
linkDynamicModule(entry, loader);
|
|
}
|
|
curGroupDeclarative = !curGroupDeclarative;
|
|
}
|
|
}
|
|
|
|
// module binding records
|
|
function ModuleRecord() {}
|
|
defineProperty(ModuleRecord, 'toString', {
|
|
value: function() {
|
|
return 'Module';
|
|
}
|
|
});
|
|
|
|
function getOrCreateModuleRecord(name, moduleRecords) {
|
|
return moduleRecords[name] || (moduleRecords[name] = {
|
|
name: name,
|
|
dependencies: [],
|
|
exports: new ModuleRecord(), // start from an empty module and extend
|
|
importers: []
|
|
});
|
|
}
|
|
|
|
function linkDeclarativeModule(entry, loader) {
|
|
// only link if already not already started linking (stops at circular)
|
|
if (entry.module)
|
|
return;
|
|
|
|
var moduleRecords = loader._loader.moduleRecords;
|
|
var module = entry.module = getOrCreateModuleRecord(entry.name, moduleRecords);
|
|
var exports = entry.module.exports;
|
|
|
|
var declaration = entry.declare.call(__global, function(name, value) {
|
|
module.locked = true;
|
|
|
|
if (typeof name == 'object') {
|
|
for (var p in name)
|
|
exports[p] = name[p];
|
|
}
|
|
else {
|
|
exports[name] = value;
|
|
}
|
|
|
|
for (var i = 0, l = module.importers.length; i < l; i++) {
|
|
var importerModule = module.importers[i];
|
|
if (!importerModule.locked) {
|
|
var importerIndex = indexOf.call(importerModule.dependencies, module);
|
|
var setter = importerModule.setters[importerIndex];
|
|
if (setter)
|
|
setter(exports);
|
|
}
|
|
}
|
|
|
|
module.locked = false;
|
|
return value;
|
|
}, { id: entry.name });
|
|
|
|
if (typeof declaration == 'function')
|
|
declaration = { setters: [], execute: declaration };
|
|
|
|
// allowing undefined declaration was a mistake! To be deprecated.
|
|
declaration = declaration || { setters: [], execute: function() {} };
|
|
|
|
module.setters = declaration.setters;
|
|
module.execute = declaration.execute;
|
|
|
|
if (!module.setters || !module.execute) {
|
|
throw new TypeError('Invalid System.register form for ' + entry.name);
|
|
}
|
|
|
|
// now link all the module dependencies
|
|
for (var i = 0, l = entry.normalizedDeps.length; i < l; i++) {
|
|
var depName = entry.normalizedDeps[i];
|
|
var depEntry = loader.defined[depName];
|
|
var depModule = moduleRecords[depName];
|
|
|
|
// work out how to set depExports based on scenarios...
|
|
var depExports;
|
|
|
|
if (depModule) {
|
|
depExports = depModule.exports;
|
|
}
|
|
// dynamic, already linked in our registry
|
|
else if (depEntry && !depEntry.declarative) {
|
|
depExports = depEntry.esModule;
|
|
}
|
|
// in the loader registry
|
|
else if (!depEntry) {
|
|
depExports = loader.get(depName);
|
|
}
|
|
// we have an entry -> link
|
|
else {
|
|
linkDeclarativeModule(depEntry, loader);
|
|
depModule = depEntry.module;
|
|
depExports = depModule.exports;
|
|
}
|
|
|
|
// only declarative modules have dynamic bindings
|
|
if (depModule && depModule.importers) {
|
|
depModule.importers.push(module);
|
|
module.dependencies.push(depModule);
|
|
}
|
|
else {
|
|
module.dependencies.push(null);
|
|
}
|
|
|
|
// run setters for all entries with the matching dependency name
|
|
var originalIndices = entry.originalIndices[i];
|
|
for (var j = 0, len = originalIndices.length; j < len; ++j) {
|
|
var index = originalIndices[j];
|
|
if (module.setters[index]) {
|
|
module.setters[index](depExports);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// An analog to loader.get covering execution of all three layers (real declarative, simulated declarative, simulated dynamic)
|
|
function getModule(name, loader) {
|
|
var exports;
|
|
var entry = loader.defined[name];
|
|
|
|
if (!entry) {
|
|
exports = loader.get(name);
|
|
if (!exports)
|
|
throw new Error('Unable to load dependency ' + name + '.');
|
|
}
|
|
|
|
else {
|
|
if (entry.declarative)
|
|
ensureEvaluated(name, entry, [], loader);
|
|
|
|
else if (!entry.evaluated)
|
|
linkDynamicModule(entry, loader);
|
|
|
|
exports = entry.module.exports;
|
|
}
|
|
|
|
if ((!entry || entry.declarative) && exports && exports.__useDefault)
|
|
return exports['default'];
|
|
|
|
return exports;
|
|
}
|
|
|
|
function linkDynamicModule(entry, loader) {
|
|
if (entry.module)
|
|
return;
|
|
|
|
var exports = {};
|
|
|
|
var module = entry.module = { exports: exports, id: entry.name };
|
|
|
|
// AMD requires execute the tree first
|
|
if (!entry.executingRequire) {
|
|
for (var i = 0, l = entry.normalizedDeps.length; i < l; i++) {
|
|
var depName = entry.normalizedDeps[i];
|
|
// we know we only need to link dynamic due to linking algorithm
|
|
var depEntry = loader.defined[depName];
|
|
if (depEntry)
|
|
linkDynamicModule(depEntry, loader);
|
|
}
|
|
}
|
|
|
|
// now execute
|
|
entry.evaluated = true;
|
|
var output = entry.execute.call(__global, function(name) {
|
|
for (var i = 0, l = entry.deps.length; i < l; i++) {
|
|
if (entry.deps[i] != name)
|
|
continue;
|
|
return getModule(entry.normalizedDeps[i], loader);
|
|
}
|
|
// try and normalize the dependency to see if we have another form
|
|
var nameNormalized = loader.normalizeSync(name, entry.name);
|
|
if (indexOf.call(entry.normalizedDeps, nameNormalized) != -1)
|
|
return getModule(nameNormalized, loader);
|
|
|
|
throw new Error('Module ' + name + ' not declared as a dependency of ' + entry.name);
|
|
}, exports, module);
|
|
|
|
if (output !== undefined)
|
|
module.exports = output;
|
|
|
|
// create the esModule object, which allows ES6 named imports of dynamics
|
|
exports = module.exports;
|
|
|
|
// __esModule flag treats as already-named
|
|
if (exports && (exports.__esModule || exports instanceof Module))
|
|
entry.esModule = loader.newModule(exports);
|
|
// set module as 'default' export, then fake named exports by iterating properties
|
|
else if (entry.esmExports && exports !== __global)
|
|
entry.esModule = loader.newModule(getESModule(exports));
|
|
// just use the 'default' export
|
|
else
|
|
entry.esModule = loader.newModule({ 'default': exports, __useDefault: true });
|
|
}
|
|
|
|
/*
|
|
* Given a module, and the list of modules for this current branch,
|
|
* ensure that each of the dependencies of this module is evaluated
|
|
* (unless one is a circular dependency already in the list of seen
|
|
* modules, in which case we execute it)
|
|
*
|
|
* Then we evaluate the module itself depth-first left to right
|
|
* execution to match ES6 modules
|
|
*/
|
|
function ensureEvaluated(moduleName, entry, seen, loader) {
|
|
// if already seen, that means it's an already-evaluated non circular dependency
|
|
if (!entry || entry.evaluated || !entry.declarative)
|
|
return;
|
|
|
|
// this only applies to declarative modules which late-execute
|
|
|
|
seen.push(moduleName);
|
|
|
|
for (var i = 0, l = entry.normalizedDeps.length; i < l; i++) {
|
|
var depName = entry.normalizedDeps[i];
|
|
if (indexOf.call(seen, depName) == -1) {
|
|
if (!loader.defined[depName])
|
|
loader.get(depName);
|
|
else
|
|
ensureEvaluated(depName, loader.defined[depName], seen, loader);
|
|
}
|
|
}
|
|
|
|
if (entry.evaluated)
|
|
return;
|
|
|
|
entry.evaluated = true;
|
|
entry.module.execute.call(__global);
|
|
}
|
|
|
|
// override the delete method to also clear the register caches
|
|
hook('delete', function(del) {
|
|
return function(name) {
|
|
delete this._loader.moduleRecords[name];
|
|
delete this.defined[name];
|
|
return del.call(this, name);
|
|
};
|
|
});
|
|
|
|
hook('fetch', function(fetch) {
|
|
return function(load) {
|
|
if (this.defined[load.name]) {
|
|
load.metadata.format = 'defined';
|
|
return '';
|
|
}
|
|
|
|
load.metadata.deps = load.metadata.deps || [];
|
|
|
|
return fetch.call(this, load);
|
|
};
|
|
});
|
|
|
|
hook('translate', function(translate) {
|
|
// we run the meta detection here (register is after meta)
|
|
return function(load) {
|
|
load.metadata.deps = load.metadata.deps || [];
|
|
return Promise.resolve(translate.apply(this, arguments)).then(function(source) {
|
|
// run detection for register format
|
|
if (load.metadata.format == 'register' || load.metadata.format == 'system' || !load.metadata.format && detectRegisterFormat(load.source))
|
|
load.metadata.format = 'register';
|
|
return source;
|
|
});
|
|
};
|
|
});
|
|
|
|
// implement a perforance shortpath for System.load with no deps
|
|
hook('load', function(doLoad) {
|
|
return function(normalized) {
|
|
var loader = this;
|
|
var entry = loader.defined[normalized];
|
|
|
|
if (!entry || entry.deps.length)
|
|
return doLoad.apply(this, arguments);
|
|
|
|
entry.originalIndices = entry.normalizedDeps = [];
|
|
|
|
// recursively ensure that the module and all its
|
|
// dependencies are linked (with dependency group handling)
|
|
link(normalized, entry, loader);
|
|
|
|
// now handle dependency execution in correct order
|
|
ensureEvaluated(normalized, entry, [], loader);
|
|
if (!entry.esModule)
|
|
entry.esModule = loader.newModule(entry.module.exports);
|
|
|
|
// remove from the registry
|
|
if (!loader.trace)
|
|
loader.defined[normalized] = undefined;
|
|
|
|
// return the defined module object
|
|
loader.set(normalized, entry.esModule);
|
|
|
|
return Promise.resolve();
|
|
};
|
|
});
|
|
|
|
hook('instantiate', function(instantiate) {
|
|
return function(load) {
|
|
if (load.metadata.format == 'detect')
|
|
load.metadata.format = undefined;
|
|
|
|
// assumes previous instantiate is sync
|
|
// (core json support)
|
|
instantiate.call(this, load);
|
|
|
|
var loader = this;
|
|
|
|
var entry;
|
|
|
|
// first we check if this module has already been defined in the registry
|
|
if (loader.defined[load.name]) {
|
|
entry = loader.defined[load.name];
|
|
// don't support deps for ES modules
|
|
if (!entry.declarative)
|
|
entry.deps = entry.deps.concat(load.metadata.deps);
|
|
entry.deps = entry.deps.concat(load.metadata.deps);
|
|
}
|
|
|
|
// picked up already by an anonymous System.register script injection
|
|
// or via the dynamic formats
|
|
else if (load.metadata.entry) {
|
|
entry = load.metadata.entry;
|
|
entry.deps = entry.deps.concat(load.metadata.deps);
|
|
}
|
|
|
|
// Contains System.register calls
|
|
// (dont run bundles in the builder)
|
|
else if (!(loader.builder && load.metadata.bundle)
|
|
&& (load.metadata.format == 'register' || load.metadata.format == 'esm' || load.metadata.format == 'es6')) {
|
|
|
|
if (typeof __exec != 'undefined')
|
|
__exec.call(loader, load);
|
|
|
|
if (!load.metadata.entry && !load.metadata.bundle)
|
|
throw new Error(load.name + ' detected as ' + load.metadata.format + ' but didn\'t execute.');
|
|
|
|
entry = load.metadata.entry;
|
|
|
|
// support metadata deps for System.register
|
|
if (entry && load.metadata.deps)
|
|
entry.deps = entry.deps.concat(load.metadata.deps);
|
|
}
|
|
|
|
// named bundles are just an empty module
|
|
if (!entry) {
|
|
entry = createEntry();
|
|
entry.deps = load.metadata.deps;
|
|
entry.execute = function() {};
|
|
}
|
|
|
|
// place this module onto defined for circular references
|
|
loader.defined[load.name] = entry;
|
|
|
|
var grouped = group(entry.deps);
|
|
|
|
entry.deps = grouped.names;
|
|
entry.originalIndices = grouped.indices;
|
|
entry.name = load.name;
|
|
entry.esmExports = load.metadata.esmExports !== false;
|
|
|
|
// first, normalize all dependencies
|
|
var normalizePromises = [];
|
|
for (var i = 0, l = entry.deps.length; i < l; i++)
|
|
normalizePromises.push(Promise.resolve(loader.normalize(entry.deps[i], load.name)));
|
|
|
|
return Promise.all(normalizePromises).then(function(normalizedDeps) {
|
|
|
|
entry.normalizedDeps = normalizedDeps;
|
|
|
|
return {
|
|
deps: entry.deps,
|
|
execute: function() {
|
|
// recursively ensure that the module and all its
|
|
// dependencies are linked (with dependency group handling)
|
|
link(load.name, entry, loader);
|
|
|
|
// now handle dependency execution in correct order
|
|
ensureEvaluated(load.name, entry, [], loader);
|
|
|
|
if (!entry.esModule)
|
|
entry.esModule = loader.newModule(entry.module.exports);
|
|
|
|
// remove from the registry
|
|
if (!loader.trace)
|
|
loader.defined[load.name] = undefined;
|
|
|
|
// return the defined module object
|
|
return entry.esModule;
|
|
}
|
|
};
|
|
});
|
|
};
|
|
});
|
|
})();
|
|
/*
|
|
* Extension to detect ES6 and auto-load Traceur or Babel for processing
|
|
*/
|
|
(function() {
|
|
// good enough ES6 module detection regex - format detections not designed to be accurate, but to handle the 99% use case
|
|
var esmRegEx = /(^\s*|[}\);\n]\s*)(import\s*(['"]|(\*\s+as\s+)?[^"'\(\)\n;]+\s*from\s*['"]|\{)|export\s+\*\s+from\s+["']|export\s*(\{|default|function|class|var|const|let|async\s+function))/;
|
|
|
|
var traceurRuntimeRegEx = /\$traceurRuntime\s*\./;
|
|
var babelHelpersRegEx = /babelHelpers\s*\./;
|
|
|
|
hook('translate', function(translate) {
|
|
return function(load) {
|
|
var loader = this;
|
|
var args = arguments;
|
|
return translate.apply(loader, args)
|
|
.then(function(source) {
|
|
// detect & transpile ES6
|
|
if (load.metadata.format == 'esm' || load.metadata.format == 'es6' || !load.metadata.format && source.match(esmRegEx)) {
|
|
if (load.metadata.format == 'es6')
|
|
warn.call(loader, 'Module ' + load.name + ' has metadata setting its format to "es6", which is deprecated.\nThis should be updated to "esm".');
|
|
|
|
load.metadata.format = 'esm';
|
|
|
|
if (load.metadata.deps) {
|
|
var depInject = '';
|
|
for (var i = 0; i < load.metadata.deps.length; i++)
|
|
depInject += 'import "' + load.metadata.deps[i] + '"; ';
|
|
load.source = depInject + source;
|
|
}
|
|
|
|
if (loader.transpiler === false) {
|
|
// we accept translation to esm for builds though to enable eg rollup optimizations
|
|
if (loader.builder)
|
|
return source;
|
|
throw new TypeError('Unable to dynamically transpile ES module as SystemJS.transpiler set to false.');
|
|
}
|
|
|
|
// setting _loader.loadedTranspiler = false tells the next block to
|
|
// do checks for setting transpiler metadata
|
|
loader._loader.loadedTranspiler = loader._loader.loadedTranspiler || false;
|
|
if (loader.pluginLoader)
|
|
loader.pluginLoader._loader.loadedTranspiler = loader._loader.loadedTranspiler || false;
|
|
|
|
// do transpilation
|
|
return (loader._loader.transpilerPromise || (
|
|
loader._loader.transpilerPromise = Promise.resolve(
|
|
__global[loader.transpiler == 'typescript' ? 'ts' : loader.transpiler] || (loader.pluginLoader || loader).normalize(loader.transpiler)
|
|
.then(function(normalized) {
|
|
loader._loader.transpilerNormalized = normalized;
|
|
return (loader.pluginLoader || loader).load(normalized)
|
|
.then(function() {
|
|
return (loader.pluginLoader || loader).get(normalized);
|
|
});
|
|
})
|
|
))).then(function(transpiler) {
|
|
loader._loader.loadedTranspilerRuntime = true;
|
|
|
|
if (typeof transpiler.default === 'function' && !__global[loader.transpiler == 'typescript' ? 'ts' : loader.transpiler]) {
|
|
// instantiate plugins dont build
|
|
if (loader.builder)
|
|
return source;
|
|
return Promise.resolve(transpiler.default.call(loader, load.address, load.name))
|
|
.then(function (result) {
|
|
createInstantiate(load, result);
|
|
return '';
|
|
});
|
|
}
|
|
|
|
// translate hooks means this is a transpiler plugin instead of a raw implementation
|
|
if (transpiler.translate) {
|
|
// if transpiler is the same as the plugin loader, then don't run twice
|
|
if (transpiler == load.metadata.loaderModule)
|
|
return load.source;
|
|
|
|
// convert the source map into an object for transpilation chaining
|
|
if (typeof load.metadata.sourceMap == 'string')
|
|
load.metadata.sourceMap = JSON.parse(load.metadata.sourceMap);
|
|
|
|
return Promise.resolve(transpiler.translate.apply(loader, args))
|
|
.then(function(source) {
|
|
// sanitize sourceMap if an object not a JSON string
|
|
var sourceMap = load.metadata.sourceMap;
|
|
if (sourceMap && typeof sourceMap == 'object') {
|
|
var originalName = load.address.split('!')[0];
|
|
|
|
// force set the filename of the original file
|
|
if (!sourceMap.file || sourceMap.file == load.address)
|
|
sourceMap.file = originalName + '!transpiled';
|
|
|
|
// force set the sources list if only one source
|
|
if (!sourceMap.sources || sourceMap.sources.length <= 1 && (!sourceMap.sources[0] || sourceMap.sources[0] == load.address))
|
|
sourceMap.sources = [originalName];
|
|
}
|
|
|
|
if (load.metadata.format == 'esm' && !loader.builder && detectRegisterFormat(source))
|
|
load.metadata.format = 'register';
|
|
return source;
|
|
});
|
|
}
|
|
|
|
// legacy builder support
|
|
if (loader.builder)
|
|
load.metadata.originalSource = load.source;
|
|
|
|
// defined in es6-module-loader/src/transpile.js
|
|
return transpile.call(loader, load)
|
|
.then(function(source) {
|
|
// clear sourceMap as transpiler embeds it
|
|
load.metadata.sourceMap = undefined;
|
|
return source;
|
|
});
|
|
}, function(err) {
|
|
throw addToError(err, 'Unable to load transpiler to transpile ' + load.name);
|
|
});
|
|
}
|
|
|
|
// skip transpiler and transpiler runtime loading when transpiler is disabled
|
|
if (loader.transpiler === false)
|
|
return source;
|
|
|
|
// load the transpiler correctly
|
|
if (loader._loader.loadedTranspiler === false && (loader.transpiler == 'traceur' || loader.transpiler == 'typescript' || loader.transpiler == 'babel')
|
|
&& load.name == loader.normalizeSync(loader.transpiler)) {
|
|
|
|
// always load transpiler as a global
|
|
if (source.length > 100 && !load.metadata.format) {
|
|
load.metadata.format = 'global';
|
|
|
|
if (loader.transpiler === 'traceur')
|
|
load.metadata.exports = 'traceur';
|
|
if (loader.transpiler === 'typescript')
|
|
load.metadata.exports = 'ts';
|
|
}
|
|
|
|
loader._loader.loadedTranspiler = true;
|
|
}
|
|
|
|
// load the transpiler runtime correctly
|
|
if (loader._loader.loadedTranspilerRuntime === false) {
|
|
if (load.name == loader.normalizeSync('traceur-runtime')
|
|
|| load.name == loader.normalizeSync('babel/external-helpers*')) {
|
|
if (source.length > 100)
|
|
load.metadata.format = load.metadata.format || 'global';
|
|
|
|
loader._loader.loadedTranspilerRuntime = true;
|
|
}
|
|
}
|
|
|
|
// detect transpiler runtime usage to load runtimes
|
|
if ((load.metadata.format == 'register' || load.metadata.bundle) && loader._loader.loadedTranspilerRuntime !== true) {
|
|
if (loader.transpiler == 'traceur' && !__global.$traceurRuntime && load.source.match(traceurRuntimeRegEx)) {
|
|
loader._loader.loadedTranspilerRuntime = loader._loader.loadedTranspilerRuntime || false;
|
|
return loader['import']('traceur-runtime').then(function() {
|
|
return source;
|
|
});
|
|
}
|
|
if (loader.transpiler == 'babel' && !__global.babelHelpers && load.source.match(babelHelpersRegEx)) {
|
|
loader._loader.loadedTranspilerRuntime = loader._loader.loadedTranspilerRuntime || false;
|
|
return loader['import']('babel/external-helpers').then(function() {
|
|
return source;
|
|
});
|
|
}
|
|
}
|
|
|
|
return source;
|
|
});
|
|
};
|
|
});
|
|
|
|
})();
|
|
/*
|
|
SystemJS Global Format
|
|
|
|
Supports
|
|
metadata.deps
|
|
metadata.globals
|
|
metadata.exports
|
|
|
|
Without metadata.exports, detects writes to the global object.
|
|
*/
|
|
var __globalName = typeof self != 'undefined' ? 'self' : 'global';
|
|
|
|
hook('fetch', function(fetch) {
|
|
return function(load) {
|
|
if (load.metadata.exports && !load.metadata.format)
|
|
load.metadata.format = 'global';
|
|
return fetch.call(this, load);
|
|
};
|
|
});
|
|
|
|
// ideally we could support script loading for globals, but the issue with that is that
|
|
// we can't do it with AMD support side-by-side since AMD support means defining the
|
|
// global define, and global support means not definining it, yet we don't have any hook
|
|
// into the "pre-execution" phase of a script tag being loaded to handle both cases
|
|
hook('instantiate', function(instantiate) {
|
|
return function(load) {
|
|
var loader = this;
|
|
|
|
if (!load.metadata.format)
|
|
load.metadata.format = 'global';
|
|
|
|
// global is a fallback module format
|
|
if (load.metadata.format == 'global' && !load.metadata.entry) {
|
|
|
|
var entry = createEntry();
|
|
|
|
load.metadata.entry = entry;
|
|
|
|
entry.deps = [];
|
|
|
|
for (var g in load.metadata.globals) {
|
|
var gl = load.metadata.globals[g];
|
|
if (gl)
|
|
entry.deps.push(gl);
|
|
}
|
|
|
|
entry.execute = function(require, exports, module) {
|
|
|
|
var globals;
|
|
if (load.metadata.globals) {
|
|
globals = {};
|
|
for (var g in load.metadata.globals)
|
|
if (load.metadata.globals[g])
|
|
globals[g] = require(load.metadata.globals[g]);
|
|
}
|
|
|
|
var exportName = load.metadata.exports;
|
|
|
|
if (exportName)
|
|
load.source += '\n' + __globalName + '["' + exportName + '"] = ' + exportName + ';';
|
|
|
|
var retrieveGlobal = loader.get('@@global-helpers').prepareGlobal(module.id, exportName, globals, !!load.metadata.encapsulateGlobal);
|
|
__exec.call(loader, load);
|
|
|
|
return retrieveGlobal();
|
|
}
|
|
}
|
|
return instantiate.call(this, load);
|
|
};
|
|
});
|
|
|
|
|
|
function getGlobalValue(exports) {
|
|
if (typeof exports == 'string')
|
|
return readMemberExpression(exports, __global);
|
|
|
|
if (!(exports instanceof Array))
|
|
throw new Error('Global exports must be a string or array.');
|
|
|
|
var globalValue = {};
|
|
var first = true;
|
|
for (var i = 0; i < exports.length; i++) {
|
|
var val = readMemberExpression(exports[i], __global);
|
|
if (first) {
|
|
globalValue['default'] = val;
|
|
first = false;
|
|
}
|
|
globalValue[exports[i].split('.').pop()] = val;
|
|
}
|
|
return globalValue;
|
|
}
|
|
|
|
hook('reduceRegister_', function(reduceRegister) {
|
|
return function(load, register) {
|
|
if (register || (!load.metadata.exports && !(isWorker && load.metadata.format == 'global')))
|
|
return reduceRegister.call(this, load, register);
|
|
|
|
load.metadata.format = 'global';
|
|
var entry = load.metadata.entry = createEntry();
|
|
entry.deps = load.metadata.deps;
|
|
var globalValue = getGlobalValue(load.metadata.exports);
|
|
entry.execute = function() {
|
|
return globalValue;
|
|
};
|
|
};
|
|
});
|
|
|
|
hookConstructor(function(constructor) {
|
|
return function() {
|
|
var loader = this;
|
|
constructor.call(loader);
|
|
|
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
|
|
// bare minimum ignores
|
|
var ignoredGlobalProps = ['_g', 'sessionStorage', 'localStorage', 'clipboardData', 'frames', 'frameElement', 'external',
|
|
'mozAnimationStartTime', 'webkitStorageInfo', 'webkitIndexedDB', 'mozInnerScreenY', 'mozInnerScreenX'];
|
|
|
|
var globalSnapshot;
|
|
|
|
function forEachGlobal(callback) {
|
|
if (Object.keys)
|
|
Object.keys(__global).forEach(callback);
|
|
else
|
|
for (var g in __global) {
|
|
if (!hasOwnProperty.call(__global, g))
|
|
continue;
|
|
callback(g);
|
|
}
|
|
}
|
|
|
|
function forEachGlobalValue(callback) {
|
|
forEachGlobal(function(globalName) {
|
|
if (indexOf.call(ignoredGlobalProps, globalName) != -1)
|
|
return;
|
|
try {
|
|
var value = __global[globalName];
|
|
}
|
|
catch (e) {
|
|
ignoredGlobalProps.push(globalName);
|
|
}
|
|
callback(globalName, value);
|
|
});
|
|
}
|
|
|
|
loader.set('@@global-helpers', loader.newModule({
|
|
prepareGlobal: function(moduleName, exports, globals, encapsulate) {
|
|
// disable module detection
|
|
var curDefine = __global.define;
|
|
|
|
__global.define = undefined;
|
|
|
|
// set globals
|
|
var oldGlobals;
|
|
if (globals) {
|
|
oldGlobals = {};
|
|
for (var g in globals) {
|
|
oldGlobals[g] = __global[g];
|
|
__global[g] = globals[g];
|
|
}
|
|
}
|
|
|
|
// store a complete copy of the global object in order to detect changes
|
|
if (!exports) {
|
|
globalSnapshot = {};
|
|
|
|
forEachGlobalValue(function(name, value) {
|
|
globalSnapshot[name] = value;
|
|
});
|
|
}
|
|
|
|
// return function to retrieve global
|
|
return function() {
|
|
var globalValue = exports ? getGlobalValue(exports) : {};
|
|
|
|
var singleGlobal;
|
|
var multipleExports = !!exports;
|
|
|
|
if (!exports || encapsulate)
|
|
forEachGlobalValue(function(name, value) {
|
|
if (globalSnapshot[name] === value)
|
|
return;
|
|
if (typeof value == 'undefined')
|
|
return;
|
|
|
|
// allow global encapsulation where globals are removed
|
|
if (encapsulate)
|
|
__global[name] = undefined;
|
|
|
|
if (!exports) {
|
|
globalValue[name] = value;
|
|
|
|
if (typeof singleGlobal != 'undefined') {
|
|
if (!multipleExports && singleGlobal !== value)
|
|
multipleExports = true;
|
|
}
|
|
else {
|
|
singleGlobal = value;
|
|
}
|
|
}
|
|
});
|
|
|
|
globalValue = multipleExports ? globalValue : singleGlobal;
|
|
|
|
// revert globals
|
|
if (oldGlobals) {
|
|
for (var g in oldGlobals)
|
|
__global[g] = oldGlobals[g];
|
|
}
|
|
__global.define = curDefine;
|
|
|
|
return globalValue;
|
|
};
|
|
}
|
|
}));
|
|
};
|
|
});
|
|
/*
|
|
SystemJS CommonJS Format
|
|
*/
|
|
(function() {
|
|
// CJS Module Format
|
|
// require('...') || exports[''] = ... || exports.asd = ... || module.exports = ...
|
|
var cjsExportsRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])(exports\s*(\[['"]|\.)|module(\.exports|\['exports'\]|\["exports"\])\s*(\[['"]|[=,\.]))/;
|
|
// RegEx adjusted from https://github.com/jbrantly/yabble/blob/master/lib/yabble.js#L339
|
|
var cjsRequireRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF."'])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g;
|
|
var commentRegEx = /(^|[^\\])(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;
|
|
|
|
var stringRegEx = /("[^"\\\n\r]*(\\.[^"\\\n\r]*)*"|'[^'\\\n\r]*(\\.[^'\\\n\r]*)*')/g;
|
|
|
|
// used to support leading #!/usr/bin/env in scripts as supported in Node
|
|
var hashBangRegEx = /^\#\!.*/;
|
|
|
|
function getCJSDeps(source) {
|
|
cjsRequireRegEx.lastIndex = commentRegEx.lastIndex = stringRegEx.lastIndex = 0;
|
|
|
|
var deps = [];
|
|
|
|
var match;
|
|
|
|
// track string and comment locations for unminified source
|
|
var stringLocations = [], commentLocations = [];
|
|
|
|
function inLocation(locations, match) {
|
|
for (var i = 0; i < locations.length; i++)
|
|
if (locations[i][0] < match.index && locations[i][1] > match.index)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
if (source.length / source.split('\n').length < 200) {
|
|
while (match = stringRegEx.exec(source))
|
|
stringLocations.push([match.index, match.index + match[0].length]);
|
|
|
|
// TODO: track template literals here before comments
|
|
|
|
while (match = commentRegEx.exec(source)) {
|
|
// only track comments not starting in strings
|
|
if (!inLocation(stringLocations, match))
|
|
commentLocations.push([match.index + match[1].length, match.index + match[0].length - 1]);
|
|
}
|
|
}
|
|
|
|
while (match = cjsRequireRegEx.exec(source)) {
|
|
// ensure we're not within a string or comment location
|
|
if (!inLocation(stringLocations, match) && !inLocation(commentLocations, match)) {
|
|
var dep = match[1].substr(1, match[1].length - 2);
|
|
// skip cases like require('" + file + "')
|
|
if (dep.match(/"|'/))
|
|
continue;
|
|
// trailing slash requires are removed as they don't map mains in SystemJS
|
|
if (dep[dep.length - 1] == '/')
|
|
dep = dep.substr(0, dep.length - 1);
|
|
deps.push(dep);
|
|
}
|
|
}
|
|
|
|
return deps;
|
|
}
|
|
|
|
hook('instantiate', function(instantiate) {
|
|
return function(load) {
|
|
var loader = this;
|
|
if (!load.metadata.format) {
|
|
cjsExportsRegEx.lastIndex = 0;
|
|
cjsRequireRegEx.lastIndex = 0;
|
|
if (cjsRequireRegEx.exec(load.source) || cjsExportsRegEx.exec(load.source))
|
|
load.metadata.format = 'cjs';
|
|
}
|
|
|
|
if (load.metadata.format == 'cjs') {
|
|
var metaDeps = load.metadata.deps;
|
|
var deps = load.metadata.cjsRequireDetection === false ? [] : getCJSDeps(load.source);
|
|
|
|
for (var g in load.metadata.globals)
|
|
if (load.metadata.globals[g])
|
|
deps.push(load.metadata.globals[g]);
|
|
|
|
var entry = createEntry();
|
|
|
|
load.metadata.entry = entry;
|
|
|
|
entry.deps = deps;
|
|
entry.executingRequire = true;
|
|
entry.execute = function(_require, exports, module) {
|
|
function require(name) {
|
|
if (name[name.length - 1] == '/')
|
|
name = name.substr(0, name.length - 1);
|
|
return _require.apply(this, arguments);
|
|
}
|
|
require.resolve = function(name) {
|
|
return loader.get('@@cjs-helpers').requireResolve(name, module.id);
|
|
};
|
|
// support module.paths ish
|
|
module.paths = [];
|
|
module.require = _require;
|
|
|
|
// ensure meta deps execute first
|
|
if (!load.metadata.cjsDeferDepsExecute)
|
|
for (var i = 0; i < metaDeps.length; i++)
|
|
require(metaDeps[i]);
|
|
|
|
var pathVars = loader.get('@@cjs-helpers').getPathVars(module.id);
|
|
var __cjsWrapper = {
|
|
exports: exports,
|
|
args: [require, exports, module, pathVars.filename, pathVars.dirname, __global, __global]
|
|
};
|
|
|
|
var cjsWrapper = "(function(require, exports, module, __filename, __dirname, global, GLOBAL";
|
|
|
|
// add metadata.globals to the wrapper arguments
|
|
if (load.metadata.globals)
|
|
for (var g in load.metadata.globals) {
|
|
__cjsWrapper.args.push(require(load.metadata.globals[g]));
|
|
cjsWrapper += ", " + g;
|
|
}
|
|
|
|
// disable AMD detection
|
|
var define = __global.define;
|
|
__global.define = undefined;
|
|
__global.__cjsWrapper = __cjsWrapper;
|
|
|
|
load.source = cjsWrapper + ") {" + load.source.replace(hashBangRegEx, '') + "\n}).apply(__cjsWrapper.exports, __cjsWrapper.args);";
|
|
|
|
__exec.call(loader, load);
|
|
|
|
__global.__cjsWrapper = undefined;
|
|
__global.define = define;
|
|
};
|
|
}
|
|
|
|
return instantiate.call(loader, load);
|
|
};
|
|
});
|
|
})();
|
|
hookConstructor(function(constructor) {
|
|
return function() {
|
|
var loader = this;
|
|
constructor.call(loader);
|
|
|
|
if (typeof window != 'undefined' && typeof document != 'undefined' && window.location)
|
|
var windowOrigin = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '');
|
|
|
|
function stripOrigin(path) {
|
|
if (path.substr(0, 8) == 'file:///')
|
|
return path.substr(7 + !!isWindows);
|
|
|
|
if (windowOrigin && path.substr(0, windowOrigin.length) == windowOrigin)
|
|
return path.substr(windowOrigin.length);
|
|
|
|
return path;
|
|
}
|
|
|
|
loader.set('@@cjs-helpers', loader.newModule({
|
|
requireResolve: function(request, parentId) {
|
|
return stripOrigin(loader.normalizeSync(request, parentId));
|
|
},
|
|
getPathVars: function(moduleId) {
|
|
// remove any plugin syntax
|
|
var pluginIndex = moduleId.lastIndexOf('!');
|
|
var filename;
|
|
if (pluginIndex != -1)
|
|
filename = moduleId.substr(0, pluginIndex);
|
|
else
|
|
filename = moduleId;
|
|
|
|
var dirname = filename.split('/');
|
|
dirname.pop();
|
|
dirname = dirname.join('/');
|
|
|
|
return {
|
|
filename: stripOrigin(filename),
|
|
dirname: stripOrigin(dirname)
|
|
};
|
|
}
|
|
}))
|
|
};
|
|
});/*
|
|
* AMD Helper function module
|
|
* Separated into its own file as this is the part needed for full AMD support in SFX builds
|
|
* NB since implementations have now diverged this can be merged back with amd.js
|
|
*/
|
|
|
|
hook('fetch', function(fetch) {
|
|
return function(load) {
|
|
// script load implies define global leak
|
|
if (load.metadata.scriptLoad && isBrowser)
|
|
__global.define = this.amdDefine;
|
|
return fetch.call(this, load);
|
|
};
|
|
});
|
|
|
|
hookConstructor(function(constructor) {
|
|
return function() {
|
|
var loader = this;
|
|
constructor.call(this);
|
|
|
|
var commentRegEx = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;
|
|
var cjsRequirePre = "(?:^|[^$_a-zA-Z\\xA0-\\uFFFF.])";
|
|
var cjsRequirePost = "\\s*\\(\\s*(\"([^\"]+)\"|'([^']+)')\\s*\\)";
|
|
var fnBracketRegEx = /\(([^\)]*)\)/;
|
|
var wsRegEx = /^\s+|\s+$/g;
|
|
|
|
var requireRegExs = {};
|
|
|
|
function getCJSDeps(source, requireIndex) {
|
|
|
|
// remove comments
|
|
source = source.replace(commentRegEx, '');
|
|
|
|
// determine the require alias
|
|
var params = source.match(fnBracketRegEx);
|
|
var requireAlias = (params[1].split(',')[requireIndex] || 'require').replace(wsRegEx, '');
|
|
|
|
// find or generate the regex for this requireAlias
|
|
var requireRegEx = requireRegExs[requireAlias] || (requireRegExs[requireAlias] = new RegExp(cjsRequirePre + requireAlias + cjsRequirePost, 'g'));
|
|
|
|
requireRegEx.lastIndex = 0;
|
|
|
|
var deps = [];
|
|
|
|
var match;
|
|
while (match = requireRegEx.exec(source))
|
|
deps.push(match[2] || match[3]);
|
|
|
|
return deps;
|
|
}
|
|
|
|
/*
|
|
AMD-compatible require
|
|
To copy RequireJS, set window.require = window.requirejs = loader.amdRequire
|
|
*/
|
|
function require(names, callback, errback, referer) {
|
|
// in amd, first arg can be a config object... we just ignore
|
|
if (typeof names == 'object' && !(names instanceof Array))
|
|
return require.apply(null, Array.prototype.splice.call(arguments, 1, arguments.length - 1));
|
|
|
|
// amd require
|
|
if (typeof names == 'string' && typeof callback == 'function')
|
|
names = [names];
|
|
if (names instanceof Array) {
|
|
var dynamicRequires = [];
|
|
for (var i = 0; i < names.length; i++)
|
|
dynamicRequires.push(loader['import'](names[i], referer));
|
|
Promise.all(dynamicRequires).then(function(modules) {
|
|
if (callback)
|
|
callback.apply(null, modules);
|
|
}, errback);
|
|
}
|
|
|
|
// commonjs require
|
|
else if (typeof names == 'string') {
|
|
var defaultJSExtension = loader.defaultJSExtensions && names.substr(names.length - 3, 3) != '.js';
|
|
var normalized = loader.decanonicalize(names, referer);
|
|
if (defaultJSExtension && normalized.substr(normalized.length - 3, 3) == '.js')
|
|
normalized = normalized.substr(0, normalized.length - 3);
|
|
var module = loader.get(normalized);
|
|
if (!module)
|
|
throw new Error('Module not already loaded loading "' + names + '" as ' + normalized + (referer ? ' from "' + referer + '".' : '.'));
|
|
return module.__useDefault ? module['default'] : module;
|
|
}
|
|
|
|
else
|
|
throw new TypeError('Invalid require');
|
|
}
|
|
|
|
function define(name, deps, factory) {
|
|
if (typeof name != 'string') {
|
|
factory = deps;
|
|
deps = name;
|
|
name = null;
|
|
}
|
|
if (!(deps instanceof Array)) {
|
|
factory = deps;
|
|
deps = ['require', 'exports', 'module'].splice(0, factory.length);
|
|
}
|
|
|
|
if (typeof factory != 'function')
|
|
factory = (function(factory) {
|
|
return function() { return factory; }
|
|
})(factory);
|
|
|
|
// in IE8, a trailing comma becomes a trailing undefined entry
|
|
if (deps[deps.length - 1] === undefined)
|
|
deps.pop();
|
|
|
|
// remove system dependencies
|
|
var requireIndex, exportsIndex, moduleIndex;
|
|
|
|
if ((requireIndex = indexOf.call(deps, 'require')) != -1) {
|
|
|
|
deps.splice(requireIndex, 1);
|
|
|
|
// only trace cjs requires for non-named
|
|
// named defines assume the trace has already been done
|
|
if (!name)
|
|
deps = deps.concat(getCJSDeps(factory.toString(), requireIndex));
|
|
}
|
|
|
|
if ((exportsIndex = indexOf.call(deps, 'exports')) != -1)
|
|
deps.splice(exportsIndex, 1);
|
|
|
|
if ((moduleIndex = indexOf.call(deps, 'module')) != -1)
|
|
deps.splice(moduleIndex, 1);
|
|
|
|
function execute(req, exports, module) {
|
|
var depValues = [];
|
|
for (var i = 0; i < deps.length; i++)
|
|
depValues.push(req(deps[i]));
|
|
|
|
module.uri = module.id;
|
|
|
|
module.config = function() {};
|
|
|
|
// add back in system dependencies
|
|
if (moduleIndex != -1)
|
|
depValues.splice(moduleIndex, 0, module);
|
|
|
|
if (exportsIndex != -1)
|
|
depValues.splice(exportsIndex, 0, exports);
|
|
|
|
if (requireIndex != -1) {
|
|
function contextualRequire(names, callback, errback) {
|
|
if (typeof names == 'string' && typeof callback != 'function')
|
|
return req(names);
|
|
return require.call(loader, names, callback, errback, module.id);
|
|
}
|
|
contextualRequire.toUrl = function(name) {
|
|
// normalize without defaultJSExtensions
|
|
var defaultJSExtension = loader.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js';
|
|
var url = loader.decanonicalize(name, module.id);
|
|
if (defaultJSExtension && url.substr(url.length - 3, 3) == '.js')
|
|
url = url.substr(0, url.length - 3);
|
|
return url;
|
|
};
|
|
depValues.splice(requireIndex, 0, contextualRequire);
|
|
}
|
|
|
|
// set global require to AMD require
|
|
var curRequire = __global.require;
|
|
__global.require = require;
|
|
|
|
var output = factory.apply(exportsIndex == -1 ? __global : exports, depValues);
|
|
|
|
__global.require = curRequire;
|
|
|
|
if (typeof output == 'undefined' && module)
|
|
output = module.exports;
|
|
|
|
if (typeof output != 'undefined')
|
|
return output;
|
|
}
|
|
|
|
var entry = createEntry();
|
|
entry.name = name && (loader.decanonicalize || loader.normalize).call(loader, name);
|
|
entry.deps = deps;
|
|
entry.execute = execute;
|
|
|
|
loader.pushRegister_({
|
|
amd: true,
|
|
entry: entry
|
|
});
|
|
}
|
|
define.amd = {};
|
|
|
|
// reduction function to attach defines to a load record
|
|
hook('reduceRegister_', function(reduceRegister) {
|
|
return function(load, register) {
|
|
// only handle AMD registers here
|
|
if (!register || !register.amd)
|
|
return reduceRegister.call(this, load, register);
|
|
|
|
var curMeta = load && load.metadata;
|
|
var entry = register.entry;
|
|
|
|
if (curMeta) {
|
|
if (!curMeta.format || curMeta.format == 'detect')
|
|
curMeta.format = 'amd';
|
|
else if (!entry.name && curMeta.format != 'amd')
|
|
throw new Error('AMD define called while executing ' + curMeta.format + ' module ' + load.name);
|
|
}
|
|
|
|
// anonymous define
|
|
if (!entry.name) {
|
|
if (!curMeta)
|
|
throw new TypeError('Unexpected anonymous AMD define.');
|
|
|
|
if (curMeta.entry && !curMeta.entry.name)
|
|
throw new Error('Multiple anonymous defines in module ' + load.name);
|
|
|
|
curMeta.entry = entry;
|
|
}
|
|
// named define
|
|
else {
|
|
// if we don't have any other defines,
|
|
// then let this be an anonymous define
|
|
// this is just to support single modules of the form:
|
|
// define('jquery')
|
|
// still loading anonymously
|
|
// because it is done widely enough to be useful
|
|
// as soon as there is more than one define, this gets removed though
|
|
if (curMeta) {
|
|
if (!curMeta.entry && !curMeta.bundle)
|
|
curMeta.entry = entry;
|
|
else if (curMeta.entry && curMeta.entry.name && curMeta.entry.name != load.name)
|
|
curMeta.entry = undefined;
|
|
|
|
// note this is now a bundle
|
|
curMeta.bundle = true;
|
|
}
|
|
|
|
// define the module through the register registry
|
|
if (!(entry.name in this.defined))
|
|
this.defined[entry.name] = entry;
|
|
}
|
|
};
|
|
});
|
|
|
|
loader.amdDefine = define;
|
|
loader.amdRequire = require;
|
|
};
|
|
});/*
|
|
SystemJS AMD Format
|
|
*/
|
|
(function() {
|
|
// AMD Module Format Detection RegEx
|
|
// define([.., .., ..], ...)
|
|
// define(varName); || define(function(require, exports) {}); || define({})
|
|
var amdRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])define\s*\(\s*("[^"]+"\s*,\s*|'[^']+'\s*,\s*)?\s*(\[(\s*(("[^"]+"|'[^']+')\s*,|\/\/.*\r?\n|\/\*(.|\s)*?\*\/))*(\s*("[^"]+"|'[^']+')\s*,?)?(\s*(\/\/.*\r?\n|\/\*(.|\s)*?\*\/))*\s*\]|function\s*|{|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*\))/;
|
|
|
|
hook('instantiate', function(instantiate) {
|
|
return function(load) {
|
|
var loader = this;
|
|
|
|
if (load.metadata.format == 'amd' || !load.metadata.format && load.source.match(amdRegEx)) {
|
|
load.metadata.format = 'amd';
|
|
|
|
if (!loader.builder && loader.execute !== false) {
|
|
var curDefine = __global.define;
|
|
__global.define = this.amdDefine;
|
|
|
|
try {
|
|
__exec.call(loader, load);
|
|
}
|
|
finally {
|
|
__global.define = curDefine;
|
|
}
|
|
|
|
if (!load.metadata.entry && !load.metadata.bundle)
|
|
throw new TypeError('AMD module ' + load.name + ' did not define');
|
|
}
|
|
else {
|
|
load.metadata.execute = function() {
|
|
return load.metadata.builderExecute.apply(this, arguments);
|
|
};
|
|
}
|
|
}
|
|
|
|
return instantiate.call(loader, load);
|
|
};
|
|
});
|
|
|
|
})();
|
|
/*
|
|
SystemJS Loader Plugin Support
|
|
|
|
Supports plugin loader syntax with "!", or via metadata.loader
|
|
|
|
The plugin name is loaded as a module itself, and can override standard loader hooks
|
|
for the plugin resource. See the plugin section of the systemjs readme.
|
|
*/
|
|
|
|
(function() {
|
|
function getParentName(loader, parentName) {
|
|
// if parent is a plugin, normalize against the parent plugin argument only
|
|
if (parentName) {
|
|
var parentPluginIndex;
|
|
if (loader.pluginFirst) {
|
|
if ((parentPluginIndex = parentName.lastIndexOf('!')) != -1)
|
|
return parentName.substr(parentPluginIndex + 1);
|
|
}
|
|
else {
|
|
if ((parentPluginIndex = parentName.indexOf('!')) != -1)
|
|
return parentName.substr(0, parentPluginIndex);
|
|
}
|
|
|
|
return parentName;
|
|
}
|
|
}
|
|
|
|
function parsePlugin(loader, name) {
|
|
var argumentName;
|
|
var pluginName;
|
|
|
|
var pluginIndex = name.lastIndexOf('!');
|
|
|
|
if (pluginIndex == -1)
|
|
return;
|
|
|
|
if (loader.pluginFirst) {
|
|
argumentName = name.substr(pluginIndex + 1);
|
|
pluginName = name.substr(0, pluginIndex);
|
|
}
|
|
else {
|
|
argumentName = name.substr(0, pluginIndex);
|
|
pluginName = name.substr(pluginIndex + 1) || argumentName.substr(argumentName.lastIndexOf('.') + 1);
|
|
}
|
|
|
|
return {
|
|
argument: argumentName,
|
|
plugin: pluginName
|
|
};
|
|
}
|
|
|
|
// put name back together after parts have been normalized
|
|
function combinePluginParts(loader, argumentName, pluginName, defaultExtension) {
|
|
if (defaultExtension && argumentName.substr(argumentName.length - 3, 3) == '.js')
|
|
argumentName = argumentName.substr(0, argumentName.length - 3);
|
|
|
|
if (loader.pluginFirst) {
|
|
return pluginName + '!' + argumentName;
|
|
}
|
|
else {
|
|
return argumentName + '!' + pluginName;
|
|
}
|
|
}
|
|
|
|
// note if normalize will add a default js extension
|
|
// if so, remove for backwards compat
|
|
// this is strange and sucks, but will be deprecated
|
|
function checkDefaultExtension(loader, arg) {
|
|
return loader.defaultJSExtensions && arg.substr(arg.length - 3, 3) != '.js';
|
|
}
|
|
|
|
function createNormalizeSync(normalizeSync) {
|
|
return function(name, parentName, isPlugin) {
|
|
var loader = this;
|
|
|
|
var parsed = parsePlugin(loader, name);
|
|
parentName = getParentName(this, parentName);
|
|
|
|
if (!parsed)
|
|
return normalizeSync.call(this, name, parentName, isPlugin);
|
|
|
|
// if this is a plugin, normalize the plugin name and the argument
|
|
var argumentName = loader.normalizeSync(parsed.argument, parentName, true);
|
|
var pluginName = loader.normalizeSync(parsed.plugin, parentName, true);
|
|
return combinePluginParts(loader, argumentName, pluginName, checkDefaultExtension(loader, parsed.argument));
|
|
};
|
|
}
|
|
|
|
hook('decanonicalize', createNormalizeSync);
|
|
hook('normalizeSync', createNormalizeSync);
|
|
|
|
hook('normalize', function(normalize) {
|
|
return function(name, parentName, isPlugin) {
|
|
var loader = this;
|
|
|
|
parentName = getParentName(this, parentName);
|
|
|
|
var parsed = parsePlugin(loader, name);
|
|
|
|
if (!parsed)
|
|
return normalize.call(loader, name, parentName, isPlugin);
|
|
|
|
return Promise.all([
|
|
loader.normalize(parsed.argument, parentName, true),
|
|
loader.normalize(parsed.plugin, parentName, false)
|
|
])
|
|
.then(function(normalized) {
|
|
return combinePluginParts(loader, normalized[0], normalized[1], checkDefaultExtension(loader, parsed.argument));
|
|
});
|
|
}
|
|
});
|
|
|
|
hook('locate', function(locate) {
|
|
return function(load) {
|
|
var loader = this;
|
|
|
|
var name = load.name;
|
|
|
|
// plugin syntax
|
|
var pluginSyntaxIndex;
|
|
if (loader.pluginFirst) {
|
|
if ((pluginSyntaxIndex = name.indexOf('!')) != -1) {
|
|
load.metadata.loader = name.substr(0, pluginSyntaxIndex);
|
|
load.name = name.substr(pluginSyntaxIndex + 1);
|
|
}
|
|
}
|
|
else {
|
|
if ((pluginSyntaxIndex = name.lastIndexOf('!')) != -1) {
|
|
load.metadata.loader = name.substr(pluginSyntaxIndex + 1);
|
|
load.name = name.substr(0, pluginSyntaxIndex);
|
|
}
|
|
}
|
|
|
|
return locate.call(loader, load)
|
|
.then(function(address) {
|
|
if (pluginSyntaxIndex != -1 || !load.metadata.loader)
|
|
return address;
|
|
|
|
// normalize plugin relative to parent in locate here when
|
|
// using plugin via loader metadata
|
|
return (loader.pluginLoader || loader).normalize(load.metadata.loader, load.name)
|
|
.then(function(loaderNormalized) {
|
|
load.metadata.loader = loaderNormalized;
|
|
return address;
|
|
});
|
|
})
|
|
.then(function(address) {
|
|
var plugin = load.metadata.loader;
|
|
|
|
if (!plugin)
|
|
return address;
|
|
|
|
// don't allow a plugin to load itself
|
|
if (load.name == plugin)
|
|
throw new Error('Plugin ' + plugin + ' cannot load itself, make sure it is excluded from any wildcard meta configuration via a custom loader: false rule.');
|
|
|
|
// only fetch the plugin itself if this name isn't defined
|
|
if (loader.defined && loader.defined[name])
|
|
return address;
|
|
|
|
var pluginLoader = loader.pluginLoader || loader;
|
|
|
|
// load the plugin module and run standard locate
|
|
return pluginLoader['import'](plugin)
|
|
.then(function(loaderModule) {
|
|
// store the plugin module itself on the metadata
|
|
load.metadata.loaderModule = loaderModule;
|
|
|
|
load.address = address;
|
|
if (loaderModule.locate)
|
|
return loaderModule.locate.call(loader, load);
|
|
|
|
return address;
|
|
});
|
|
});
|
|
};
|
|
});
|
|
|
|
hook('fetch', function(fetch) {
|
|
return function(load) {
|
|
var loader = this;
|
|
if (load.metadata.loaderModule && load.metadata.format != 'defined') {
|
|
if (typeof load.metadata.loaderModule === 'function' || load.metadata.loaderModule instanceof Module && typeof load.metadata.loaderModule.default === 'function')
|
|
return '';
|
|
load.metadata.scriptLoad = false;
|
|
if (load.metadata.loaderModule.fetch)
|
|
return load.metadata.loaderModule.fetch.call(loader, load, function(load) {
|
|
return fetch.call(loader, load);
|
|
});
|
|
}
|
|
return fetch.call(loader, load);
|
|
};
|
|
});
|
|
|
|
hook('translate', function(translate) {
|
|
return function(load) {
|
|
var loader = this;
|
|
var args = arguments;
|
|
if (load.metadata.loaderModule && load.metadata.loaderModule.translate && load.metadata.format != 'defined') {
|
|
return Promise.resolve(load.metadata.loaderModule.translate.apply(loader, args)).then(function(result) {
|
|
var sourceMap = load.metadata.sourceMap;
|
|
|
|
// sanitize sourceMap if an object not a JSON string
|
|
if (sourceMap) {
|
|
if (typeof sourceMap != 'object')
|
|
throw new Error('load.metadata.sourceMap must be set to an object.');
|
|
|
|
var originalName = load.address.split('!')[0];
|
|
|
|
// force set the filename of the original file
|
|
if (!sourceMap.file || sourceMap.file == load.address)
|
|
sourceMap.file = originalName + '!transpiled';
|
|
|
|
// force set the sources list if only one source
|
|
if (!sourceMap.sources || sourceMap.sources.length <= 1 && (!sourceMap.sources[0] || sourceMap.sources[0] == load.address))
|
|
sourceMap.sources = [originalName];
|
|
}
|
|
|
|
// if running on file:/// URLs, sourcesContent is necessary
|
|
// load.metadata.sourceMap.sourcesContent = [load.source];
|
|
|
|
if (typeof result == 'string')
|
|
load.source = result;
|
|
|
|
return translate.apply(loader, args);
|
|
});
|
|
}
|
|
return translate.apply(loader, args);
|
|
};
|
|
});
|
|
|
|
hook('instantiate', function(instantiate) {
|
|
return function(load) {
|
|
var loader = this;
|
|
var calledInstantiate = false;
|
|
|
|
if (load.metadata.loaderModule && !loader.builder && load.metadata.format != 'defined') {
|
|
if (load.metadata.loaderModule.instantiate)
|
|
return Promise.resolve(load.metadata.loaderModule.instantiate.call(loader, load, function(load) {
|
|
if (calledInstantiate)
|
|
throw new Error('Instantiate must only be called once.');
|
|
calledInstantiate = true;
|
|
return instantiate.call(loader, load);
|
|
})).then(function(result) {
|
|
if (calledInstantiate)
|
|
return result;
|
|
|
|
if (result !== undefined)
|
|
createInstantiate(load, result);
|
|
return instantiate.call(loader, load);
|
|
});
|
|
else if (typeof load.metadata.loaderModule === 'function' || load.metadata.loaderModule instanceof Module && typeof load.metadata.loaderModule.default === 'function')
|
|
return Promise.resolve((load.metadata.loaderModule.default || load.metadata.loaderModule).call(loader, load.address, load.name))
|
|
.then(function (result) {
|
|
if (result !== undefined)
|
|
createInstantiate(load, result);
|
|
return instantiate.call(loader, load);
|
|
});
|
|
}
|
|
return instantiate.call(loader, load);
|
|
};
|
|
});
|
|
|
|
})();
|
|
/*
|
|
* Conditions Extension
|
|
*
|
|
* Allows a condition module to alter the resolution of an import via syntax:
|
|
*
|
|
* import $ from 'jquery/#{browser}';
|
|
*
|
|
* Will first load the module 'browser' via `SystemJS.import('browser')` and
|
|
* take the default export of that module.
|
|
* If the default export is not a string, an error is thrown.
|
|
*
|
|
* We then substitute the string into the require to get the conditional resolution
|
|
* enabling environment-specific variations like:
|
|
*
|
|
* import $ from 'jquery/ie'
|
|
* import $ from 'jquery/firefox'
|
|
* import $ from 'jquery/chrome'
|
|
* import $ from 'jquery/safari'
|
|
*
|
|
* It can be useful for a condition module to define multiple conditions.
|
|
* This can be done via the `|` modifier to specify an export member expression:
|
|
*
|
|
* import 'jquery/#{./browser.js|grade.version}'
|
|
*
|
|
* Where the `grade` export `version` member in the `browser.js` module is substituted.
|
|
*
|
|
*
|
|
* Boolean Conditionals
|
|
*
|
|
* For polyfill modules, that are used as imports but have no module value,
|
|
* a binary conditional allows a module not to be loaded at all if not needed:
|
|
*
|
|
* import 'es5-shim#?./conditions.js|needs-es5shim'
|
|
*
|
|
* These conditions can also be negated via:
|
|
*
|
|
* import 'es5-shim#?./conditions.js|~es6'
|
|
*
|
|
*/
|
|
|
|
var sysConditions = ['browser', 'node', 'dev', 'build', 'production', 'default'];
|
|
|
|
function parseCondition(condition) {
|
|
var conditionExport, conditionModule, negation;
|
|
|
|
var negation = condition[0] == '~';
|
|
var conditionExportIndex = condition.lastIndexOf('|');
|
|
if (conditionExportIndex != -1) {
|
|
conditionExport = condition.substr(conditionExportIndex + 1);
|
|
conditionModule = condition.substr(negation, conditionExportIndex - negation);
|
|
|
|
if (negation)
|
|
warn.call(this, 'Condition negation form "' + condition + '" is deprecated for "' + conditionModule + '|~' + conditionExport + '"');
|
|
|
|
if (conditionExport[0] == '~') {
|
|
negation = true;
|
|
conditionExport = conditionExport.substr(1);
|
|
}
|
|
}
|
|
else {
|
|
conditionExport = 'default';
|
|
conditionModule = condition.substr(negation);
|
|
if (sysConditions.indexOf(conditionModule) != -1) {
|
|
conditionExport = conditionModule;
|
|
conditionModule = null;
|
|
}
|
|
}
|
|
|
|
return {
|
|
module: conditionModule || '@system-env',
|
|
prop: conditionExport,
|
|
negate: negation
|
|
};
|
|
}
|
|
|
|
function serializeCondition(conditionObj) {
|
|
return conditionObj.module + '|' + (conditionObj.negate ? '~' : '') + conditionObj.prop;
|
|
}
|
|
|
|
function resolveCondition(conditionObj, parentName, bool) {
|
|
var self = this;
|
|
return this.normalize(conditionObj.module, parentName)
|
|
.then(function(normalizedCondition) {
|
|
return self.load(normalizedCondition)
|
|
.then(function(q) {
|
|
var m = readMemberExpression(conditionObj.prop, self.get(normalizedCondition));
|
|
|
|
if (bool && typeof m != 'boolean')
|
|
throw new TypeError('Condition ' + serializeCondition(conditionObj) + ' did not resolve to a boolean.');
|
|
|
|
return conditionObj.negate ? !m : m;
|
|
});
|
|
});
|
|
}
|
|
|
|
var interpolationRegEx = /#\{[^\}]+\}/;
|
|
function interpolateConditional(name, parentName) {
|
|
// first we normalize the conditional
|
|
var conditionalMatch = name.match(interpolationRegEx);
|
|
|
|
if (!conditionalMatch)
|
|
return Promise.resolve(name);
|
|
|
|
var conditionObj = parseCondition.call(this, conditionalMatch[0].substr(2, conditionalMatch[0].length - 3));
|
|
|
|
// in builds, return normalized conditional
|
|
if (this.builder)
|
|
return this['normalize'](conditionObj.module, parentName)
|
|
.then(function(conditionModule) {
|
|
conditionObj.module = conditionModule;
|
|
return name.replace(interpolationRegEx, '#{' + serializeCondition(conditionObj) + '}');
|
|
});
|
|
|
|
return resolveCondition.call(this, conditionObj, parentName, false)
|
|
.then(function(conditionValue) {
|
|
if (typeof conditionValue !== 'string')
|
|
throw new TypeError('The condition value for ' + name + ' doesn\'t resolve to a string.');
|
|
|
|
if (conditionValue.indexOf('/') != -1)
|
|
throw new TypeError('Unabled to interpolate conditional ' + name + (parentName ? ' in ' + parentName : '') + '\n\tThe condition value ' + conditionValue + ' cannot contain a "/" separator.');
|
|
|
|
return name.replace(interpolationRegEx, conditionValue);
|
|
});
|
|
}
|
|
|
|
function booleanConditional(name, parentName) {
|
|
// first we normalize the conditional
|
|
var booleanIndex = name.lastIndexOf('#?');
|
|
|
|
if (booleanIndex == -1)
|
|
return Promise.resolve(name);
|
|
|
|
var conditionObj = parseCondition.call(this, name.substr(booleanIndex + 2));
|
|
|
|
// in builds, return normalized conditional
|
|
if (this.builder)
|
|
return this['normalize'](conditionObj.module, parentName)
|
|
.then(function(conditionModule) {
|
|
conditionObj.module = conditionModule;
|
|
return name.substr(0, booleanIndex) + '#?' + serializeCondition(conditionObj);
|
|
});
|
|
|
|
return resolveCondition.call(this, conditionObj, parentName, true)
|
|
.then(function(conditionValue) {
|
|
return conditionValue ? name.substr(0, booleanIndex) : '@empty';
|
|
});
|
|
}
|
|
|
|
// normalizeSync does not parse conditionals at all although it could
|
|
hook('normalize', function(normalize) {
|
|
return function(name, parentName, skipExt) {
|
|
var loader = this;
|
|
return booleanConditional.call(loader, name, parentName)
|
|
.then(function(name) {
|
|
return normalize.call(loader, name, parentName, skipExt);
|
|
})
|
|
.then(function(normalized) {
|
|
return interpolateConditional.call(loader, normalized, parentName);
|
|
});
|
|
};
|
|
});
|
|
/*
|
|
* Alias Extension
|
|
*
|
|
* Allows a module to be a plain copy of another module by module name
|
|
*
|
|
* SystemJS.meta['mybootstrapalias'] = { alias: 'bootstrap' };
|
|
*
|
|
*/
|
|
(function() {
|
|
// aliases
|
|
hook('fetch', function(fetch) {
|
|
return function(load) {
|
|
var alias = load.metadata.alias;
|
|
var aliasDeps = load.metadata.deps || [];
|
|
if (alias) {
|
|
load.metadata.format = 'defined';
|
|
var entry = createEntry();
|
|
this.defined[load.name] = entry;
|
|
entry.declarative = true;
|
|
entry.deps = aliasDeps.concat([alias]);
|
|
entry.declare = function(_export) {
|
|
return {
|
|
setters: [function(module) {
|
|
for (var p in module)
|
|
_export(p, module[p]);
|
|
if (module.__useDefault)
|
|
entry.module.exports.__useDefault = true;
|
|
}],
|
|
execute: function() {}
|
|
};
|
|
};
|
|
return '';
|
|
}
|
|
|
|
return fetch.call(this, load);
|
|
};
|
|
});
|
|
})();/*
|
|
* Meta Extension
|
|
*
|
|
* Sets default metadata on a load record (load.metadata) from
|
|
* loader.metadata via SystemJS.meta function.
|
|
*
|
|
*
|
|
* Also provides an inline meta syntax for module meta in source.
|
|
*
|
|
* Eg:
|
|
*
|
|
* loader.meta({
|
|
* 'my/module': { deps: ['jquery'] }
|
|
* 'my/*': { format: 'amd' }
|
|
* });
|
|
*
|
|
* Which in turn populates loader.metadata.
|
|
*
|
|
* load.metadata.deps and load.metadata.format will then be set
|
|
* for 'my/module'
|
|
*
|
|
* The same meta could be set with a my/module.js file containing:
|
|
*
|
|
* my/module.js
|
|
* "format amd";
|
|
* "deps[] jquery";
|
|
* "globals.some value"
|
|
* console.log('this is my/module');
|
|
*
|
|
* Configuration meta always takes preference to inline meta.
|
|
*
|
|
* Multiple matches in wildcards are supported and ammend the meta.
|
|
*
|
|
*
|
|
* The benefits of the function form is that paths are URL-normalized
|
|
* supporting say
|
|
*
|
|
* loader.meta({ './app': { format: 'cjs' } });
|
|
*
|
|
* Instead of needing to set against the absolute URL (https://site.com/app.js)
|
|
*
|
|
*/
|
|
|
|
(function() {
|
|
|
|
hookConstructor(function(constructor) {
|
|
return function() {
|
|
this.meta = {};
|
|
constructor.call(this);
|
|
};
|
|
});
|
|
|
|
hook('locate', function(locate) {
|
|
return function(load) {
|
|
var meta = this.meta;
|
|
var name = load.name;
|
|
|
|
// NB for perf, maybe introduce a fast-path wildcard lookup cache here
|
|
// which is checked first
|
|
|
|
// apply wildcard metas
|
|
var bestDepth = 0;
|
|
var wildcardIndex;
|
|
for (var module in meta) {
|
|
wildcardIndex = module.indexOf('*');
|
|
if (wildcardIndex === -1)
|
|
continue;
|
|
if (module.substr(0, wildcardIndex) === name.substr(0, wildcardIndex)
|
|
&& module.substr(wildcardIndex + 1) === name.substr(name.length - module.length + wildcardIndex + 1)) {
|
|
var depth = module.split('/').length;
|
|
if (depth > bestDepth)
|
|
bestDepth = depth;
|
|
extendMeta(load.metadata, meta[module], bestDepth != depth);
|
|
}
|
|
}
|
|
|
|
// apply exact meta
|
|
if (meta[name])
|
|
extendMeta(load.metadata, meta[name]);
|
|
|
|
return locate.call(this, load);
|
|
};
|
|
});
|
|
|
|
// detect any meta header syntax
|
|
// only set if not already set
|
|
var metaRegEx = /^(\s*\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)+/;
|
|
var metaPartRegEx = /\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\/\/[^\n]*|"[^"]+"\s*;?|'[^']+'\s*;?/g;
|
|
|
|
function setMetaProperty(target, p, value) {
|
|
var pParts = p.split('.');
|
|
var curPart;
|
|
while (pParts.length > 1) {
|
|
curPart = pParts.shift();
|
|
target = target[curPart] = target[curPart] || {};
|
|
}
|
|
curPart = pParts.shift();
|
|
if (!(curPart in target))
|
|
target[curPart] = value;
|
|
}
|
|
|
|
hook('translate', function(translate) {
|
|
return function(load) {
|
|
// shortpath for bundled
|
|
if (load.metadata.format == 'defined') {
|
|
load.metadata.deps = load.metadata.deps || [];
|
|
return Promise.resolve(load.source);
|
|
}
|
|
|
|
// NB meta will be post-translate pending transpiler conversion to plugins
|
|
var meta = load.source.match(metaRegEx);
|
|
if (meta) {
|
|
var metaParts = meta[0].match(metaPartRegEx);
|
|
|
|
for (var i = 0; i < metaParts.length; i++) {
|
|
var curPart = metaParts[i];
|
|
var len = curPart.length;
|
|
|
|
var firstChar = curPart.substr(0, 1);
|
|
if (curPart.substr(len - 1, 1) == ';')
|
|
len--;
|
|
|
|
if (firstChar != '"' && firstChar != "'")
|
|
continue;
|
|
|
|
var metaString = curPart.substr(1, curPart.length - 3);
|
|
var metaName = metaString.substr(0, metaString.indexOf(' '));
|
|
|
|
if (metaName) {
|
|
var metaValue = metaString.substr(metaName.length + 1, metaString.length - metaName.length - 1);
|
|
|
|
if (metaName.substr(metaName.length - 2, 2) == '[]') {
|
|
metaName = metaName.substr(0, metaName.length - 2);
|
|
load.metadata[metaName] = load.metadata[metaName] || [];
|
|
load.metadata[metaName].push(metaValue);
|
|
}
|
|
else if (load.metadata[metaName] instanceof Array) {
|
|
// temporary backwards compat for previous "deps" syntax
|
|
warn.call(this, 'Module ' + load.name + ' contains deprecated "deps ' + metaValue + '" meta syntax.\nThis should be updated to "deps[] ' + metaValue + '" for pushing to array meta.');
|
|
load.metadata[metaName].push(metaValue);
|
|
}
|
|
else {
|
|
setMetaProperty(load.metadata, metaName, metaValue);
|
|
}
|
|
}
|
|
else {
|
|
load.metadata[metaString] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return translate.apply(this, arguments);
|
|
};
|
|
});
|
|
})();
|
|
/*
|
|
System bundles
|
|
|
|
Allows a bundle module to be specified which will be dynamically
|
|
loaded before trying to load a given module.
|
|
|
|
For example:
|
|
SystemJS.bundles['mybundle'] = ['jquery', 'bootstrap/js/bootstrap']
|
|
|
|
Will result in a load to "mybundle" whenever a load to "jquery"
|
|
or "bootstrap/js/bootstrap" is made.
|
|
|
|
In this way, the bundle becomes the request that provides the module
|
|
*/
|
|
|
|
(function() {
|
|
// bundles support (just like RequireJS)
|
|
// bundle name is module name of bundle itself
|
|
// bundle is array of modules defined by the bundle
|
|
// when a module in the bundle is requested, the bundle is loaded instead
|
|
// of the form SystemJS.bundles['mybundle'] = ['jquery', 'bootstrap/js/bootstrap']
|
|
hookConstructor(function(constructor) {
|
|
return function() {
|
|
constructor.call(this);
|
|
this.bundles = {};
|
|
this._loader.loadedBundles = {};
|
|
};
|
|
});
|
|
|
|
// assign bundle metadata for bundle loads
|
|
hook('locate', function(locate) {
|
|
return function(load) {
|
|
var loader = this;
|
|
var matched = false;
|
|
|
|
if (!(load.name in loader.defined))
|
|
for (var b in loader.bundles) {
|
|
for (var i = 0; i < loader.bundles[b].length; i++) {
|
|
var curModule = loader.bundles[b][i];
|
|
|
|
if (curModule == load.name) {
|
|
matched = true;
|
|
break;
|
|
}
|
|
|
|
// wildcard in bundles does not include / boundaries
|
|
if (curModule.indexOf('*') != -1) {
|
|
var parts = curModule.split('*');
|
|
if (parts.length != 2) {
|
|
loader.bundles[b].splice(i--, 1);
|
|
continue;
|
|
}
|
|
|
|
if (load.name.substring(0, parts[0].length) == parts[0] &&
|
|
load.name.substr(load.name.length - parts[1].length, parts[1].length) == parts[1] &&
|
|
load.name.substr(parts[0].length, load.name.length - parts[1].length - parts[0].length).indexOf('/') == -1) {
|
|
matched = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (matched)
|
|
return loader['import'](b)
|
|
.then(function() {
|
|
return locate.call(loader, load);
|
|
});
|
|
}
|
|
|
|
return locate.call(loader, load);
|
|
};
|
|
});
|
|
})();
|
|
/*
|
|
* Dependency Tree Cache
|
|
*
|
|
* Allows a build to pre-populate a dependency trace tree on the loader of
|
|
* the expected dependency tree, to be loaded upfront when requesting the
|
|
* module, avoinding the n round trips latency of module loading, where
|
|
* n is the dependency tree depth.
|
|
*
|
|
* eg:
|
|
* SystemJS.depCache = {
|
|
* 'app': ['normalized', 'deps'],
|
|
* 'normalized': ['another'],
|
|
* 'deps': ['tree']
|
|
* };
|
|
*
|
|
* SystemJS.import('app')
|
|
* // simultaneously starts loading all of:
|
|
* // 'normalized', 'deps', 'another', 'tree'
|
|
* // before "app" source is even loaded
|
|
*
|
|
*/
|
|
|
|
(function() {
|
|
hookConstructor(function(constructor) {
|
|
return function() {
|
|
constructor.call(this);
|
|
this.depCache = {};
|
|
}
|
|
});
|
|
|
|
hook('locate', function(locate) {
|
|
return function(load) {
|
|
var loader = this;
|
|
// load direct deps, in turn will pick up their trace trees
|
|
var deps = loader.depCache[load.name];
|
|
if (deps)
|
|
for (var i = 0; i < deps.length; i++)
|
|
loader['import'](deps[i], load.name);
|
|
|
|
return locate.call(loader, load);
|
|
};
|
|
});
|
|
})();
|
|
|
|
System = new SystemJSLoader();
|
|
|
|
__global.SystemJS = System;
|
|
System.version = '0.19.47 Standard';
|
|
if (typeof module == 'object' && module.exports && typeof exports == 'object')
|
|
module.exports = System;
|
|
|
|
__global.System = System;
|
|
|
|
})(typeof self != 'undefined' ? self : global);}
|
|
|
|
// auto-load Promise polyfill if needed in the browser
|
|
var doPolyfill = typeof Promise === 'undefined';
|
|
|
|
// document.write
|
|
if (typeof document !== 'undefined') {
|
|
var scripts = document.getElementsByTagName('script');
|
|
$__curScript = scripts[scripts.length - 1];
|
|
if (document.currentScript && ($__curScript.defer || $__curScript.async))
|
|
$__curScript = document.currentScript;
|
|
if (!$__curScript.src)
|
|
$__curScript = undefined;
|
|
if (doPolyfill) {
|
|
var curPath = $__curScript.src;
|
|
var basePath = curPath.substr(0, curPath.lastIndexOf('/') + 1);
|
|
window.systemJSBootstrap = bootstrap;
|
|
document.write(
|
|
'<' + 'script type="text/javascript" src="' + basePath + 'system-polyfills.js">' + '<' + '/script>'
|
|
);
|
|
}
|
|
else {
|
|
bootstrap();
|
|
}
|
|
}
|
|
// importScripts
|
|
else if (typeof importScripts !== 'undefined') {
|
|
var basePath = '';
|
|
try {
|
|
throw new Error('_');
|
|
} catch (e) {
|
|
e.stack.replace(/(?:at|@).*(http.+):[\d]+:[\d]+/, function(m, url) {
|
|
$__curScript = { src: url };
|
|
basePath = url.replace(/\/[^\/]*$/, '/');
|
|
});
|
|
}
|
|
if (doPolyfill)
|
|
importScripts(basePath + 'system-polyfills.js');
|
|
bootstrap();
|
|
}
|
|
else {
|
|
$__curScript = typeof __filename != 'undefined' ? { src: __filename } : null;
|
|
bootstrap();
|
|
}
|
|
|
|
|
|
})();
|