|
|
- "use strict";
-
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.default = void 0;
-
- var _convert = _interopRequireDefault(require("./convert"));
-
- 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) {
- return left.type === right.type && left.value === right.value;
- }
-
- function isValueType(type) {
- switch (type) {
- case 'LengthValue':
- case 'AngleValue':
- case 'TimeValue':
- case 'FrequencyValue':
- case 'ResolutionValue':
- case 'EmValue':
- case 'ExValue':
- case 'ChValue':
- case 'RemValue':
- case 'VhValue':
- case 'VwValue':
- case 'VminValue':
- case 'VmaxValue':
- case 'PercentageValue':
- case 'Value':
- return true;
- }
-
- return false;
- }
-
- 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) {
- 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);
- }
- return node;
- }
-
- 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
-
- if (right.value === 0) return left; // 0 + something => something
-
- if (left.value === 0 && op === "+") return right; // 0 - something => -something
-
- if (left.value === 0 && op === "-") return flipValue(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;
- } // 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);
- node.left = reduce({
- type: 'MathExpression',
- operator: op === '-' ? flip(right.operator) : right.operator,
- left: left,
- right: right.right
- }, precision);
- node.right = right.left;
- 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);
- }
- } // (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({
- type: 'MathExpression',
- operator: op,
- left: left.left,
- right: right
- }, 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);
-
- 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.value < 0) {
- node.right.value *= -1;
- node.operator = node.operator === '-' ? '+' : '-';
- }
-
- return reduce(node, precision);
- }
- }
-
- if (left.type === 'MathExpression' && right.type === 'MathExpression' && op === '-' && right.operator === '-') {
- node.right.operator = flip(node.right.operator);
- }
-
- return node;
- }
-
- 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.left.type)) {
- node.left.value /= node.right.value;
- return node.left;
- }
-
- return node;
- }
-
- function reduceMultiplicationExpression(node) {
- // (expr) * value
- if (node.left.type === 'MathExpression' && node.right.type === 'Value') {
- if (isValueType(node.left.left.type) && isValueType(node.left.right.type)) {
- node.left.left.value *= node.right.value;
- node.left.right.value *= node.right.value;
- return node.left;
- }
- } // 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;
- }
-
- return node;
- }
-
- function reduceMathExpression(node, precision) {
- node = convertMathExpression(node, precision);
-
- switch (node.operator) {
- case "+":
- case "-":
- return reduceAddSubExpression(node, precision);
-
- case "/":
- return reduceDivisionExpression(node, precision);
-
- case "*":
- return reduceMultiplicationExpression(node);
- }
-
- return node;
- }
-
- var _default = reduce;
- exports.default = _default;
- module.exports = exports.default;
|