mirror of
https://github.com/kasmtech/KasmVNC.git
synced 2024-12-04 22:11:32 +01:00
edb5fee88b
There has been a lot of renaming and restructuring in babel, so we need to modify our code to handle the latest version. We also need to adjust the way we build our babel worker as babel itself no longer runs in older browsers such as Internet Explorer.
1482 lines
47 KiB
JavaScript
1482 lines
47 KiB
JavaScript
(function (global, factory) {
|
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
(global = global || self, global.BrowserESModuleLoader = factory());
|
|
}(this, (function () { 'use strict';
|
|
|
|
/*
|
|
* Environment
|
|
*/
|
|
var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
var isNode = typeof process !== 'undefined' && process.versions && process.versions.node;
|
|
var isWindows = typeof process !== 'undefined' && typeof process.platform === 'string' && process.platform.match(/^win/);
|
|
|
|
var envGlobal = typeof self !== 'undefined' ? self : global;
|
|
|
|
/*
|
|
* Simple Symbol() shim
|
|
*/
|
|
var hasSymbol = typeof Symbol !== 'undefined';
|
|
function createSymbol (name) {
|
|
return hasSymbol ? Symbol() : '@@' + name;
|
|
}
|
|
|
|
var toStringTag = hasSymbol && Symbol.toStringTag;
|
|
|
|
/*
|
|
* Environment baseURI
|
|
*/
|
|
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 = location.href;
|
|
}
|
|
|
|
// sanitize out the hash and querystring
|
|
if (baseURI) {
|
|
baseURI = baseURI.split('#')[0].split('?')[0];
|
|
var slashIndex = baseURI.lastIndexOf('/');
|
|
if (slashIndex !== -1)
|
|
baseURI = baseURI.substr(0, slashIndex + 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');
|
|
}
|
|
|
|
// ensure baseURI has trailing "/"
|
|
if (baseURI[baseURI.length - 1] !== '/')
|
|
baseURI += '/';
|
|
|
|
/*
|
|
* LoaderError with chaining for loader stacks
|
|
*/
|
|
var errArgs = new Error(0, '_').fileName == '_';
|
|
function LoaderError__Check_error_message_for_loader_stack (childErr, newMessage) {
|
|
// Convert file:/// URLs to paths in Node
|
|
if (!isBrowser)
|
|
newMessage = newMessage.replace(isWindows ? /file:\/\/\//g : /file:\/\//g, '');
|
|
|
|
var message = (childErr.message || childErr) + '\n ' + newMessage;
|
|
|
|
var err;
|
|
if (errArgs && childErr.fileName)
|
|
err = new Error(message, childErr.fileName, childErr.lineNumber);
|
|
else
|
|
err = new Error(message);
|
|
|
|
|
|
var stack = childErr.originalErr ? childErr.originalErr.stack : childErr.stack;
|
|
|
|
if (isNode)
|
|
// node doesn't show the message otherwise
|
|
err.stack = message + '\n ' + stack;
|
|
else
|
|
err.stack = stack;
|
|
|
|
err.originalErr = childErr.originalErr || childErr;
|
|
|
|
return err;
|
|
}
|
|
|
|
var resolvedPromise = Promise.resolve();
|
|
|
|
/*
|
|
* Simple Array values shim
|
|
*/
|
|
function arrayValues (arr) {
|
|
if (arr.values)
|
|
return arr.values();
|
|
|
|
if (typeof Symbol === 'undefined' || !Symbol.iterator)
|
|
throw new Error('Symbol.iterator not supported in this browser');
|
|
|
|
var iterable = {};
|
|
iterable[Symbol.iterator] = function () {
|
|
var keys = Object.keys(arr);
|
|
var keyIndex = 0;
|
|
return {
|
|
next: function () {
|
|
if (keyIndex < keys.length)
|
|
return {
|
|
value: arr[keys[keyIndex++]],
|
|
done: false
|
|
};
|
|
else
|
|
return {
|
|
value: undefined,
|
|
done: true
|
|
};
|
|
}
|
|
};
|
|
};
|
|
return iterable;
|
|
}
|
|
|
|
/*
|
|
* 3. Reflect.Loader
|
|
*
|
|
* We skip the entire native internal pipeline, just providing the bare API
|
|
*/
|
|
// 3.1.1
|
|
function Loader () {
|
|
this.registry = new Registry();
|
|
}
|
|
// 3.3.1
|
|
Loader.prototype.constructor = Loader;
|
|
|
|
function ensureInstantiated (module) {
|
|
if (module === undefined)
|
|
return;
|
|
if (module instanceof ModuleNamespace === false && module[toStringTag] !== 'module')
|
|
throw new TypeError('Module instantiation did not return a valid namespace object.');
|
|
return module;
|
|
}
|
|
|
|
// 3.3.2
|
|
Loader.prototype.import = function (key, parent) {
|
|
if (typeof key !== 'string')
|
|
throw new TypeError('Loader import method must be passed a module key string');
|
|
// custom resolveInstantiate combined hook for better perf
|
|
var loader = this;
|
|
return resolvedPromise
|
|
.then(function () {
|
|
return loader[RESOLVE_INSTANTIATE](key, parent);
|
|
})
|
|
.then(ensureInstantiated)
|
|
//.then(Module.evaluate)
|
|
.catch(function (err) {
|
|
throw LoaderError__Check_error_message_for_loader_stack(err, 'Loading ' + key + (parent ? ' from ' + parent : ''));
|
|
});
|
|
};
|
|
// 3.3.3
|
|
var RESOLVE = Loader.resolve = createSymbol('resolve');
|
|
|
|
/*
|
|
* Combined resolve / instantiate hook
|
|
*
|
|
* Not in current reduced spec, but necessary to separate RESOLVE from RESOLVE + INSTANTIATE as described
|
|
* in the spec notes of this repo to ensure that loader.resolve doesn't instantiate when not wanted.
|
|
*
|
|
* We implement RESOLVE_INSTANTIATE as a single hook instead of a separate INSTANTIATE in order to avoid
|
|
* the need for double registry lookups as a performance optimization.
|
|
*/
|
|
var RESOLVE_INSTANTIATE = Loader.resolveInstantiate = createSymbol('resolveInstantiate');
|
|
|
|
// default resolveInstantiate is just to call resolve and then get from the registry
|
|
// this provides compatibility for the resolveInstantiate optimization
|
|
Loader.prototype[RESOLVE_INSTANTIATE] = function (key, parent) {
|
|
var loader = this;
|
|
return loader.resolve(key, parent)
|
|
.then(function (resolved) {
|
|
return loader.registry.get(resolved);
|
|
});
|
|
};
|
|
|
|
function ensureResolution (resolvedKey) {
|
|
if (resolvedKey === undefined)
|
|
throw new RangeError('No resolution found.');
|
|
return resolvedKey;
|
|
}
|
|
|
|
Loader.prototype.resolve = function (key, parent) {
|
|
var loader = this;
|
|
return resolvedPromise
|
|
.then(function() {
|
|
return loader[RESOLVE](key, parent);
|
|
})
|
|
.then(ensureResolution)
|
|
.catch(function (err) {
|
|
throw LoaderError__Check_error_message_for_loader_stack(err, 'Resolving ' + key + (parent ? ' to ' + parent : ''));
|
|
});
|
|
};
|
|
|
|
// 3.3.4 (import without evaluate)
|
|
// this is not documented because the use of deferred evaluation as in Module.evaluate is not
|
|
// documented, as it is not considered a stable feature to be encouraged
|
|
// Loader.prototype.load may well be deprecated if this stays disabled
|
|
/* Loader.prototype.load = function (key, parent) {
|
|
return Promise.resolve(this[RESOLVE_INSTANTIATE](key, parent || this.key))
|
|
.catch(function (err) {
|
|
throw addToError(err, 'Loading ' + key + (parent ? ' from ' + parent : ''));
|
|
});
|
|
}; */
|
|
|
|
/*
|
|
* 4. Registry
|
|
*
|
|
* Instead of structuring through a Map, just use a dictionary object
|
|
* We throw for construction attempts so this doesn't affect the public API
|
|
*
|
|
* Registry has been adjusted to use Namespace objects over ModuleStatus objects
|
|
* as part of simplifying loader API implementation
|
|
*/
|
|
var iteratorSupport = typeof Symbol !== 'undefined' && Symbol.iterator;
|
|
var REGISTRY = createSymbol('registry');
|
|
function Registry() {
|
|
this[REGISTRY] = {};
|
|
}
|
|
// 4.4.1
|
|
if (iteratorSupport) {
|
|
// 4.4.2
|
|
Registry.prototype[Symbol.iterator] = function () {
|
|
return this.entries()[Symbol.iterator]();
|
|
};
|
|
|
|
// 4.4.3
|
|
Registry.prototype.entries = function () {
|
|
var registry = this[REGISTRY];
|
|
return arrayValues(Object.keys(registry).map(function (key) {
|
|
return [key, registry[key]];
|
|
}));
|
|
};
|
|
}
|
|
|
|
// 4.4.4
|
|
Registry.prototype.keys = function () {
|
|
return arrayValues(Object.keys(this[REGISTRY]));
|
|
};
|
|
// 4.4.5
|
|
Registry.prototype.values = function () {
|
|
var registry = this[REGISTRY];
|
|
return arrayValues(Object.keys(registry).map(function (key) {
|
|
return registry[key];
|
|
}));
|
|
};
|
|
// 4.4.6
|
|
Registry.prototype.get = function (key) {
|
|
return this[REGISTRY][key];
|
|
};
|
|
// 4.4.7
|
|
Registry.prototype.set = function (key, namespace) {
|
|
if (!(namespace instanceof ModuleNamespace || namespace[toStringTag] === 'module'))
|
|
throw new Error('Registry must be set with an instance of Module Namespace');
|
|
this[REGISTRY][key] = namespace;
|
|
return this;
|
|
};
|
|
// 4.4.8
|
|
Registry.prototype.has = function (key) {
|
|
return Object.hasOwnProperty.call(this[REGISTRY], key);
|
|
};
|
|
// 4.4.9
|
|
Registry.prototype.delete = function (key) {
|
|
if (Object.hasOwnProperty.call(this[REGISTRY], key)) {
|
|
delete this[REGISTRY][key];
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
/*
|
|
* Simple ModuleNamespace Exotic object based on a baseObject
|
|
* We export this for allowing a fast-path for module namespace creation over Module descriptors
|
|
*/
|
|
// var EVALUATE = createSymbol('evaluate');
|
|
var BASE_OBJECT = createSymbol('baseObject');
|
|
|
|
// 8.3.1 Reflect.Module
|
|
/*
|
|
* Best-effort simplified non-spec implementation based on
|
|
* a baseObject referenced via getters.
|
|
*
|
|
* Allows:
|
|
*
|
|
* loader.registry.set('x', new Module({ default: 'x' }));
|
|
*
|
|
* Optional evaluation function provides experimental Module.evaluate
|
|
* support for non-executed modules in registry.
|
|
*/
|
|
function ModuleNamespace (baseObject/*, evaluate*/) {
|
|
Object.defineProperty(this, BASE_OBJECT, {
|
|
value: baseObject
|
|
});
|
|
|
|
// evaluate defers namespace population
|
|
/* if (evaluate) {
|
|
Object.defineProperty(this, EVALUATE, {
|
|
value: evaluate,
|
|
configurable: true,
|
|
writable: true
|
|
});
|
|
}
|
|
else { */
|
|
Object.keys(baseObject).forEach(extendNamespace, this);
|
|
//}
|
|
}// 8.4.2
|
|
ModuleNamespace.prototype = Object.create(null);
|
|
|
|
if (toStringTag)
|
|
Object.defineProperty(ModuleNamespace.prototype, toStringTag, {
|
|
value: 'Module'
|
|
});
|
|
|
|
function extendNamespace (key) {
|
|
Object.defineProperty(this, key, {
|
|
enumerable: true,
|
|
get: function () {
|
|
return this[BASE_OBJECT][key];
|
|
}
|
|
});
|
|
}
|
|
|
|
/* function doEvaluate (evaluate, context) {
|
|
try {
|
|
evaluate.call(context);
|
|
}
|
|
catch (e) {
|
|
return e;
|
|
}
|
|
}
|
|
|
|
// 8.4.1 Module.evaluate... not documented or used because this is potentially unstable
|
|
Module.evaluate = function (ns) {
|
|
var evaluate = ns[EVALUATE];
|
|
if (evaluate) {
|
|
ns[EVALUATE] = undefined;
|
|
var err = doEvaluate(evaluate);
|
|
if (err) {
|
|
// cache the error
|
|
ns[EVALUATE] = function () {
|
|
throw err;
|
|
};
|
|
throw err;
|
|
}
|
|
Object.keys(ns[BASE_OBJECT]).forEach(extendNamespace, ns);
|
|
}
|
|
// make chainable
|
|
return ns;
|
|
}; */
|
|
|
|
/*
|
|
* Optimized URL normalization assuming a syntax-valid URL parent
|
|
*/
|
|
function throwResolveError (relUrl, parentUrl) {
|
|
throw new RangeError('Unable to resolve "' + relUrl + '" to ' + parentUrl);
|
|
}
|
|
var backslashRegEx = /\\/g;
|
|
function resolveIfNotPlain (relUrl, parentUrl) {
|
|
if (relUrl[0] === ' ' || relUrl[relUrl.length - 1] === ' ')
|
|
relUrl = relUrl.trim();
|
|
var parentProtocol = parentUrl && parentUrl.substr(0, parentUrl.indexOf(':') + 1);
|
|
|
|
var firstChar = relUrl[0];
|
|
var secondChar = relUrl[1];
|
|
|
|
// protocol-relative
|
|
if (firstChar === '/' && secondChar === '/') {
|
|
if (!parentProtocol)
|
|
throwResolveError(relUrl, parentUrl);
|
|
if (relUrl.indexOf('\\') !== -1)
|
|
relUrl = relUrl.replace(backslashRegEx, '/');
|
|
return parentProtocol + relUrl;
|
|
}
|
|
// relative-url
|
|
else if (firstChar === '.' && (secondChar === '/' || secondChar === '.' && (relUrl[2] === '/' || relUrl.length === 2 && (relUrl += '/')) ||
|
|
relUrl.length === 1 && (relUrl += '/')) ||
|
|
firstChar === '/') {
|
|
if (relUrl.indexOf('\\') !== -1)
|
|
relUrl = relUrl.replace(backslashRegEx, '/');
|
|
var parentIsPlain = !parentProtocol || parentUrl[parentProtocol.length] !== '/';
|
|
|
|
// read pathname from parent if a URL
|
|
// pathname taken to be part after leading "/"
|
|
var pathname;
|
|
if (parentIsPlain) {
|
|
// resolving to a plain parent -> skip standard URL prefix, and treat entire parent as pathname
|
|
if (parentUrl === undefined)
|
|
throwResolveError(relUrl, parentUrl);
|
|
pathname = parentUrl;
|
|
}
|
|
else if (parentUrl[parentProtocol.length + 1] === '/') {
|
|
// resolving to a :// so we need to read out the auth and host
|
|
if (parentProtocol !== 'file:') {
|
|
pathname = parentUrl.substr(parentProtocol.length + 2);
|
|
pathname = pathname.substr(pathname.indexOf('/') + 1);
|
|
}
|
|
else {
|
|
pathname = parentUrl.substr(8);
|
|
}
|
|
}
|
|
else {
|
|
// resolving to :/ so pathname is the /... part
|
|
pathname = parentUrl.substr(parentProtocol.length + 1);
|
|
}
|
|
|
|
if (firstChar === '/') {
|
|
if (parentIsPlain)
|
|
throwResolveError(relUrl, parentUrl);
|
|
else
|
|
return parentUrl.substr(0, parentUrl.length - pathname.length - 1) + relUrl;
|
|
}
|
|
|
|
// join together and split for removal of .. and . segments
|
|
// looping the string instead of anything fancy for perf reasons
|
|
// '../../../../../z' resolved to 'x/y' is just 'z' regardless of parentIsPlain
|
|
var segmented = pathname.substr(0, pathname.lastIndexOf('/') + 1) + relUrl;
|
|
|
|
var output = [];
|
|
var segmentIndex = -1;
|
|
|
|
for (var i = 0; i < segmented.length; i++) {
|
|
// busy reading a segment - only terminate on '/'
|
|
if (segmentIndex !== -1) {
|
|
if (segmented[i] === '/') {
|
|
output.push(segmented.substring(segmentIndex, i + 1));
|
|
segmentIndex = -1;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
// new segment - check if it is relative
|
|
if (segmented[i] === '.') {
|
|
// ../ segment
|
|
if (segmented[i + 1] === '.' && (segmented[i + 2] === '/' || i + 2 === segmented.length)) {
|
|
output.pop();
|
|
i += 2;
|
|
}
|
|
// ./ segment
|
|
else if (segmented[i + 1] === '/' || i + 1 === segmented.length) {
|
|
i += 1;
|
|
}
|
|
else {
|
|
// the start of a new segment as below
|
|
segmentIndex = i;
|
|
continue;
|
|
}
|
|
|
|
// this is the plain URI backtracking error (../, package:x -> error)
|
|
if (parentIsPlain && output.length === 0)
|
|
throwResolveError(relUrl, parentUrl);
|
|
|
|
continue;
|
|
}
|
|
|
|
// it is the start of a new segment
|
|
segmentIndex = i;
|
|
}
|
|
// finish reading out the last segment
|
|
if (segmentIndex !== -1)
|
|
output.push(segmented.substr(segmentIndex));
|
|
|
|
return parentUrl.substr(0, parentUrl.length - pathname.length) + output.join('');
|
|
}
|
|
|
|
// sanitizes and verifies (by returning undefined if not a valid URL-like form)
|
|
// Windows filepath compatibility is an added convenience here
|
|
var protocolIndex = relUrl.indexOf(':');
|
|
if (protocolIndex !== -1) {
|
|
if (isNode) {
|
|
// C:\x becomes file:///c:/x (we don't support C|\x)
|
|
if (relUrl[1] === ':' && relUrl[2] === '\\' && relUrl[0].match(/[a-z]/i))
|
|
return 'file:///' + relUrl.replace(backslashRegEx, '/');
|
|
}
|
|
return relUrl;
|
|
}
|
|
}
|
|
|
|
var resolvedPromise$1 = Promise.resolve();
|
|
|
|
/*
|
|
* Register Loader
|
|
*
|
|
* Builds directly on top of loader polyfill to provide:
|
|
* - loader.register support
|
|
* - hookable higher-level resolve
|
|
* - instantiate hook returning a ModuleNamespace or undefined for es module loading
|
|
* - loader error behaviour as in HTML and loader specs, caching load and eval errors separately
|
|
* - build tracing support by providing a .trace=true and .loads object format
|
|
*/
|
|
|
|
var REGISTER_INTERNAL = createSymbol('register-internal');
|
|
|
|
function RegisterLoader () {
|
|
Loader.call(this);
|
|
|
|
var registryDelete = this.registry.delete;
|
|
this.registry.delete = function (key) {
|
|
var deleted = registryDelete.call(this, key);
|
|
|
|
// also delete from register registry if linked
|
|
if (records.hasOwnProperty(key) && !records[key].linkRecord) {
|
|
delete records[key];
|
|
deleted = true;
|
|
}
|
|
|
|
return deleted;
|
|
};
|
|
|
|
var records = {};
|
|
|
|
this[REGISTER_INTERNAL] = {
|
|
// last anonymous System.register call
|
|
lastRegister: undefined,
|
|
// in-flight es module load records
|
|
records: records
|
|
};
|
|
|
|
// tracing
|
|
this.trace = false;
|
|
}
|
|
|
|
RegisterLoader.prototype = Object.create(Loader.prototype);
|
|
RegisterLoader.prototype.constructor = RegisterLoader;
|
|
|
|
var INSTANTIATE = RegisterLoader.instantiate = createSymbol('instantiate');
|
|
|
|
// default normalize is the WhatWG style normalizer
|
|
RegisterLoader.prototype[RegisterLoader.resolve = Loader.resolve] = function (key, parentKey) {
|
|
return resolveIfNotPlain(key, parentKey || baseURI);
|
|
};
|
|
|
|
RegisterLoader.prototype[INSTANTIATE] = function (key, processAnonRegister) {};
|
|
|
|
// once evaluated, the linkRecord is set to undefined leaving just the other load record properties
|
|
// this allows tracking new binding listeners for es modules through importerSetters
|
|
// for dynamic modules, the load record is removed entirely.
|
|
function createLoadRecord (state, key, registration) {
|
|
return state.records[key] = {
|
|
key: key,
|
|
|
|
// defined System.register cache
|
|
registration: registration,
|
|
|
|
// module namespace object
|
|
module: undefined,
|
|
|
|
// es-only
|
|
// this sticks around so new module loads can listen to binding changes
|
|
// for already-loaded modules by adding themselves to their importerSetters
|
|
importerSetters: undefined,
|
|
|
|
loadError: undefined,
|
|
evalError: undefined,
|
|
|
|
// in-flight linking record
|
|
linkRecord: {
|
|
// promise for instantiated
|
|
instantiatePromise: undefined,
|
|
dependencies: undefined,
|
|
execute: undefined,
|
|
executingRequire: false,
|
|
|
|
// underlying module object bindings
|
|
moduleObj: undefined,
|
|
|
|
// es only, also indicates if es or not
|
|
setters: undefined,
|
|
|
|
// promise for instantiated dependencies (dependencyInstantiations populated)
|
|
depsInstantiatePromise: undefined,
|
|
// will be the array of dependency load record or a module namespace
|
|
dependencyInstantiations: undefined,
|
|
|
|
// top-level await!
|
|
evaluatePromise: undefined,
|
|
|
|
// NB optimization and way of ensuring module objects in setters
|
|
// indicates setters which should run pre-execution of that dependency
|
|
// setters is then just for completely executed module objects
|
|
// alternatively we just pass the partially filled module objects as
|
|
// arguments into the execute function
|
|
// hoisted: undefined
|
|
}
|
|
};
|
|
}
|
|
|
|
RegisterLoader.prototype[Loader.resolveInstantiate] = function (key, parentKey) {
|
|
var loader = this;
|
|
var state = this[REGISTER_INTERNAL];
|
|
var registry = this.registry[REGISTRY];
|
|
|
|
return resolveInstantiate(loader, key, parentKey, registry, state)
|
|
.then(function (instantiated) {
|
|
if (instantiated instanceof ModuleNamespace || instantiated[toStringTag] === 'module')
|
|
return instantiated;
|
|
|
|
// resolveInstantiate always returns a load record with a link record and no module value
|
|
var link = instantiated.linkRecord;
|
|
|
|
// if already beaten to done, return
|
|
if (!link) {
|
|
if (instantiated.module)
|
|
return instantiated.module;
|
|
throw instantiated.evalError;
|
|
}
|
|
|
|
return deepInstantiateDeps(loader, instantiated, link, registry, state)
|
|
.then(function () {
|
|
return ensureEvaluate(loader, instantiated, link, registry, state);
|
|
});
|
|
});
|
|
};
|
|
|
|
function resolveInstantiate (loader, key, parentKey, registry, state) {
|
|
// normalization shortpath for already-normalized key
|
|
// could add a plain name filter, but doesn't yet seem necessary for perf
|
|
var module = registry[key];
|
|
if (module)
|
|
return Promise.resolve(module);
|
|
|
|
var load = state.records[key];
|
|
|
|
// already linked but not in main registry is ignored
|
|
if (load && !load.module) {
|
|
if (load.loadError)
|
|
return Promise.reject(load.loadError);
|
|
return instantiate(loader, load, load.linkRecord, registry, state);
|
|
}
|
|
|
|
return loader.resolve(key, parentKey)
|
|
.then(function (resolvedKey) {
|
|
// main loader registry always takes preference
|
|
module = registry[resolvedKey];
|
|
if (module)
|
|
return module;
|
|
|
|
load = state.records[resolvedKey];
|
|
|
|
// already has a module value but not already in the registry (load.module)
|
|
// means it was removed by registry.delete, so we should
|
|
// disgard the current load record creating a new one over it
|
|
// but keep any existing registration
|
|
if (!load || load.module)
|
|
load = createLoadRecord(state, resolvedKey, load && load.registration);
|
|
|
|
if (load.loadError)
|
|
return Promise.reject(load.loadError);
|
|
|
|
var link = load.linkRecord;
|
|
if (!link)
|
|
return load;
|
|
|
|
return instantiate(loader, load, link, registry, state);
|
|
});
|
|
}
|
|
|
|
function createProcessAnonRegister (loader, load, state) {
|
|
return function () {
|
|
var lastRegister = state.lastRegister;
|
|
|
|
if (!lastRegister)
|
|
return !!load.registration;
|
|
|
|
state.lastRegister = undefined;
|
|
load.registration = lastRegister;
|
|
|
|
return true;
|
|
};
|
|
}
|
|
|
|
function instantiate (loader, load, link, registry, state) {
|
|
return link.instantiatePromise || (link.instantiatePromise =
|
|
// if there is already an existing registration, skip running instantiate
|
|
(load.registration ? resolvedPromise$1 : resolvedPromise$1.then(function () {
|
|
state.lastRegister = undefined;
|
|
return loader[INSTANTIATE](load.key, loader[INSTANTIATE].length > 1 && createProcessAnonRegister(loader, load, state));
|
|
}))
|
|
.then(function (instantiation) {
|
|
// direct module return from instantiate -> we're done
|
|
if (instantiation !== undefined) {
|
|
if (!(instantiation instanceof ModuleNamespace || instantiation[toStringTag] === 'module'))
|
|
throw new TypeError('Instantiate did not return a valid Module object.');
|
|
|
|
delete state.records[load.key];
|
|
if (loader.trace)
|
|
traceLoad(loader, load, link);
|
|
return registry[load.key] = instantiation;
|
|
}
|
|
|
|
// run the cached loader.register declaration if there is one
|
|
var registration = load.registration;
|
|
// clear to allow new registrations for future loads (combined with registry delete)
|
|
load.registration = undefined;
|
|
if (!registration)
|
|
throw new TypeError('Module instantiation did not call an anonymous or correctly named System.register.');
|
|
|
|
link.dependencies = registration[0];
|
|
|
|
load.importerSetters = [];
|
|
|
|
link.moduleObj = {};
|
|
|
|
// process System.registerDynamic declaration
|
|
if (registration[2]) {
|
|
link.moduleObj.default = link.moduleObj.__useDefault = {};
|
|
link.executingRequire = registration[1];
|
|
link.execute = registration[2];
|
|
}
|
|
|
|
// process System.register declaration
|
|
else {
|
|
registerDeclarative(loader, load, link, registration[1]);
|
|
}
|
|
|
|
return load;
|
|
})
|
|
.catch(function (err) {
|
|
load.linkRecord = undefined;
|
|
throw load.loadError = load.loadError || LoaderError__Check_error_message_for_loader_stack(err, 'Instantiating ' + load.key);
|
|
}));
|
|
}
|
|
|
|
// like resolveInstantiate, but returning load records for linking
|
|
function resolveInstantiateDep (loader, key, parentKey, registry, state, traceDepMap) {
|
|
// normalization shortpaths for already-normalized key
|
|
// DISABLED to prioritise consistent resolver calls
|
|
// could add a plain name filter, but doesn't yet seem necessary for perf
|
|
/* var load = state.records[key];
|
|
var module = registry[key];
|
|
|
|
if (module) {
|
|
if (traceDepMap)
|
|
traceDepMap[key] = key;
|
|
|
|
// registry authority check in case module was deleted or replaced in main registry
|
|
if (load && load.module && load.module === module)
|
|
return load;
|
|
else
|
|
return module;
|
|
}
|
|
|
|
// already linked but not in main registry is ignored
|
|
if (load && !load.module) {
|
|
if (traceDepMap)
|
|
traceDepMap[key] = key;
|
|
return instantiate(loader, load, load.linkRecord, registry, state);
|
|
} */
|
|
return loader.resolve(key, parentKey)
|
|
.then(function (resolvedKey) {
|
|
if (traceDepMap)
|
|
traceDepMap[key] = resolvedKey;
|
|
|
|
// normalization shortpaths for already-normalized key
|
|
var load = state.records[resolvedKey];
|
|
var module = registry[resolvedKey];
|
|
|
|
// main loader registry always takes preference
|
|
if (module && (!load || load.module && module !== load.module))
|
|
return module;
|
|
|
|
if (load && load.loadError)
|
|
throw load.loadError;
|
|
|
|
// already has a module value but not already in the registry (load.module)
|
|
// means it was removed by registry.delete, so we should
|
|
// disgard the current load record creating a new one over it
|
|
// but keep any existing registration
|
|
if (!load || !module && load.module)
|
|
load = createLoadRecord(state, resolvedKey, load && load.registration);
|
|
|
|
var link = load.linkRecord;
|
|
if (!link)
|
|
return load;
|
|
|
|
return instantiate(loader, load, link, registry, state);
|
|
});
|
|
}
|
|
|
|
function traceLoad (loader, load, link) {
|
|
loader.loads = loader.loads || {};
|
|
loader.loads[load.key] = {
|
|
key: load.key,
|
|
deps: link.dependencies,
|
|
dynamicDeps: [],
|
|
depMap: link.depMap || {}
|
|
};
|
|
}
|
|
|
|
/*
|
|
* Convert a CJS module.exports into a valid object for new Module:
|
|
*
|
|
* new Module(getEsModule(module.exports))
|
|
*
|
|
* Sets the default value to the module, while also reading off named exports carefully.
|
|
*/
|
|
function registerDeclarative (loader, load, link, declare) {
|
|
var moduleObj = link.moduleObj;
|
|
var importerSetters = load.importerSetters;
|
|
|
|
var definedExports = false;
|
|
|
|
// closure especially not based on link to allow link record disposal
|
|
var declared = declare.call(envGlobal, function (name, value) {
|
|
if (typeof name === 'object') {
|
|
var changed = false;
|
|
for (var p in name) {
|
|
value = name[p];
|
|
if (p !== '__useDefault' && (!(p in moduleObj) || moduleObj[p] !== value)) {
|
|
changed = true;
|
|
moduleObj[p] = value;
|
|
}
|
|
}
|
|
if (changed === false)
|
|
return value;
|
|
}
|
|
else {
|
|
if ((definedExports || name in moduleObj) && moduleObj[name] === value)
|
|
return value;
|
|
moduleObj[name] = value;
|
|
}
|
|
|
|
for (var i = 0; i < importerSetters.length; i++)
|
|
importerSetters[i](moduleObj);
|
|
|
|
return value;
|
|
}, new ContextualLoader(loader, load.key));
|
|
|
|
link.setters = declared.setters || [];
|
|
link.execute = declared.execute;
|
|
if (declared.exports) {
|
|
link.moduleObj = moduleObj = declared.exports;
|
|
definedExports = true;
|
|
}
|
|
}
|
|
|
|
function instantiateDeps (loader, load, link, registry, state) {
|
|
if (link.depsInstantiatePromise)
|
|
return link.depsInstantiatePromise;
|
|
|
|
var depsInstantiatePromises = Array(link.dependencies.length);
|
|
|
|
for (var i = 0; i < link.dependencies.length; i++)
|
|
depsInstantiatePromises[i] = resolveInstantiateDep(loader, link.dependencies[i], load.key, registry, state, loader.trace && link.depMap || (link.depMap = {}));
|
|
|
|
var depsInstantiatePromise = Promise.all(depsInstantiatePromises)
|
|
.then(function (dependencyInstantiations) {
|
|
link.dependencyInstantiations = dependencyInstantiations;
|
|
|
|
// run setters to set up bindings to instantiated dependencies
|
|
if (link.setters) {
|
|
for (var i = 0; i < dependencyInstantiations.length; i++) {
|
|
var setter = link.setters[i];
|
|
if (setter) {
|
|
var instantiation = dependencyInstantiations[i];
|
|
|
|
if (instantiation instanceof ModuleNamespace || instantiation[toStringTag] === 'module') {
|
|
setter(instantiation);
|
|
}
|
|
else {
|
|
if (instantiation.loadError)
|
|
throw instantiation.loadError;
|
|
setter(instantiation.module || instantiation.linkRecord.moduleObj);
|
|
// this applies to both es and dynamic registrations
|
|
if (instantiation.importerSetters)
|
|
instantiation.importerSetters.push(setter);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return load;
|
|
});
|
|
|
|
if (loader.trace)
|
|
depsInstantiatePromise = depsInstantiatePromise.then(function () {
|
|
traceLoad(loader, load, link);
|
|
return load;
|
|
});
|
|
|
|
depsInstantiatePromise = depsInstantiatePromise.catch(function (err) {
|
|
// throw up the instantiateDeps stack
|
|
link.depsInstantiatePromise = undefined;
|
|
throw LoaderError__Check_error_message_for_loader_stack(err, 'Loading ' + load.key);
|
|
});
|
|
|
|
depsInstantiatePromise.catch(function () {});
|
|
|
|
return link.depsInstantiatePromise = depsInstantiatePromise;
|
|
}
|
|
|
|
function deepInstantiateDeps (loader, load, link, registry, state) {
|
|
var seen = [];
|
|
function addDeps (load, link) {
|
|
if (!link)
|
|
return resolvedPromise$1;
|
|
if (seen.indexOf(load) !== -1)
|
|
return resolvedPromise$1;
|
|
seen.push(load);
|
|
|
|
return instantiateDeps(loader, load, link, registry, state)
|
|
.then(function () {
|
|
var depPromises;
|
|
for (var i = 0; i < link.dependencies.length; i++) {
|
|
var depLoad = link.dependencyInstantiations[i];
|
|
if (!(depLoad instanceof ModuleNamespace || depLoad[toStringTag] === 'module')) {
|
|
depPromises = depPromises || [];
|
|
depPromises.push(addDeps(depLoad, depLoad.linkRecord));
|
|
}
|
|
}
|
|
if (depPromises)
|
|
return Promise.all(depPromises);
|
|
});
|
|
}
|
|
return addDeps(load, link);
|
|
}
|
|
|
|
/*
|
|
* System.register
|
|
*/
|
|
RegisterLoader.prototype.register = function (key, deps, declare) {
|
|
var state = this[REGISTER_INTERNAL];
|
|
|
|
// anonymous modules get stored as lastAnon
|
|
if (declare === undefined) {
|
|
state.lastRegister = [key, deps, undefined];
|
|
}
|
|
|
|
// everything else registers into the register cache
|
|
else {
|
|
var load = state.records[key] || createLoadRecord(state, key, undefined);
|
|
load.registration = [deps, declare, undefined];
|
|
}
|
|
};
|
|
|
|
/*
|
|
* System.registerDyanmic
|
|
*/
|
|
RegisterLoader.prototype.registerDynamic = function (key, deps, executingRequire, execute) {
|
|
var state = this[REGISTER_INTERNAL];
|
|
|
|
// anonymous modules get stored as lastAnon
|
|
if (typeof key !== 'string') {
|
|
state.lastRegister = [key, deps, executingRequire];
|
|
}
|
|
|
|
// everything else registers into the register cache
|
|
else {
|
|
var load = state.records[key] || createLoadRecord(state, key, undefined);
|
|
load.registration = [deps, executingRequire, execute];
|
|
}
|
|
};
|
|
|
|
// ContextualLoader class
|
|
// backwards-compatible with previous System.register context argument by exposing .id, .key
|
|
function ContextualLoader (loader, key) {
|
|
this.loader = loader;
|
|
this.key = this.id = key;
|
|
this.meta = {
|
|
url: key
|
|
// scriptElement: null
|
|
};
|
|
}
|
|
/*ContextualLoader.prototype.constructor = function () {
|
|
throw new TypeError('Cannot subclass the contextual loader only Reflect.Loader.');
|
|
};*/
|
|
ContextualLoader.prototype.import = function (key) {
|
|
if (this.loader.trace)
|
|
this.loader.loads[this.key].dynamicDeps.push(key);
|
|
return this.loader.import(key, this.key);
|
|
};
|
|
/*ContextualLoader.prototype.resolve = function (key) {
|
|
return this.loader.resolve(key, this.key);
|
|
};*/
|
|
|
|
function ensureEvaluate (loader, load, link, registry, state) {
|
|
if (load.module)
|
|
return load.module;
|
|
if (load.evalError)
|
|
throw load.evalError;
|
|
if (link.evaluatePromise)
|
|
return link.evaluatePromise;
|
|
|
|
if (link.setters) {
|
|
var evaluatePromise = doEvaluateDeclarative(loader, load, link, registry, state, [load]);
|
|
if (evaluatePromise)
|
|
return evaluatePromise;
|
|
}
|
|
else {
|
|
doEvaluateDynamic(loader, load, link, registry, state, [load]);
|
|
}
|
|
return load.module;
|
|
}
|
|
|
|
function makeDynamicRequire (loader, key, dependencies, dependencyInstantiations, registry, state, seen) {
|
|
// we can only require from already-known dependencies
|
|
return function (name) {
|
|
for (var i = 0; i < dependencies.length; i++) {
|
|
if (dependencies[i] === name) {
|
|
var depLoad = dependencyInstantiations[i];
|
|
var module;
|
|
|
|
if (depLoad instanceof ModuleNamespace || depLoad[toStringTag] === 'module') {
|
|
module = depLoad;
|
|
}
|
|
else {
|
|
if (depLoad.evalError)
|
|
throw depLoad.evalError;
|
|
if (depLoad.module === undefined && seen.indexOf(depLoad) === -1 && !depLoad.linkRecord.evaluatePromise) {
|
|
if (depLoad.linkRecord.setters) {
|
|
doEvaluateDeclarative(loader, depLoad, depLoad.linkRecord, registry, state, [depLoad]);
|
|
}
|
|
else {
|
|
seen.push(depLoad);
|
|
doEvaluateDynamic(loader, depLoad, depLoad.linkRecord, registry, state, seen);
|
|
}
|
|
}
|
|
module = depLoad.module || depLoad.linkRecord.moduleObj;
|
|
}
|
|
|
|
return '__useDefault' in module ? module.__useDefault : module;
|
|
}
|
|
}
|
|
throw new Error('Module ' + name + ' not declared as a System.registerDynamic dependency of ' + key);
|
|
};
|
|
}
|
|
|
|
function evalError (load, err) {
|
|
load.linkRecord = undefined;
|
|
var evalError = LoaderError__Check_error_message_for_loader_stack(err, 'Evaluating ' + load.key);
|
|
if (load.evalError === undefined)
|
|
load.evalError = evalError;
|
|
throw evalError;
|
|
}
|
|
|
|
// es modules evaluate dependencies first
|
|
// returns the error if any
|
|
function doEvaluateDeclarative (loader, load, link, registry, state, seen) {
|
|
var depLoad, depLink;
|
|
var depLoadPromises;
|
|
for (var i = 0; i < link.dependencies.length; i++) {
|
|
var depLoad = link.dependencyInstantiations[i];
|
|
if (depLoad instanceof ModuleNamespace || depLoad[toStringTag] === 'module')
|
|
continue;
|
|
|
|
// custom Module returned from instantiate
|
|
depLink = depLoad.linkRecord;
|
|
if (depLink) {
|
|
if (depLoad.evalError) {
|
|
evalError(load, depLoad.evalError);
|
|
}
|
|
else if (depLink.setters) {
|
|
if (seen.indexOf(depLoad) === -1) {
|
|
seen.push(depLoad);
|
|
try {
|
|
var depLoadPromise = doEvaluateDeclarative(loader, depLoad, depLink, registry, state, seen);
|
|
}
|
|
catch (e) {
|
|
evalError(load, e);
|
|
}
|
|
if (depLoadPromise) {
|
|
depLoadPromises = depLoadPromises || [];
|
|
depLoadPromises.push(depLoadPromise.catch(function (err) {
|
|
evalError(load, err);
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
try {
|
|
doEvaluateDynamic(loader, depLoad, depLink, registry, state, [depLoad]);
|
|
}
|
|
catch (e) {
|
|
evalError(load, e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (depLoadPromises)
|
|
return link.evaluatePromise = Promise.all(depLoadPromises)
|
|
.then(function () {
|
|
if (link.execute) {
|
|
// ES System.register execute
|
|
// "this" is null in ES
|
|
try {
|
|
var execPromise = link.execute.call(nullContext);
|
|
}
|
|
catch (e) {
|
|
evalError(load, e);
|
|
}
|
|
if (execPromise)
|
|
return execPromise.catch(function (e) {
|
|
evalError(load, e);
|
|
})
|
|
.then(function () {
|
|
load.linkRecord = undefined;
|
|
return registry[load.key] = load.module = new ModuleNamespace(link.moduleObj);
|
|
});
|
|
}
|
|
|
|
// dispose link record
|
|
load.linkRecord = undefined;
|
|
registry[load.key] = load.module = new ModuleNamespace(link.moduleObj);
|
|
});
|
|
|
|
if (link.execute) {
|
|
// ES System.register execute
|
|
// "this" is null in ES
|
|
try {
|
|
var execPromise = link.execute.call(nullContext);
|
|
}
|
|
catch (e) {
|
|
evalError(load, e);
|
|
}
|
|
if (execPromise)
|
|
return link.evaluatePromise = execPromise.catch(function (e) {
|
|
evalError(load, e);
|
|
})
|
|
.then(function () {
|
|
load.linkRecord = undefined;
|
|
return registry[load.key] = load.module = new ModuleNamespace(link.moduleObj);
|
|
});
|
|
}
|
|
|
|
// dispose link record
|
|
load.linkRecord = undefined;
|
|
registry[load.key] = load.module = new ModuleNamespace(link.moduleObj);
|
|
}
|
|
|
|
// non es modules explicitly call moduleEvaluate through require
|
|
function doEvaluateDynamic (loader, load, link, registry, state, seen) {
|
|
// System.registerDynamic execute
|
|
// "this" is "exports" in CJS
|
|
var module = { id: load.key };
|
|
var moduleObj = link.moduleObj;
|
|
Object.defineProperty(module, 'exports', {
|
|
configurable: true,
|
|
set: function (exports) {
|
|
moduleObj.default = moduleObj.__useDefault = exports;
|
|
},
|
|
get: function () {
|
|
return moduleObj.__useDefault;
|
|
}
|
|
});
|
|
|
|
var require = makeDynamicRequire(loader, load.key, link.dependencies, link.dependencyInstantiations, registry, state, seen);
|
|
|
|
// evaluate deps first
|
|
if (!link.executingRequire)
|
|
for (var i = 0; i < link.dependencies.length; i++)
|
|
require(link.dependencies[i]);
|
|
|
|
try {
|
|
var output = link.execute.call(envGlobal, require, moduleObj.default, module);
|
|
if (output !== undefined)
|
|
module.exports = output;
|
|
}
|
|
catch (e) {
|
|
evalError(load, e);
|
|
}
|
|
|
|
load.linkRecord = undefined;
|
|
|
|
// pick up defineProperty calls to module.exports when we can
|
|
if (module.exports !== moduleObj.__useDefault)
|
|
moduleObj.default = moduleObj.__useDefault = module.exports;
|
|
|
|
var moduleDefault = moduleObj.default;
|
|
|
|
// __esModule flag extension support via lifting
|
|
if (moduleDefault && moduleDefault.__esModule) {
|
|
for (var p in moduleDefault) {
|
|
if (Object.hasOwnProperty.call(moduleDefault, p))
|
|
moduleObj[p] = moduleDefault[p];
|
|
}
|
|
}
|
|
|
|
registry[load.key] = load.module = new ModuleNamespace(link.moduleObj);
|
|
|
|
// run importer setters and clear them
|
|
// this allows dynamic modules to update themselves into es modules
|
|
// as soon as execution has completed
|
|
if (load.importerSetters)
|
|
for (var i = 0; i < load.importerSetters.length; i++)
|
|
load.importerSetters[i](load.module);
|
|
load.importerSetters = undefined;
|
|
}
|
|
|
|
// the closest we can get to call(undefined)
|
|
var nullContext = Object.create(null);
|
|
if (Object.freeze)
|
|
Object.freeze(nullContext);
|
|
|
|
var loader;
|
|
|
|
// <script type="module"> support
|
|
var anonSources = {};
|
|
if (typeof document != 'undefined' && document.getElementsByTagName) {
|
|
var handleError = function(err) {
|
|
// dispatch an error event so that we can display in errors in browsers
|
|
// that don't yet support unhandledrejection
|
|
if (window.onunhandledrejection === undefined) {
|
|
try {
|
|
var evt = new Event('error');
|
|
} catch (_eventError) {
|
|
var evt = document.createEvent('Event');
|
|
evt.initEvent('error', true, true);
|
|
}
|
|
evt.message = err.message;
|
|
if (err.fileName) {
|
|
evt.filename = err.fileName;
|
|
evt.lineno = err.lineNumber;
|
|
evt.colno = err.columnNumber;
|
|
} else if (err.sourceURL) {
|
|
evt.filename = err.sourceURL;
|
|
evt.lineno = err.line;
|
|
evt.colno = err.column;
|
|
}
|
|
evt.error = err;
|
|
window.dispatchEvent(evt);
|
|
}
|
|
|
|
// throw so it still shows up in the console
|
|
throw err;
|
|
};
|
|
|
|
var ready = function() {
|
|
document.removeEventListener('DOMContentLoaded', ready, false );
|
|
|
|
var anonCnt = 0;
|
|
|
|
var scripts = document.getElementsByTagName('script');
|
|
for (var i = 0; i < scripts.length; i++) {
|
|
var script = scripts[i];
|
|
if (script.type == 'module' && !script.loaded) {
|
|
script.loaded = true;
|
|
if (script.src) {
|
|
loader.import(script.src).catch(handleError);
|
|
}
|
|
// anonymous modules supported via a custom naming scheme and registry
|
|
else {
|
|
var uri = './<anon' + ++anonCnt + '>.js';
|
|
if (script.id !== ""){
|
|
uri = "./" + script.id;
|
|
}
|
|
|
|
var anonName = resolveIfNotPlain(uri, baseURI);
|
|
anonSources[anonName] = script.innerHTML;
|
|
loader.import(anonName).catch(handleError);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// simple DOM ready
|
|
if (document.readyState !== 'loading')
|
|
setTimeout(ready);
|
|
else
|
|
document.addEventListener('DOMContentLoaded', ready, false);
|
|
}
|
|
|
|
function BrowserESModuleLoader(baseKey) {
|
|
if (baseKey)
|
|
this.baseKey = resolveIfNotPlain(baseKey, baseURI) || resolveIfNotPlain('./' + baseKey, baseURI);
|
|
|
|
RegisterLoader.call(this);
|
|
|
|
var loader = this;
|
|
|
|
// ensure System.register is available
|
|
envGlobal.System = envGlobal.System || {};
|
|
if (typeof envGlobal.System.register == 'function')
|
|
var prevRegister = envGlobal.System.register;
|
|
envGlobal.System.register = function() {
|
|
loader.register.apply(loader, arguments);
|
|
if (prevRegister)
|
|
prevRegister.apply(this, arguments);
|
|
};
|
|
}
|
|
BrowserESModuleLoader.prototype = Object.create(RegisterLoader.prototype);
|
|
|
|
// normalize is never given a relative name like "./x", that part is already handled
|
|
BrowserESModuleLoader.prototype[RegisterLoader.resolve] = function(key, parent) {
|
|
var resolved = RegisterLoader.prototype[RegisterLoader.resolve].call(this, key, parent || this.baseKey) || key;
|
|
if (!resolved)
|
|
throw new RangeError('ES module loader does not resolve plain module names, resolving "' + key + '" to ' + parent);
|
|
|
|
return resolved;
|
|
};
|
|
|
|
function xhrFetch(url, resolve, reject) {
|
|
var xhr = new XMLHttpRequest();
|
|
var load = function(source) {
|
|
resolve(xhr.responseText);
|
|
};
|
|
var error = function() {
|
|
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);
|
|
xhr.send(null);
|
|
}
|
|
|
|
var WorkerPool = function (script, size) {
|
|
var current = document.currentScript;
|
|
// IE doesn't support currentScript
|
|
if (!current) {
|
|
// Find an entry with out basename
|
|
var scripts = document.getElementsByTagName('script');
|
|
for (var i = 0; i < scripts.length; i++) {
|
|
if (scripts[i].src.indexOf("browser-es-module-loader.js") !== -1) {
|
|
current = scripts[i];
|
|
break;
|
|
}
|
|
}
|
|
if (!current)
|
|
throw Error("Could not find own <script> element");
|
|
}
|
|
script = current.src.substr(0, current.src.lastIndexOf("/")) + "/" + script;
|
|
this._workers = new Array(size);
|
|
this._ind = 0;
|
|
this._size = size;
|
|
this._jobs = 0;
|
|
this.onmessage = undefined;
|
|
this._stopTimeout = undefined;
|
|
for (var i = 0; i < size; i++) {
|
|
var wrkr = new Worker(script);
|
|
wrkr._count = 0;
|
|
wrkr._ind = i;
|
|
wrkr.onmessage = this._onmessage.bind(this, wrkr);
|
|
wrkr.onerror = this._onerror.bind(this);
|
|
this._workers[i] = wrkr;
|
|
}
|
|
|
|
this._checkJobs();
|
|
};
|
|
WorkerPool.prototype = {
|
|
postMessage: function (msg) {
|
|
if (this._stopTimeout !== undefined) {
|
|
clearTimeout(this._stopTimeout);
|
|
this._stopTimeout = undefined;
|
|
}
|
|
var wrkr = this._workers[this._ind % this._size];
|
|
wrkr._count++;
|
|
this._jobs++;
|
|
wrkr.postMessage(msg);
|
|
this._ind++;
|
|
},
|
|
|
|
_onmessage: function (wrkr, evt) {
|
|
wrkr._count--;
|
|
this._jobs--;
|
|
this.onmessage(evt, wrkr);
|
|
this._checkJobs();
|
|
},
|
|
|
|
_onerror: function(err) {
|
|
try {
|
|
var evt = new Event('error');
|
|
} catch (_eventError) {
|
|
var evt = document.createEvent('Event');
|
|
evt.initEvent('error', true, true);
|
|
}
|
|
evt.message = err.message;
|
|
evt.filename = err.filename;
|
|
evt.lineno = err.lineno;
|
|
evt.colno = err.colno;
|
|
evt.error = err.error;
|
|
window.dispatchEvent(evt);
|
|
},
|
|
|
|
_checkJobs: function () {
|
|
if (this._jobs === 0 && this._stopTimeout === undefined) {
|
|
// wait for 2s of inactivity before stopping (that should be enough for local loading)
|
|
this._stopTimeout = setTimeout(this._stop.bind(this), 2000);
|
|
}
|
|
},
|
|
|
|
_stop: function () {
|
|
this._workers.forEach(function(wrkr) {
|
|
wrkr.terminate();
|
|
});
|
|
}
|
|
};
|
|
|
|
var promiseMap = new Map();
|
|
var babelWorker = new WorkerPool('babel-worker.js', 3);
|
|
babelWorker.onmessage = function (evt) {
|
|
var promFuncs = promiseMap.get(evt.data.key);
|
|
promFuncs.resolve(evt.data);
|
|
promiseMap.delete(evt.data.key);
|
|
};
|
|
|
|
// instantiate just needs to run System.register
|
|
// so we fetch the source, convert into the Babel System module format, then evaluate it
|
|
BrowserESModuleLoader.prototype[RegisterLoader.instantiate] = function(key, processAnonRegister) {
|
|
|
|
// load as ES with Babel converting into System.register
|
|
return new Promise(function(resolve, reject) {
|
|
// anonymous module
|
|
if (anonSources[key]) {
|
|
resolve(anonSources[key]);
|
|
anonSources[key] = undefined;
|
|
}
|
|
// otherwise we fetch
|
|
else {
|
|
xhrFetch(key, resolve, reject);
|
|
}
|
|
})
|
|
.then(function(source) {
|
|
// check our cache first
|
|
var cacheEntry = localStorage.getItem(key);
|
|
if (cacheEntry) {
|
|
cacheEntry = JSON.parse(cacheEntry);
|
|
// TODO: store a hash instead
|
|
if (cacheEntry.source === source) {
|
|
return Promise.resolve({key: key, code: cacheEntry.code, source: cacheEntry.source});
|
|
}
|
|
}
|
|
return new Promise(function (resolve, reject) {
|
|
promiseMap.set(key, {resolve: resolve, reject: reject});
|
|
babelWorker.postMessage({key: key, source: source});
|
|
});
|
|
}).then(function (data) {
|
|
// evaluate without require, exports and module variables
|
|
// we leave module in for now to allow module.require access
|
|
try {
|
|
var cacheEntry = JSON.stringify({source: data.source, code: data.code});
|
|
localStorage.setItem(key, cacheEntry);
|
|
} catch (e) {
|
|
if (window.console) {
|
|
window.console.warn('Unable to cache transpiled version of ' + key + ': ' + e);
|
|
}
|
|
}
|
|
(0, eval)(data.code + '\n//# sourceURL=' + data.key + '!transpiled');
|
|
processAnonRegister();
|
|
});
|
|
};
|
|
|
|
// create a default loader instance in the browser
|
|
if (isBrowser)
|
|
loader = new BrowserESModuleLoader();
|
|
|
|
return BrowserESModuleLoader;
|
|
|
|
})));
|
|
//# sourceMappingURL=browser-es-module-loader.js.map
|