consolidate normalization in Makefile, split conditional order of boolean and interpolation

This commit is contained in:
guybedford 2015-09-09 20:39:30 +02:00
parent af607fe2f1
commit e88e47460b
7 changed files with 73 additions and 55 deletions

View File

@ -80,7 +80,10 @@ dist/system.src.js: lib/*.js $(ESML)/*.js
$(ESML)/transpiler.js \
lib/global-eval.js \
lib/proto.js \
lib/map.js \
lib/core.js \
lib/paths.js \
lib/package.js \
lib/scriptLoader.js \
lib/register.js \
lib/esm.js \
@ -89,15 +92,12 @@ dist/system.src.js: lib/*.js $(ESML)/*.js
lib/cjs.js \
lib/amd-helpers.js \
lib/amd.js \
lib/map.js \
lib/paths.js \
lib/package.js \
lib/conditionals.js \
lib/plugins.js \
lib/alias.js \
lib/meta.js \
lib/bundles.js \
lib/depCache.js \
lib/conditionals.js \
lib/createSystem.js \
; echo "$$STANDARD_VERSION" ; cat \
$(ESML)/wrapper-end.js \
@ -113,21 +113,21 @@ dist/system-csp-production.src.js: lib/*.js $(ESML)/*.js
$(ESML)/dynamic-only.js \
$(ESML)/system.js \
lib/proto.js \
lib/map.js \
lib/core.js \
lib/paths.js \
lib/package.js \
lib/scriptLoader.js \
lib/scriptOnly.js \
lib/register.js \
lib/global-helpers.js \
lib/amd-helpers.js \
lib/map.js \
lib/paths.js \
lib/package.js \
lib/conditionals.js \
lib/plugins.js \
lib/alias.js \
lib/meta.js \
lib/bundles.js \
lib/depCache.js \
lib/conditionals.js \
lib/createSystem.js \
; echo "$$CSP_VERSION" ; cat \
$(ESML)/wrapper-end.js \

View File

@ -51,7 +51,7 @@
});
hook('normalize', function(normalize) {
return function (name, parentName) {
return function(name, parentName) {
// dynamically load node-core modules when requiring `@node/fs` for example
if (name.substr(0, 6) == '@node/') {
if (!this._nodeRequire)

View File

@ -34,18 +34,7 @@
*
*/
var conditionalRegEx = /#\{[^\}]+\}|#\?.+$/;
function resolveConditionals(name, parentName) {
// first we normalize the conditional
var conditionalMatch = name.match(conditionalRegEx);
if (!conditionalMatch)
return name;
var substitution = conditionalMatch[0][1] != '?';
var conditionModule = substitution ? conditionalMatch[0].substr(2, conditionalMatch[0].length - 3) : conditionalMatch[0].substr(2);
function resolveCondition(conditionModule, parentName, bool) {
var conditionExport;
var conditionExportIndex = conditionModule.lastIndexOf('|');
if (conditionExportIndex != -1) {
@ -53,7 +42,7 @@
conditionModule = conditionModule.substr(0, conditionExportIndex);
}
var booleanNegation = !substitution && conditionModule[0] == '~';
var booleanNegation = bool && conditionModule[0] == '~';
if (booleanNegation)
conditionModule = conditionModule.substr(1);
@ -63,7 +52,7 @@
.then(function(conditionModule) {
return name.replace(conditionalRegEx, substitution ? '#{' + conditionModule + '}' : '#?' + conditionModule);
});
return this['import'](conditionModule, parentName)
.then(function(m) {
if (conditionExport === undefined) {
@ -74,25 +63,50 @@
return m['default'];
}
return readMemberExpression(conditionExport, m);
})
var conditionValue = readMemberExpression(conditionExport, m);
if (bool && typeof conditionValue !== 'boolean')
throw new TypeError('The condition value for ' + conditionModule + ' isn\'t resolving to a boolean.');
if (booleanNegation)
conditionValue = !conditionValue;
return conditionValue;
});
}
var interpolationRegEx = /#\{[^\}]+\}/;
function interpolateConditional(name, parentName) {
// first we normalize the conditional
var conditionalMatch = name.match(interpolationRegEx);
if (!conditionalMatch)
return Promise.resolve(name);
var conditionModule = conditionalMatch[0].substr(2, conditionalMatch[0].length - 3);
return resolveCondition.call(this, conditionModule, parentName, false)
.then(function(conditionValue) {
if (substitution) {
if (typeof conditionValue !== 'string')
throw new TypeError('The condition value for ' + conditionModule + ' doesn\'t resolve to a string.');
name = name.replace(conditionalRegEx, conditionValue);
}
else {
if (typeof conditionValue !== 'boolean')
throw new TypeError('The condition value for ' + conditionModule + ' isn\'t resolving to a boolean.');
if (booleanNegation)
conditionValue = !conditionValue;
if (!conditionValue)
name = '@empty';
else
name = name.replace(conditionalRegEx, '');
}
return name;
if (typeof conditionValue !== 'string')
throw new TypeError('The condition value for ' + conditionModule + ' doesn\'t resolve to a string.');
return name.replace(interpolationRegEx, conditionValue);
});
}
var booleanRegEx = /#\?.+$/;
function booleanConditional(name, parentName) {
// first we normalize the conditional
var conditionalMatch = name.match(booleanRegEx);
if (!conditionalMatch)
return Promise.resolve(name);
var conditionModule = conditionalMatch[0].substr(2);
return resolveCondition.call(this, conditionModule, parentName, true)
.then(function(conditionValue) {
return conditionValue ? name.substr(0, name.length - conditionModule.length - 2) : '@empty';
});
}
@ -108,13 +122,16 @@
};
});
// no normalizeSync
hook('normalize', function(normalize) {
return function(name, parentName, parentAddress) {
var loader = this;
return Promise.resolve(resolveConditionals.call(this, name, parentName))
return booleanConditional.call(loader, name, parentName)
.then(function(name) {
return normalize.call(loader, name, parentName, parentAddress);
})
.then(function(normalized) {
return interpolateConditional.call(loader, normalized, parentName);
});
};
});

