postcss-custom-properties
Advanced tools
Comparing version 3.1.0 to 3.2.0
@@ -0,1 +1,5 @@ | ||
# 3.2.0 - 2015-03-31 | ||
- Added: JS defined variables are now resolved too ([#22](https://github.com/postcss/postcss-custom-properties/issues/22)) | ||
# 3.1.0 - 2015-03-16 | ||
@@ -2,0 +6,0 @@ |
152
index.js
@@ -17,2 +17,75 @@ /** | ||
/** | ||
* Resolve CSS variables in a value | ||
* | ||
* The second argument to a CSS variable function, if provided, is a fallback | ||
* value, which is used as the substitution value when the referenced variable | ||
* is invalid. | ||
* | ||
* var(name[, fallback]) | ||
* | ||
* @param {String} value A property value known to contain CSS variable functions | ||
* @param {Object} variables A map of variable names and values | ||
* @param {Object} source source object of the declaration containing the rule | ||
* @return {String} A property value with all CSS variables substituted. | ||
*/ | ||
function resolveValue(value, variables, source) { | ||
var results = [] | ||
var start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") | ||
if (start === -1) { | ||
return [value] | ||
} | ||
var matches = balanced("(", ")", value.substring(start)) | ||
if (!matches) { | ||
throw new SyntaxError("missing closing ')' in the value '" + value + "'") | ||
} | ||
if (matches.body === "") { | ||
throw new Error("var() must contain a non-whitespace string") | ||
} | ||
matches.body.replace(RE_VAR, function(_, name, fallback) { | ||
var replacement = variables[name] | ||
if (!replacement && !fallback) { | ||
console.warn(helpers.message("variable '" + name + "' is undefined and used without a fallback", source)) | ||
} | ||
// prepend with fallbacks | ||
if (fallback) { | ||
// resolve the end of the expression before the rest | ||
(matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { | ||
// resolve fallback values | ||
resolveValue(fallback, variables, source).forEach(function(fbValue) { | ||
results.push(value.slice(0, start) + fbValue + afterValue) | ||
}) | ||
}) | ||
} | ||
// replace with computed custom properties | ||
if (replacement) { | ||
// resolve the end of the expression | ||
(matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { | ||
// resolve replacement if it use a custom property | ||
resolveValue(replacement, variables, source).forEach(function(replacementValue) { | ||
results.push(value.slice(0, start) + replacementValue + afterValue) | ||
}) | ||
}) | ||
} | ||
// nothing, just keep original value | ||
if (!replacement && !fallback) { | ||
// resolve the end of the expression | ||
(matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { | ||
results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) | ||
}) | ||
} | ||
}) | ||
return results | ||
} | ||
/** | ||
* Module export. | ||
@@ -60,3 +133,3 @@ */ | ||
rule.each(function(decl, i) { | ||
rule.each(function(decl, index) { | ||
var prop = decl.prop | ||
@@ -68,3 +141,3 @@ if (prop && prop.indexOf(VAR_PROP_IDENTIFIER) === 0) { | ||
} | ||
toRemove.push(i) | ||
toRemove.push(index) | ||
} | ||
@@ -88,3 +161,3 @@ }) | ||
Object.keys(variables).forEach(function(variable) { | ||
map[variable] = variables[variable] | ||
map[variable] = resolveValue(variables[variable], map) | ||
}) | ||
@@ -114,74 +187,1 @@ | ||
} | ||
/** | ||
* Resolve CSS variables in a value | ||
* | ||
* The second argument to a CSS variable function, if provided, is a fallback | ||
* value, which is used as the substitution value when the referenced variable | ||
* is invalid. | ||
* | ||
* var(name[, fallback]) | ||
* | ||
* @param {String} value A property value known to contain CSS variable functions | ||
* @param {Object} variables A map of variable names and values | ||
* @param {Object} source source object of the declaration containing the rule | ||
* @return {String} A property value with all CSS variables substituted. | ||
*/ | ||
function resolveValue(value, variables, source) { | ||
var results = [] | ||
var start = value.indexOf(VAR_FUNC_IDENTIFIER + "(") | ||
if (start === -1) { | ||
return [value] | ||
} | ||
var matches = balanced("(", ")", value.substring(start)) | ||
if (!matches) { | ||
throw new SyntaxError("missing closing ')' in the value '" + value + "'") | ||
} | ||
if (matches.body === "") { | ||
throw new Error("var() must contain a non-whitespace string") | ||
} | ||
matches.body.replace(RE_VAR, function(_, name, fallback) { | ||
var replacement = variables[name] | ||
if (!replacement && !fallback) { | ||
console.warn(helpers.message("variable '" + name + "' is undefined and used without a fallback", source)) | ||
} | ||
// prepend with fallbacks | ||
if (fallback) { | ||
// resolve the end of the expression before the rest | ||
(matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { | ||
// resolve fallback values | ||
resolveValue(fallback, variables, source).forEach(function(fbValue) { | ||
results.push(value.slice(0, start) + fbValue + afterValue) | ||
}) | ||
}) | ||
} | ||
// replace with computed custom properties | ||
if (replacement) { | ||
// resolve the end of the expression | ||
(matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { | ||
// resolve replacement if it use a custom property | ||
resolveValue(replacement, variables, source).forEach(function(replacementValue) { | ||
results.push(value.slice(0, start) + replacementValue + afterValue) | ||
}) | ||
}) | ||
} | ||
// nothing, just keep original value | ||
if (!replacement && !fallback) { | ||
// resolve the end of the expression | ||
(matches.post ? resolveValue(matches.post, variables, source) : [""]).forEach(function(afterValue) { | ||
results.push(value.slice(0, start) + VAR_FUNC_IDENTIFIER + "(" + name + ")" + afterValue) | ||
}) | ||
} | ||
}) | ||
return results | ||
} |
{ | ||
"name": "postcss-custom-properties", | ||
"version": "3.1.0", | ||
"version": "3.2.0", | ||
"description": "PostCSS plugin to polyfill W3C CSS Custom Properties for cascading variables", | ||
@@ -29,4 +29,3 @@ "keywords": [ | ||
"devDependencies": { | ||
"jscs": "^1.6.2", | ||
"jshint": "^2.5.6", | ||
"eslint": "^0.18.0", | ||
"postcss": "^4.0.0", | ||
@@ -36,5 +35,4 @@ "tape": "^3.0.0" | ||
"scripts": { | ||
"lint": "jscs *.js **/*.js && jshint . --exclude-path .gitignore", | ||
"test": "npm run lint && tape test" | ||
"test": "eslint . && tape test" | ||
} | ||
} |
11658
3