Skip to content

Commit d134c16

Browse files
PoetroMadLittleMods
authored andcommitted
Fix algorithm to find balanced var() pairs
1 parent 8b458f7 commit d134c16

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

lib/resolve-value.js

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,45 @@ function toString(value) {
1414
return String(value);
1515
}
1616

17+
// Check for balanced `var(` and `)` pairs inside `value`, and return the 3 fragments:
18+
// `body` (inside), `pre` (before), `post` (after) of the found wrapper
19+
function balancedVar(value) {
20+
var match = balanced('(', ')', value)
21+
if (match) {
22+
// Check if it was prepended with var
23+
if (/(?:^|\s)var$/.test(match.pre)) {
24+
// Remove the var from the end of pre
25+
return {
26+
pre: match.pre.slice(0, -3),
27+
body: match.body,
28+
post: match.post
29+
}
30+
} else {
31+
// Check inside body
32+
var bodyMatch = balancedVar(match.body)
33+
if (bodyMatch) {
34+
// Reconstruct pre and post
35+
return {
36+
pre: match.pre + '(' + bodyMatch.pre,
37+
body: bodyMatch.body,
38+
post: bodyMatch.post + ')' + match.post
39+
}
40+
} else {
41+
// Check inside post
42+
var postMatch = balancedVar(match.post)
43+
if (postMatch) {
44+
// Reconstruct pre
45+
return {
46+
pre: match.pre + '(' + match.body + ')' + postMatch.pre,
47+
body: postMatch.body,
48+
post: postMatch.post
49+
}
50+
}
51+
}
52+
}
53+
}
54+
}
55+
1756
// Pass in a value string to parse/resolve and a map of available values
1857
// and we can figure out the final value
1958
//
@@ -34,7 +73,7 @@ var resolveValue = function(decl, map, /*optional*/ignorePseudoScope, /*internal
3473
// Create a temporary variable, storing resultantValue variable value
3574
var remainingVariableValue = resultantValue;
3675
// Use balanced lib to find var() declarations and store variable names
37-
while ((matchingVarDecl = balanced('var(', ')', remainingVariableValue))) {
76+
while ((matchingVarDecl = balancedVar(remainingVariableValue))) {
3877
// Split at the comma to find variable name and fallback value
3978
// There may be other commas in the values so this isn't necessarily just 2 pieces
4079
var variableFallbackSplitPieces = matchingVarDecl.body.split(',');
@@ -61,7 +100,7 @@ var resolveValue = function(decl, map, /*optional*/ignorePseudoScope, /*internal
61100
// var() = var( <custom-property-name> [, <any-value> ]? )
62101
// matches `name[, fallback]`, captures "name" and "fallback"
63102
// See: http://dev.w3.org/csswg/css-variables/#funcdef-var
64-
while ((matchingVarDecl = balanced('var(', ')', resultantValue))) {
103+
while ((matchingVarDecl = balancedVar(resultantValue))) {
65104
var matchingVarDeclMapItem = undefined;
66105

67106
// Split at the comma to find variable name and fallback value
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
:root {
2+
--box-shadow: 0px 2px 2px 0px #fff;
3+
}
4+
.box {
5+
box-shadow: var(--box-shadow, 0px 2px 8px 0px rgba(0, 0, 0, 0.5));
6+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.box {
2+
box-shadow: 0px 2px 2px 0px #fff;
3+
}

0 commit comments

Comments
 (0)