View File

@ -25,8 +25,6 @@ function getBaseURLObj() {
var baseURIObj = new URL(baseURI);
(function() {
hookConstructor(function(constructor) {
return function() {
constructor.call(this);
@ -54,8 +52,12 @@ hookConstructor(function(constructor) {
The final normalization
*/
hook('normalize', function() {
hook('normalize', function(normalize) {
return function(name, parentName) {
// first run map config
name = normalize.apply(this, arguments);
// relative URL-normalization
if (name[0] == '.' || name[0] == '/')
return new URL(name, parentName || baseURIObj).href;
@ -282,6 +284,4 @@ SystemJSLoader.prototype.config = function(cfg) {
}
}
}
};
})();
};

View File

@ -19,7 +19,7 @@ hookConstructor(function(constructor) {
};
});
hook('normalize', function(normalize) {
hook('normalize', function() {
return function(name, parentName) {
if (name.substr(0, 1) != '.' && name.substr(0, 1) != '/' && !name.match(absURLRegEx)) {
var bestMatch, bestMatchLength = 0;
@ -39,6 +39,7 @@ hook('normalize', function(normalize) {
name = this.map[bestMatch] + name.substr(bestMatch.length);
}
return normalize.apply(this, arguments);
// map is the first normalizer
return name;
};
});

View File

@ -47,7 +47,7 @@
* import 'jquery/vendor/another' -> another/index.js
*
* Detailed Behaviours
* - main is the only property where a leading "./" can be added optionally
* - main can have a leading "./" can be added optionally
* - map and defaultExtension are applied to the main
* - defaultExtension adds the extension only if no other extension is present
* - defaultJSExtensions applies after map when defaultExtension is not set
@ -152,6 +152,7 @@
// allowing package map and package mains to point to conditionals
function toPackagePath(loader, pkgName, pkg, basePath, subPath, sync, isPlugin) {
var hasExtensionMeta = isPlugin;
if (pkg.meta)
getMetaMatches(pkg.meta, pkgName, subPath, function(metaPattern, matchMeta, matchDepth) {
// exact meta or meta with any content after the last wildcard skips extension
@ -161,7 +162,7 @@
var normalized = pkgName + '/' + basePath + subPath + (hasExtensionMeta ? '' : getDefaultExtension(pkg, subPath));
return sync ? normalized : resolveConditionals.call(loader, normalized, pkgName + '/');
return sync ? normalized : interpolateConditional.call(loader, normalized, pkgName + '/');
}
function getDefaultExtension(pkg, subPath) {
@ -282,7 +283,7 @@
var defaultJSExtension = this.defaultJSExtensions && name.substr(name.length - 3, 3) != '.js';
// apply global map, relative normalization
// apply map, core, paths
var normalized = normalize.call(this, name, parentName);
// undo defaultJSExtension

View File

@ -4,7 +4,6 @@
* Applies paths and normalizes to a full URL
*/
hook('normalize', function(normalize) {
return function(name, parentName) {
var normalized = normalize.apply(this, arguments);