systemjs/dist/system-amd-production.js

550 lines
17 KiB
JavaScript

/*
* SystemJS
*
* Copyright (c) 2013 Guy Bedford
* MIT License
*/
(function(global) {
global.upgradeSystemLoader = function() {
delete global.upgradeSystemLoader;
/*
SystemJS Core
Adds normalization to the import function, as well as __defaultOnly support
*/
(function() {
// check we have System
if (typeof System == 'undefined')
throw 'System not defined. Include the `es6-module-loader.js` polyfill before SystemJS.';
/*
__defaultOnly
When a module object looks like:
new Module({
__defaultOnly: true,
default: 'some-module'
})
Then the import of that module is taken to be the 'default' export and not the module object itself.
Useful for module.exports = function() {} handling
*/
var checkDefaultOnly = function(module) {
if (!(module instanceof Module)) {
var out = [];
for (var i = 0; i < module.length; i++)
out[i] = checkDefaultOnly(module[i]);
return out;
}
return module.__defaultOnly ? module['default'] : module;
}
// a variation on System.get that does the __defaultOnly check
System.getModule = function(key) {
return checkDefaultOnly(System.get(key));
}
// support the empty module, as a concept
System.set('@empty', Module({}));
var systemImport = System.import;
var loadingPromises = {};
System.import = function(name, options) {
// patch System.import to do normalization
return new Promise(function(resolve) {
resolve(System.normalize.call(this, name, options && options.name, options && options.address))
})
// add defaultOnly support
.then(function(name) {
return Promise.resolve(systemImport.call(System, name, options)).then(function(module) {
return checkDefaultOnly(module);
});
});
}
})();
/*
SystemJS map support
Provides map configuration through
System.map['jquery'] = 'some/module/map'
As well as contextual map config through
System.map['bootstrap'] = {
jquery: 'some/module/map2'
}
Note that this applies for subpaths, just like RequireJS
jquery -> 'some/module/map'
jquery/path -> 'some/module/map/path'
bootstrap -> 'bootstrap'
Inside any module name of the form 'bootstrap' or 'bootstrap/*'
jquery -> 'some/module/map2'
jquery/p -> 'some/module/map2/p'
Maps are carefully applied from most specific contextual map, to least specific global map
*/
(function() {
System.map = System.map || {};
// return the number of prefix parts (separated by '/') matching the name
// eg prefixMatchLength('jquery/some/thing', 'jquery') -> 1
function prefixMatchLength(name, prefix) {
var prefixParts = prefix.split('/');
var nameParts = name.split('/');
if (prefixParts.length > nameParts.length)
return 0;
for (var i = 0; i < prefixParts.length; i++)
if (nameParts[i] != prefixParts[i])
return 0;
return prefixParts.length;
}
// given a relative-resolved module name and normalized parent name,
// apply the map configuration
function applyMap(name, parentName) {
var curMatch, curMatchLength = 0;
var curParent, curParentMatchLength = 0;
// first find most specific contextual match
if (parentName) {
for (var p in System.map) {
var curMap = System.map[p];
if (typeof curMap != 'object')
continue;
// most specific parent match wins first
if (prefixMatchLength(parentName, p) <= curParentMatchLength)
continue;
for (var q in curMap) {
// most specific name match wins
if (prefixMatchLength(name, q) <= curMatchLength)
continue;
curMatch = q;
curMatchLength = q.split('/').length;
curParent = p;
curParentMatchLength = p.split('/').length;
}
}
if (curMatch) {
var subPath = name.split('/').splice(curMatchLength).join('/');
return System.map[curParent][curMatch] + (subPath ? '/' + subPath : '');
}
}
// if we didn't find a contextual match, try the global map
for (var p in System.map) {
var curMap = System.map[p];
if (typeof curMap != 'string')
continue;
if (prefixMatchLength(name, p) <= curMatchLength)
continue;
curMatch = p;
curMatchLength = p.split('/').length;
}
// return a match if any
if (!curMatch)
return name;
var subPath = name.split('/').splice(curMatchLength).join('/');
return System.map[curMatch] + (subPath ? '/' + subPath : '');
}
var systemNormalize = System.normalize.bind(System);
System.normalize = function(name, parentName, parentAddress) {
return Promise.resolve(systemNormalize(name, parentName, parentAddress))
.then(function(name) {
return applyMap(name, parentName);
});
}
})();
(function(global) {
var head = document.getElementsByTagName('head')[0];
// override fetch to use script injection
System.fetch = function(load) {
// if already defined, skip
if (System.defined[load.name])
return '';
// script injection fetch system
return new Promise(function(resolve, reject) {
var s = document.createElement('script');
s.async = true;
s.addEventListener('load', function(evt) {
if (lastAnonymous)
System.defined[load.name] = lastAnonymous;
lastAnonymous = null;
resolve('');
}, false);
s.addEventListener('error', function(err) {
reject(err);
}, false);
s.src = load.address;
head.appendChild(s);
});
}
var lastAnonymous = null;
global.define = function(name, deps, factory) {
// anonymous define
if (typeof name != 'string') {
factory = deps;
deps = name;
name = null;
}
if (!(deps instanceof Array)) {
factory = deps;
deps = [];
}
if (typeof factory != 'function')
factory = (function(factory) {
return function() { return factory; }
})(factory);
for (var i = 0; i < deps.length; i++)
if (deps.lastIndexOf(deps[i]) != i)
deps.splice(i--, 1);
var instantiate = {
deps: deps,
execute: function() {
var args = [];
for (var i = 0; i < arguments.length; i++)
args.push(System.get(arguments[i]));
var output = factory.apply(this, args);
return new global.Module(output && output.__transpiledModule ? (delete output.__transpiledModule, output) : { __defaultOnly: true, 'default': output });
}
};
if (name)
System.defined[name] = instantiate;
else
lastAnonymous = instantiate;
}
global.define.amd = {};
// no translate at all
System.translate = function() {}
/*
AMD-compatible require
To copy RequireJS, set window.require = window.requirejs = System.requirejs
*/
var require = System.requirejs = function(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));
// amd require
if (names instanceof Array)
Promise.all(names.map(function(name) {
return System.import(name, referer);
})).then(callback, errback);
// commonjs require
else if (typeof names == 'string')
return System.get(names);
else
throw 'Invalid require';
}
})(typeof window != 'undefined' ? window : global);(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 System.bundles['mybundle'] = ['jquery', 'bootstrap/js/bootstrap']
System.bundles = System.bundles || {};
// store a cache of defined modules
// of the form System.defined['moduleName'] = { deps: [], execute: function() {} }
System.defined = System.defined || {};
var systemFetch = System.fetch;
System.fetch = function(load) {
// if the module is already defined, skip fetch
if (System.defined[load.name])
return '';
// if this module is in a bundle, load the bundle first then
for (var b in System.bundles) {
if (System.bundles[b].indexOf(load.name) == -1)
continue;
// we do manual normalization in case the bundle is mapped
// this is so we can still know the normalized name is a bundle
return Promise.resolve(System.normalize(b))
.then(function(normalized) {
System.bundles[normalized] = System.bundles[normalized] || System.bundles[b];
return System.load(normalized);
});
return System.import(b).then(function() { return ''; });
}
return systemFetch.apply(this, arguments);
}
var systemLocate = System.locate;
System.locate = function(load) {
if (System.bundles[load.name])
load.metadata.bundle = true;
return systemLocate.call(this, load);
}
var systemInstantiate = System.instantiate;
System.instantiate = function(load) {
// if the module has been defined by a bundle, use that
if (System.defined[load.name]) {
var instantiateResult = System.defined[load.name];
delete System.defined[load.name];
return instantiateResult;
}
// if it is a bundle itself, it doesn't define anything
if (load.metadata.bundle)
return {
deps: [],
execute: function() {
return new Module({});
}
};
return systemInstantiate.apply(this, arguments);
}
})();/*
SystemJS Semver Version Addon
1. Uses Semver convention for major and minor forms
Supports requesting a module from a package that contains a version suffix
with the following semver ranges:
module - any version
module@1 - major version 1, any minor (not prerelease)
module@1.2 - minor version 1.2, any patch (not prerelease)
module@1.2.3 - exact version
It is assumed that these modules are provided by the server / file system.
First checks the already-requested packages to see if there are any packages
that would match the same package and version range.
This provides a greedy algorithm as a simple fix for sharing version-managed
dependencies as much as possible, which can later be optimized through version
hint configuration created out of deeper version tree analysis.
2. Semver-compatibility syntax (caret operator - ^)
Compatible version request support is then also provided for:
module@^1.2.3 - module@1, >=1.2.3
module@^1.2 - module@1, >=1.2.0
module@^1 - module@1
module@^0.5.3 - module@0.5, >= 0.5.3
module@^0.0.1 - module@0.0.1
The ^ symbol is always normalized out to a normal version request.
This provides comprehensive semver compatibility.
3. System.versions version hints and version report
Note this addon should be provided after all other normalize overrides.
The full list of versions can be found at System.versions providing an insight
into any possible version forks.
It is also possible to create version solution hints on the System global:
System.versions = {
jquery: ['1.9.2', '2.0.3'],
bootstrap: '3.0.1'
};
Versions can be an array or string for a single version.
When a matching semver request is made (jquery@1.9, jquery@1, bootstrap@3)
they will be converted to the latest version match contained here, if present.
Prereleases in this versions list are also allowed to satisfy ranges when present.
*/
(function() {
// match x, x.y, x.y.z, x.y.z-prerelease.1
var semverRegEx = /^(\d+)(?:\.(\d+)(?:\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?)?)?$/;
var semverCompare = function(v1, v2) {
var v1Parts = v1.split('.');
var v2Parts = v2.split('.');
var prereleaseIndex;
if (v1Parts[2] && (prereleaseIndex = v1Parts[2].indexOf('-')) != -1)
v1Parts.splice(2, 1, v1Parts[2].substr(0, prereleaseIndex), v1Parts[2].substr(prereleaseIndex + 1));
if (v2Parts[2] && (prereleaseIndex = v2Parts[2].indexOf('-')) != -1)
v2Parts.splice(2, 1, v2Parts[2].substr(0, prereleaseIndex), v2Parts[2].substr(prereleaseIndex + 1));
for (var i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
if (!v1Parts[i])
return 1;
else if (!v2Parts[i])
return -1;
if (v1Parts[i] != v2Parts[i])
return parseInt(v1Parts[i]) > parseInt(v2Parts[i]) ? 1 : -1;
}
return 0;
}
var systemNormalize = System.normalize;
System.versions = System.versions || {};
// hook normalize and store a record of all versioned packages
System.normalize = function(name, parentName, parentAddress) {
var packageVersions = System.versions;
// run all other normalizers first
return Promise.resolve(systemNormalize.call(this, name, parentName, parentAddress)).then(function(normalized) {
var version, semverMatch, nextChar, versions;
var index = normalized.indexOf('@');
// see if this module corresponds to a package already in out versioned packages list
// no version specified - check against the list (given we don't know the package name)
if (index == -1) {
for (var p in packageVersions) {
versions = packageVersions[p];
if (typeof versions == 'string')
versions = [versions];
if (normalized.substr(0, p.length) != p)
continue;
nextChar = normalized.charAt(p.length);
if (nextChar && nextChar != '/')
continue;
// match -> take latest version
return p + '@' + versions[versions.length - 1] + normalized.substr(p.length);
}
return normalized;
}
// get the version info
version = normalized.substr(index + 1).split('/')[0];
var minVersion;
if (version.substr(0, 1) == '^') {
version = version.substr(1);
minVersion = true;
}
semverMatch = version.match(semverRegEx);
// translate '^' handling as described above
if (minVersion) {
// >= 1.0.0
if (semverMatch[1] > 0) {
minVersion = version;
semverMatch = [semverMatch[1]];
}
// >= 0.1.0
else if (semverMatch[2] > 0) {
minVersion = version;
semverMatch = [0, semverMatch[2]];
}
// >= 0.0.0
else {
minVersion = false;
semverMatch = [0, 0, semverMatch[3]]
}
version = semverMatch.join('.');
// remove the ^ now
normalized = normalized.substr(0, index + 1) + version;
}
// if not a semver, we cant help
if (!semverMatch)
return normalized;
var packageName = normalized.substr(0, index);
versions = packageVersions[packageName] || [];
if (typeof versions == 'string')
versions = [versions];
// look for a version match
// if an exact semver, theres nothing to match, just record it
if (!semverMatch[3] || minVersion)
for (var i = versions.length - 1; i >= 0; i--) {
var curVersion = versions[i];
// if I have requested x.y, find an x.y.z-b
// if I have requested x, find any x.y / x.y.z-b
if (curVersion.substr(0, version.length) == version && curVersion.charAt(version.length).match(/^[\.\-]?$/)) {
// if a minimum version, then check too
if (!minVersion || minVersion && semverCompare(curVersion, minVersion) != -1)
return packageName + '@' + curVersion + normalized.substr(packageName.length + version.length + 1);
}
}
// record the package and semver for reuse since we're now asking the server
// x.y and x versions will now be latest by default, so they are useful in the version list
if (versions.indexOf(version) == -1) {
versions.push(version);
versions.sort(semverCompare);
packageVersions[packageName] = versions.length == 1 ? versions[0] : versions;
// could also add a catch here to another System.import, so if the import fails we can remove the version
}
return normalized;
});
}
})();
};
(function() {
if (!global.System || global.System.registerModule) {
if (typeof window != 'undefined') {
// determine the current script path as the base path
var scripts = document.getElementsByTagName('script');
var curPath = scripts[scripts.length - 1].src;
var basePath = curPath.substr(0, curPath.lastIndexOf('/') + 1);
document.write(
'<' + 'script type="text/javascript" src="' + basePath + 'es6-module-loader.js" data-init="upgradeSystemLoader">' + '<' + '/script>'
);
}
else {
var es6ModuleLoader = require('es6-module-loader');
global.System = es6ModuleLoader.System;
global.Loader = es6ModuleLoader.Loader;
global.Module = es6ModuleLoader.Module;
module.exports = global.System;
global.upgradeSystemLoader();
}
}
else
global.upgradeSystemLoader();
})();
})(typeof window != 'undefined' ? window : global);