postcss-calc 7.0.4 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +43 -21
- package/dist/lib/convertUnit.js +15 -5
- package/dist/lib/reducer.js +245 -232
- package/dist/lib/stringifier.js +32 -10
- package/dist/lib/transform.js +54 -16
- package/package.json +29 -31
- package/types/index.d.ts +30 -0
- package/types/lib/convertUnit.d.ts +8 -0
- package/types/lib/reducer.d.ts +10 -0
- package/types/lib/stringifier.d.ts +14 -0
- package/types/lib/transform.d.ts +6 -0
- package/CHANGELOG.md +0 -118
package/dist/index.js
CHANGED
|
@@ -5,38 +5,60 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
var _postcss = require("postcss");
|
|
9
|
-
|
|
10
8
|
var _transform = _interopRequireDefault(require("./lib/transform"));
|
|
11
9
|
|
|
12
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {{precision?: number | false,
|
|
14
|
+
* preserve?: boolean,
|
|
15
|
+
* warnWhenCannotResolve?: boolean,
|
|
16
|
+
* mediaQueries?: boolean,
|
|
17
|
+
* selectors?: boolean}} PostCssCalcOptions
|
|
18
|
+
*
|
|
19
|
+
* @param {PostCssCalcOptions} opts
|
|
20
|
+
*/
|
|
21
|
+
function pluginCreator(opts) {
|
|
22
|
+
const options = Object.assign({
|
|
16
23
|
precision: 5,
|
|
17
24
|
preserve: false,
|
|
18
25
|
warnWhenCannotResolve: false,
|
|
19
26
|
mediaQueries: false,
|
|
20
27
|
selectors: false
|
|
21
28
|
}, opts);
|
|
22
|
-
return
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
return {
|
|
30
|
+
postcssPlugin: 'postcss-calc',
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {import('postcss').Root} css
|
|
34
|
+
* @param {{result: import('postcss').Result}} helpers
|
|
35
|
+
*/
|
|
36
|
+
OnceExit(css, {
|
|
37
|
+
result
|
|
38
|
+
}) {
|
|
39
|
+
css.walk(node => {
|
|
40
|
+
const {
|
|
41
|
+
type
|
|
42
|
+
} = node;
|
|
43
|
+
|
|
44
|
+
if (type === 'decl') {
|
|
45
|
+
(0, _transform.default)(node, "value", options, result);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (type === 'atrule' && options.mediaQueries) {
|
|
49
|
+
(0, _transform.default)(node, "params", options, result);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (type === 'rule' && options.selectors) {
|
|
53
|
+
(0, _transform.default)(node, "selector", options, result);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
38
58
|
};
|
|
39
|
-
}
|
|
59
|
+
}
|
|
40
60
|
|
|
61
|
+
pluginCreator.postcss = true;
|
|
62
|
+
var _default = pluginCreator;
|
|
41
63
|
exports.default = _default;
|
|
42
64
|
module.exports = exports.default;
|
package/dist/lib/convertUnit.js
CHANGED
|
@@ -4,7 +4,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @type {{[key:string]: {[key:string]: number}}}
|
|
10
|
+
*/
|
|
11
|
+
const conversions = {
|
|
8
12
|
// Absolute length units
|
|
9
13
|
'px': {
|
|
10
14
|
'px': 1,
|
|
@@ -129,10 +133,16 @@ var conversions = {
|
|
|
129
133
|
'dppx': 1
|
|
130
134
|
}
|
|
131
135
|
};
|
|
136
|
+
/**
|
|
137
|
+
* @param {number} value
|
|
138
|
+
* @param {string} sourceUnit
|
|
139
|
+
* @param {string} targetUnit
|
|
140
|
+
* @param {number|false} precision
|
|
141
|
+
*/
|
|
132
142
|
|
|
133
143
|
function convertUnit(value, sourceUnit, targetUnit, precision) {
|
|
134
|
-
|
|
135
|
-
|
|
144
|
+
const sourceUnitNormalized = sourceUnit.toLowerCase();
|
|
145
|
+
const targetUnitNormalized = targetUnit.toLowerCase();
|
|
136
146
|
|
|
137
147
|
if (!conversions[targetUnitNormalized]) {
|
|
138
148
|
throw new Error("Cannot convert to " + targetUnit);
|
|
@@ -142,10 +152,10 @@ function convertUnit(value, sourceUnit, targetUnit, precision) {
|
|
|
142
152
|
throw new Error("Cannot convert from " + sourceUnit + " to " + targetUnit);
|
|
143
153
|
}
|
|
144
154
|
|
|
145
|
-
|
|
155
|
+
const converted = conversions[targetUnitNormalized][sourceUnitNormalized] * value;
|
|
146
156
|
|
|
147
157
|
if (precision !== false) {
|
|
148
|
-
precision = Math.pow(10,
|
|
158
|
+
precision = Math.pow(10, Math.ceil(precision) || 5);
|
|
149
159
|
return Math.round(converted * precision) / precision;
|
|
150
160
|
}
|
|
151
161
|
|
package/dist/lib/reducer.js
CHANGED
|
@@ -9,12 +9,12 @@ var _convertUnit = _interopRequireDefault(require("./convertUnit"));
|
|
|
9
9
|
|
|
10
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function isValueType(
|
|
17
|
-
switch (type) {
|
|
12
|
+
/**
|
|
13
|
+
* @param {import('../parser').CalcNode} node
|
|
14
|
+
* @return {node is import('../parser').ValueExpression}
|
|
15
|
+
*/
|
|
16
|
+
function isValueType(node) {
|
|
17
|
+
switch (node.type) {
|
|
18
18
|
case 'LengthValue':
|
|
19
19
|
case 'AngleValue':
|
|
20
20
|
case 'TimeValue':
|
|
@@ -35,213 +35,168 @@ function isValueType(type) {
|
|
|
35
35
|
|
|
36
36
|
return false;
|
|
37
37
|
}
|
|
38
|
+
/** @param {'-'|'+'} operator */
|
|
39
|
+
|
|
38
40
|
|
|
39
41
|
function flip(operator) {
|
|
40
42
|
return operator === '+' ? '-' : '+';
|
|
41
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* @param {string} operator
|
|
46
|
+
* @returns {operator is '+'|'-'}
|
|
47
|
+
*/
|
|
42
48
|
|
|
43
|
-
function flipValue(node) {
|
|
44
|
-
if (isValueType(node.type)) {
|
|
45
|
-
node.value = -node.value;
|
|
46
|
-
} else if (node.type === 'MathExpression') {
|
|
47
|
-
if (node.operator === '*' || node.operator === '/') {
|
|
48
|
-
node.left = flipValue(node.left);
|
|
49
|
-
} else {
|
|
50
|
-
node.left = flipValue(node.left);
|
|
51
|
-
node.right = flipValue(node.right);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
49
|
|
|
55
|
-
|
|
50
|
+
function isAddSubOperator(operator) {
|
|
51
|
+
return operator === '+' || operator === '-';
|
|
56
52
|
}
|
|
53
|
+
/**
|
|
54
|
+
* @typedef {{preOperator: '+'|'-', node: import('../parser').CalcNode}} Collectible
|
|
55
|
+
*/
|
|
57
56
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
/**
|
|
58
|
+
* @param {'+'|'-'} preOperator
|
|
59
|
+
* @param {import('../parser').CalcNode} node
|
|
60
|
+
* @param {Collectible[]} collected
|
|
61
|
+
* @param {number} precision
|
|
62
|
+
*/
|
|
65
63
|
|
|
66
|
-
if (isValueType(node.left.type) && node.left.value === 0 && node.operator === "+") {
|
|
67
|
-
return node.right;
|
|
68
|
-
} // 0 - something => -something
|
|
69
64
|
|
|
65
|
+
function collectAddSubItems(preOperator, node, collected, precision) {
|
|
66
|
+
if (!isAddSubOperator(preOperator)) {
|
|
67
|
+
throw new Error(`invalid operator ${preOperator}`);
|
|
68
|
+
}
|
|
70
69
|
|
|
71
|
-
if (isValueType(node
|
|
72
|
-
|
|
73
|
-
} // value + value
|
|
74
|
-
// value - value
|
|
70
|
+
if (isValueType(node)) {
|
|
71
|
+
const itemIndex = collected.findIndex(x => x.node.type === node.type);
|
|
75
72
|
|
|
73
|
+
if (itemIndex >= 0) {
|
|
74
|
+
if (node.value === 0) {
|
|
75
|
+
return;
|
|
76
|
+
} // can cast because of the criterion used to find itemIndex
|
|
76
77
|
|
|
77
|
-
if (isValueType(node.left.type) && node.left.type === node.right.type) {
|
|
78
|
-
var operator = node.operator;
|
|
79
78
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
const otherValueNode =
|
|
80
|
+
/** @type import('../parser').ValueExpression*/
|
|
81
|
+
collected[itemIndex].node;
|
|
82
|
+
const {
|
|
83
|
+
left: reducedNode,
|
|
84
|
+
right: current
|
|
85
|
+
} = convertNodesUnits(otherValueNode, node, precision);
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
return left;
|
|
91
|
-
} // value <op> (expr)
|
|
87
|
+
if (collected[itemIndex].preOperator === '-') {
|
|
88
|
+
collected[itemIndex].preOperator = '+';
|
|
89
|
+
reducedNode.value *= -1;
|
|
90
|
+
}
|
|
92
91
|
|
|
92
|
+
if (preOperator === "+") {
|
|
93
|
+
reducedNode.value += current.value;
|
|
94
|
+
} else {
|
|
95
|
+
reducedNode.value -= current.value;
|
|
96
|
+
} // make sure reducedNode.value >= 0
|
|
93
97
|
|
|
94
|
-
if (node.right.type === 'MathExpression' && (node.right.operator === '+' || node.right.operator === '-')) {
|
|
95
|
-
// something - (something + something) => something - something - something
|
|
96
|
-
// something - (something - something) => something - something + something
|
|
97
|
-
if ((node.right.operator === '+' || node.right.operator === '-') && node.operator === '-') {
|
|
98
|
-
node.right.operator = flip(node.right.operator);
|
|
99
|
-
}
|
|
100
98
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
99
|
+
if (reducedNode.value >= 0) {
|
|
100
|
+
collected[itemIndex] = {
|
|
101
|
+
node: reducedNode,
|
|
102
|
+
preOperator: '+'
|
|
103
|
+
};
|
|
104
|
+
} else {
|
|
105
|
+
reducedNode.value *= -1;
|
|
106
|
+
collected[itemIndex] = {
|
|
107
|
+
node: reducedNode,
|
|
108
|
+
preOperator: '-'
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
// make sure node.value >= 0
|
|
113
|
+
if (node.value >= 0) {
|
|
114
|
+
collected.push({
|
|
115
|
+
node,
|
|
116
|
+
preOperator
|
|
115
117
|
});
|
|
116
|
-
|
|
117
|
-
node.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// something - (something + value) => dimension - something
|
|
122
|
-
// something - (something - value) => dimension - something
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (node.left.type === node.right.right.type) {
|
|
126
|
-
var _left2 = node.left,
|
|
127
|
-
_right2 = node.right;
|
|
128
|
-
node.left = reduce({
|
|
129
|
-
type: 'MathExpression',
|
|
130
|
-
operator: _right2.operator,
|
|
131
|
-
left: _left2,
|
|
132
|
-
right: _right2.right
|
|
118
|
+
} else {
|
|
119
|
+
node.value *= -1;
|
|
120
|
+
collected.push({
|
|
121
|
+
node,
|
|
122
|
+
preOperator: flip(preOperator)
|
|
133
123
|
});
|
|
134
|
-
node.right = _right2.left;
|
|
135
|
-
return reduce(node, precision);
|
|
136
124
|
}
|
|
137
125
|
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
_right3 = node.right;
|
|
150
|
-
_left3.left = reduce({
|
|
151
|
-
type: 'MathExpression',
|
|
152
|
-
operator: _operator2,
|
|
153
|
-
left: _left3.left,
|
|
154
|
-
right: _right3
|
|
155
|
-
}, precision);
|
|
156
|
-
return reduce(_left3, precision);
|
|
157
|
-
} // (something + dimension) + dimension => something + dimension
|
|
158
|
-
// (something - dimension) + dimension => something - dimension
|
|
159
|
-
// (something + dimension) - dimension => something + dimension
|
|
160
|
-
// (something - dimension) - dimension => something - dimension
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (node.right.type === node.left.right.type) {
|
|
164
|
-
var _left4 = node.left,
|
|
165
|
-
_operator3 = node.operator,
|
|
166
|
-
_right4 = node.right;
|
|
167
|
-
|
|
168
|
-
if (_left4.operator === '-') {
|
|
169
|
-
_left4.operator = _operator3 === '-' ? '-' : '+';
|
|
170
|
-
_left4.right = reduce({
|
|
171
|
-
type: 'MathExpression',
|
|
172
|
-
operator: _operator3 === '-' ? '+' : '-',
|
|
173
|
-
left: _right4,
|
|
174
|
-
right: _left4.right
|
|
175
|
-
}, precision);
|
|
126
|
+
} else if (node.type === "MathExpression") {
|
|
127
|
+
if (isAddSubOperator(node.operator)) {
|
|
128
|
+
collectAddSubItems(preOperator, node.left, collected, precision);
|
|
129
|
+
const collectRightOperator = preOperator === '-' ? flip(node.operator) : node.operator;
|
|
130
|
+
collectAddSubItems(collectRightOperator, node.right, collected, precision);
|
|
131
|
+
} else {
|
|
132
|
+
// * or /
|
|
133
|
+
const reducedNode = reduce(node, precision); // prevent infinite recursive call
|
|
134
|
+
|
|
135
|
+
if (reducedNode.type !== "MathExpression" || isAddSubOperator(reducedNode.operator)) {
|
|
136
|
+
collectAddSubItems(preOperator, reducedNode, collected, precision);
|
|
176
137
|
} else {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
right: _right4
|
|
182
|
-
}, precision);
|
|
138
|
+
collected.push({
|
|
139
|
+
node: reducedNode,
|
|
140
|
+
preOperator
|
|
141
|
+
});
|
|
183
142
|
}
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
collected.push({
|
|
146
|
+
node,
|
|
147
|
+
preOperator
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* @param {import('../parser').CalcNode} node
|
|
153
|
+
* @param {number} precision
|
|
154
|
+
*/
|
|
184
155
|
|
|
185
|
-
if (_left4.right.value < 0) {
|
|
186
|
-
_left4.right.value *= -1;
|
|
187
|
-
_left4.operator = _left4.operator === '-' ? '+' : '-';
|
|
188
|
-
}
|
|
189
156
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
var newNodes = covertNodesUnits(node.left.left, node.right.left, precision);
|
|
205
|
-
node.left = newNodes.left;
|
|
206
|
-
node.right = newNodes.right;
|
|
207
|
-
return reduce(node, precision);
|
|
208
|
-
} // (expr1 - something) + (something + expr2) => expr1 + expr2
|
|
209
|
-
// (expr1 + something) + (something - expr2) => expr1 + expr2
|
|
210
|
-
// (expr1 - something) - (something + expr2) => expr1 + expr2
|
|
211
|
-
// (expr1 + something) - (something - expr2) => expr1 + expr2
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
if (isEqual(node.left.right, node.right.left)) {
|
|
215
|
-
var _newNodes = covertNodesUnits(node.left.left, node.right.right, precision);
|
|
216
|
-
|
|
217
|
-
node.left = _newNodes.left;
|
|
218
|
-
node.right = _newNodes.right;
|
|
219
|
-
return reduce(node, precision);
|
|
220
|
-
} // (expr1 / something) + (expr2 / something) => (expr1 + expr2) / something
|
|
221
|
-
// (expr1 * something) + (expr2 * something) => (expr1 + expr2) * something
|
|
222
|
-
// (expr1 / something) - (expr2 / something) => (expr1 - expr2) / something
|
|
223
|
-
// (expr1 * something) - (expr2 * something) => (expr1 - expr2) * something
|
|
224
|
-
|
|
225
|
-
} else if ((node.left.operator === "/" || node.left.operator === "*") && node.left.operator === node.right.operator && isEqual(node.left.right, node.right.right)) {
|
|
226
|
-
return reduce({
|
|
227
|
-
type: "MathExpression",
|
|
228
|
-
operator: node.left.operator,
|
|
229
|
-
left: {
|
|
230
|
-
type: "MathExpression",
|
|
231
|
-
operator: node.operator,
|
|
232
|
-
left: node.left.left,
|
|
233
|
-
right: node.right.left
|
|
234
|
-
},
|
|
235
|
-
right: node.left.right
|
|
236
|
-
}, precision);
|
|
157
|
+
function reduceAddSubExpression(node, precision) {
|
|
158
|
+
/** @type Collectible[] */
|
|
159
|
+
const collected = [];
|
|
160
|
+
collectAddSubItems('+', node, collected, precision);
|
|
161
|
+
const withoutZeroItem = collected.filter(item => !(isValueType(item.node) && item.node.value === 0));
|
|
162
|
+
const firstNonZeroItem = withoutZeroItem[0]; // could be undefined
|
|
163
|
+
// prevent producing "calc(-var(--a))" or "calc()"
|
|
164
|
+
// which is invalid css
|
|
165
|
+
|
|
166
|
+
if (!firstNonZeroItem || firstNonZeroItem.preOperator === '-' && !isValueType(firstNonZeroItem.node)) {
|
|
167
|
+
const firstZeroItem = collected.find(item => isValueType(item.node) && item.node.value === 0);
|
|
168
|
+
|
|
169
|
+
if (firstZeroItem) {
|
|
170
|
+
withoutZeroItem.unshift(firstZeroItem);
|
|
237
171
|
}
|
|
172
|
+
} // make sure the preOperator of the first item is +
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
if (withoutZeroItem[0].preOperator === '-' && isValueType(withoutZeroItem[0].node)) {
|
|
176
|
+
withoutZeroItem[0].node.value *= -1;
|
|
177
|
+
withoutZeroItem[0].preOperator = '+';
|
|
238
178
|
}
|
|
239
179
|
|
|
240
|
-
|
|
180
|
+
let root = withoutZeroItem[0].node;
|
|
181
|
+
|
|
182
|
+
for (let i = 1; i < withoutZeroItem.length; i++) {
|
|
183
|
+
root = {
|
|
184
|
+
type: 'MathExpression',
|
|
185
|
+
operator: withoutZeroItem[i].preOperator,
|
|
186
|
+
left: root,
|
|
187
|
+
right: withoutZeroItem[i].node
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return root;
|
|
241
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* @param {import('../parser').MathExpression} node
|
|
195
|
+
*/
|
|
196
|
+
|
|
242
197
|
|
|
243
198
|
function reduceDivisionExpression(node) {
|
|
244
|
-
if (!isValueType(node.right
|
|
199
|
+
if (!isValueType(node.right)) {
|
|
245
200
|
return node;
|
|
246
201
|
}
|
|
247
202
|
|
|
@@ -249,54 +204,119 @@ function reduceDivisionExpression(node) {
|
|
|
249
204
|
throw new Error(`Cannot divide by "${node.right.unit}", number expected`);
|
|
250
205
|
}
|
|
251
206
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
207
|
+
return applyNumberDivision(node.left, node.right.value);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* apply (expr) / number
|
|
211
|
+
*
|
|
212
|
+
* @param {import('../parser').CalcNode} node
|
|
213
|
+
* @param {number} divisor
|
|
214
|
+
* @return {import('../parser').CalcNode}
|
|
215
|
+
*/
|
|
255
216
|
|
|
256
217
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
218
|
+
function applyNumberDivision(node, divisor) {
|
|
219
|
+
if (divisor === 0) {
|
|
220
|
+
throw new Error('Cannot divide by zero');
|
|
260
221
|
}
|
|
261
222
|
|
|
262
|
-
|
|
263
|
-
|
|
223
|
+
if (isValueType(node)) {
|
|
224
|
+
node.value /= divisor;
|
|
225
|
+
return node;
|
|
226
|
+
}
|
|
264
227
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
228
|
+
if (node.type === "MathExpression" && isAddSubOperator(node.operator)) {
|
|
229
|
+
// turn (a + b) / num into a/num + b/num
|
|
230
|
+
// is good for further reduction
|
|
231
|
+
// checkout the test case
|
|
232
|
+
// "should reduce division before reducing additions"
|
|
233
|
+
return {
|
|
234
|
+
type: "MathExpression",
|
|
235
|
+
operator: node.operator,
|
|
236
|
+
left: applyNumberDivision(node.left, divisor),
|
|
237
|
+
right: applyNumberDivision(node.right, divisor)
|
|
238
|
+
};
|
|
239
|
+
} // it is impossible to reduce it into a single value
|
|
240
|
+
// .e.g the node contains css variable
|
|
241
|
+
// so we just preserve the division and let browser do it
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
type: "MathExpression",
|
|
246
|
+
operator: '/',
|
|
247
|
+
left: node,
|
|
248
|
+
right: {
|
|
249
|
+
type: "Number",
|
|
250
|
+
value: divisor
|
|
272
251
|
}
|
|
273
|
-
}
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* @param {import('../parser').MathExpression} node
|
|
256
|
+
*/
|
|
274
257
|
|
|
275
258
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
259
|
+
function reduceMultiplicationExpression(node) {
|
|
260
|
+
// (expr) * number
|
|
261
|
+
if (node.right.type === 'Number') {
|
|
262
|
+
return applyNumberMultiplication(node.left, node.right.value);
|
|
279
263
|
} // number * (expr)
|
|
280
264
|
|
|
281
265
|
|
|
282
|
-
if (node.left.type === 'Number'
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
266
|
+
if (node.left.type === 'Number') {
|
|
267
|
+
return applyNumberMultiplication(node.right, node.left.value);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return node;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* apply (expr) * number
|
|
274
|
+
* @param {number} multiplier
|
|
275
|
+
* @param {import('../parser').CalcNode} node
|
|
276
|
+
* @return {import('../parser').CalcNode}
|
|
277
|
+
*/
|
|
289
278
|
|
|
290
279
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
280
|
+
function applyNumberMultiplication(node, multiplier) {
|
|
281
|
+
if (isValueType(node)) {
|
|
282
|
+
node.value *= multiplier;
|
|
283
|
+
return node;
|
|
294
284
|
}
|
|
295
285
|
|
|
296
|
-
|
|
286
|
+
if (node.type === "MathExpression" && isAddSubOperator(node.operator)) {
|
|
287
|
+
// turn (a + b) * num into a*num + b*num
|
|
288
|
+
// is good for further reduction
|
|
289
|
+
// checkout the test case
|
|
290
|
+
// "should reduce multiplication before reducing additions"
|
|
291
|
+
return {
|
|
292
|
+
type: "MathExpression",
|
|
293
|
+
operator: node.operator,
|
|
294
|
+
left: applyNumberMultiplication(node.left, multiplier),
|
|
295
|
+
right: applyNumberMultiplication(node.right, multiplier)
|
|
296
|
+
};
|
|
297
|
+
} // it is impossible to reduce it into a single value
|
|
298
|
+
// .e.g the node contains css variable
|
|
299
|
+
// so we just preserve the division and let browser do it
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
return {
|
|
303
|
+
type: "MathExpression",
|
|
304
|
+
operator: '*',
|
|
305
|
+
left: node,
|
|
306
|
+
right: {
|
|
307
|
+
type: "Number",
|
|
308
|
+
value: multiplier
|
|
309
|
+
}
|
|
310
|
+
};
|
|
297
311
|
}
|
|
312
|
+
/**
|
|
313
|
+
* @param {import('../parser').ValueExpression} left
|
|
314
|
+
* @param {import('../parser').ValueExpression} right
|
|
315
|
+
* @param {number} precision
|
|
316
|
+
*/
|
|
317
|
+
|
|
298
318
|
|
|
299
|
-
function
|
|
319
|
+
function convertNodesUnits(left, right, precision) {
|
|
300
320
|
switch (left.type) {
|
|
301
321
|
case 'LengthValue':
|
|
302
322
|
case 'AngleValue':
|
|
@@ -304,7 +324,7 @@ function covertNodesUnits(left, right, precision) {
|
|
|
304
324
|
case 'FrequencyValue':
|
|
305
325
|
case 'ResolutionValue':
|
|
306
326
|
if (right.type === left.type && right.unit && left.unit) {
|
|
307
|
-
|
|
327
|
+
const converted = (0, _convertUnit.default)(right.value, right.unit, left.unit, precision);
|
|
308
328
|
right = {
|
|
309
329
|
type: left.type,
|
|
310
330
|
value: converted,
|
|
@@ -324,22 +344,28 @@ function covertNodesUnits(left, right, precision) {
|
|
|
324
344
|
};
|
|
325
345
|
}
|
|
326
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* @param {import('../parser').CalcNode} node
|
|
349
|
+
* @param {number} precision
|
|
350
|
+
*/
|
|
351
|
+
|
|
327
352
|
|
|
328
353
|
function reduce(node, precision) {
|
|
329
354
|
if (node.type === "MathExpression") {
|
|
355
|
+
if (isAddSubOperator(node.operator)) {
|
|
356
|
+
// reduceAddSubExpression will call reduce recursively
|
|
357
|
+
return reduceAddSubExpression(node, precision);
|
|
358
|
+
}
|
|
359
|
+
|
|
330
360
|
node.left = reduce(node.left, precision);
|
|
331
361
|
node.right = reduce(node.right, precision);
|
|
332
362
|
|
|
333
363
|
switch (node.operator) {
|
|
334
|
-
case "+":
|
|
335
|
-
case "-":
|
|
336
|
-
return reduceAddSubExpression(node, precision);
|
|
337
|
-
|
|
338
364
|
case "/":
|
|
339
|
-
return reduceDivisionExpression(node
|
|
365
|
+
return reduceDivisionExpression(node);
|
|
340
366
|
|
|
341
367
|
case "*":
|
|
342
|
-
return reduceMultiplicationExpression(node
|
|
368
|
+
return reduceMultiplicationExpression(node);
|
|
343
369
|
}
|
|
344
370
|
|
|
345
371
|
return node;
|
|
@@ -350,17 +376,4 @@ function reduce(node, precision) {
|
|
|
350
376
|
|
|
351
377
|
var _default = reduce;
|
|
352
378
|
exports.default = _default;
|
|
353
|
-
|
|
354
|
-
function isCSSFunction(node) {
|
|
355
|
-
if (node.type === "Function") {
|
|
356
|
-
return true;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
if (node.type === "MathExpression") {
|
|
360
|
-
return isCSSFunction(node.left) || isCSSFunction(node.right);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
return false;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
379
|
module.exports = exports.default;
|
package/dist/lib/stringifier.js
CHANGED
|
@@ -4,30 +4,41 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = _default;
|
|
7
|
-
|
|
7
|
+
const order = {
|
|
8
8
|
"*": 0,
|
|
9
9
|
"/": 0,
|
|
10
10
|
"+": 1,
|
|
11
11
|
"-": 1
|
|
12
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* @param {number} value
|
|
15
|
+
* @param {number | false} prec
|
|
16
|
+
*/
|
|
13
17
|
|
|
14
18
|
function round(value, prec) {
|
|
15
19
|
if (prec !== false) {
|
|
16
|
-
|
|
20
|
+
const precision = Math.pow(10, prec);
|
|
17
21
|
return Math.round(value * precision) / precision;
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
return value;
|
|
21
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* @param {number | false} prec
|
|
28
|
+
* @param {import('../parser').CalcNode} node
|
|
29
|
+
*/
|
|
30
|
+
|
|
22
31
|
|
|
23
32
|
function stringify(node, prec) {
|
|
24
33
|
switch (node.type) {
|
|
25
34
|
case "MathExpression":
|
|
26
35
|
{
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
const {
|
|
37
|
+
left,
|
|
38
|
+
right,
|
|
39
|
+
operator: op
|
|
40
|
+
} = node;
|
|
41
|
+
let str = "";
|
|
31
42
|
|
|
32
43
|
if (left.type === 'MathExpression' && order[op] < order[left.operator]) {
|
|
33
44
|
str += `(${stringify(left, prec)})`;
|
|
@@ -47,19 +58,30 @@ function stringify(node, prec) {
|
|
|
47
58
|
}
|
|
48
59
|
|
|
49
60
|
case 'Number':
|
|
50
|
-
return round(node.value, prec);
|
|
61
|
+
return round(node.value, prec).toString();
|
|
51
62
|
|
|
52
63
|
case 'Function':
|
|
53
|
-
return node.value;
|
|
64
|
+
return node.value.toString();
|
|
54
65
|
|
|
55
66
|
default:
|
|
56
67
|
return round(node.value, prec) + node.unit;
|
|
57
68
|
}
|
|
58
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* @param {string} calc
|
|
72
|
+
* @param {import('../parser').CalcNode} node
|
|
73
|
+
* @param {string} originalValue
|
|
74
|
+
* @param {{precision: number | false, warnWhenCannotResolve: boolean}} options
|
|
75
|
+
* @param {import("postcss").Result} result
|
|
76
|
+
* @param {import("postcss").ChildNode} item
|
|
77
|
+
*
|
|
78
|
+
* @returns {string}
|
|
79
|
+
*/
|
|
80
|
+
|
|
59
81
|
|
|
60
82
|
function _default(calc, node, originalValue, options, result, item) {
|
|
61
|
-
|
|
62
|
-
|
|
83
|
+
let str = stringify(node, options.precision);
|
|
84
|
+
const shouldPrintCalc = node.type === "MathExpression" || node.type === "Function";
|
|
63
85
|
|
|
64
86
|
if (shouldPrintCalc) {
|
|
65
87
|
// if calc expression couldn't be resolved to a single value, re-wrap it as
|
package/dist/lib/transform.js
CHANGED
|
@@ -18,42 +18,56 @@ var _stringifier = _interopRequireDefault(require("./stringifier"));
|
|
|
18
18
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
19
|
|
|
20
20
|
// eslint-disable-next-line import/no-unresolved
|
|
21
|
-
|
|
21
|
+
const MATCH_CALC = /((?:-(moz|webkit)-)?calc)/i;
|
|
22
|
+
/**
|
|
23
|
+
* @param {string} value
|
|
24
|
+
* @param {{precision: number, warnWhenCannotResolve: boolean}} options
|
|
25
|
+
* @param {import("postcss").Result} result
|
|
26
|
+
* @param {import("postcss").ChildNode} item
|
|
27
|
+
*/
|
|
22
28
|
|
|
23
29
|
function transformValue(value, options, result, item) {
|
|
24
|
-
return (0, _postcssValueParser.default)(value).walk(
|
|
30
|
+
return (0, _postcssValueParser.default)(value).walk(node => {
|
|
25
31
|
// skip anything which isn't a calc() function
|
|
26
|
-
if (node.type !==
|
|
27
|
-
return
|
|
32
|
+
if (node.type !== "function" || !MATCH_CALC.test(node.value)) {
|
|
33
|
+
return;
|
|
28
34
|
} // stringify calc expression and produce an AST
|
|
29
35
|
|
|
30
36
|
|
|
31
|
-
|
|
37
|
+
const contents = _postcssValueParser.default.stringify(node.nodes);
|
|
32
38
|
|
|
33
|
-
|
|
39
|
+
const ast = _parser.parser.parse(contents); // reduce AST to its simplest form, that is, either to a single value
|
|
34
40
|
// or a simplified calc expression
|
|
35
41
|
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
const reducedAst = (0, _reducer.default)(ast, options.precision); // stringify AST and write it back
|
|
38
44
|
|
|
39
|
-
|
|
45
|
+
/** @type {valueParser.Node} */
|
|
46
|
+
node.type = "word";
|
|
40
47
|
node.value = (0, _stringifier.default)(node.value, reducedAst, value, options, result, item);
|
|
41
48
|
return false;
|
|
42
49
|
}).toString();
|
|
43
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* @param {import("postcss-selector-parser").Selectors} value
|
|
53
|
+
* @param {{precision: number, warnWhenCannotResolve: boolean}} options
|
|
54
|
+
* @param {import("postcss").Result} result
|
|
55
|
+
* @param {import("postcss").ChildNode} item
|
|
56
|
+
*/
|
|
57
|
+
|
|
44
58
|
|
|
45
59
|
function transformSelector(value, options, result, item) {
|
|
46
|
-
return (0, _postcssSelectorParser.default)(
|
|
47
|
-
selectors.walk(
|
|
60
|
+
return (0, _postcssSelectorParser.default)(selectors => {
|
|
61
|
+
selectors.walk(node => {
|
|
48
62
|
// attribute value
|
|
49
63
|
// e.g. the "calc(3*3)" part of "div[data-size="calc(3*3)"]"
|
|
50
|
-
if (node.type ===
|
|
64
|
+
if (node.type === "attribute" && node.value) {
|
|
51
65
|
node.setValue(transformValue(node.value, options, result, item));
|
|
52
66
|
} // tag value
|
|
53
67
|
// e.g. the "calc(3*3)" part of "div:nth-child(2n + calc(3*3))"
|
|
54
68
|
|
|
55
69
|
|
|
56
|
-
if (node.type ===
|
|
70
|
+
if (node.type === "tag") {
|
|
57
71
|
node.value = transformValue(node.value, options, result, item);
|
|
58
72
|
}
|
|
59
73
|
|
|
@@ -61,15 +75,39 @@ function transformSelector(value, options, result, item) {
|
|
|
61
75
|
});
|
|
62
76
|
}).processSync(value);
|
|
63
77
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
78
|
+
/**
|
|
79
|
+
* @param {any} node
|
|
80
|
+
* @param {{precision: number, preserve: boolean, warnWhenCannotResolve: boolean}} options
|
|
81
|
+
* @param {'value'|'params'|'selector'} property
|
|
82
|
+
* @param {import("postcss").Result} result
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
var _default = (node, property, options, result) => {
|
|
87
|
+
let value = node[property];
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
value = property === "selector" ? transformSelector(node[property], options, result, node) : transformValue(node[property], options, result, node);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (error instanceof Error) {
|
|
93
|
+
result.warn(error.message, {
|
|
94
|
+
node
|
|
95
|
+
});
|
|
96
|
+
} else {
|
|
97
|
+
result.warn('Error', {
|
|
98
|
+
node
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return;
|
|
103
|
+
} // if the preserve option is enabled and the value has changed, write the
|
|
67
104
|
// transformed value into a cloned node which is inserted before the current
|
|
68
105
|
// node, preserving the original value. Otherwise, overwrite the original
|
|
69
106
|
// value.
|
|
70
107
|
|
|
108
|
+
|
|
71
109
|
if (options.preserve && node[property] !== value) {
|
|
72
|
-
|
|
110
|
+
const clone = node.clone();
|
|
73
111
|
clone[property] = value;
|
|
74
112
|
node.parent.insertBefore(node, clone);
|
|
75
113
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "postcss-calc",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.2.0",
|
|
4
4
|
"description": "PostCSS plugin to reduce calc()",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css",
|
|
@@ -10,52 +10,50 @@
|
|
|
10
10
|
"calc"
|
|
11
11
|
],
|
|
12
12
|
"main": "dist/index.js",
|
|
13
|
+
"types": "types/index.d.ts",
|
|
13
14
|
"files": [
|
|
14
15
|
"dist",
|
|
16
|
+
"types",
|
|
15
17
|
"LICENSE"
|
|
16
18
|
],
|
|
17
|
-
"scripts": {
|
|
18
|
-
"prepublish": "npm run build",
|
|
19
|
-
"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",
|
|
20
|
-
"pretest": "npm run build && eslint src",
|
|
21
|
-
"test": "ava"
|
|
22
|
-
},
|
|
23
19
|
"author": "Andy Jansson",
|
|
24
20
|
"license": "MIT",
|
|
25
21
|
"repository": "https://github.com/postcss/postcss-calc.git",
|
|
26
22
|
"eslintConfig": {
|
|
27
|
-
"
|
|
28
|
-
|
|
23
|
+
"extends": [
|
|
24
|
+
"eslint:recommended",
|
|
25
|
+
"plugin:import/recommended"
|
|
26
|
+
],
|
|
29
27
|
"rules": {
|
|
30
28
|
"curly": "error"
|
|
31
29
|
}
|
|
32
30
|
},
|
|
33
31
|
"devDependencies": {
|
|
34
|
-
"@babel/cli": "^7.
|
|
35
|
-
"@babel/core": "^7.
|
|
36
|
-
"@babel/
|
|
37
|
-
"@babel/
|
|
38
|
-
"@babel/register": "^7.0.0",
|
|
39
|
-
"ava": "^1.4.1",
|
|
40
|
-
"babel-eslint": "^10.0.1",
|
|
32
|
+
"@babel/cli": "^7.16.0",
|
|
33
|
+
"@babel/core": "^7.16.5",
|
|
34
|
+
"@babel/plugin-transform-modules-commonjs": "^7.16.5",
|
|
35
|
+
"@babel/register": "^7.16.7",
|
|
41
36
|
"babel-plugin-add-module-exports": "^1.0.0",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
37
|
+
"eslint": "^8.5.0",
|
|
38
|
+
"eslint-plugin-import": "^2.25.3",
|
|
39
|
+
"jison-gho": "^0.6.1-216",
|
|
40
|
+
"postcss": "^8.2.2",
|
|
41
|
+
"rimraf": "^3.0.2",
|
|
42
|
+
"typescript": "^4.5.4",
|
|
43
|
+
"uvu": "^0.5.2"
|
|
49
44
|
},
|
|
50
45
|
"dependencies": {
|
|
51
|
-
"postcss": "^7.0.27",
|
|
52
46
|
"postcss-selector-parser": "^6.0.2",
|
|
53
47
|
"postcss-value-parser": "^4.0.2"
|
|
54
48
|
},
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"postcss": "^8.2.2"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "rimraf dist && babel src --out-dir dist --ignore src/__tests__/**/*.js && jison src/parser.jison -o dist/parser.js",
|
|
54
|
+
"lint": "eslint src && tsc",
|
|
55
|
+
"pretest": "pnpm run build",
|
|
56
|
+
"test": "uvu -r @babel/register src/__tests__"
|
|
57
|
+
},
|
|
58
|
+
"readme": "# PostCSS Calc [<img src=\"https://postcss.github.io/postcss/logo.svg\" alt=\"PostCSS\" width=\"90\" height=\"90\" align=\"right\">][PostCSS]\n\n[![NPM Version][npm-img]][npm-url]\n[![Build Status][cli-img]][cli-url]\n[![Support Chat][git-img]][git-url]\n\n[PostCSS Calc] lets you reduce `calc()` references whenever it's possible. This\ncan be particularly useful with the [PostCSS Custom Properties] plugin.\n\nWhen multiple units are mixed together in the same expression, the `calc()`\nstatement is left as is, to fallback to the [W3C calc() implementation].\n\n## Installation\n\n```bash\nnpm install postcss-calc\n```\n\n## Usage\n\n```js\n// dependencies\nvar fs = require(\"fs\")\nvar postcss = require(\"postcss\")\nvar calc = require(\"postcss-calc\")\n\n// css to be processed\nvar css = fs.readFileSync(\"input.css\", \"utf8\")\n\n// process css\nvar output = postcss()\n .use(calc())\n .process(css)\n .css\n```\n\n**Example** (with [PostCSS Custom Properties] enabled as well):\n\n```js\n// dependencies\nvar fs = require(\"fs\")\nvar postcss = require(\"postcss\")\nvar customProperties = require(\"postcss-custom-properties\")\nvar calc = require(\"postcss-calc\")\n\n// css to be processed\nvar css = fs.readFileSync(\"input.css\", \"utf8\")\n\n// process css\nvar output = postcss()\n .use(customProperties())\n .use(calc())\n .process(css)\n .css\n```\n\nUsing this `input.css`:\n\n```css\n:root {\n --main-font-size: 16px;\n}\n\nbody {\n font-size: var(--main-font-size);\n}\n\nh1 {\n font-size: calc(var(--main-font-size) * 2);\n height: calc(100px - 2em);\n margin-bottom: calc(\n var(--main-font-size)\n * 1.5\n )\n}\n```\n\nyou will get:\n\n```css\nbody {\n font-size: 16px\n}\n\nh1 {\n font-size: 32px;\n height: calc(100px - 2em);\n margin-bottom: 24px\n}\n```\n\nCheckout [tests] for more examples.\n\n### Options\n\n#### `precision` (default: `5`)\n\nAllow you to define the precision for decimal numbers.\n\n```js\nvar out = postcss()\n .use(calc({precision: 10}))\n .process(css)\n .css\n```\n\n#### `preserve` (default: `false`)\n\nAllow you to preserve calc() usage in output so browsers will handle decimal\nprecision themselves.\n\n```js\nvar out = postcss()\n .use(calc({preserve: true}))\n .process(css)\n .css\n```\n\n#### `warnWhenCannotResolve` (default: `false`)\n\nAdds warnings when calc() are not reduced to a single value.\n\n```js\nvar out = postcss()\n .use(calc({warnWhenCannotResolve: true}))\n .process(css)\n .css\n```\n\n#### `mediaQueries` (default: `false`)\n\nAllows calc() usage as part of media query declarations.\n\n```js\nvar out = postcss()\n .use(calc({mediaQueries: true}))\n .process(css)\n .css\n```\n\n#### `selectors` (default: `false`)\n\nAllows calc() usage as part of selectors.\n\n```js\nvar out = postcss()\n .use(calc({selectors: true}))\n .process(css)\n .css\n```\n\nExample:\n\n```css\ndiv[data-size=\"calc(3*3)\"] {\n width: 100px;\n}\n```\n\n---\n\n## Contributing\n\nWork on a branch, install dev-dependencies, respect coding style & run tests\nbefore submitting a bug fix or a feature.\n\n```bash\ngit clone git@github.com:postcss/postcss-calc.git\ngit checkout -b patch-1\nnpm install\nnpm test\n```\n\n## [Changelog](CHANGELOG.md)\n\n## [License](LICENSE)\n\n[cli-img]: https://img.shields.io/travis/postcss/postcss-calc/master.svg\n[cli-url]: https://travis-ci.org/postcss/postcss-calc\n[git-img]: https://img.shields.io/badge/support-chat-blue.svg\n[git-url]: https://gitter.im/postcss/postcss\n[npm-img]: https://img.shields.io/npm/v/postcss-calc.svg\n[npm-url]: https://www.npmjs.com/package/postcss-calc\n\n[PostCSS]: https://github.com/postcss\n[PostCSS Calc]: https://github.com/postcss/postcss-calc\n[PostCSS Custom Properties]: https://github.com/postcss/postcss-custom-properties\n[tests]: src/__tests__/index.js\n[W3C calc() implementation]: https://www.w3.org/TR/css3-values/#calc-notation\n"
|
|
59
|
+
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export default pluginCreator;
|
|
2
|
+
export type PostCssCalcOptions = {
|
|
3
|
+
precision?: number | false;
|
|
4
|
+
preserve?: boolean;
|
|
5
|
+
warnWhenCannotResolve?: boolean;
|
|
6
|
+
mediaQueries?: boolean;
|
|
7
|
+
selectors?: boolean;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {{precision?: number | false,
|
|
11
|
+
* preserve?: boolean,
|
|
12
|
+
* warnWhenCannotResolve?: boolean,
|
|
13
|
+
* mediaQueries?: boolean,
|
|
14
|
+
* selectors?: boolean}} PostCssCalcOptions
|
|
15
|
+
*
|
|
16
|
+
* @param {PostCssCalcOptions} opts
|
|
17
|
+
*/
|
|
18
|
+
declare function pluginCreator(opts: PostCssCalcOptions): {
|
|
19
|
+
postcssPlugin: string;
|
|
20
|
+
/**
|
|
21
|
+
* @param {import('postcss').Root} css
|
|
22
|
+
* @param {{result: import('postcss').Result}} helpers
|
|
23
|
+
*/
|
|
24
|
+
OnceExit(css: import('postcss').Root, { result }: {
|
|
25
|
+
result: import('postcss').Result;
|
|
26
|
+
}): void;
|
|
27
|
+
};
|
|
28
|
+
declare namespace pluginCreator {
|
|
29
|
+
const postcss: boolean;
|
|
30
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export default convertUnit;
|
|
2
|
+
/**
|
|
3
|
+
* @param {number} value
|
|
4
|
+
* @param {string} sourceUnit
|
|
5
|
+
* @param {string} targetUnit
|
|
6
|
+
* @param {number|false} precision
|
|
7
|
+
*/
|
|
8
|
+
declare function convertUnit(value: number, sourceUnit: string, targetUnit: string, precision: number | false): number;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export default reduce;
|
|
2
|
+
export type Collectible = {
|
|
3
|
+
preOperator: '+' | '-';
|
|
4
|
+
node: import('../parser').CalcNode;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* @param {import('../parser').CalcNode} node
|
|
8
|
+
* @param {number} precision
|
|
9
|
+
*/
|
|
10
|
+
declare function reduce(node: import('../parser').CalcNode, precision: number): import("../parser").MathExpression | import("../parser").DimensionExpression | import("../parser").NumberExpression | import("../parser").FunctionExpression;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string} calc
|
|
3
|
+
* @param {import('../parser').CalcNode} node
|
|
4
|
+
* @param {string} originalValue
|
|
5
|
+
* @param {{precision: number | false, warnWhenCannotResolve: boolean}} options
|
|
6
|
+
* @param {import("postcss").Result} result
|
|
7
|
+
* @param {import("postcss").ChildNode} item
|
|
8
|
+
*
|
|
9
|
+
* @returns {string}
|
|
10
|
+
*/
|
|
11
|
+
export default function _default(calc: string, node: import('../parser').CalcNode, originalValue: string, options: {
|
|
12
|
+
precision: number | false;
|
|
13
|
+
warnWhenCannotResolve: boolean;
|
|
14
|
+
}, result: import("postcss").Result, item: import("postcss").ChildNode): string;
|
package/CHANGELOG.md
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
# 7.0.4
|
|
2
|
-
|
|
3
|
-
- Fixed: strips away important factors from multiplications in calc() ([#107](https://github.com/postcss/postcss-calc/issues/107))
|
|
4
|
-
|
|
5
|
-
# 7.0.3
|
|
6
|
-
|
|
7
|
-
- Fixed: substracted css-variable from zero ([#111](https://github.com/postcss/postcss-calc/issues/111))
|
|
8
|
-
|
|
9
|
-
# 7.0.2
|
|
10
|
-
|
|
11
|
-
- Fixed: incorrect reduction of subtraction from zero ([#88](https://github.com/postcss/postcss-calc/issues/88))
|
|
12
|
-
- Fixed: doesn't remove calc for single function
|
|
13
|
-
- Fixed: relax parser on unknown units ([#76](https://github.com/postcss/postcss-calc/issues/76))
|
|
14
|
-
- Fixed: handle numbers with exponen composed ([#83](https://github.com/postcss/postcss-calc/pull/83))
|
|
15
|
-
- Fixed: handle plus sign before value ([#79](https://github.com/postcss/postcss-calc/pull/79))
|
|
16
|
-
- Fixed: better handle precision for nested calc ([#75](https://github.com/postcss/postcss-calc/pull/75))
|
|
17
|
-
- Fixed: properly handle nested add and sub expression inside sub expression ([#64](https://github.com/postcss/postcss-calc/issues/64))
|
|
18
|
-
- Fixed: handle uppercase units and functions ([#71](https://github.com/postcss/postcss-calc/pull/71))
|
|
19
|
-
- Fixed: do not break `calc` with single var ([cssnano/cssnano#725](https://github.com/cssnano/cssnano/issues/725))
|
|
20
|
-
- Updated: `postcss` to 7.0.27 (patch)
|
|
21
|
-
- Updated: `postcss-selector-parser` to 6.0.2
|
|
22
|
-
- Updated: `postcss-value-parser` to 4.0.2
|
|
23
|
-
|
|
24
|
-
# 7.0.1
|
|
25
|
-
|
|
26
|
-
- Updated: `postcss` to 7.0.2 (patch)
|
|
27
|
-
- Updated: `postcss-selector-parser` to 5.0.0-rc.4 (patch)
|
|
28
|
-
- Updated: `postcss-value-parser` to 3.3.1 (patch)
|
|
29
|
-
|
|
30
|
-
# 7.0.0
|
|
31
|
-
|
|
32
|
-
- Changed: Updated postcss-selector-parser to version 5.0.0-rc.3
|
|
33
|
-
- Changed: Dropped reduce-css-calc as a dependency
|
|
34
|
-
- Fixed: Support constant() and env() ([#42](https://github.com/postcss/postcss-calc/issues/42), [#48](https://github.com/postcss/postcss-calc/issues/48))
|
|
35
|
-
- Fixed: Support custom properties with "calc" in its name ([#50](https://github.com/postcss/postcss-calc/issues/50))
|
|
36
|
-
- Fixed: Remove unnecessary whitespace around `*` and `/` ([cssnano#625](https://github.com/cssnano/cssnano/issues/625))
|
|
37
|
-
- Fixed: Arithmetic bugs around subtraction ([#49](https://github.com/postcss/postcss-calc/issues/49))
|
|
38
|
-
- Fixed: Handling of nested calc statements ([reduce-css-calc#49](https://github.com/MoOx/reduce-css-calc/issues/49))
|
|
39
|
-
- Fixed: Bugs regarding complex calculations ([reduce-cs-calc#45](https://github.com/MoOx/reduce-css-calc/issues/45))
|
|
40
|
-
- Fixed: `100%` incorrectly being transformed to `1` ([reduce-css-calc#44](https://github.com/MoOx/reduce-css-calc/issues/44))
|
|
41
|
-
- Added: support for case-insensitive calc statements
|
|
42
|
-
|
|
43
|
-
# 6.0.2 - 2018-09-25
|
|
44
|
-
|
|
45
|
-
- Fixed: use PostCSS 7 (thanks to @douglasduteil)
|
|
46
|
-
|
|
47
|
-
# 6.0.1 - 2017-10-10
|
|
48
|
-
|
|
49
|
-
- Fixed: throwing error for attribute selectors without a value
|
|
50
|
-
|
|
51
|
-
# 6.0.0 - 2017-05-08
|
|
52
|
-
|
|
53
|
-
- Breaking: Updated PostCSS from v5.x to v6.x, and reduce-css-calc from v1.x
|
|
54
|
-
to v2.x (thanks to @andyjansson).
|
|
55
|
-
|
|
56
|
-
# 5.3.1 - 2016-08-22
|
|
57
|
-
|
|
58
|
-
- Fixed: avoid security issue related to ``reduce-css-calc@< 1.2.4``.
|
|
59
|
-
|
|
60
|
-
# 5.3.0 - 2016-07-11
|
|
61
|
-
|
|
62
|
-
- Added: support for selector transformation via `selectors` option.
|
|
63
|
-
([#29](https://github.com/postcss/postcss-calc/pull/29) - @uniquegestaltung)
|
|
64
|
-
|
|
65
|
-
# 5.2.1 - 2016-04-10
|
|
66
|
-
|
|
67
|
-
- Fixed: support for multiline value
|
|
68
|
-
([#27](https://github.com/postcss/postcss-calc/pull/27))
|
|
69
|
-
|
|
70
|
-
# 5.2.0 - 2016-01-08
|
|
71
|
-
|
|
72
|
-
- Added: "mediaQueries" option for `@media` support
|
|
73
|
-
([#22](https://github.com/postcss/postcss-calc/pull/22))
|
|
74
|
-
|
|
75
|
-
# 5.1.0 - 2016-01-07
|
|
76
|
-
|
|
77
|
-
- Added: "warnWhenCannotResolve" option to warn when calc() are not reduced to a single value
|
|
78
|
-
([#20](https://github.com/postcss/postcss-calc/pull/20))
|
|
79
|
-
|
|
80
|
-
# 5.0.0 - 2015-08-25
|
|
81
|
-
|
|
82
|
-
- Removed: compatibility with postcss v4.x
|
|
83
|
-
- Added: compatibility with postcss v5.x
|
|
84
|
-
|
|
85
|
-
# 4.1.0 - 2015-04-09
|
|
86
|
-
|
|
87
|
-
- Added: compatibility with postcss v4.1.x ([#12](https://github.com/postcss/postcss-calc/pull/12))
|
|
88
|
-
|
|
89
|
-
# 4.0.1 - 2015-04-09
|
|
90
|
-
|
|
91
|
-
- Fixed: `preserve` option does not create duplicated values ([#7](https://github.com/postcss/postcss-calc/issues/7))
|
|
92
|
-
|
|
93
|
-
# 4.0.0 - 2015-01-26
|
|
94
|
-
|
|
95
|
-
- Added: compatibility with postcss v4.x
|
|
96
|
-
- Changed: partial compatiblity with postcss v3.x (stack traces have lost filename)
|
|
97
|
-
|
|
98
|
-
# 3.0.0 - 2014-11-24
|
|
99
|
-
|
|
100
|
-
- Added: GNU like exceptions ([#4](https://github.com/postcss/postcss-calc/issues/4))
|
|
101
|
-
- Added: `precision` option ([#5](https://github.com/postcss/postcss-calc/issues/5))
|
|
102
|
-
- Added: `preserve` option ([#6](https://github.com/postcss/postcss-calc/issues/6))
|
|
103
|
-
|
|
104
|
-
# 2.1.0 - 2014-10-15
|
|
105
|
-
|
|
106
|
-
- Added: source of the error (gnu like message) (fix [#3](https://github.com/postcss/postcss-calc/issues/3))
|
|
107
|
-
|
|
108
|
-
# 2.0.1 - 2014-08-10
|
|
109
|
-
|
|
110
|
-
- Fixed: correctly ignore unrecognized values (fix [#2](https://github.com/postcss/postcss-calc/issues/2))
|
|
111
|
-
|
|
112
|
-
# 2.0.0 - 2014-08-06
|
|
113
|
-
|
|
114
|
-
- Changed: Plugin now return a function to have a consistent api. ([ref 1](https://github.com/ianstormtaylor/rework-color-function/issues/6), [ref 2](https://twitter.com/jongleberry/status/496552790416576513))
|
|
115
|
-
|
|
116
|
-
# 1.0.0 - 2014-08-04
|
|
117
|
-
|
|
118
|
-
✨ First release based on [rework-calc](https://github.com/reworkcss/rework-calc) v1.1.0 (code mainly exported to [`reduce-css-calc`](https://github.com/MoOx/reduce-css-calc))
|