postcss-css-variables
Advanced tools
Comparing version
# v0.3.6 - 2015-5-21 | ||
- Fix #6. Variable usage in comma separated selector to use proper scope | ||
# v0.3.5 - 2015-5-12 | ||
@@ -3,0 +7,0 @@ |
170
index.js
// PostCSS CSS Variables (postcss-css-variables) | ||
// v0.3.5 | ||
// v0.3.6 | ||
// | ||
@@ -12,8 +12,4 @@ // https://github.com/MadLittleMods/postcss-css-variables | ||
var cloneSpliceParentOntoNodeWhen = require('./lib/clone-splice-parent-onto-node-when'); | ||
var findNodeAncestorWithSelector = require('./lib/find-node-ancestor-with-selector'); | ||
var resolveValue = require('./lib/resolve-value'); | ||
var isNodeUnderScope = require('./lib/is-node-under-scope'); | ||
var generateScopeList = require('./lib/generate-scope-list'); | ||
var gatherVariableDependencies = require('./lib/gather-variable-dependencies'); | ||
var resolveDecl = require('./lib/resolve-decl'); | ||
@@ -40,39 +36,13 @@ | ||
function eachMapItemUnderAtRuleUsedByVariable(variablesUsedList, map, decl, cb) { | ||
// Now find any at-rule declarations that pertains to each rule | ||
// Loop through the variables used | ||
variablesUsedList.forEach(function(variableUsedName) { | ||
// Find anything in the map that corresponds to that variable | ||
gatherVariableDependencies(variablesUsedList, map).deps.forEach(function(mapItem) { | ||
if(mapItem.isUnderAtRule) { | ||
// Get the inner-most selector of the at-rule scope variable declaration we are matching | ||
// Because the inner-most selector will be the same for each branch, we can look at the first one [0] or any of the others | ||
var varDeclScopeList = generateScopeList(mapItem.parent, true); | ||
var innerMostAtRuleSelector = varDeclScopeList[0].slice(-1)[0]; | ||
var nodeToSpliceParentOnto = findNodeAncestorWithSelector(innerMostAtRuleSelector, decl.parent); | ||
function cleanUpNode(currentNodeToRemove) { | ||
// If we removed all of the declarations in the rule(making it empty), then just remove it | ||
var currentNodeToPossiblyCleanUp = currentNodeToRemove; | ||
while(currentNodeToPossiblyCleanUp && currentNodeToPossiblyCleanUp.nodes.length <= 0) { | ||
var nodeToRemove = currentNodeToPossiblyCleanUp; | ||
// Get a reference to it before we remove and lose reference to the child after removing it | ||
currentNodeToPossiblyCleanUp = currentNodeToPossiblyCleanUp.parent; | ||
// Splice on where the selector starts matching the selector inside at-rule | ||
// See: `test/fixtures/cascade-on-nested-rules.css` | ||
var varDeclAtRule = mapItem.parent.parent; | ||
var mimicDecl = cloneSpliceParentOntoNodeWhen(decl, varDeclAtRule, function(ancestor) { | ||
return ancestor === nodeToSpliceParentOnto; | ||
}); | ||
//console.log('amd og', generateScopeList(decl.parent, true)); | ||
//console.log('amd', generateScopeList(mimicDecl.parent, true)); | ||
//console.log(generateScopeList(mapItem.parent, true)); | ||
//console.log('amd isNodeUnderScope', isNodeUnderScope(mimicDecl.parent, mapItem.parent), mapItem.decl.value); | ||
// If it is under the proper scope, | ||
// we need to check because we are iterating over all map entries that are `isUnderAtRule` | ||
// Then lets create the new rules | ||
if(isNodeUnderScope(mimicDecl.parent, mapItem.parent)) { | ||
cb(mimicDecl, mapItem); | ||
} | ||
} | ||
}); | ||
}); | ||
nodeToRemove.removeSelf(); | ||
} | ||
} | ||
@@ -83,3 +53,2 @@ | ||
module.exports = postcss.plugin('postcss-css-variables', function(options) { | ||
@@ -106,5 +75,2 @@ var defaults = { | ||
// List of nodes to add at the end | ||
// We use this so we don't add to the tree as we are processing it (infinite loop) | ||
var createNodeCallbackList = []; | ||
// List of nodes that if empty, will be removed | ||
@@ -210,2 +176,3 @@ // We use this because we don't want to modify the AST when we still need to reference these later on | ||
// We add to the clean up list if we removed some variable declarations to make it become an empty rule | ||
// We clean up later on because we don't want to modify the AST when we still need to reference these later on | ||
if(declParentRule.nodes.length <= 0) { | ||
@@ -218,93 +185,66 @@ nodesToRemoveAtEnd.push(declParentRule); | ||
// Resolve variables everywhere | ||
// --------------------------------------------------------- | ||
// --------------------------------------------------------- | ||
css.eachDecl(function(decl) { | ||
// Ignore any variable declarations that we may be preserving from earlier | ||
// Don't worry, they are already processed | ||
// If not a variable decalaraton... then resolve | ||
if(!RE_VAR_PROP.test(decl.prop)) { | ||
// Collect all the rules that have declarations that use variables | ||
var rulesThatHaveDeclarationsWithVariablesList = []; | ||
css.eachRule(function(rule) { | ||
var doesRuleUseVariables = rule.nodes.some(function(node) { | ||
if(node.type == 'decl') { | ||
var decl = node; | ||
// If it uses variables | ||
// and is not a variable declarations that we may be preserving from earlier | ||
if(resolveValue.RE_VAR_FUNC.test(decl.value) && !RE_VAR_PROP.test(decl.prop)) { | ||
return true; | ||
} | ||
} | ||
// Grab the balue for this declarations | ||
var valueResults = logResolveValueResult(resolveValue(decl, map)); | ||
return false; | ||
}); | ||
if(doesRuleUseVariables) { | ||
rulesThatHaveDeclarationsWithVariablesList.push(rule); | ||
} | ||
}); | ||
// Resolve the cascade | ||
// Now find any at-rule declarations that need to be added below each rule | ||
eachMapItemUnderAtRuleUsedByVariable(valueResults.variablesUsed, map, decl, function(mimicDecl, mapItem) { | ||
// Create the clean atRule for which we place the declaration under | ||
var atRuleNode = mapItem.parent.parent.clone().removeAll(); | ||
rulesThatHaveDeclarationsWithVariablesList.forEach(function(rule) { | ||
var rulesToWorkOn = [].concat(rule); | ||
// Split out the rule into each comma separated selector piece | ||
// We only need to split if is actually comma separted(selectors > 1) | ||
if(rule.selectors.length > 1) { | ||
// Reverse the selectors so that we can cloneAfter in the same comma separated order | ||
rulesToWorkOn = rule.selectors.reverse().map(function(selector) { | ||
var ruleClone = rule.cloneAfter(); | ||
ruleClone.selector = selector; | ||
var ruleClone = decl.parent.clone().removeAll(); | ||
var declClone = decl.clone(); | ||
declClone.value = logResolveValueResult(resolveValue(mimicDecl, map)).value; | ||
return ruleClone; | ||
}); | ||
// Add the declaration to our new rule | ||
ruleClone.append(declClone); | ||
// Add the rule to the atRule | ||
atRuleNode.append(ruleClone); | ||
rule.removeSelf(); | ||
} | ||
// Since that atRuleNode can be nested in other atRules, we need to make the appropriate structure | ||
var parentAtRuleNode = atRuleNode; | ||
var currentAtRuleNode = mapItem.parent.parent; | ||
while(currentAtRuleNode.parent.type === 'atrule') { | ||
// Create a new clean clone of that at rule to nest under | ||
var newParentAtRuleNode = currentAtRuleNode.parent.clone().removeAll(); | ||
// Append the old parent | ||
newParentAtRuleNode.append(parentAtRuleNode); | ||
// Then set the new one as the current for next iteration | ||
parentAtRuleNode = newParentAtRuleNode; | ||
currentAtRuleNode = currentAtRuleNode.parent; | ||
// Resolve the declarations | ||
rulesToWorkOn.forEach(function(ruleToWorkOn) { | ||
ruleToWorkOn.nodes.slice(0).forEach(function(node) { | ||
if(node.type == 'decl') { | ||
var decl = node; | ||
resolveDecl(decl, map); | ||
} | ||
createNodeCallbackList.push(function() { | ||
// Put the atRuleStructure after the declaration's rule | ||
decl.parent.parent.insertAfter(decl.parent, parentAtRuleNode); | ||
}); | ||
}); | ||
}); | ||
// If we are preserving var(...) usage and the value changed meaning it had some | ||
if(opts.preserve === true && decl.value !== valueResults.value) { | ||
createNodeCallbackList.push(function() { | ||
decl.cloneAfter(); | ||
// Set the new value after we are done dealing with at-rule stuff | ||
decl.value = valueResults.value; | ||
}); | ||
} | ||
else { | ||
// Set the new value after we are done dealing with at-rule stuff | ||
decl.value = valueResults.value; | ||
} | ||
} | ||
}); | ||
// Add some nodes that we need to add | ||
// We use this so we don't add to the tree as we are processing it (infinite loop) | ||
createNodeCallbackList.forEach(function(cb) { | ||
cb(); | ||
}); | ||
// Clean up any nodes we don't want anymore | ||
nodesToRemoveAtEnd.forEach(function(currentChildToRemove) { | ||
// If we removed all of the declarations in the rule(making it empty), then just remove it | ||
var currentNodeToPossiblyCleanUp = currentChildToRemove; | ||
while(currentNodeToPossiblyCleanUp && currentNodeToPossiblyCleanUp.nodes.length <= 0) { | ||
var nodeToRemove = currentNodeToPossiblyCleanUp; | ||
// Get a reference to it before we remove and lose reference to the child after removing it | ||
currentNodeToPossiblyCleanUp = currentNodeToPossiblyCleanUp.parent; | ||
// We clean up at the end because we don't want to modify the AST when we still need to reference these later on | ||
nodesToRemoveAtEnd.forEach(cleanUpNode); | ||
nodeToRemove.removeSelf(); | ||
} | ||
}); | ||
//console.log('map', map); | ||
@@ -311,0 +251,0 @@ |
@@ -10,4 +10,4 @@ var generateScopeList = require('./generate-scope-list'); | ||
// var() = var( <custom-property-name> [, <any-value> ]? ) | ||
// matches `name[, fallback]`, captures "name" and "fallback" | ||
// var() = var( <custom-property-name> [, <any-value> ]? ) | ||
// See: http://dev.w3.org/csswg/css-variables/#funcdef-var | ||
@@ -99,3 +99,5 @@ var RE_VAR_FUNC = (/var\((--[^,\s]+?)(?:\s*,\s*(.+))?\)/); | ||
resolveValue.RE_VAR_FUNC = RE_VAR_FUNC; | ||
module.exports = resolveValue; |
{ | ||
"name": "postcss-css-variables", | ||
"version": "0.3.5", | ||
"version": "0.3.6", | ||
"description": "PostCSS plugin to transform CSS Custom Properties(CSS variables) syntax into a static representation", | ||
@@ -25,2 +25,3 @@ "keywords": [ | ||
"chai-as-promised": "^5.0.0", | ||
"clean-css": "^3.2.10", | ||
"gulp": "^3.8.11", | ||
@@ -27,0 +28,0 @@ "gulp-eslint": "^0.11.1", |
@@ -5,9 +5,9 @@ [](http://badge.fury.io/js/postcss-css-variables) [](https://travis-ci.org/MadLittleMods/postcss-css-variables) | ||
[PostCSS](https://github.com/postcss/postcss) plugin to transform [`CSS Custom Properties(CSS variables)`](http://dev.w3.org/csswg/css-variables/) syntax into a static representation. This plugin provides a future-proof way of using **most** of CSS variables featuers. | ||
[PostCSS](https://github.com/postcss/postcss) plugin to transform [`CSS Custom Properties(CSS variables)`](http://dev.w3.org/csswg/css-variables/) syntax into a static representation. This plugin provides a future-proof way of using **most** of CSS variables features. | ||
CSS variables or CSS Custom Properties limited subset polyfill/shim. | ||
We strive for the most complete transformation but we/no plugin can achieve true complete parity according to the [speficification](http://dev.w3.org/csswg/css-variables/) because of the DOM cascade unknowns. | ||
We strive for the most complete transformation but we/no plugin can achieve true complete parity according to the [specification](http://dev.w3.org/csswg/css-variables/) because of the DOM cascade unknowns. | ||
## Latest Version: v0.3.5 | ||
## Latest Version: v0.3.6 | ||
### [Changelog](https://github.com/MadLittleMods/postcss-css-variables/blob/master/CHANGELOG.md) | ||
@@ -197,3 +197,3 @@ | ||
If you are using [`postcss-custom-properties`](https://github.com/postcss/postcss-custom-properties) previosly, we have a compatible feature set and more so you can switch over without having to refactor any of your code. You can just start writing the new awesome stuff. | ||
If you are using [`postcss-custom-properties`](https://github.com/postcss/postcss-custom-properties) previously, we have a compatible feature set and more so you can switch over without having to refactor any of your code. You can just start writing the new awesome stuff. | ||
@@ -212,3 +212,3 @@ | ||
- No limitation on what scope CSS variables can be declared or used (`:root` or wherever) | ||
- Proper value substition based on explicit DOM/structure traversal | ||
- Proper value substitution based on explicit DOM/structure traversal | ||
- At-rule support `@media`, `@support`, etc | ||
@@ -215,0 +215,0 @@ - Nested rules which can be fully deduced with [`postcss-nested`](https://github.com/postcss/postcss-nested). |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
40234
3.85%16
6.67%618
5.82%0
-100%8
14.29%