🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more →

postcss-css-variables

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

postcss-css-variables - npm Package Compare versions

Comparing version

to
0.3.6

# 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 @@

// 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 @@ [![npm version](https://badge.fury.io/js/postcss-css-variables.svg)](http://badge.fury.io/js/postcss-css-variables) [![Build Status](https://travis-ci.org/MadLittleMods/postcss-css-variables.svg)](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).