postcss-calc
Advanced tools
Comparing version
@@ -0,1 +1,16 @@ | ||
# 7.0.2 | ||
- Fixed: incorrect reduction of subtraction from zero ([#88](https://github.com/postcss/postcss-calc/issues/88)) | ||
- Fixed: doesn't remove calc for single function | ||
- Fixed: relax parser on unknown units ([#76](https://github.com/postcss/postcss-calc/issues/76)) | ||
- Fixed: handle numbers with exponen composed ([#83](https://github.com/postcss/postcss-calc/pull/83)) | ||
- Fixed: handle plus sign before value ([#79](https://github.com/postcss/postcss-calc/pull/79)) | ||
- Fixed: better handle precision for nested calc ([#75](https://github.com/postcss/postcss-calc/pull/75)) | ||
- Fixed: properly handle nested add and sub expression inside sub expression ([#64](https://github.com/postcss/postcss-calc/issues/64)) | ||
- Fixed: handle uppercase units and functions ([#71](https://github.com/postcss/postcss-calc/pull/71)) | ||
- Fixed: do not break `calc` with single var ([cssnano/cssnano#725](https://github.com/cssnano/cssnano/issues/725)) | ||
- Updated: `postcss` to 7.0.27 (patch) | ||
- Updated: `postcss-selector-parser` to 6.0.2 | ||
- Updated: `postcss-value-parser` to 4.0.2 | ||
# 7.0.1 | ||
@@ -2,0 +17,0 @@ |
@@ -25,5 +25,14 @@ "use strict"; | ||
var type = node.type; | ||
if (type === 'decl') (0, _transform.default)(node, "value", options, result); | ||
if (type === 'atrule' && options.mediaQueries) (0, _transform.default)(node, "params", options, result); | ||
if (type === 'rule' && options.selectors) (0, _transform.default)(node, "selector", options, result); | ||
if (type === 'decl') { | ||
(0, _transform.default)(node, "value", options, result); | ||
} | ||
if (type === 'atrule' && options.mediaQueries) { | ||
(0, _transform.default)(node, "params", options, result); | ||
} | ||
if (type === 'rule' && options.selectors) { | ||
(0, _transform.default)(node, "selector", options, result); | ||
} | ||
}); | ||
@@ -30,0 +39,0 @@ }; |
@@ -8,11 +8,6 @@ "use strict"; | ||
var _convert = _interopRequireDefault(require("./convert")); | ||
var _convertUnit = _interopRequireDefault(require("./convertUnit")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function reduce(node, precision) { | ||
if (node.type === "MathExpression") return reduceMathExpression(node, precision); | ||
return node; | ||
} | ||
function isEqual(left, right) { | ||
@@ -38,3 +33,3 @@ return left.type === right.type && left.value === right.value; | ||
case 'PercentageValue': | ||
case 'Value': | ||
case 'Number': | ||
return true; | ||
@@ -46,20 +41,2 @@ } | ||
function convertMathExpression(node, precision) { | ||
var nodes = (0, _convert.default)(node.left, node.right, precision); | ||
var left = reduce(nodes.left, precision); | ||
var right = reduce(nodes.right, precision); | ||
if (left.type === "MathExpression" && right.type === "MathExpression") { | ||
if (left.operator === '/' && right.operator === '*' || left.operator === '-' && right.operator === '+' || left.operator === '*' && right.operator === '/' || left.operator === '+' && right.operator === '-') { | ||
if (isEqual(left.right, right.right)) nodes = (0, _convert.default)(left.left, right.left, precision);else if (isEqual(left.right, right.left)) nodes = (0, _convert.default)(left.left, right.right, precision); | ||
left = reduce(nodes.left, precision); | ||
right = reduce(nodes.right, precision); | ||
} | ||
} | ||
node.left = left; | ||
node.right = right; | ||
return node; | ||
} | ||
function flip(operator) { | ||
@@ -70,6 +47,13 @@ return operator === '+' ? '-' : '+'; | ||
function flipValue(node) { | ||
if (isValueType(node.type)) node.value = -node.value;else if (node.type == 'MathExpression') { | ||
node.left = flipValue(node.left); | ||
node.right = flipValue(node.right); | ||
if (isValueType(node.type)) { | ||
node.value = -node.value; | ||
} else if (node.type === 'MathExpression') { | ||
if (node.operator === '*' || node.operator === '/') { | ||
node.left = flipValue(node.left); | ||
} else { | ||
node.left = flipValue(node.left); | ||
node.right = flipValue(node.right); | ||
} | ||
} | ||
return node; | ||
@@ -79,116 +63,155 @@ } | ||
function reduceAddSubExpression(node, precision) { | ||
var _node = node, | ||
left = _node.left, | ||
right = _node.right, | ||
op = _node.operator; | ||
if (left.type === 'Function' || right.type === 'Function') return node; // something + 0 => something | ||
// something + 0 => something | ||
// something - 0 => something | ||
if (isValueType(node.right.type) && node.right.value === 0) { | ||
return node.left; | ||
} // 0 + something => something | ||
if (right.value === 0) return left; // 0 + something => something | ||
if (left.value === 0 && op === "+") return right; // 0 - something => -something | ||
if (isValueType(node.left.type) && node.left.value === 0 && node.operator === "+") { | ||
return node.right; | ||
} // 0 - something => -something | ||
if (left.value === 0 && op === "-") return flipValue(right); // value + value | ||
if (isValueType(node.left.type) && node.left.value === 0 && node.operator === "-" && node.right.type !== "Function") { | ||
return flipValue(node.right); | ||
} // value + value | ||
// value - value | ||
if (left.type === right.type && isValueType(left.type)) { | ||
node = Object.assign({}, left); | ||
if (op === "+") node.value = left.value + right.value;else node.value = left.value - right.value; | ||
if (isValueType(node.left.type) && node.left.type === node.right.type) { | ||
var operator = node.operator; | ||
var _covertNodesUnits = covertNodesUnits(node.left, node.right, precision), | ||
left = _covertNodesUnits.left, | ||
right = _covertNodesUnits.right; | ||
if (operator === "+") { | ||
left.value += right.value; | ||
} else { | ||
left.value -= right.value; | ||
} | ||
return left; | ||
} // value <op> (expr) | ||
if (isValueType(left.type) && (right.operator === '+' || right.operator === '-') && right.type === 'MathExpression') { | ||
// value + (value + something) => (value + value) + something | ||
// value + (value - something) => (value + value) - something | ||
// value - (value + something) => (value - value) - something | ||
// value - (value - something) => (value - value) + something | ||
if (left.type === right.left.type) { | ||
node = Object.assign({}, node); | ||
node.left = reduce({ | ||
type: 'MathExpression', | ||
operator: op, | ||
left: left, | ||
right: right.left | ||
}, precision); | ||
node.right = right.right; | ||
node.operator = op === '-' ? flip(right.operator) : right.operator; | ||
return reduce(node, precision); | ||
} // value + (something + value) => (value + value) + something | ||
// value + (something - value) => (value - value) + something | ||
// value - (something + value) => (value - value) - something | ||
// value - (something - value) => (value + value) - something | ||
else if (left.type === right.right.type) { | ||
node = Object.assign({}, node); | ||
if (node.right.type === 'MathExpression' && (node.right.operator === '+' || node.right.operator === '-')) { | ||
// something - (something + something) => something - something - something | ||
// something - (something - something) => something - something + something | ||
if ((node.right.operator === '+' || node.right.operator === '-') && node.operator === '-') { | ||
node.right.operator = flip(node.right.operator); | ||
} | ||
if (isValueType(node.left.type)) { | ||
// value + (value + something) => value + something | ||
// value + (value - something) => value - something | ||
// value - (value + something) => value - something | ||
// value - (value - something) => value + something | ||
if (node.left.type === node.right.left.type) { | ||
var _left = node.left, | ||
_operator = node.operator, | ||
_right = node.right; | ||
node.left = reduce({ | ||
type: 'MathExpression', | ||
operator: op === '-' ? flip(right.operator) : right.operator, | ||
left: left, | ||
right: right.right | ||
}, precision); | ||
node.right = right.left; | ||
operator: _operator, | ||
left: _left, | ||
right: _right.left | ||
}); | ||
node.operator = _right.operator; | ||
node.right = _right.right; | ||
return reduce(node, precision); | ||
} // value - (something + something) => value - something - something | ||
else if (op === '-' && right.operator === '+') { | ||
node = Object.assign({}, node); | ||
node.right.operator = '-'; | ||
return reduce(node, precision); | ||
} | ||
} // something + (something + value) => dimension + something | ||
// something + (something - value) => dimension + something | ||
// something - (something + value) => dimension - something | ||
// something - (something - value) => dimension - something | ||
if (node.left.type === node.right.right.type) { | ||
var _left2 = node.left, | ||
_right2 = node.right; | ||
node.left = reduce({ | ||
type: 'MathExpression', | ||
operator: _right2.operator, | ||
left: _left2, | ||
right: _right2.right | ||
}); | ||
node.right = _right2.left; | ||
return reduce(node, precision); | ||
} | ||
} | ||
} // (expr) <op> value | ||
if (left.type === 'MathExpression' && (left.operator === '+' || left.operator === '-') && isValueType(right.type)) { | ||
// (value + something) + value => (value + value) + something | ||
// (value - something) + value => (value + value) - something | ||
// (value + something) - value => (value - value) + something | ||
// (value - something) - value => (value - value) - something | ||
if (right.type === left.left.type) { | ||
node = Object.assign({}, left); | ||
node.left = reduce({ | ||
if (node.left.type === 'MathExpression' && (node.left.operator === '+' || node.left.operator === '-') && isValueType(node.right.type)) { | ||
// (value + something) + value => value + something | ||
// (value - something) + value => value - something | ||
// (value + something) - value => value + something | ||
// (value - something) - value => value - something | ||
if (node.right.type === node.left.left.type) { | ||
var _left3 = node.left, | ||
_operator2 = node.operator, | ||
_right3 = node.right; | ||
_left3.left = reduce({ | ||
type: 'MathExpression', | ||
operator: op, | ||
left: left.left, | ||
right: right | ||
operator: _operator2, | ||
left: _left3.left, | ||
right: _right3 | ||
}, precision); | ||
return reduce(node, precision); | ||
} // (something + value) + value => something + (value + value) | ||
// (something - value1) + value2 => something - (value2 - value1) | ||
// (something + value) - value => something + (value - value) | ||
// (something - value) - value => something - (value + value) | ||
else if (right.type === left.right.type) { | ||
node = Object.assign({}, left); | ||
return reduce(_left3, precision); | ||
} // (something + dimension) + dimension => something + dimension | ||
// (something - dimension) + dimension => something - dimension | ||
// (something + dimension) - dimension => something + dimension | ||
// (something - dimension) - dimension => something - dimension | ||
if (left.operator === '-') { | ||
node.right = reduce({ | ||
type: 'MathExpression', | ||
operator: flip(op), | ||
left: left.right, | ||
right: right | ||
}, precision); | ||
if (node.right.value && node.right.value < 0) { | ||
node.right.value = Math.abs(node.right.value); | ||
node.operator = '+'; | ||
} else { | ||
node.operator = left.operator; | ||
} | ||
} else { | ||
node.right = reduce({ | ||
type: 'MathExpression', | ||
operator: op, | ||
left: left.right, | ||
right: right | ||
}, precision); | ||
} | ||
if (node.right.type === node.left.right.type) { | ||
var _left4 = node.left, | ||
_operator3 = node.operator, | ||
_right4 = node.right; | ||
if (node.right.value < 0) { | ||
node.right.value *= -1; | ||
node.operator = node.operator === '-' ? '+' : '-'; | ||
} | ||
if (_left4.operator === '-') { | ||
_left4.operator = _operator3 === '-' ? '-' : '+'; | ||
_left4.right = reduce({ | ||
type: 'MathExpression', | ||
operator: _operator3 === '-' ? '+' : '-', | ||
left: _right4, | ||
right: _left4.right | ||
}, precision); | ||
} else { | ||
_left4.right = reduce({ | ||
type: 'MathExpression', | ||
operator: _operator3, | ||
left: _left4.right, | ||
right: _right4 | ||
}, precision); | ||
} | ||
return reduce(node, precision); | ||
if (_left4.right.value < 0) { | ||
_left4.right.value *= -1; | ||
_left4.operator = _left4.operator === '-' ? '+' : '-'; | ||
} | ||
} | ||
if (left.type === 'MathExpression' && right.type === 'MathExpression' && op === '-' && right.operator === '-') { | ||
node.right.operator = flip(node.right.operator); | ||
_left4.parenthesized = node.parenthesized; | ||
return reduce(_left4, precision); | ||
} | ||
} // (expr) + (expr) => number | ||
// (expr) - (expr) => number | ||
if (node.right.type === 'MathExpression' && node.left.type === 'MathExpression') { | ||
if (isEqual(node.left.right, node.right.right)) { | ||
var newNodes = covertNodesUnits(node.left.left, node.right.left, precision); | ||
node.left = newNodes.left; | ||
node.right = newNodes.right; | ||
return reduce(node); | ||
} | ||
if (isEqual(node.left.right, node.right.left)) { | ||
var _newNodes = covertNodesUnits(node.left.left, node.right.right, precision); | ||
node.left = _newNodes.left; | ||
node.right = _newNodes.right; | ||
return reduce(node); | ||
} | ||
} | ||
@@ -200,6 +223,15 @@ | ||
function reduceDivisionExpression(node) { | ||
if (!isValueType(node.right.type)) return node; | ||
if (node.right.type !== 'Value') throw new Error(`Cannot divide by "${node.right.unit}", number expected`); | ||
if (node.right.value === 0) throw new Error('Cannot divide by zero'); // something / value | ||
if (!isValueType(node.right.type)) { | ||
return node; | ||
} | ||
if (node.right.type !== 'Number') { | ||
throw new Error(`Cannot divide by "${node.right.unit}", number expected`); | ||
} | ||
if (node.right.value === 0) { | ||
throw new Error('Cannot divide by zero'); | ||
} // something / value | ||
if (isValueType(node.left.type)) { | ||
@@ -214,4 +246,4 @@ node.left.value /= node.right.value; | ||
function reduceMultiplicationExpression(node) { | ||
// (expr) * value | ||
if (node.left.type === 'MathExpression' && node.right.type === 'Value') { | ||
// (expr) * number | ||
if (node.left.type === 'MathExpression' && node.right.type === 'Number') { | ||
if (isValueType(node.left.left.type) && isValueType(node.left.right.type)) { | ||
@@ -222,35 +254,75 @@ node.left.left.value *= node.right.value; | ||
} | ||
} // something * value | ||
else if (isValueType(node.left.type) && node.right.type === 'Value') { | ||
node.left.value *= node.right.value; | ||
return node.left; | ||
} // value * (expr) | ||
else if (node.left.type === 'Value' && node.right.type === 'MathExpression') { | ||
if (isValueType(node.right.left.type) && isValueType(node.right.right.type)) { | ||
node.right.left.value *= node.left.value; | ||
node.right.right.value *= node.left.value; | ||
return node.right; | ||
} | ||
} // value * something | ||
else if (node.left.type === 'Value' && isValueType(node.right.type)) { | ||
node.right.value *= node.left.value; | ||
return node.right; | ||
} | ||
} // something * number | ||
if (isValueType(node.left.type) && node.right.type === 'Number') { | ||
node.left.value *= node.right.value; | ||
return node.left; | ||
} // number * (expr) | ||
if (node.left.type === 'Number' && node.right.type === 'MathExpression') { | ||
if (isValueType(node.right.left.type) && isValueType(node.right.right.type)) { | ||
node.right.left.value *= node.left.value; | ||
node.right.right.value *= node.left.value; | ||
return node.right; | ||
} | ||
} // number * something | ||
if (node.left.type === 'Number' && isValueType(node.right.type)) { | ||
node.right.value *= node.left.value; | ||
return node.right; | ||
} | ||
return node; | ||
} | ||
function reduceMathExpression(node, precision) { | ||
node = convertMathExpression(node, precision); | ||
function covertNodesUnits(left, right, precision) { | ||
switch (left.type) { | ||
case 'LengthValue': | ||
case 'AngleValue': | ||
case 'TimeValue': | ||
case 'FrequencyValue': | ||
case 'ResolutionValue': | ||
if (right.type === left.type && right.unit && left.unit) { | ||
var converted = (0, _convertUnit.default)(right.value, right.unit, left.unit, precision); | ||
right = { | ||
type: left.type, | ||
value: converted, | ||
unit: left.unit | ||
}; | ||
} | ||
switch (node.operator) { | ||
case "+": | ||
case "-": | ||
return reduceAddSubExpression(node, precision); | ||
return { | ||
left, | ||
right | ||
}; | ||
case "/": | ||
return reduceDivisionExpression(node, precision); | ||
default: | ||
return { | ||
left, | ||
right | ||
}; | ||
} | ||
} | ||
case "*": | ||
return reduceMultiplicationExpression(node); | ||
function reduce(node, precision) { | ||
if (node.type === "MathExpression") { | ||
node.left = reduce(node.left, precision); | ||
node.right = reduce(node.right, precision); | ||
switch (node.operator) { | ||
case "+": | ||
case "-": | ||
return reduceAddSubExpression(node, precision); | ||
case "/": | ||
return reduceDivisionExpression(node, precision); | ||
case "*": | ||
return reduceMultiplicationExpression(node, precision); | ||
} | ||
return node; | ||
} | ||
@@ -257,0 +329,0 @@ |
@@ -31,9 +31,21 @@ "use strict"; | ||
var str = ""; | ||
if (left.type === 'MathExpression' && order[op] < order[left.operator]) str += `(${stringify(left, prec)})`;else str += stringify(left, prec); | ||
if (left.type === 'MathExpression' && order[op] < order[left.operator]) { | ||
str += `(${stringify(left, prec)})`; | ||
} else { | ||
str += stringify(left, prec); | ||
} | ||
str += order[op] ? ` ${node.operator} ` : node.operator; | ||
if (right.type === 'MathExpression' && order[op] < order[right.operator]) str += `(${stringify(right, prec)})`;else str += stringify(right, prec); | ||
if (right.type === 'MathExpression' && order[op] < order[right.operator]) { | ||
str += `(${stringify(right, prec)})`; | ||
} else { | ||
str += stringify(right, prec); | ||
} | ||
return str; | ||
} | ||
case "Value": | ||
case 'Number': | ||
return round(node.value, prec); | ||
@@ -51,4 +63,5 @@ | ||
var str = stringify(node, options.precision); | ||
var shouldPrintCalc = node.type === "MathExpression" || node.type === "Function"; | ||
if (node.type === "MathExpression") { | ||
if (shouldPrintCalc) { | ||
// if calc expression couldn't be resolved to a single value, re-wrap it as | ||
@@ -55,0 +68,0 @@ // a calc() |
@@ -26,4 +26,7 @@ "use strict"; | ||
// skip anything which isn't a calc() function | ||
if (node.type !== 'function' || !MATCH_CALC.test(node.value)) return node; // stringify calc expression and produce an AST | ||
if (node.type !== 'function' || !MATCH_CALC.test(node.value)) { | ||
return node; | ||
} // stringify calc expression and produce an AST | ||
var contents = _postcssValueParser.default.stringify(node.nodes); | ||
@@ -35,7 +38,8 @@ | ||
var reducedAst = (0, _reducer.default)(ast, options.precision, item); // stringify AST and write it back | ||
var reducedAst = (0, _reducer.default)(ast, options.precision); // stringify AST and write it back | ||
node.type = 'word'; | ||
node.value = (0, _stringifier.default)(node.value, reducedAst, value, options, result, item); | ||
}, true).toString(); | ||
return false; | ||
}).toString(); | ||
} | ||
@@ -54,3 +58,6 @@ | ||
if (node.type === 'tag') node.value = transformValue(node.value, options, result, item); | ||
if (node.type === 'tag') { | ||
node.value = transformValue(node.value, options, result, item); | ||
} | ||
return; | ||
@@ -71,3 +78,5 @@ }); | ||
node.parent.insertBefore(node, clone); | ||
} else node[property] = value; | ||
} else { | ||
node[property] = value; | ||
} | ||
}; | ||
@@ -74,0 +83,0 @@ |
{ | ||
"name": "postcss-calc", | ||
"version": "7.0.1", | ||
"version": "7.0.2", | ||
"description": "PostCSS plugin to reduce calc()", | ||
@@ -20,3 +20,3 @@ "keywords": [ | ||
"build": "del-cli dist && cross-env BABEL_ENV=publish babel src --out-dir dist --ignore src/__tests__/**/*.js && jison src/parser.jison -o dist/parser.js", | ||
"pretest": "eslint src && npm run build", | ||
"pretest": "npm run build && eslint src", | ||
"test": "ava" | ||
@@ -29,3 +29,6 @@ }, | ||
"parser": "babel-eslint", | ||
"extends": "eslint-config-i-am-meticulous" | ||
"extends": "eslint-config-i-am-meticulous", | ||
"rules": { | ||
"curly": "error" | ||
} | ||
}, | ||
@@ -38,3 +41,3 @@ "devDependencies": { | ||
"@babel/register": "^7.0.0", | ||
"ava": "^1.0.0-beta.8", | ||
"ava": "^1.4.1", | ||
"babel-eslint": "^10.0.1", | ||
@@ -51,6 +54,5 @@ "babel-plugin-add-module-exports": "^1.0.0", | ||
"dependencies": { | ||
"css-unit-converter": "^1.1.1", | ||
"postcss": "^7.0.5", | ||
"postcss-selector-parser": "^5.0.0-rc.4", | ||
"postcss-value-parser": "^3.3.1" | ||
"postcss": "^7.0.27", | ||
"postcss-selector-parser": "^6.0.2", | ||
"postcss-value-parser": "^4.0.2" | ||
}, | ||
@@ -57,0 +59,0 @@ "ava": { |
Sorry, the diff of this file is too big to display
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
151473
4.17%3
-25%3737
6.44%0
-100%+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated