postcss-calc 8.2.3 → 9.0.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.
@@ -0,0 +1,109 @@
1
+ 'use strict';
2
+ const selectorParser = require('postcss-selector-parser');
3
+ const valueParser = require('postcss-value-parser');
4
+
5
+ const { parser } = require('../parser.js');
6
+
7
+ const reducer = require('./reducer.js');
8
+ const stringifier = require('./stringifier.js');
9
+
10
+ const MATCH_CALC = /((?:-(moz|webkit)-)?calc)/i;
11
+
12
+ /**
13
+ * @param {string} value
14
+ * @param {{precision: number, warnWhenCannotResolve: boolean}} options
15
+ * @param {import("postcss").Result} result
16
+ * @param {import("postcss").ChildNode} item
17
+ */
18
+ function transformValue(value, options, result, item) {
19
+ return valueParser(value)
20
+ .walk((node) => {
21
+ // skip anything which isn't a calc() function
22
+ if (node.type !== 'function' || !MATCH_CALC.test(node.value)) {
23
+ return;
24
+ }
25
+
26
+ // stringify calc expression and produce an AST
27
+ const contents = valueParser.stringify(node.nodes);
28
+ const ast = parser.parse(contents);
29
+
30
+ // reduce AST to its simplest form, that is, either to a single value
31
+ // or a simplified calc expression
32
+ const reducedAst = reducer(ast, options.precision);
33
+
34
+ // stringify AST and write it back
35
+ /** @type {valueParser.Node} */ (node).type = 'word';
36
+ node.value = stringifier(
37
+ node.value,
38
+ reducedAst,
39
+ value,
40
+ options,
41
+ result,
42
+ item
43
+ );
44
+
45
+ return false;
46
+ })
47
+ .toString();
48
+ }
49
+ /**
50
+ * @param {import("postcss-selector-parser").Selectors} value
51
+ * @param {{precision: number, warnWhenCannotResolve: boolean}} options
52
+ * @param {import("postcss").Result} result
53
+ * @param {import("postcss").ChildNode} item
54
+ */
55
+ function transformSelector(value, options, result, item) {
56
+ return selectorParser((selectors) => {
57
+ selectors.walk((node) => {
58
+ // attribute value
59
+ // e.g. the "calc(3*3)" part of "div[data-size="calc(3*3)"]"
60
+ if (node.type === 'attribute' && node.value) {
61
+ node.setValue(transformValue(node.value, options, result, item));
62
+ }
63
+
64
+ // tag value
65
+ // e.g. the "calc(3*3)" part of "div:nth-child(2n + calc(3*3))"
66
+ if (node.type === 'tag') {
67
+ node.value = transformValue(node.value, options, result, item);
68
+ }
69
+
70
+ return;
71
+ });
72
+ }).processSync(value);
73
+ }
74
+
75
+ /**
76
+ * @param {any} node
77
+ * @param {{precision: number, preserve: boolean, warnWhenCannotResolve: boolean}} options
78
+ * @param {'value'|'params'|'selector'} property
79
+ * @param {import("postcss").Result} result
80
+ */
81
+ module.exports = (node, property, options, result) => {
82
+ let value = node[property];
83
+
84
+ try {
85
+ value =
86
+ property === 'selector'
87
+ ? transformSelector(node[property], options, result, node)
88
+ : transformValue(node[property], options, result, node);
89
+ } catch (error) {
90
+ if (error instanceof Error) {
91
+ result.warn(error.message, { node });
92
+ } else {
93
+ result.warn('Error', { node });
94
+ }
95
+ return;
96
+ }
97
+
98
+ // if the preserve option is enabled and the value has changed, write the
99
+ // transformed value into a cloned node which is inserted before the current
100
+ // node, preserving the original value. Otherwise, overwrite the original
101
+ // value.
102
+ if (options.preserve && node[property] !== value) {
103
+ const clone = node.clone();
104
+ clone[property] = value;
105
+ node.parent.insertBefore(node, clone);
106
+ } else {
107
+ node[property] = value;
108
+ }
109
+ };
@@ -0,0 +1,51 @@
1
+ export interface MathExpression {
2
+ type: 'MathExpression';
3
+ right: CalcNode;
4
+ left: CalcNode;
5
+ operator: '*' | '+' | '-' | '/';
6
+ }
7
+
8
+ export interface ParenthesizedExpression {
9
+ type: 'ParenthesizedExpression';
10
+ content: CalcNode;
11
+ }
12
+
13
+ export interface DimensionExpression {
14
+ type:
15
+ | 'LengthValue'
16
+ | 'AngleValue'
17
+ | 'TimeValue'
18
+ | 'FrequencyValue'
19
+ | 'PercentageValue'
20
+ | 'ResolutionValue'
21
+ | 'EmValue'
22
+ | 'ExValue'
23
+ | 'ChValue'
24
+ | 'RemValue'
25
+ | 'VhValue'
26
+ | 'VwValue'
27
+ | 'VminValue'
28
+ | 'VmaxValue';
29
+ value: number;
30
+ unit: string;
31
+ }
32
+
33
+ export interface NumberExpression {
34
+ type: 'Number';
35
+ value: number;
36
+ }
37
+
38
+ export interface FunctionExpression {
39
+ type: 'Function';
40
+ value: string;
41
+ }
42
+
43
+ export type ValueExpression = DimensionExpression | NumberExpression;
44
+
45
+ export type CalcNode = MathExpression | ValueExpression | FunctionExpression | ParenthesizedExpression;
46
+
47
+ export interface Parser {
48
+ parse: (arg: string) => CalcNode;
49
+ }
50
+
51
+ export const parser: Parser;
package/types/index.d.ts CHANGED
@@ -1,11 +1,4 @@
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
- };
1
+ export = pluginCreator;
9
2
  /**
10
3
  * @typedef {{precision?: number | false,
11
4
  * preserve?: boolean,
@@ -14,11 +7,19 @@ export type PostCssCalcOptions = {
14
7
  * selectors?: boolean}} PostCssCalcOptions
15
8
  */
