From e88e47460b30a85eb024df7ee2fdfcbe825a5124 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 9 Sep 2015 20:39:30 +0200 Subject: [PATCH] consolidate normalization in Makefile, split conditional order of boolean and interpolation --- Makefile | 16 ++++----- lib/cjs.js | 2 +- lib/conditionals.js | 85 +++++++++++++++++++++++++++------------------ lib/core.js | 12 +++---- lib/map.js | 5 +-- lib/package.js | 7 ++-- lib/paths.js | 1 - 7 files changed, 73 insertions(+), 55 deletions(-) diff --git a/Makefile b/Makefile index 8ecb68bf..193d153d 100755 --- a/Makefile +++ b/Makefile @@ -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 \ diff --git a/lib/cjs.js b/lib/cjs.js index 17e5d6c7..b6b09211 100644 --- a/lib/cjs.js +++ b/lib/cjs.js @@ -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) diff --git a/lib/conditionals.js b/lib/conditionals.js index 64e6f38b..e0577e2c 100644 --- a/lib/conditionals.js +++ b/lib/conditionals.js @@ -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); }); }; }); diff --git a/lib/core.js b/lib/core.js index dbf13d15..e8dadc9c 100644 --- a/lib/core.js +++ b/lib/core.js @@ -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) { } } } -}; - -})(); \ No newline at end of file +}; \ No newline at end of file diff --git a/lib/map.js b/lib/map.js index 44ff4eaf..209b0cb9 100644 --- a/lib/map.js +++ b/lib/map.js @@ -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; }; }); diff --git a/lib/package.js b/lib/package.js index 13a3b75d..bee1bccb 100644 --- a/lib/package.js +++ b/lib/package.js @@ -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 diff --git a/lib/paths.js b/lib/paths.js index a5689700..ab06e258 100644 --- a/lib/paths.js +++ b/lib/paths.js @@ -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);