Skip to content

Commit 0cd0b0b

Browse files
authored
Fix Parse error on custom property fallback (#68)
1 parent 0f6c532 commit 0cd0b0b

File tree

4 files changed

+51
-9
lines changed

4 files changed

+51
-9
lines changed

parser.jison

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
/* lexical grammar */
44
%lex
55
%%
6+
(--[0-9a-z-A-Z-]*) return 'CSS_CPROP';
67
\s+ /* skip whitespace */
78
"*" return 'MUL';
89
"/" return 'DIV';
@@ -38,11 +39,12 @@
3839
([0-9]+("."[0-9]*)?|"."[0-9]+)\b return 'NUMBER';
3940

4041
(calc) return 'NESTED_CALC';
41-
(var\([^\)]*\)) return 'CSS_VAR';
42+
(var) return 'CSS_VAR';
4243
([a-z]+) return 'PREFIX';
4344

4445
"(" return 'LPAREN';
4546
")" return 'RPAREN';
47+
"," return 'COMMA';
4648

4749
<<EOF>> return 'EOF';
4850

@@ -67,8 +69,8 @@ expression
6769
| math_expression MUL math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; }
6870
| math_expression DIV math_expression { $$ = { type: 'MathExpression', operator: $2, left: $1, right: $3 }; }
6971
| LPAREN math_expression RPAREN { $$ = $2; }
70-
| NESTED_CALC LPAREN math_expression RPAREN { $$ = $3; }
71-
| SUB PREFIX SUB NESTED_CALC LPAREN math_expression RPAREN { $$ = $6; }
72+
| NESTED_CALC LPAREN math_expression RPAREN { $$ = { type: 'Calc', value: $3 }; }
73+
| SUB PREFIX SUB NESTED_CALC LPAREN math_expression RPAREN { $$ = { type: 'Calc', value: $6, prefix: $2 }; }
7274
| css_variable { $$ = $1; }
7375
| css_value { $$ = $1; }
7476
| value { $$ = $1; }
@@ -80,7 +82,8 @@ expression
8082
;
8183

8284
css_variable
83-
: CSS_VAR { $$ = { type: 'CssVariable', value: $1 }; }
85+
: CSS_VAR LPAREN CSS_CPROP RPAREN { $$ = { type: 'CssVariable', value: $3 }; }
86+
| CSS_VAR LPAREN CSS_CPROP COMMA math_expression RPAREN { $$ = { type: 'CssVariable', value: $3, fallback: $5 }; }
8487
;
8588

8689
css_value

src/__tests__/index.js

+29
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,35 @@ test(
168168
'calc(var(--popupHeight) / 2)'
169169
)
170170

171+
test(
172+
'should ignore calc with css variables (7)',
173+
testFixture,
174+
'calc(var(--popupHeight, var(--defaultHeight, var(--height-150))) / 2)',
175+
'calc(var(--popupHeight, var(--defaultHeight, var(--height-150))) / 2)'
176+
)
177+
178+
test(
179+
'should ignore calc with css variables (8)',
180+
testFixture,
181+
'calc(var(--popupHeight, var(--defaultHeight, calc(100% - 50px))) / 2)',
182+
'calc(var(--popupHeight, var(--defaultHeight, calc(100% - 50px))) / 2)'
183+
)
184+
185+
test(
186+
'should ignore calc with css variables (9)',
187+
testFixture,
188+
'calc(var(--popupHeight, var(--defaultHeight, calc(100% - 50px + 25px))) / 2)',
189+
'calc(var(--popupHeight, var(--defaultHeight, calc(100% - 25px))) / 2)'
190+
)
191+
192+
test(
193+
'should ignore calc with css variables (10)',
194+
testFixture,
195+
'calc(var(--popupHeight, var(--defaultHeight, 150px)) / 2)',
196+
'calc(var(--popupHeight, var(--defaultHeight, 150px)) / 2)'
197+
)
198+
199+
171200
test(
172201
'should reduce calc with newline characters',
173202
testFixture,

src/lib/reducer.js

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import convert from './convert'
33
function reduce(node, precision) {
44
if (node.type === "MathExpression")
55
return reduceMathExpression(node, precision)
6+
if (node.type === "Calc")
7+
return reduce(node.value, precision)
68

79
return node
810
}

src/lib/stringifier.js

+13-5
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,30 @@ function stringify(node, prec) {
2828

2929
str += " " + node.operator + " "
3030

31-
if (right.type === 'MathExpression' && order[op] < order[right.operator])
31+
if (right.type === 'MathExpression' && order[op] < order[right.operator]) {
3232
str += "(" + stringify(right, prec) + ")"
33-
else if (right.type === 'MathExpression' && op === "-" && ["+", "-"].includes(right.operator)) {
33+
} else if (right.type === 'MathExpression' && op === "-" && ["+", "-"].includes(right.operator)) {
3434
// fix #52 : a-(b+c) = a-b-c
3535
right.operator = flip(right.operator);
3636
str += stringify(right, prec)
37-
}
38-
else
37+
} else {
3938
str += stringify(right, prec)
39+
}
4040

4141
return str
4242
}
4343
case "Value":
4444
return round(node.value, prec)
4545
case 'CssVariable':
46-
return node.value
46+
if (node.fallback) {
47+
return `var(${node.value}, ${stringify(node.fallback, prec, true)})`
48+
}
49+
return `var(${node.value})`
50+
case 'Calc':
51+
if (node.prefix) {
52+
return `-${node.prefix}-calc(${stringify(node.value, prec)})`;
53+
}
54+
return `calc(${stringify(node.value, prec)})`;
4755
default:
4856
return round(node.value, prec) + node.unit
4957
}

0 commit comments

Comments
 (0)