16
9
  /**
17
- * @type {import('postcss').PluginCreator<PostCssCalcOptions>}
18
- * @param {PostCssCalcOptions} opts
19
- * @return {import('postcss').Plugin}
20
- */
10
+ * @type {import('postcss').PluginCreator<PostCssCalcOptions>}
11
+ * @param {PostCssCalcOptions} opts
12
+ * @return {import('postcss').Plugin}
13
+ */
21
14
  declare function pluginCreator(opts: PostCssCalcOptions): import('postcss').Plugin;
22
15
  declare namespace pluginCreator {
23
- const postcss: true;
16
+ export { postcss, PostCssCalcOptions };
24
17
  }
18
+ type PostCssCalcOptions = {
19
+ precision?: number | false;
20
+ preserve?: boolean;
21
+ warnWhenCannotResolve?: boolean;
22
+ mediaQueries?: boolean;
23
+ selectors?: boolean;
24
+ };
25
+ declare var postcss: true;
@@ -1,4 +1,4 @@
1
- export default convertUnit;
1
+ export = convertUnit;
2
2
  /**
3
3
  * @param {number} value
4
4
  * @param {string} sourceUnit
@@ -1,11 +1,14 @@
1
- export default reduce;
2
- export type Collectible = {
3
- preOperator: '+' | '-';
4
- node: import('../parser').CalcNode;
5
- };
1
+ export = reduce;
6
2
  /**
7
3
  * @param {import('../parser').CalcNode} node
8
4
  * @param {number} precision
9
5
  * @return {import('../parser').CalcNode}
10
6
  */
11
7
  declare function reduce(node: import('../parser').CalcNode, precision: number): import('../parser').CalcNode;
