Skip to content

Commit

Permalink
fix: respect CSS var when reducing
Browse files Browse the repository at this point in the history
Fix cssnano/cssnano#1235

Preserve the parentheses around a math expression that contains
a var() function call, to guarantee that the expression value stays the same.

The CSS custom properties might contain an addition or
subtraction, so even distributing multiplication or division is not safe.
  • Loading branch information
ludofischer committed Jan 11, 2022
1 parent 3f2c424 commit 99d9fa5
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
25 changes: 19 additions & 6 deletions src/__tests__/index.js
Expand Up @@ -106,7 +106,7 @@ test(
'should reduce additions and subtractions (7)',
testValue(
'calc(0px - (24px - (var(--a) - var(--b)) / 2 + var(--c)))',
'calc(-24px + var(--a)/2 - var(--b)/2 - var(--c))'
'calc(-24px + (var(--a) - var(--b))/2 - var(--c))'
)
);

Expand All @@ -122,27 +122,27 @@ test(

test(
'should reduce multiplication',
testValue('calc(((var(--a) + 4px) * 2) * 2)', 'calc(var(--a)*2*2 + 16px)')
testValue('calc(((var(--a) + 4px) * 2) * 2)', 'calc((var(--a) + 4px)*2*2)')
);

test(
'should reduce multiplication before reducing additions',
testValue(
'calc(((var(--a) + 4px) * 2) * 2 + 4px)',
'calc(var(--a)*2*2 + 20px)'
'calc((var(--a) + 4px)*2*2 + 4px)'
)
);

test(
'should reduce division',
testValue('calc(((var(--a) + 4px) / 2) / 2)', 'calc(var(--a)/2/2 + 1px)')
testValue('calc(((var(--a) + 4px) / 2) / 2)', 'calc((var(--a) + 4px)/2/2)')
);

test(
'should reduce division before reducing additions',
testValue(
'calc(((var(--a) + 4px) / 2) / 2 + 4px)',
'calc(var(--a)/2/2 + 5px)'
'calc((var(--a) + 4px)/2/2 + 4px)'
)
);

Expand Down Expand Up @@ -750,7 +750,20 @@ test(
(var(--fluid-screen) - ((var(--fluid-min-width) / 16) * 1rem)) /
((var(--fluid-max-width) / 16) - (var(--fluid-min-width) / 16))
)`,
'calc((var(--fluid-screen) - var(--fluid-min-width)/16*1rem)/(var(--fluid-max-width)/16 - var(--fluid-min-width)/16))'
'calc((var(--fluid-screen) - ((var(--fluid-min-width)/16)*1rem))/(var(--fluid-max-width)/16 - var(--fluid-min-width)/16))'
)
);

test(
'should preserve division precedence (3)',
testValue('calc(1/(10/var(--dot-size)))', 'calc(1/(10/var(--dot-size)))')
);

test(
'should correctly preserve parentheses',
testValue(
'calc(1/((var(--a) - var(--b))/16))',
'calc(1/(var(--a) - var(--b))/16)'
)
);

Expand Down
12 changes: 11 additions & 1 deletion src/lib/reducer.js
Expand Up @@ -285,6 +285,16 @@ function convertNodesUnits(left, right, precision) {
}
}

/**
* @param {import('../parser').ParenthesizedExpression} node
*/
function includesNoCssProperties(node) {
return node.content.type !== 'Function' &&
(node.content.type !== 'MathExpression' ||
(node.content.right.type !== 'Function' &&
node.content.left.type !== 'Function')
);
}
/**
* @param {import('../parser').CalcNode} node
* @param {number} precision
Expand All @@ -309,7 +319,7 @@ function reduce(node, precision) {
}

if (node.type === 'ParenthesizedExpression') {
if (node.content.type !== 'Function') {
if (includesNoCssProperties(node)) {
return reduce(node.content, precision);
}
}
Expand Down

0 comments on commit 99d9fa5

Please sign in to comment.