mirror of
https://github.com/systemjs/systemjs.git
synced 2026-01-18 14:53:14 +00:00
115 lines
3.3 KiB
JavaScript
115 lines
3.3 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 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, loader) {
|
|
|
|
var curMatch, curMatchLength = 0;
|
|
var curParent, curParentMatchLength = 0;
|
|
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 (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 we found a contextual match, apply it now
|
|
if (curMatch) {
|
|
nameParts = name.split('/');
|
|
subPath = nameParts.splice(curMatchLength, nameParts.length - curMatchLength).join('/');
|
|
name = loader.map[curParent][curMatch] + (subPath ? '/' + subPath : '');
|
|
curMatchLength = 0;
|
|
}
|
|
|
|
// now do the global map
|
|
for (var p in loader.map) {
|
|
var curMap = loader.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 (!curMatchLength)
|
|
return name;
|
|
|
|
nameParts = name.split('/');
|
|
subPath = nameParts.splice(curMatchLength, nameParts.length - curMatchLength).join('/');
|
|
return loader.map[curMatch] + (subPath ? '/' + subPath : '');
|
|
}
|
|
|
|
var loaderNormalize = loader.normalize;
|
|
loader.normalize = function(name, parentName, parentAddress) {
|
|
var loader = this;
|
|
if (!loader.map)
|
|
loader.map = {};
|
|
return Promise.resolve(loaderNormalize.call(loader, name, parentName, parentAddress))
|
|
.then(function(name) {
|
|
return applyMap(name, parentName, loader);
|
|
});
|
|
}
|
|
}
|