Skip to content

Commit e7fb818

Browse files
committed
Fix subtraction expressions
closes #38
1 parent ef5ea6a commit e7fb818

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

src/__tests__/index.js

+21
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,24 @@ test(
303303
'calc(500px/2px)',
304304
'Cannot divide by "px", number expected'
305305
)
306+
307+
test(
308+
'should reduce substraction from zero',
309+
testFixture,
310+
'calc( 0 - 10px)',
311+
'-10px'
312+
)
313+
314+
test(
315+
'should reduce subtracted expression from zero',
316+
testFixture,
317+
'calc( 0 - calc(1px + 1em) )',
318+
'calc(-1px + -1em)'
319+
)
320+
321+
test(
322+
'should reduce nested expression',
323+
testFixture,
324+
'calc( (1em - calc( 10px + 1em)) / 2)',
325+
'-5px'
326+
)

src/lib/reducer.js

+24-6
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@ function convertMathExpression(node, precision) {
6262
return node
6363
}
6464

65+
function flip(operator) {
66+
return operator === '+' ? '-' : '+'
67+
}
68+
69+
function flipValue(node) {
70+
if (isValueType(node.type))
71+
node.value = -node.value
72+
else if (node.type == 'MathExpression') {
73+
node.left = flipValue(node.left)
74+
node.right = flipValue(node.right)
75+
}
76+
return node
77+
}
78+
6579
function reduceAddSubExpression(node, precision) {
6680
const {left, right, operator: op} = node
6781

@@ -77,6 +91,10 @@ function reduceAddSubExpression(node, precision) {
7791
if (left.value === 0 && op === "+")
7892
return right
7993

94+
// 0 - something => -something
95+
if (left.value === 0 && op === "-")
96+
return flipValue(right)
97+
8098
// value + value
8199
// value - value
82100
if (left.type === right.type && isValueType(left.type)) {
@@ -115,13 +133,13 @@ function reduceAddSubExpression(node, precision) {
115133
}
116134
// value + (something + value) => (value + value) + something
117135
// value + (something - value) => (value - value) + something
118-
// value - (something + value) => (value + value) - something
119-
// value - (something - value) => (value - value) - something
136+
// value - (something + value) => (value - value) - something
137+
// value - (something - value) => (value + value) - something
120138
else if (left.type === right.right.type) {
121139
node = Object.assign({ }, node)
122140
node.left = reduce({
123141
type: 'MathExpression',
124-
operator: right.operator,
142+
operator: op === '-' ? flip(right.operator) : right.operator,
125143
left: left,
126144
right: right.right
127145
}, precision)
@@ -183,7 +201,7 @@ function reduceAddSubExpression(node, precision) {
183201
return node
184202
}
185203

186-
function reduceDivisionExpression(node) {
204+
function reduceDivisionExpression(node, precision) {
187205
if (!isValueType(node.right.type))
188206
return node
189207

@@ -201,7 +219,7 @@ function reduceDivisionExpression(node) {
201219
) {
202220
node.left.left.value /= node.right.value
203221
node.left.right.value /= node.right.value
204-
return node.left
222+
return reduce(node.left, precision)
205223
}
206224
return node
207225
}
@@ -255,7 +273,7 @@ function reduceMathExpression(node, precision) {
255273
case "-":
256274
return reduceAddSubExpression(node, precision)
257275
case "/":
258-
return reduceDivisionExpression(node)
276+
return reduceDivisionExpression(node, precision)
259277
case "*":
260278
return reduceMultiplicationExpression(node)
261279
}

0 commit comments

Comments
 (0)