Skip to content

Commit b1a6ef2

Browse files
committed
Remove opts global leak. Fix MadLittleMods#13 - v0.3.9
1 parent 14dec8f commit b1a6ef2

15 files changed

+109
-97
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2+
# v0.3.9 - 2015-6-29
3+
4+
- Remove `opts` global leak. Fix #13
5+
6+
17
# v0.3.8 - 2015-5-28
28

39
- Add support for pseudo selectors `:hover` `:before`

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ CSS variables or CSS Custom Properties limited subset polyfill/shim.
88

99
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.
1010

11-
## Latest Version: v0.3.8
11+
## Latest Version: v0.3.9
1212
### [Changelog](https://github.com/MadLittleMods/postcss-css-variables/blob/master/CHANGELOG.md)
1313

1414
### Install
@@ -217,7 +217,7 @@ will be processed to:
217217

218218
## Interoperability
219219

220-
`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)*
220+
`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)*
221221

222222
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.
223223

@@ -230,7 +230,7 @@ There is another similar plugin available, [`postcss-custom-properties`](https:/
230230

231231
### Differences from `postcss-custom-properties`
232232

233-
The main features that we`post-css-variables` add/provide are:
233+
The main features that we`postcss-css-variables` add/provide are:
234234

235235
- No limitation on what scope CSS variables can be declared or used (`:root` or wherever)
236236
- Proper value substitution based on explicit DOM/structure traversal

index.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ var defaults = {
5757
};
5858

5959
module.exports = postcss.plugin('postcss-css-variables', function(options) {
60-
61-
opts = extend({}, defaults, options);
60+
61+
var opts = extend({}, defaults, options);
6262

6363
// Work with opts here
6464

@@ -78,7 +78,7 @@ module.exports = postcss.plugin('postcss-css-variables', function(options) {
7878

7979
// Add the js defined variables `opts.variables` to the map
8080
map = extend(
81-
map,
81+
map,
8282
Object.keys(opts.variables).reduce(function(prevVariableMap, variableName) {
8383
var variableEntry = opts.variables[variableName];
8484
// Automatically prefix any variable with `--` (CSS custom property syntax) if it doesn't have it already
@@ -187,7 +187,7 @@ module.exports = postcss.plugin('postcss-css-variables', function(options) {
187187
var rulesThatHaveDeclarationsWithVariablesList = [];
188188
css.eachRule(function(rule) {
189189
var doesRuleUseVariables = rule.nodes.some(function(node) {
190-
if(node.type == 'decl') {
190+
if(node.type === 'decl') {
191191
var decl = node;
192192
// If it uses variables
193193
// and is not a variable declarations that we may be preserving from earlier
@@ -223,16 +223,16 @@ module.exports = postcss.plugin('postcss-css-variables', function(options) {
223223
// Resolve the declarations
224224
rulesToWorkOn.forEach(function(ruleToWorkOn) {
225225
ruleToWorkOn.nodes.slice(0).forEach(function(node) {
226-
if(node.type == 'decl') {
226+
if(node.type === 'decl') {
227227
var decl = node;
228-
resolveDecl(decl, map);
228+
resolveDecl(decl, map, opts.preserve);
229229
}
230230
});
231231
});
232232

233233
});
234234

235-
235+
236236

237237

238238

lib/clone-splice-parent-onto-node-when.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,19 @@ var cloneSpliceParentOntoNodeWhen = function(node, parent, /*optional*/whenCb) {
3535
// Assign parents to our parent clones
3636
cloneParentList.forEach(function(parentClone, index, cloneParentList) {
3737
// Keep assigning parents detached until just very end
38-
if(index+1 < cloneParentList.length) {
38+
if(index + 1 < cloneParentList.length) {
3939
//parentClone.moveTo(cloneParentList[index+1]);
40-
parentClone.parent = cloneParentList[index+1];
40+
parentClone.parent = cloneParentList[index + 1];
4141
}
4242
});
4343

4444

4545
// Assign parents to our node clones
4646
cloneList.forEach(function(clone, index, cloneList) {
4747
// Keep assigning parents detached until just very end
48-
if(index+1 < cloneList.length) {
48+
if(index + 1 < cloneList.length) {
4949
//clone.moveTo(cloneList[index+1]);
50-
clone.parent = cloneList[index+1];
50+
clone.parent = cloneList[index + 1];
5151
// Then splice on the new parent scope
5252
} else {
5353
// Set the highest parent ancestor to back to where we should splice in
@@ -61,4 +61,4 @@ var cloneSpliceParentOntoNodeWhen = function(node, parent, /*optional*/whenCb) {
6161
return cloneList[0];
6262
};
6363

64-
module.exports = cloneSpliceParentOntoNodeWhen;
64+
module.exports = cloneSpliceParentOntoNodeWhen;

lib/find-node-ancestor-with-selector.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ var generateScopeList = require('./generate-scope-list');
55
var findNodeAncestorWithSelector = function(selector, node) {
66
var matchingNode;
77

8-
var currentNode = node;
9-
var stillFindingNode = true;
108
// Keep going until we run out of parents to search
119
// or we found the node
10+
var currentNode = node;
1211
while(currentNode.parent && !matchingNode) {
1312
// A trick to get the selector split up. Generate a scope list on a clone(clean parent)
1413
var currentNodeScopeList = generateScopeList(currentNode.clone(), true);
@@ -30,4 +29,4 @@ var findNodeAncestorWithSelector = function(selector, node) {
3029
return matchingNode;
3130
};
3231

33-
module.exports = findNodeAncestorWithSelector;
32+
module.exports = findNodeAncestorWithSelector;

lib/gather-variable-dependencies.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,4 @@ var gatherVariableDependencies = function(variablesUsed, map, _dependencyVariabl
4747
};
4848
};
4949

50-
module.exports = gatherVariableDependencies;
50+
module.exports = gatherVariableDependencies;

lib/generate-descendant-pieces-from-selector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ var generateDescendantPiecesFromSelector = function(selector) {
2020
});
2121
};
2222

23-
module.exports = generateDescendantPiecesFromSelector;
23+
module.exports = generateDescendantPiecesFromSelector;

lib/generate-direct-descendant-pieces-from-selector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ var generateDirectDescendantPiecesFromSelector = function(selector) {
1818
});
1919
};
2020

21-
module.exports = generateDirectDescendantPiecesFromSelector;
21+
module.exports = generateDirectDescendantPiecesFromSelector;

lib/generate-scope-list.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ var generateScopeList = function(node, /*optional*/includeSelf) {
5050

5151
// Add to the front of the array
5252
scopeStringPieces.unshift.apply(scopeStringPieces, descendantPieces);
53-
53+
5454
return scopeStringPieces;
5555
});
5656
});
@@ -66,6 +66,6 @@ var generateScopeList = function(node, /*optional*/includeSelf) {
6666
}
6767

6868
return selectorScopeList;
69-
}
69+
};
7070

71-
module.exports = generateScopeList;
71+
module.exports = generateScopeList;

lib/is-node-under-scope.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ var isNodeUnderScope = function(node, scopeNode, /*optional*/ignorePseudo) {
88
return isUnderScope(nodeScopeList, scopeNodeScopeList, ignorePseudo);
99
};
1010

11-
module.exports = isNodeUnderScope;
11+
module.exports = isNodeUnderScope;

lib/is-piece-always-ancestor-selector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ var isPieceIsAlwaysAncestorSelector = function(piece) {
99
return !!alwaysAncestorSelector[piece];
1010
};
1111

12-
module.exports = isPieceIsAlwaysAncestorSelector;
12+
module.exports = isPieceIsAlwaysAncestorSelector;

lib/is-under-scope.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function getScopeMatchResults(nodeScopeList, scopeNodeScopeList) {
5151
//
5252
// Or the node scope piece could be an always-ancestor selector itself
5353
// And we only want the first occurence so we can keep matching future scope pieces
54-
if(isPieceAlwaysAncestorSelector(scopePiece) || isPieceAlwaysAncestorSelector(nodeScopePiece)) {
54+
if(isPieceAlwaysAncestorSelector(scopePiece) || isPieceAlwaysAncestorSelector(nodeScopePiece)) {
5555
foundIndex = overallIndex;
5656

5757
break;
@@ -76,11 +76,11 @@ function getScopeMatchResults(nodeScopeList, scopeNodeScopeList) {
7676

7777
// If it matches completely
7878
// or there are still more pieces to match in the future
79-
if(result.doesMatchScope || scopePieceIndex+1 < scopeNodeScopePieces.length) {
79+
if(result.doesMatchScope || scopePieceIndex + 1 < scopeNodeScopePieces.length) {
8080
foundIndex = overallIndex;
8181
// Move the scope forward the amount that piece consumed
8282
// -1 because the of for-loop increments at each iteration
83-
scopePieceIndex += result.scopePieceIndex-1;
83+
scopePieceIndex += result.scopePieceIndex - 1;
8484
}
8585

8686
break;
@@ -90,7 +90,7 @@ function getScopeMatchResults(nodeScopeList, scopeNodeScopeList) {
9090

9191
var isFurther = foundIndex >= pieceOffset;
9292

93-
currentPieceOffset = foundIndex+1;
93+
currentPieceOffset = foundIndex + 1;
9494

9595
// Mimicing a `[].every` with a for-loop
9696
wasEveryPieceFound = wasEveryPieceFound && isFurther;
@@ -105,7 +105,7 @@ function getScopeMatchResults(nodeScopeList, scopeNodeScopeList) {
105105

106106
return {
107107
doesMatchScope: doesMatchScope,
108-
nodeScopePieceIndex: currentPieceOffset-1,
108+
nodeScopePieceIndex: currentPieceOffset - 1,
109109
scopePieceIndex: scopePieceIndex
110110
};
111111
}
@@ -148,4 +148,4 @@ var isUnderScope = function(nodeScopeList, scopeNodeScopeList, /*optional*/ignor
148148

149149
isUnderScope.RE_PSEUDO_SELECTOR = RE_PSEUDO_SELECTOR;
150150

151-
module.exports = isUnderScope;
151+
module.exports = isUnderScope;

lib/resolve-decl.js

Lines changed: 66 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,72 @@ var isNodeUnderScope = require('./is-node-under-scope');
88
var findNodeAncestorWithSelector = require('./find-node-ancestor-with-selector');
99
var cloneSpliceParentOntoNodeWhen = require('./clone-splice-parent-onto-node-when');
1010

11+
12+
13+
function eachMapItemDependencyOfDecl(variablesUsedList, map, decl, cb) {
14+
// Now find any at-rule declarations that pertains to each rule
15+
// Loop through the variables used
16+
variablesUsedList.forEach(function(variableUsedName) {
17+
18+
// Find anything in the map that corresponds to that variable
19+
gatherVariableDependencies(variablesUsedList, map).deps.forEach(function(mapItem) {
20+
21+
var mimicDecl;
22+
if(mapItem.isUnderAtRule) {
23+
24+
// Get the inner-most selector of the at-rule scope variable declaration we are matching
25+
// 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
26+
var varDeclScopeList = generateScopeList(mapItem.parent, true);
27+
var innerMostAtRuleSelector = varDeclScopeList[0].slice(-1)[0];
28+
var nodeToSpliceParentOnto = findNodeAncestorWithSelector(innerMostAtRuleSelector, decl.parent);
29+
30+
// Splice on where the selector starts matching the selector inside at-rule
31+
// See: `test/fixtures/cascade-on-nested-rules.css`
32+
var varDeclAtRule = mapItem.parent.parent;
33+
mimicDecl = cloneSpliceParentOntoNodeWhen(decl, varDeclAtRule, function(ancestor) {
34+
return ancestor === nodeToSpliceParentOnto;
35+
});
36+
37+
38+
//console.log('amd og', generateScopeList(decl.parent, true));
39+
//console.log('amd', generateScopeList(mimicDecl.parent, true));
40+
//console.log(generateScopeList(mapItem.parent, true));
41+
//console.log('amd isNodeUnderScope', isNodeUnderScope(mimicDecl.parent, mapItem.parent), mapItem.decl.value);
42+
}
43+
// TODO: use regex from `isUnderScope`
44+
else if(isUnderScope.RE_PSEUDO_SELECTOR.test(mapItem.parent.selector)) {
45+
// Create a detached clone
46+
var ruleClone = decl.parent.clone().removeAll();
47+
ruleClone.parent = decl.parent.parent;
48+
49+
// Add the declaration to it
50+
mimicDecl = decl.clone();
51+
ruleClone.append(mimicDecl);
52+
53+
var lastPseudoSelectorMatches = mapItem.parent.selector.match(new RegExp(isUnderScope.RE_PSEUDO_SELECTOR.source + '$'));
54+
var lastPseudoSelector = lastPseudoSelectorMatches ? lastPseudoSelectorMatches[2] : '';
55+
56+
ruleClone.selector += lastPseudoSelector;
57+
}
58+
59+
// If it is under the proper scope,
60+
// we need to check because we are iterating over all map entries
61+
if(mimicDecl && isNodeUnderScope(mimicDecl, mapItem.parent, true)) {
62+
cb(mimicDecl, mapItem);
63+
}
64+
});
65+
});
66+
}
67+
68+
69+
70+
1171
// Resolve the decl with the computed value
1272
// Also add in any media queries that change the value as necessary
13-
function resolveDecl(decl, map, /*optional*/logResolveValueResult) {
73+
function resolveDecl(decl, map, /*optional*/shouldPreserve, /*optional*/logResolveValueResult) {
74+
shouldPreserve = shouldPreserve || false;
75+
76+
// Make it chainable
1477
var _logResolveValueResult = function(valueResults) {
1578
if(logResolveValueResult) {
1679
logResolveValueResult(valueResults);
@@ -23,7 +86,6 @@ function resolveDecl(decl, map, /*optional*/logResolveValueResult) {
2386

2487
// Grab the balue for this declarations
2588
var valueResults = _logResolveValueResult(resolveValue(decl, map));
26-
2789

2890

2991
// Resolve the cascade dependencies
@@ -74,72 +136,17 @@ function resolveDecl(decl, map, /*optional*/logResolveValueResult) {
74136

75137

76138
// If we are preserving var(...) usage and the value changed meaning it had some
77-
if(opts.preserve === true && decl.value !== valueResults.value) {
139+
if(shouldPreserve === true && decl.value !== valueResults.value) {
78140
decl.cloneAfter();
79141
}
80142

81143
// Set the new value after we are done dealing with at-rule stuff
82144
decl.value = valueResults.value;
83-
84145
}
85146

86147

87-
function eachMapItemDependencyOfDecl(variablesUsedList, map, decl, cb) {
88-
// Now find any at-rule declarations that pertains to each rule
89-
// Loop through the variables used
90-
variablesUsedList.forEach(function(variableUsedName) {
91-
92-
// Find anything in the map that corresponds to that variable
93-
gatherVariableDependencies(variablesUsedList, map).deps.forEach(function(mapItem) {
94-
95-
var mimicDecl;
96-
if(mapItem.isUnderAtRule) {
97-
98-
// Get the inner-most selector of the at-rule scope variable declaration we are matching
99-
// 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
100-
var varDeclScopeList = generateScopeList(mapItem.parent, true);
101-
var innerMostAtRuleSelector = varDeclScopeList[0].slice(-1)[0];
102-
var nodeToSpliceParentOnto = findNodeAncestorWithSelector(innerMostAtRuleSelector, decl.parent);
103-
104-
// Splice on where the selector starts matching the selector inside at-rule
105-
// See: `test/fixtures/cascade-on-nested-rules.css`
106-
var varDeclAtRule = mapItem.parent.parent;
107-
mimicDecl = cloneSpliceParentOntoNodeWhen(decl, varDeclAtRule, function(ancestor) {
108-
return ancestor === nodeToSpliceParentOnto;
109-
});
110-
111-
112-
//console.log('amd og', generateScopeList(decl.parent, true));
113-
//console.log('amd', generateScopeList(mimicDecl.parent, true));
114-
//console.log(generateScopeList(mapItem.parent, true));
115-
//console.log('amd isNodeUnderScope', isNodeUnderScope(mimicDecl.parent, mapItem.parent), mapItem.decl.value);
116-
}
117-
// TODO: use regex from `isUnderScope`
118-
else if(isUnderScope.RE_PSEUDO_SELECTOR.test(mapItem.parent.selector)) {
119-
// Create a detached clone
120-
var ruleClone = decl.parent.clone().removeAll();
121-
ruleClone.parent = decl.parent.parent;
122-
123-
// Add the declaration to it
124-
mimicDecl = decl.clone();
125-
ruleClone.append(mimicDecl);
126-
127-
var lastPseudoSelectorMatches = mapItem.parent.selector.match(new RegExp(isUnderScope.RE_PSEUDO_SELECTOR.source + '$'));
128-
var lastPseudoSelector = lastPseudoSelectorMatches ? lastPseudoSelectorMatches[2] : '';
129-
130-
ruleClone.selector += lastPseudoSelector;
131-
}
132-
133-
// If it is under the proper scope,
134-
// we need to check because we are iterating over all map entries
135-
if(mimicDecl && isNodeUnderScope(mimicDecl, mapItem.parent, true)) {
136-
cb(mimicDecl, mapItem);
137-
}
138-
});
139-
});
140-
}
141148

142149

143150

144151

145-
module.exports = resolveDecl;
152+
module.exports = resolveDecl;

0 commit comments

Comments
 (0)