postcss-calc 11.1.2 → 11.2.1

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,8 @@
1
+ /** @typedef {import('./node.js').Node} Node */
2
+ export type Node = import('./node.js').Node;
3
+ declare const MAX_CALCULATION_DEPTH = 1024;
4
+ /** @param {number} depth @return {void} */
5
+ declare function assertDepth(depth: number): void;
6
+ /** @param {Node} node @param {number} [depth] @return {void} */
7
+ declare function checkCalculationDepth(node: Node, depth?: number): void;
8
+ export { MAX_CALCULATION_DEPTH, assertDepth, checkCalculationDepth };
@@ -19,6 +19,13 @@ export type Call = {
19
19
  args: Node[];
20
20
  rawName?: string;
21
21
  };
22
+ export type OpaqueComponent = string | Node | OpaqueComponent[];
23
+ export type OpaqueCall = {
24
+ type: 'OpaqueCall';
25
+ name: string;
26
+ components: OpaqueComponent[];
27
+ rawName?: string;
28
+ };
22
29
  export type SumTerm = {
23
30
  sign: 1 | -1;
24
31
  node: Node;
@@ -36,17 +43,19 @@ export type Product = {
36
43
  type: 'Product';
37
44
  factors: ProductFactor[];
38
45
  };
39
- export type Node = Num | Dim | Ident | Call | Sum | Product;
46
+ export type Node = Num | Dim | Ident | Call | OpaqueCall | Sum | Product;
40
47
  /**
41
48
  * @typedef {{type: 'Num', value: number}} Num
42
49
  * @typedef {{type: 'Dim', value: number, unit: string, rawUnit?: string}} Dim
43
50
  * @typedef {{type: 'Ident', name: string, rawName?: string}} Ident
44
51
  * @typedef {{type: 'Call', name: string, args: Node[], rawName?: string}} Call
52
+ * @typedef {string | Node | OpaqueComponent[]} OpaqueComponent
53
+ * @typedef {{type: 'OpaqueCall', name: string, components: OpaqueComponent[], rawName?: string}} OpaqueCall
45
54
  * @typedef {{sign: 1 | -1, node: Node}} SumTerm Sign is always +1 when node is Num or Dim.
46
55
  * @typedef {{type: 'Sum', terms: SumTerm[], grouped?: boolean}} Sum
47
56
  * @typedef {{exponent: 1 | -1, node: Node}} ProductFactor exponent +1 = numerator, -1 = denominator.
48
57
  * @typedef {{type: 'Product', factors: ProductFactor[]}} Product
49
- * @typedef {Num | Dim | Ident | Call | Sum | Product} Node
58
+ * @typedef {Num | Dim | Ident | Call | OpaqueCall | Sum | Product} Node
50
59
  */
51
60
  /**
52
61
  * @param {number} value
@@ -73,6 +82,13 @@ declare function ident(name: string, rawName?: string): Ident;
73
82
  * @return {Call}
74
83
  */
75
84
  declare function call(name: string, args: Node[], rawName?: string): Call;
85
+ /**
86
+ * @param {string} name
87
+ * @param {OpaqueComponent[]} components
88
+ * @param {string} [rawName]
89
+ * @return {OpaqueCall}
90
+ */
91
+ declare function opaqueCall(name: string, components: OpaqueComponent[], rawName?: string): OpaqueCall;
76
92
  /**
77
93
  * @param {SumTerm[]} rawTerms
78
94
  * @return {Node}
@@ -89,4 +105,4 @@ declare function mkProduct(rawFactors: ProductFactor[]): Node;
89
105
  * @return {Node}
90
106
  */
91
107
  declare function negate(node: Node): Node;
92
- export { num, dim, ident, call, mkSum, mkProduct, negate };
108
+ export { num, dim, ident, call, opaqueCall, mkSum, mkProduct, negate };
@@ -1,15 +1,9 @@
1
+ /** @typedef {import('./node.js').Node} Node */
2
+ /** @typedef {import('./node.js').OpaqueComponent} OpaqueComponent */
1
3
  export type Node = import('./node.js').Node;
2
- export type Component = string | Node | Component[];
3
- /** @param {Extract<Node, {type: 'Call'}>} node @param {Component[]} tree */
4
- declare function setComponents(node: Extract<Node, {
5
- type: 'Call';
6
- }>, tree: Component[]): import("./node.js").Call;
7
- /** @param {Extract<Node, {type: 'Call'}>} node */
8
- declare function getComponents(node: Extract<Node, {
9
- type: 'Call';
10
- }>): Component[] | undefined;
11
- /** @param {Component[]} tree @param {(node: Node) => Node} simplify @return {Component[]} */
12
- declare function simplifyComponents(tree: Component[], simplify: (node: Node) => Node): Component[];
13
- /** @param {Component[]} tree @param {(node: Node) => string} serialize @return {string} */
14
- declare function serializeComponents(tree: Component[], serialize: (node: Node) => string): string;
15
- export { getComponents, setComponents, simplifyComponents, serializeComponents, };
4
+ export type OpaqueComponent = import('./node.js').OpaqueComponent;
5
+ /** @param {OpaqueComponent[]} components @param {(node: Node) => Node} simplify @return {OpaqueComponent[]} */
6
+ declare function simplifyComponents(components: OpaqueComponent[], simplify: (node: Node) => Node): OpaqueComponent[];
7
+ /** @param {OpaqueComponent[]} components @param {string[]} buffer @param {(node: Node, buffer: string[]) => void} serialize @return {void} */
8
+ declare function serializeComponents(components: OpaqueComponent[], buffer: string[], serialize: (node: Node, buffer: string[]) => void): void;
9
+ export { simplifyComponents, serializeComponents };
@@ -1,55 +1,49 @@
1
1
  export type CSSToken = import('@csstools/css-tokenizer').CSSToken;
2
2
  export type Node = import('./node.js').Node;
3
- export type Component = string | Node | Component[];
4
- export type Token = {
5
- type: 'number' | 'dimension' | 'ident' | 'function' | 'punct' | 'eof';
6
- value: string | number;
3
+ export type OpaqueComponent = import('./node.js').OpaqueComponent;
4
+ export type BlockIndex = ReturnType<typeof import('./block-index.js').indexBlocks>;
5
+ export type TokenBase = {
7
6
  raw: string;
8
- unit?: string;
9
- rawUnit?: string;
10
- signCharacter?: '+' | '-';
11
7
  pos: number;
12
8
  ws: boolean;
9
+ index: number;
10
+ };
11
+ export type NumberToken = TokenBase & {
12
+ type: 'number';
13
+ value: number;
14
+ signCharacter?: '+' | '-';
15
+ };
16
+ export type DimensionToken = TokenBase & {
17
+ type: 'dimension';
18
+ value: number;
19
+ unit: string;
20
+ rawUnit: string;
21
+ signCharacter?: '+' | '-';
22
+ };
23
+ export type IdentToken = TokenBase & {
24
+ type: 'ident';
25
+ value: string;
26
+ };
27
+ export type FunctionToken = TokenBase & {
28
+ type: 'function';
29
+ value: string;
30
+ };
31
+ export type Punctuator = '(' | ')' | ',' | '+' | '-' | '*' | '/';
32
+ export type PunctToken = TokenBase & {
33
+ type: 'punct';
34
+ value: Punctuator;
35
+ };
36
+ export type EofToken = TokenBase & {
37
+ type: 'eof';
38
+ value: '';
39
+ raw: '';
13
40
  };
14
- export type PrefixParselet = (p: Parser, token: Token) => Node;
15
- /** Bounded cursor that skips trivia but records whether it preceded a token. */
16
- declare class Parser {
17
- #private;
18
- /**
19
- * @param {CSSToken[]} tokens
20
- * @param {number} start
21
- * @param {number} end
22
- * @param {Map<number, number>} [ends]
23
- */
24
- constructor(tokens: CSSToken[], start: number, end: number, ends?: Map<number, number>);
25
- /** @return {Map<number, number>} */
26
- get ends(): Map<number, number>;
27
- /** @return {number} */
28
- eofPosition(): number;
29
- /** @return {Token} */
30
- read(): Token;
31
- /** @return {Token} */
32
- peek(): Token;
33
- /** @return {Token} */
34
- next(): Token;
35
- /** @return {{start: number, close: number, tokens: CSSToken[], ends: Map<number, number>}} */
36
- functionRange(): {
37
- start: number;
38
- close: number;
39
- tokens: CSSToken[];
40
- ends: Map<number, number>;
41
- };
42
- /** @param {number} index */
43
- consumeThrough(index: number): void;
44
- /** @param {string} value @param {string} [value2] @return {boolean} */
45
- isPunct(value: string, value2?: string): boolean;
46
- /** @param {string} value @return {boolean} */
47
- matchPunct(value: string): boolean;
48
- /** @param {string} value @return {Token} */
49
- expectPunct(value: string): Token;
50
- /** @param {number} [minBp] @return {Node} */
51
- parseExpr(minBp?: number): Node;
52
- }
53
- /** @param {CSSToken[]} tokens @param {number} [start] @param {number} [end] @return {Node} */
54
- declare function parse(tokens: CSSToken[], start?: number, end?: number): Node;
41
+ export type Token = NumberToken | DimensionToken | IdentToken | FunctionToken | PunctToken | EofToken;
42
+ export type ParseInput = Readonly<{
43
+ tokens: CSSToken[];
44
+ end: number;
45
+ index: BlockIndex;
46
+ }>;
47
+ /** @param {CSSToken[]} tokens @param {number} start @param {number} end @param {BlockIndex} index @return {Node} */
48
+ declare function parse(tokens: CSSToken[], start: number, end: number, index: BlockIndex): Node;
55
49
  export { parse };
@@ -0,0 +1,16 @@
1
+ export type ResolvedReduceCalcOptions = import('../reduce.js').ResolvedReduceCalcOptions;
2
+ export type Replacement = import('../reduce.js').Replacement;
3
+ export type SerializeOptions = import('./serialize.js').SerializeOptions;
4
+ /**
5
+ * Serialize compiled candidates and splice the resulting text into the
6
+ * original source. Replacements are already non-overlapping because the
7
+ * finder treats a supported outer function as one range.
8
+ *
9
+ * @param {string} value
10
+ * @param {Replacement[]} replacements
11
+ * @param {ResolvedReduceCalcOptions} options
12
+ * @param {SerializeOptions} serializeOptions
13
+ * @return {string}
14
+ */
15
+ declare function applyReplacements(value: string, replacements: Replacement[], options: ResolvedReduceCalcOptions, serializeOptions: SerializeOptions): string;
16
+ export { applyReplacements };
@@ -0,0 +1,2 @@
1
+ declare const CSS_NUMBER_PREFIX: RegExp;
2
+ export { CSS_NUMBER_PREFIX };
@@ -0,0 +1,35 @@
1
+ export type Candidate = {
2
+ name: string;
3
+ normalizedName: string;
4
+ start: number;
5
+ end: number;
6
+ rootSpelling: string;
7
+ calculation: boolean;
8
+ sliceStart: number;
9
+ sliceEnd: number;
10
+ closed: boolean;
11
+ };
12
+ /**
13
+ * @typedef {object} Candidate
14
+ * @property {string} name
15
+ * @property {string} normalizedName
16
+ * @property {number} start
17
+ * @property {number} end
18
+ * @property {string} rootSpelling
19
+ * @property {boolean} calculation
20
+ * @property {number} sliceStart
21
+ * @property {number} sliceEnd
22
+ * @property {boolean} closed
23
+ */
24
+ /**
25
+ * Find complete supported math-function ranges. A supported function is
26
+ * treated as one candidate even when parsing it later fails, so nested
27
+ * calculations cannot produce partial output for an invalid outer function.
28
+ *
29
+ * @param {string} value
30
+ * @param {import('@csstools/css-tokenizer').CSSToken[]} tokens
31
+ * @param {ReturnType<typeof import('./block-index.js').indexBlocks>} index
32
+ * @return {Candidate[]}
33
+ */
34
+ declare function findCalculations(value: string, tokens: import('@csstools/css-tokenizer').CSSToken[], index: ReturnType<typeof import('./block-index.js').indexBlocks>): Candidate[];
35
+ export { findCalculations };
@@ -12,9 +12,13 @@ export type SerializeOptions = {
12
12
  */
13
13
  calcName?: string;
14
14
  /**
15
- * Serialize finite negative scalars without a wrapper. Internal selector-only mode.
15
+ * Deprecated alias for `unwrapSingleValue`.
16
16
  */
17
17
  unwrapSingleNegativeNumber?: boolean;
18
+ /**
19
+ * Serialize fully resolved finite scalar results without calculation syntax.
20
+ */
21
+ unwrapSingleValue?: boolean;
18
22
  };
19
23
  /**
20
24
  * @param {Node} node
@@ -22,4 +26,17 @@ export type SerializeOptions = {
22
26
  * @return {string}
23
27
  */
24
28
  declare function serialize(node: Node, opts?: SerializeOptions): string;
25
- export { serialize };
29
+ /**
30
+ * @param {{tree: Node, status: 'resolved' | 'unresolved', rootName: string, rootSpelling: string, calculation?: boolean, original?: string}} result
31
+ * @param {SerializeOptions} [opts]
32
+ * @return {string}
33
+ */
34
+ declare function serializeResult(result: {
35
+ tree: Node;
36
+ status: 'resolved' | 'unresolved';
37
+ rootName: string;
38
+ rootSpelling: string;
39
+ calculation?: boolean;
40
+ original?: string;
41
+ }, opts?: SerializeOptions): string;
42
+ export { serialize, serializeResult };
@@ -1,23 +1,9 @@
1
1
  export type Node = import('../node.js').Node;
2
2
  export type SimplifyFn = import('../simplify.js').SimplifyFn;
3
3
  export type MathSimplifier = (name: string, args: Node[]) => Node;
4
- declare const QUICK_MATH_TEST: RegExp;
5
- /**
6
- * Fast check to determine whether a CSS component value could contain
7
- * a supported calculation or math function call (or an escape sequence
8
- * that could decode to one).
9
- *
10
- * @param {string} value
11
- * @return {boolean}
12
- */
13
- declare function hasPotentialMathFunction(value: string): boolean;
14
- /**
15
- * Whether a bare CSS math function has an implemented simplifier.
16
- *
17
- * @param {string} name
18
- * @return {boolean}
19
- */
20
- declare function isSupportedMathFunction(name: string): boolean;
4
+ /** @typedef {import('../node.js').Node} Node */
5
+ /** @typedef {import('../simplify.js').SimplifyFn} SimplifyFn */
6
+ /** @typedef {(name: string, args: Node[]) => Node} MathSimplifier */
21
7
  /**
22
8
  * @param {Extract<Node, { type: 'Call' }>} node
23
9
  * @param {SimplifyFn} simplify
@@ -26,4 +12,4 @@ declare function isSupportedMathFunction(name: string): boolean;
26
12
  declare function simplifyCall(node: Extract<Node, {
27
13
  type: 'Call';
28
14
  }>, simplify: SimplifyFn): Node;
29
- export { isSupportedMathFunction, simplifyCall, hasPotentialMathFunction, QUICK_MATH_TEST, };
15
+ export { simplifyCall };
@@ -1,4 +1,6 @@
1
1
  export type Node = import('../node.js').Node;
2
+ /** @typedef {import('../node.js').Node} Node */
3
+ declare const ROUND_STRATEGIES: Set<string>;
2
4
  export type RoundStrategy = 'nearest' | 'up' | 'down' | 'to-zero';
3
5
  /** @typedef {'nearest' | 'up' | 'down' | 'to-zero'} RoundStrategy */
4
6
  /**
@@ -6,4 +8,4 @@ export type RoundStrategy = 'nearest' | 'up' | 'down' | 'to-zero';
6
8
  * @return {Node}
7
9
  */
8
10
  declare function simplifyRound(args: Node[]): Node;
9
- export { simplifyRound };
11
+ export { ROUND_STRATEGIES, simplifyRound };
@@ -3,13 +3,16 @@ export type SimplifyFn = (node: Node) => Node;
3
3
  /**
4
4
  * @typedef {import('./node.js').Node} Node
5
5
  *
6
- * Recursive simplifier reference, threaded into Sum/Product/Call. Lets
6
+ * Recursive simplifier reference, threaded into Sum/Product/Call/OpaqueCall. Lets
7
7
  * leaf fold modules avoid circular imports of the entry function.
8
8
  * @typedef {(node: Node) => Node} SimplifyFn
9
9
  */
10
10
  /**
11
+ * Simplify is an independent, composable AST transformation. It may
12
+ * synthesize canonical nodes while preserving the Node -> Node contract.
11
13
  * @param {Node} node
14
+ * @param {number} [depth]
12
15
  * @return {Node}
13
16
  */
14
- declare function simplify(node: Node): Node;
17
+ declare function simplify(node: Node, depth?: number): Node;
15
18
  export { simplify };
package/types/reduce.d.ts CHANGED
@@ -1,11 +1,14 @@
1
- import { hasPotentialMathFunction, QUICK_MATH_TEST } from './lib/simplify/call.js';
2
1
  export type ReduceCalcOptions = {
3
2
  precision?: number | false;
4
3
  warnWhenCannotResolve?: boolean;
5
4
  /**
6
- * Serialize finite negative results without a `calc()` wrapper. Defaults to `false`.
5
+ * Deprecated alias for `unwrapSingleValue`.
7
6
  */
8
7
  unwrapSingleNegativeNumber?: boolean;
8
+ /**
9
+ * Serialize fully resolved finite scalar results without calculation syntax. Defaults to `false`.
10
+ */
11
+ unwrapSingleValue?: boolean;
9
12
  /**
10
13
  * Invoked when parse/simplify throws.
11
14
  */
@@ -20,14 +23,53 @@ export type TransformContext = {
20
23
  options: ResolvedReduceCalcOptions;
21
24
  value: string;
22
25
  tokens: import('@csstools/css-tokenizer').CSSToken[];
23
- replacements: Replacement[];
24
26
  };
25
27
  export type Replacement = {
26
28
  start: number;
27
29
  end: number;
28
- node: import('./lib/node.js').Node;
29
- calcName: string;
30
+ result: CalculationResult;
31
+ };
32
+ export type CalculationResult = {
33
+ tree: import('./lib/node.js').Node;
34
+ status: 'resolved' | 'unresolved';
35
+ rootName: string;
36
+ rootSpelling: string;
37
+ calculation: boolean;
38
+ original: string | undefined;
30
39
  };
40
+ /**
41
+ * @typedef {object} ReduceCalcOptions
42
+ * @property {number | false} [precision]
43
+ * @property {boolean} [warnWhenCannotResolve]
44
+ * @property {boolean} [unwrapSingleNegativeNumber] Deprecated alias for `unwrapSingleValue`.
45
+ * @property {boolean} [unwrapSingleValue] Serialize fully resolved finite scalar results without calculation syntax. Defaults to `false`.
46
+ * @property {(error: Error, input: string) => void} [onParseError] Invoked when parse/simplify throws.
47
+ * @property {(message: string) => void} [onWarn] Invoked when `warnWhenCannotResolve` is set and an expression cannot be reduced to a single value.
48
+ */
49
+ /** @typedef {Required<Omit<ReduceCalcOptions, 'onParseError' | 'onWarn'>> & Pick<ReduceCalcOptions, 'onParseError' | 'onWarn'>} ResolvedReduceCalcOptions */
50
+ /**
51
+ * Fields threaded through the internal token-range walk.
52
+ *
53
+ * @typedef {object} TransformContext
54
+ * @property {ResolvedReduceCalcOptions} options
55
+ * @property {string} value
56
+ * @property {import('@csstools/css-tokenizer').CSSToken[]} tokens
57
+ */
58
+ /**
59
+ * @typedef {object} Replacement
60
+ * @property {number} start
61
+ * @property {number} end
62
+ * @property {CalculationResult} result
63
+ */
64
+ /**
65
+ * @typedef {object} CalculationResult
66
+ * @property {import('./lib/node.js').Node} tree
67
+ * @property {'resolved' | 'unresolved'} status
68
+ * @property {string} rootName
69
+ * @property {string} rootSpelling
70
+ * @property {boolean} calculation
71
+ * @property {string | undefined} original
72
+ */
31
73
  /**
32
74
  * Simplify every supported CSS math function in a component-value string.
33
75
  * Text outside those functions is preserved byte-for-byte.
@@ -37,5 +79,4 @@ export type Replacement = {
37
79
  * @return {string}
38
80
  */
39
81
  declare function reduceCalc(value: string, opts?: ReduceCalcOptions): string;
40
- export { QUICK_MATH_TEST, hasPotentialMathFunction };
41
82
  export default reduceCalc;
@@ -1,10 +0,0 @@
1
- // Thin project-local entry point for the CSS Syntax tokenizer. The parser
2
- // consumes native tokens directly so decoded values and source spelling remain available.
3
- import { tokenize as tokenizeCss } from '@csstools/css-tokenizer';
4
-
5
- /** @param {string} input @return {import('@csstools/css-tokenizer').CSSToken[]} */
6
- function tokenize(input) {
7
- return tokenizeCss({ css: input });
8
- }
9
-
10
- export { tokenize };
@@ -1,3 +0,0 @@
1
- /** @param {string} input @return {import('@csstools/css-tokenizer').CSSToken[]} */
2
- declare function tokenize(input: string): import('@csstools/css-tokenizer').CSSToken[];
3
- export { tokenize };