mirror of
https://github.com/systemjs/systemjs.git
synced 2026-01-25 14:57:38 +00:00
153 lines
4.0 KiB
JavaScript
153 lines
4.0 KiB
JavaScript
/*
|
|
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 map(loader) {
|
|
loader.map = loader.map || {};
|
|
|
|
// return if prefix parts (separated by '/') match the name
|
|
// eg prefixMatch('jquery/some/thing', 'jquery') -> true
|
|
// prefixMatch('jqueryhere/', 'jquery') -> false
|
|
function prefixMatch(name, prefix) {
|
|
if (name.length < prefix.length)
|
|
return false;
|
|
if (name.substr(0, prefix.length) != prefix)
|
|
return false;
|
|
if (name[prefix.length] && name[prefix.length] != '/')
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
// get the depth of a given path
|
|
// eg pathLen('some/name') -> 2
|
|
function pathLen(name) {
|
|
var len = 1;
|
|
for (var i = 0, l = name.length; i < l; i++)
|
|
if (name[i] === '/')
|
|
len++;
|
|
return len;
|
|
}
|
|
|
|
function doMap(name, matchLen, map) {
|
|
return map + name.substr(matchLen);
|
|
}
|
|
|
|
// given a relative-resolved module name and normalized parent name,
|
|
// apply the map configuration
|
|
function applyMap(name, parentName, loader) {
|
|
var curMatch, curMatchLength = 0;
|
|
var curParent, curParentMatchLength = 0;
|
|
var tmpParentLength, tmpPrefixLength;
|
|
var subPath;
|
|
var nameParts;
|
|
|
|
// first find most specific contextual match
|
|
if (parentName) {
|
|
for (var p in loader.map) {
|
|
var curMap = loader.map[p];
|
|
if (typeof curMap != 'object')
|
|
continue;
|
|
|
|
// most specific parent match wins first
|
|
if (!prefixMatch(parentName, p))
|
|
continue;
|
|
|
|
tmpParentLength = pathLen(p);
|
|
if (tmpParentLength <= curParentMatchLength)
|
|
continue;
|
|
|
|
for (var q in curMap) {
|
|
// most specific name match wins
|
|
if (!prefixMatch(name, q))
|
|
continue;
|
|
tmpPrefixLength = pathLen(q);
|
|
if (tmpPrefixLength <= curMatchLength)
|
|
continue;
|
|
|
|
curMatch = q;
|
|
curMatchLength = tmpPrefixLength;
|
|
curParent = p;
|
|
curParentMatchLength = tmpParentLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if we found a contextual match, apply it now
|
|
if (curMatch)
|
|
return doMap(name, curMatch.length, loader.map[curParent][curMatch]);
|
|
|
|
// now do the global map
|
|
for (var p in loader.map) {
|
|
var curMap = loader.map[p];
|
|
if (typeof curMap != 'string')
|
|
continue;
|
|
|
|
if (!prefixMatch(name, p))
|
|
continue;
|
|
|
|
var tmpPrefixLength = pathLen(p);
|
|
|
|
if (tmpPrefixLength <= curMatchLength)
|
|
continue;
|
|
|
|
curMatch = p;
|
|
curMatchLength = tmpPrefixLength;
|
|
}
|
|
|
|
if (curMatch)
|
|
return doMap(name, curMatch.length, loader.map[curMatch]);
|
|
|
|
return name;
|
|
}
|
|
|
|
var loaderNormalize = loader.normalize;
|
|
loader.normalize = function(name, parentName, parentAddress) {
|
|
var loader = this;
|
|
if (!loader.map)
|
|
loader.map = {};
|
|
|
|
var isPackage = false;
|
|
if (name.substr(name.length - 1, 1) == '/') {
|
|
isPackage = true;
|
|
name += '#';
|
|
}
|
|
|
|
return Promise.resolve(loaderNormalize.call(loader, name, parentName, parentAddress))
|
|
.then(function(name) {
|
|
name = applyMap(name, parentName, loader);
|
|
|
|
// Normalize "module/" into "module/module"
|
|
// Convenient for packages
|
|
if (isPackage) {
|
|
var nameParts = name.split('/');
|
|
nameParts.pop();
|
|
var pkgName = nameParts.pop();
|
|
nameParts.push(pkgName);
|
|
nameParts.push(pkgName);
|
|
name = nameParts.join('/');
|
|
}
|
|
|
|
return name;
|
|
});
|
|
}
|
|
}
|