8
+ declare namespace reduce {
9
+ export { Collectible };
10
+ }
11
+ type Collectible = {
12
+ preOperator: '+' | '-';
13
+ node: import('../parser').CalcNode;
14
+ };
@@ -1,14 +1,5 @@
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: {
1
+ declare function _exports(calc: string, node: import('../parser').CalcNode, originalValue: string, options: {
12
2
  precision: number | false;
13
3
  warnWhenCannotResolve: boolean;
14
4
  }, result: import("postcss").Result, item: import("postcss").ChildNode): string;
5
+ export = _exports;
@@ -1,6 +1,6 @@
1
- declare function _default(node: any, property: 'value' | 'params' | 'selector', options: {
1
+ declare function _exports(node: any, property: 'value' | 'params' | 'selector', options: {
2
2
  precision: number;
3
3
  preserve: boolean;
4
4
  warnWhenCannotResolve: boolean;
5
5
  }, result: import("postcss").Result): void;
6
- export default _default;
6
+ export = _exports;
package/dist/index.js DELETED
@@ -1,64 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _transform = _interopRequireDefault(require("./lib/transform"));
9
-
10
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
-
12
- /**
13
- * @typedef {{precision?: number | false,
14
- * preserve?: boolean,
15
- * warnWhenCannotResolve?: boolean,
16
- * mediaQueries?: boolean,
17
- * selectors?: boolean}} PostCssCalcOptions
18
- */
19
-
20
- /**
21
- * @type {import('postcss').PluginCreator<PostCssCalcOptions>}
22
- * @param {PostCssCalcOptions} opts
23
- * @return {import('postcss').Plugin}
24
- */
25
- function pluginCreator(opts) {
26
- const options = Object.assign({
27
- precision: 5,
28
- preserve: false,
29
- warnWhenCannotResolve: false,
30
- mediaQueries: false,
31
- selectors: false
32
- }, opts);
33
- return {
34
- postcssPlugin: 'postcss-calc',
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
-
58
- };
59
- }
60
-
61
- pluginCreator.postcss = true;
62
- var _default = pluginCreator;
63
- exports.default = _default;
64
- module.exports = exports.default;
@@ -1,167 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- /**
9
- * @type {{[key:string]: {[key:string]: number}}}
10
- */
11
- const conversions = {
12
- // Absolute length units
13
- 'px': {
14
- 'px': 1,
15
- 'cm': 96 / 2.54,
16
- 'mm': 96 / 25.4,
17
- 'q': 96 / 101.6,
18
- 'in': 96,
19
- 'pt': 96 / 72,
20
- 'pc': 16
21
- },
22
- 'cm': {
23
- 'px': 2.54 / 96,
24
- 'cm': 1,
25
- 'mm': 0.1,
26
- 'q': 0.025,
27
- 'in': 2.54,
28
- 'pt': 2.54 / 72,
29
- 'pc': 2.54 / 6
30
- },
31
- 'mm': {
32
- 'px': 25.4 / 96,
33
- 'cm': 10,
34
- 'mm': 1,
35
- 'q': 0.25,
36
- 'in': 25.4,
37
- 'pt': 25.4 / 72,
38
- 'pc': 25.4 / 6
39
- },
40
- 'q': {
41
- 'px': 101.6 / 96,
42
- 'cm': 40,
43
- 'mm': 4,
44
- 'q': 1,
45
- 'in': 101.6,
46
- 'pt': 101.6 / 72,
47
- 'pc': 101.6 / 6
48
- },
49
- 'in': {
50
- 'px': 1 / 96,
51
- 'cm': 1 / 2.54,
52
- 'mm': 1 / 25.4,
53
- 'q': 1 / 101.6,
54
- 'in': 1,
55
- 'pt': 1 / 72,
56
- 'pc': 1 / 6
57
- },
58
- 'pt': {
59
- 'px': 0.75,
60
- 'cm': 72 / 2.54,
61
- 'mm': 72 / 25.4,
62
- 'q': 72 / 101.6,
63
- 'in': 72,
64
- 'pt': 1,
65
- 'pc': 12
66
- },
67
- 'pc': {
68
- 'px': 0.0625,
69
- 'cm': 6 / 2.54,
70
- 'mm': 6 / 25.4,
71
- 'q': 6 / 101.6,
72
- 'in': 6,
73
- 'pt': 6 / 72,
74
- 'pc': 1
75
- },
76
- // Angle units
77
- 'deg': {
78
- 'deg': 1,
79
- 'grad': 0.9,
80
- 'rad': 180 / Math.PI,
81
- 'turn': 360
82
- },
83
- 'grad': {
84
- 'deg': 400 / 360,
85
- 'grad': 1,
86
- 'rad': 200 / Math.PI,
87
- 'turn': 400
88
- },
89
- 'rad': {
90
- 'deg': Math.PI / 180,
91
- 'grad': Math.PI / 200,
92
- 'rad': 1,
93
- 'turn': Math.PI * 2
94
- },
95
- 'turn': {
96
- 'deg': 1 / 360,
97
- 'grad': 0.0025,
98
- 'rad': 0.5 / Math.PI,
99
- 'turn': 1
100
- },
101
- // Duration units
102
- 's': {
103
- 's': 1,
104
- 'ms': 0.001
105
- },
106
- 'ms': {
107
- 's': 1000,
108
- 'ms': 1
109
- },
110
- // Frequency units
111
- 'hz': {
112
- 'hz': 1,
113
- 'khz': 1000
114
- },
115
- 'khz': {
116
- 'hz': 0.001,
117
- 'khz': 1
118
- },
119
- // Resolution units
120
- 'dpi': {
121
- 'dpi': 1,
122
- 'dpcm': 1 / 2.54,
123
- 'dppx': 1 / 96
124
- },
125
- 'dpcm': {
126
- 'dpi': 2.54,
127
- 'dpcm': 1,
128
- 'dppx': 2.54 / 96
129
- },
130
- 'dppx': {
131
- 'dpi': 96,
132
- 'dpcm': 96 / 2.54,
133
- 'dppx': 1
134
- }
135
- };
136
- /**
137
- * @param {number} value
138
- * @param {string} sourceUnit
139
- * @param {string} targetUnit
140
- * @param {number|false} precision
141
- */
142
-
143
- function convertUnit(value, sourceUnit, targetUnit, precision) {
144
- const sourceUnitNormalized = sourceUnit.toLowerCase();
145
- const targetUnitNormalized = targetUnit.toLowerCase();
146
-
147
- if (!conversions[targetUnitNormalized]) {
148
- throw new Error("Cannot convert to " + targetUnit);
149
- }
150
-
151
- if (!conversions[targetUnitNormalized][sourceUnitNormalized]) {
152
- throw new Error("Cannot convert from " + sourceUnit + " to " + targetUnit);
153
- }
154
-
155
- const converted = conversions[targetUnitNormalized][sourceUnitNormalized] * value;
156
-
157
- if (precision !== false) {
158
- precision = Math.pow(10, Math.ceil(precision) || 5);
159
- return Math.round(converted * precision) / precision;
160
- }
161
-
162
- return converted;
163
- }
164
-
165
- var _default = convertUnit;
166
- exports.default = _default;
167
- module.exports = exports.default;
@@ -1,119 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.default = void 0;
7
-
8
- var _postcssSelectorParser = _interopRequireDefault(require("postcss-selector-parser"));
9
-
10
- var _postcssValueParser = _interopRequireDefault(require("postcss-value-parser"));
11
-
12
- var _parser = require("../parser");
13
-
14
- var _reducer = _interopRequireDefault(require("./reducer"));
15
-
16
- var _stringifier = _interopRequireDefault(require("./stringifier"));
17
-
18
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
-
20
- // eslint-disable-next-line import/no-unresolved
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
- */
28
-
29
- function transformValue(value, options, result, item) {
30
- return (0, _postcssValueParser.default)(value).walk(node => {
31
- // skip anything which isn't a calc() function
32
- if (node.type !== "function" || !MATCH_CALC.test(node.value)) {
33
- return;
34
- } // stringify calc expression and produce an AST
35
-
36
-
37
- const contents = _postcssValueParser.default.stringify(node.nodes);
38
-
39
- const ast = _parser.parser.parse(contents); // reduce AST to its simplest form, that is, either to a single value
40
- // or a simplified calc expression
41
-
42
-
43
- const reducedAst = (0, _reducer.default)(ast, options.precision); // stringify AST and write it back
44
-
45
- /** @type {valueParser.Node} */
46
- node.type = "word";
47
- node.value = (0, _stringifier.default)(node.value, reducedAst, value, options, result, item);
48
- return false;
49
- }).toString();
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
-
58
-
59
- function transformSelector(value, options, result, item) {
60
- return (0, _postcssSelectorParser.default)(selectors => {
61
- selectors.walk(node => {
62
- // attribute value
63
- // e.g. the "calc(3*3)" part of "div[data-size="calc(3*3)"]"
64
- if (node.type === "attribute" && node.value) {
65
- node.setValue(transformValue(node.value, options, result, item));
66
- } // tag value
67
- // e.g. the "calc(3*3)" part of "div:nth-child(2n + calc(3*3))"
68
-
69
-
70
- if (node.type === "tag") {
71
- node.value = transformValue(node.value, options, result, item);
72
- }
73
-
74
- return;
75
- });
76
- }).processSync(value);
77
- }
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
104
- // transformed value into a cloned node which is inserted before the current
105
- // node, preserving the original value. Otherwise, overwrite the original
106
- // value.
107
-
108
-
109
- if (options.preserve && node[property] !== value) {
110
- const clone = node.clone();
111
- clone[property] = value;
112
- node.parent.insertBefore(node, clone);
113
- } else {
114
- node[property] = value;
115
- }
116
- };
117
-
118
- exports.default = _default;
119
- module.exports = exports.default;
File without changes