aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/systemjs/lib/conditionals.js
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/systemjs/lib/conditionals.js')
-rw-r--r--thirdparty/systemjs/lib/conditionals.js161
1 files changed, 161 insertions, 0 deletions
diff --git a/thirdparty/systemjs/lib/conditionals.js b/thirdparty/systemjs/lib/conditionals.js
new file mode 100644
index 000000000..d30a6f9ac
--- /dev/null
+++ b/thirdparty/systemjs/lib/conditionals.js
@@ -0,0 +1,161 @@
+/*
+ * Conditions Extension
+ *
+ * Allows a condition module to alter the resolution of an import via syntax:
+ *
+ * import $ from 'jquery/#{browser}';
+ *
+ * Will first load the module 'browser' via `SystemJS.import('browser')` and
+ * take the default export of that module.
+ * If the default export is not a string, an error is thrown.
+ *
+ * We then substitute the string into the require to get the conditional resolution
+ * enabling environment-specific variations like:
+ *
+ * import $ from 'jquery/ie'
+ * import $ from 'jquery/firefox'
+ * import $ from 'jquery/chrome'
+ * import $ from 'jquery/safari'
+ *
+ * It can be useful for a condition module to define multiple conditions.
+ * This can be done via the `|` modifier to specify an export member expression:
+ *
+ * import 'jquery/#{./browser.js|grade.version}'
+ *
+ * Where the `grade` export `version` member in the `browser.js` module is substituted.
+ *
+ *
+ * Boolean Conditionals
+ *
+ * For polyfill modules, that are used as imports but have no module value,
+ * a binary conditional allows a module not to be loaded at all if not needed:
+ *
+ * import 'es5-shim#?./conditions.js|needs-es5shim'
+ *
+ * These conditions can also be negated via:
+ *
+ * import 'es5-shim#?./conditions.js|~es6'
+ *
+ */
+
+ var sysConditions = ['browser', 'node', 'dev', 'build', 'production', 'default'];
+
+ function parseCondition(condition) {
+ var conditionExport, conditionModule, negation;
+
+ var negation = condition[0] == '~';
+ var conditionExportIndex = condition.lastIndexOf('|');
+ if (conditionExportIndex != -1) {
+ conditionExport = condition.substr(conditionExportIndex + 1);
+ conditionModule = condition.substr(negation, conditionExportIndex - negation);
+
+ if (negation)
+ warn.call(this, 'Condition negation form "' + condition + '" is deprecated for "' + conditionModule + '|~' + conditionExport + '"');
+
+ if (conditionExport[0] == '~') {
+ negation = true;
+ conditionExport = conditionExport.substr(1);
+ }
+ }
+ else {
+ conditionExport = 'default';
+ conditionModule = condition.substr(negation);
+ if (sysConditions.indexOf(conditionModule) != -1) {
+ conditionExport = conditionModule;
+ conditionModule = null;
+ }
+ }
+
+ return {
+ module: conditionModule || '@system-env',
+ prop: conditionExport,
+ negate: negation
+ };
+ }
+
+ function serializeCondition(conditionObj) {
+ return conditionObj.module + '|' + (conditionObj.negate ? '~' : '') + conditionObj.prop;
+ }
+
+ function resolveCondition(conditionObj, parentName, bool) {
+ var self = this;
+ return this.normalize(conditionObj.module, parentName)
+ .then(function(normalizedCondition) {
+ return self.load(normalizedCondition)
+ .then(function(q) {
+ var m = readMemberExpression(conditionObj.prop, self.get(normalizedCondition));
+
+ if (bool && typeof m != 'boolean')
+ throw new TypeError('Condition ' + serializeCondition(conditionObj) + ' did not resolve to a boolean.');
+
+ return conditionObj.negate ? !m : m;
+ });
+ });
+ }
+
+ var interpolationRegEx = /#\{[^\}]+\}/;
+ function interpolateConditional(name, parentName) {
+ // first we normalize the conditional
+ var conditionalMatch = name.match(interpolationRegEx);
+
+ if (!conditionalMatch)
+ return Promise.resolve(name);
+
+ var conditionObj = parseCondition.call(this, conditionalMatch[0].substr(2, conditionalMatch[0].length - 3));
+
+ // in builds, return normalized conditional
+ if (this.builder)
+ return this['normalize'](conditionObj.module, parentName)
+ .then(function(conditionModule) {
+ conditionObj.module = conditionModule;
+ return name.replace(interpolationRegEx, '#{' + serializeCondition(conditionObj) + '}');
+ });
+
+ return resolveCondition.call(this, conditionObj, parentName, false)
+ .then(function(conditionValue) {
+ if (typeof conditionValue !== 'string')
+ throw new TypeError('The condition value for ' + name + ' doesn\'t resolve to a string.');
+
+ if (conditionValue.indexOf('/') != -1)
+ throw new TypeError('Unabled to interpolate conditional ' + name + (parentName ? ' in ' + parentName : '') + '\n\tThe condition value ' + conditionValue + ' cannot contain a "/" separator.');
+
+ return name.replace(interpolationRegEx, conditionValue);
+ });
+ }
+
+ function booleanConditional(name, parentName) {
+ // first we normalize the conditional
+ var booleanIndex = name.lastIndexOf('#?');
+
+ if (booleanIndex == -1)
+ return Promise.resolve(name);
+
+ var conditionObj = parseCondition.call(this, name.substr(booleanIndex + 2));
+
+ // in builds, return normalized conditional
+ if (this.builder)
+ return this['normalize'](conditionObj.module, parentName)
+ .then(function(conditionModule) {
+ conditionObj.module = conditionModule;
+ return name.substr(0, booleanIndex) + '#?' + serializeCondition(conditionObj);
+ });
+
+ return resolveCondition.call(this, conditionObj, parentName, true)
+ .then(function(conditionValue) {
+ return conditionValue ? name.substr(0, booleanIndex) : '@empty';
+ });
+ }
+
+ // normalizeSync does not parse conditionals at all although it could
+ hook('normalize', function(normalize) {
+ return function(name, parentName, skipExt) {
+ var loader = this;
+ return booleanConditional.call(loader, name, parentName)
+ .then(function(name) {
+ return normalize.call(loader, name, parentName, skipExt);
+ })
+ .then(function(normalized) {
+ return interpolateConditional.call(loader, normalized, parentName);
+ });
+ };
+ });