postcss-css-variables
Advanced tools
@@ -0,1 +1,7 @@ | ||
# v0.3.9 - 2015-6-29 | ||
- Remove `opts` global leak. Fix #13 | ||
# v0.3.8 - 2015-5-28 | ||
@@ -2,0 +8,0 @@ |
14
index.js
@@ -60,5 +60,5 @@ // PostCSS CSS Variables (postcss-css-variables) | ||
module.exports = postcss.plugin('postcss-css-variables', function(options) { | ||
opts = extend({}, defaults, options); | ||
var opts = extend({}, defaults, options); | ||
// Work with opts here | ||
@@ -82,3 +82,3 @@ | ||
map = extend( | ||
map, | ||
map, | ||
Object.keys(opts.variables).reduce(function(prevVariableMap, variableName) { | ||
@@ -192,3 +192,3 @@ var variableEntry = opts.variables[variableName]; | ||
var doesRuleUseVariables = rule.nodes.some(function(node) { | ||
if(node.type == 'decl') { | ||
if(node.type === 'decl') { | ||
var decl = node; | ||
@@ -229,5 +229,5 @@ // If it uses variables | ||
ruleToWorkOn.nodes.slice(0).forEach(function(node) { | ||
if(node.type == 'decl') { | ||
if(node.type === 'decl') { | ||
var decl = node; | ||
resolveDecl(decl, map); | ||
resolveDecl(decl, map, opts.preserve); | ||
} | ||
@@ -239,6 +239,6 @@ }); | ||
// Clean up any nodes we don't want anymore | ||
@@ -245,0 +245,0 @@ // We clean up at the end because we don't want to modify the AST when we still need to reference these later on |
@@ -38,5 +38,5 @@ // Splice on a parent scope onto a node | ||
// Keep assigning parents detached until just very end | ||
if(index+1 < cloneParentList.length) { | ||
if(index + 1 < cloneParentList.length) { | ||
//parentClone.moveTo(cloneParentList[index+1]); | ||
parentClone.parent = cloneParentList[index+1]; | ||
parentClone.parent = cloneParentList[index + 1]; | ||
} | ||
@@ -49,5 +49,5 @@ }); | ||
// Keep assigning parents detached until just very end | ||
if(index+1 < cloneList.length) { | ||
if(index + 1 < cloneList.length) { | ||
//clone.moveTo(cloneList[index+1]); | ||
clone.parent = cloneList[index+1]; | ||
clone.parent = cloneList[index + 1]; | ||
// Then splice on the new parent scope | ||
@@ -66,2 +66,2 @@ } else { | ||
module.exports = cloneSpliceParentOntoNodeWhen; | ||
module.exports = cloneSpliceParentOntoNodeWhen; |
@@ -8,6 +8,5 @@ var generateScopeList = require('./generate-scope-list'); | ||
var currentNode = node; | ||
var stillFindingNode = true; | ||
// Keep going until we run out of parents to search | ||
// or we found the node | ||
var currentNode = node; | ||
while(currentNode.parent && !matchingNode) { | ||
@@ -34,2 +33,2 @@ // A trick to get the selector split up. Generate a scope list on a clone(clean parent) | ||
module.exports = findNodeAncestorWithSelector; | ||
module.exports = findNodeAncestorWithSelector; |
@@ -50,2 +50,2 @@ // Variables that referenced in some way by the target variable | ||
module.exports = gatherVariableDependencies; | ||
module.exports = gatherVariableDependencies; |
@@ -23,2 +23,2 @@ // Unit Tests: https://regex101.com/r/oP0fM9/15 | ||
module.exports = generateDescendantPiecesFromSelector; | ||
module.exports = generateDescendantPiecesFromSelector; |
@@ -21,2 +21,2 @@ // Unit Tests: https://regex101.com/r/oS4zJ8/3 | ||
module.exports = generateDirectDescendantPiecesFromSelector; | ||
module.exports = generateDirectDescendantPiecesFromSelector; |
@@ -53,3 +53,3 @@ | ||
scopeStringPieces.unshift.apply(scopeStringPieces, descendantPieces); | ||
return scopeStringPieces; | ||
@@ -70,4 +70,4 @@ }); | ||
return selectorScopeList; | ||
} | ||
}; | ||
module.exports = generateScopeList; | ||
module.exports = generateScopeList; |
@@ -11,2 +11,2 @@ var isUnderScope = require('./is-under-scope'); | ||
module.exports = isNodeUnderScope; | ||
module.exports = isNodeUnderScope; |
@@ -12,2 +12,2 @@ var alwaysAncestorSelector = { | ||
module.exports = isPieceIsAlwaysAncestorSelector; | ||
module.exports = isPieceIsAlwaysAncestorSelector; |
@@ -54,3 +54,3 @@ var escapeStringRegexp = require('escape-string-regexp'); | ||
// And we only want the first occurence so we can keep matching future scope pieces | ||
if(isPieceAlwaysAncestorSelector(scopePiece) || isPieceAlwaysAncestorSelector(nodeScopePiece)) { | ||
if(isPieceAlwaysAncestorSelector(scopePiece) || isPieceAlwaysAncestorSelector(nodeScopePiece)) { | ||
foundIndex = overallIndex; | ||
@@ -80,7 +80,7 @@ | ||
// or there are still more pieces to match in the future | ||
if(result.doesMatchScope || scopePieceIndex+1 < scopeNodeScopePieces.length) { | ||
if(result.doesMatchScope || scopePieceIndex + 1 < scopeNodeScopePieces.length) { | ||
foundIndex = overallIndex; | ||
// Move the scope forward the amount that piece consumed | ||
// -1 because the of for-loop increments at each iteration | ||
scopePieceIndex += result.scopePieceIndex-1; | ||
scopePieceIndex += result.scopePieceIndex - 1; | ||
} | ||
@@ -95,3 +95,3 @@ | ||
currentPieceOffset = foundIndex+1; | ||
currentPieceOffset = foundIndex + 1; | ||
@@ -111,3 +111,3 @@ // Mimicing a `[].every` with a for-loop | ||
doesMatchScope: doesMatchScope, | ||
nodeScopePieceIndex: currentPieceOffset-1, | ||
nodeScopePieceIndex: currentPieceOffset - 1, | ||
scopePieceIndex: scopePieceIndex | ||
@@ -155,2 +155,2 @@ }; | ||
module.exports = isUnderScope; | ||
module.exports = isUnderScope; |
@@ -11,5 +11,68 @@ var resolveValue = require('./resolve-value'); | ||
function eachMapItemDependencyOfDecl(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) { | ||
var mimicDecl; | ||
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); | ||
// 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; | ||
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); | ||
} | ||
// TODO: use regex from `isUnderScope` | ||
else if(isUnderScope.RE_PSEUDO_SELECTOR.test(mapItem.parent.selector)) { | ||
// Create a detached clone | ||
var ruleClone = decl.parent.clone().removeAll(); | ||
ruleClone.parent = decl.parent.parent; | ||
// Add the declaration to it | ||
mimicDecl = decl.clone(); | ||
ruleClone.append(mimicDecl); | ||
var lastPseudoSelectorMatches = mapItem.parent.selector.match(new RegExp(isUnderScope.RE_PSEUDO_SELECTOR.source + '$')); | ||
var lastPseudoSelector = lastPseudoSelectorMatches ? lastPseudoSelectorMatches[2] : ''; | ||
ruleClone.selector += lastPseudoSelector; | ||
} | ||
// If it is under the proper scope, | ||
// we need to check because we are iterating over all map entries | ||
if(mimicDecl && isNodeUnderScope(mimicDecl, mapItem.parent, true)) { | ||
cb(mimicDecl, mapItem); | ||
} | ||
}); | ||
}); | ||
} | ||
// Resolve the decl with the computed value | ||
// Also add in any media queries that change the value as necessary | ||
function resolveDecl(decl, map, /*optional*/logResolveValueResult) { | ||
function resolveDecl(decl, map, /*optional*/shouldPreserve, /*optional*/logResolveValueResult) { | ||
shouldPreserve = shouldPreserve || false; | ||
// Make it chainable | ||
var _logResolveValueResult = function(valueResults) { | ||
@@ -27,3 +90,2 @@ if(logResolveValueResult) { | ||
var valueResults = _logResolveValueResult(resolveValue(decl, map)); | ||
@@ -79,3 +141,3 @@ | ||
// If we are preserving var(...) usage and the value changed meaning it had some | ||
if(opts.preserve === true && decl.value !== valueResults.value) { | ||
if(shouldPreserve === true && decl.value !== valueResults.value) { | ||
decl.cloneAfter(); | ||
@@ -86,64 +148,9 @@ } | ||
decl.value = valueResults.value; | ||
} | ||
function eachMapItemDependencyOfDecl(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) { | ||
var mimicDecl; | ||
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); | ||
// 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; | ||
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); | ||
} | ||
// TODO: use regex from `isUnderScope` | ||
else if(isUnderScope.RE_PSEUDO_SELECTOR.test(mapItem.parent.selector)) { | ||
// Create a detached clone | ||
var ruleClone = decl.parent.clone().removeAll(); | ||
ruleClone.parent = decl.parent.parent; | ||
// Add the declaration to it | ||
mimicDecl = decl.clone(); | ||
ruleClone.append(mimicDecl); | ||
var lastPseudoSelectorMatches = mapItem.parent.selector.match(new RegExp(isUnderScope.RE_PSEUDO_SELECTOR.source + '$')); | ||
var lastPseudoSelector = lastPseudoSelectorMatches ? lastPseudoSelectorMatches[2] : ''; | ||
ruleClone.selector += lastPseudoSelector; | ||
} | ||
// If it is under the proper scope, | ||
// we need to check because we are iterating over all map entries | ||
if(mimicDecl && isNodeUnderScope(mimicDecl, mapItem.parent, true)) { | ||
cb(mimicDecl, mapItem); | ||
} | ||
}); | ||
}); | ||
} | ||
module.exports = resolveDecl; | ||
module.exports = resolveDecl; |
@@ -19,5 +19,5 @@ var generateScopeList = require('./generate-scope-list'); | ||
// `ignorePseudoScope`: Optional bool to determine whether the scope resolution should be left alone or not | ||
// | ||
// | ||
// Note: We do not modify the declaration | ||
// Note: Resolving a declaration value without any `var(...)` does not harm the final value. | ||
// Note: Resolving a declaration value without any `var(...)` does not harm the final value. | ||
// This means, feel free to run everything through this function | ||
@@ -79,3 +79,3 @@ var resolveValue = function(decl, map, /*optional*/ignorePseudoScope, /*internal debugging*/_debugIsInternal) { | ||
replaceValue = resolveValue(matchingMimicDecl, map, /*internal*/true).value; | ||
replaceValue = resolveValue(matchingMimicDecl, map, false, /*internal*/true).value; | ||
} | ||
@@ -85,3 +85,3 @@ | ||
if(isResultantValueUndefined) { | ||
warnings.push(["variable '" + variableName + "' is undefined and used without a fallback", { node: decl }]); | ||
warnings.push(['variable ' + variableName + ' is undefined and used without a fallback', { node: decl }]); | ||
} | ||
@@ -105,2 +105,2 @@ | ||
module.exports = resolveValue; | ||
module.exports = resolveValue; |
{ | ||
"name": "postcss-css-variables", | ||
"version": "0.3.8", | ||
"version": "0.3.9", | ||
"description": "PostCSS plugin to transform CSS Custom Properties(CSS variables) syntax into a static representation", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -11,3 +11,3 @@ [](http://badge.fury.io/js/postcss-css-variables) [](https://travis-ci.org/MadLittleMods/postcss-css-variables) | ||
## Latest Version: v0.3.8 | ||
## Latest Version: v0.3.9 | ||
### [Changelog](https://github.com/MadLittleMods/postcss-css-variables/blob/master/CHANGELOG.md) | ||
@@ -221,3 +221,3 @@ | ||
`post-css-variables` plays really nice with [`postcss-nested`](https://github.com/postcss/postcss-nested) in order to get a larger subset of CSS variables features. *See [Nested rules, Usage section](#nested-rules)* | ||
`postcss-css-variables` plays really nice with [`postcss-nested`](https://github.com/postcss/postcss-nested) in order to get a larger subset of CSS variables features. *See [Nested rules, Usage section](#nested-rules)* | ||
@@ -235,3 +235,3 @@ 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. | ||
The main features that we`post-css-variables` add/provide are: | ||
The main features that we`postcss-css-variables` add/provide are: | ||
@@ -238,0 +238,0 @@ - No limitation on what scope CSS variables can be declared or used (`:root` or wherever) |
46046
0.43%735
1.66%