@tbela99/css-parser 1.4.2 → 1.4.3

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.
Files changed (216) hide show
  1. package/.nyc_output/4874b20e-6f53-4d7a-be5a-cf68316925f2.json +1 -0
  2. package/.nyc_output/6193bc4c-6f5f-4898-8950-c628825e6342.json +1 -0
  3. package/.nyc_output/processinfo/4874b20e-6f53-4d7a-be5a-cf68316925f2.json +1 -0
  4. package/.nyc_output/processinfo/6193bc4c-6f5f-4898-8950-c628825e6342.json +1 -0
  5. package/.repl_history +4 -0
  6. package/CHANGELOG.md +164 -4
  7. package/README.md +43 -0
  8. package/badges/coverage.svg +20 -0
  9. package/deno.lock +2861 -0
  10. package/dist/config.json.js +33 -1
  11. package/dist/index-umd-web.js +24382 -18476
  12. package/dist/index.cjs +24522 -18618
  13. package/dist/index.d.ts +1396 -929
  14. package/dist/lib/ast/clone.d.ts +10 -0
  15. package/dist/lib/ast/clone.js +45 -0
  16. package/dist/lib/ast/expand.d.ts +14 -0
  17. package/dist/lib/ast/expand.js +89 -64
  18. package/dist/lib/ast/features/calc.d.ts +10 -0
  19. package/dist/lib/ast/features/calc.js +62 -24
  20. package/dist/lib/ast/features/if.d.ts +10 -0
  21. package/dist/lib/ast/features/if.js +215 -0
  22. package/dist/lib/ast/features/index.d.ts +6 -0
  23. package/dist/lib/ast/features/index.js +1 -0
  24. package/dist/lib/ast/features/inlinecssvariables.d.ts +15 -0
  25. package/dist/lib/ast/features/inlinecssvariables.js +32 -27
  26. package/dist/lib/ast/features/prefix.d.ts +8 -0
  27. package/dist/lib/ast/features/prefix.js +68 -43
  28. package/dist/lib/ast/features/shorthand.d.ts +12 -0
  29. package/dist/lib/ast/features/shorthand.js +6 -9
  30. package/dist/lib/ast/features/transform.d.ts +10 -0
  31. package/dist/lib/ast/features/transform.js +9 -13
  32. package/dist/lib/ast/features/type.d.ts +15 -0
  33. package/dist/lib/ast/find.d.ts +165 -0
  34. package/dist/lib/ast/find.js +175 -0
  35. package/dist/lib/ast/math/expression.d.ts +18 -0
  36. package/dist/lib/ast/math/expression.js +140 -98
  37. package/dist/lib/ast/math/math.d.ts +6 -0
  38. package/dist/lib/ast/math/math.js +30 -41
  39. package/dist/lib/ast/minify.d.ts +19 -0
  40. package/dist/lib/ast/minify.js +541 -217
  41. package/dist/lib/ast/transform/compute.d.ts +8 -0
  42. package/dist/lib/ast/transform/compute.js +82 -69
  43. package/dist/lib/ast/transform/matrix.d.ts +22 -0
  44. package/dist/lib/ast/transform/matrix.js +12 -26
  45. package/dist/lib/ast/transform/minify.d.ts +5 -0
  46. package/dist/lib/ast/transform/minify.js +20 -20
  47. package/dist/lib/ast/transform/perspective.d.ts +3 -0
  48. package/dist/lib/ast/transform/perspective.js +1 -1
  49. package/dist/lib/ast/transform/rotate.d.ts +12 -0
  50. package/dist/lib/ast/transform/rotate.js +1 -1
  51. package/dist/lib/ast/transform/scale.d.ts +6 -0
  52. package/dist/lib/ast/transform/scale.js +1 -1
  53. package/dist/lib/ast/transform/skew.d.ts +4 -0
  54. package/dist/lib/ast/transform/skew.js +1 -1
  55. package/dist/lib/ast/transform/translate.d.ts +6 -0
  56. package/dist/lib/ast/transform/translate.js +1 -1
  57. package/dist/lib/ast/transform/utils.d.ts +9 -0
  58. package/dist/lib/ast/types.d.ts +903 -0
  59. package/dist/lib/ast/types.js +277 -23
  60. package/dist/lib/ast/walk.d.ts +162 -0
  61. package/dist/lib/ast/walk.js +116 -60
  62. package/dist/lib/fs/resolve.d.ts +20 -0
  63. package/dist/lib/fs/resolve.js +37 -45
  64. package/dist/lib/parser/declaration/list.d.ts +16 -0
  65. package/dist/lib/parser/declaration/list.js +26 -24
  66. package/dist/lib/parser/declaration/map.d.ts +15 -0
  67. package/dist/lib/parser/declaration/map.js +140 -95
  68. package/dist/lib/parser/declaration/set.d.ts +9 -0
  69. package/dist/lib/parser/declaration/set.js +30 -25
  70. package/dist/lib/parser/node.d.ts +7 -0
  71. package/dist/lib/parser/parse.d.ts +107 -0
  72. package/dist/lib/parser/parse.js +1454 -1445
  73. package/dist/lib/parser/tokenize.d.ts +57 -0
  74. package/dist/lib/parser/tokenize.js +557 -404
  75. package/dist/lib/parser/utils/at-rule-container.d.ts +5 -0
  76. package/dist/lib/parser/utils/at-rule-container.js +486 -0
  77. package/dist/lib/parser/utils/at-rule-font-feature-values.d.ts +5 -0
  78. package/dist/lib/parser/utils/at-rule-font-feature-values.js +13 -0
  79. package/dist/lib/parser/utils/at-rule-generic.d.ts +5 -0
  80. package/dist/lib/parser/utils/at-rule-generic.js +118 -0
  81. package/dist/lib/parser/utils/at-rule-import.d.ts +5 -0
  82. package/dist/lib/parser/utils/at-rule-import.js +393 -0
  83. package/dist/lib/parser/utils/at-rule-media.d.ts +5 -0
  84. package/dist/lib/parser/utils/at-rule-media.js +603 -0
  85. package/dist/lib/parser/utils/at-rule-page.d.ts +5 -0
  86. package/dist/lib/parser/utils/at-rule-page.js +28 -0
  87. package/dist/lib/parser/utils/at-rule-support.d.ts +5 -0
  88. package/dist/lib/parser/utils/at-rule-support.js +366 -0
  89. package/dist/lib/parser/utils/at-rule-token.d.ts +1 -0
  90. package/dist/lib/parser/utils/at-rule-when-else.d.ts +5 -0
  91. package/dist/lib/parser/utils/at-rule-when-else.js +363 -0
  92. package/dist/lib/parser/utils/at-rule.d.ts +13 -0
  93. package/dist/lib/parser/utils/at-rule.js +37 -0
  94. package/dist/lib/parser/utils/cache.d.ts +6 -0
  95. package/dist/lib/parser/utils/cache.js +19 -0
  96. package/dist/lib/parser/utils/config.d.ts +2 -0
  97. package/dist/lib/parser/utils/config.js +1 -0
  98. package/dist/lib/parser/utils/declaration-list.d.ts +5 -0
  99. package/dist/lib/parser/utils/declaration.d.ts +18 -0
  100. package/dist/lib/parser/utils/declaration.js +569 -91
  101. package/dist/lib/parser/utils/eq.d.ts +1 -0
  102. package/dist/lib/parser/utils/hash.d.ts +21 -0
  103. package/dist/lib/parser/utils/hash.js +1 -1
  104. package/dist/lib/parser/utils/selector.d.ts +5 -0
  105. package/dist/lib/parser/utils/selector.js +476 -0
  106. package/dist/lib/parser/utils/text.d.ts +3 -0
  107. package/dist/lib/parser/utils/text.js +17 -1
  108. package/dist/lib/parser/utils/token.d.ts +14 -0
  109. package/dist/lib/parser/utils/token.js +102 -0
  110. package/dist/lib/parser/utils/type.d.ts +2 -0
  111. package/dist/lib/parser/utils/type.js +29 -18
  112. package/dist/lib/renderer/render.d.ts +28 -0
  113. package/dist/lib/renderer/render.js +421 -262
  114. package/dist/lib/renderer/sourcemap/lib/encode.d.ts +1 -0
  115. package/dist/lib/renderer/sourcemap/sourcemap.d.ts +26 -0
  116. package/dist/lib/renderer/sourcemap/sourcemap.js +17 -7
  117. package/dist/lib/syntax/color/a98rgb.d.ts +2 -0
  118. package/dist/lib/syntax/color/a98rgb.js +8 -12
  119. package/dist/lib/syntax/color/cmyk.d.ts +10 -0
  120. package/dist/lib/syntax/color/cmyk.js +23 -21
  121. package/dist/lib/syntax/color/color-mix.d.ts +2 -0
  122. package/dist/lib/syntax/color/color-mix.js +88 -77
  123. package/dist/lib/syntax/color/color.d.ts +42 -0
  124. package/dist/lib/syntax/color/color.js +65 -68
  125. package/dist/lib/syntax/color/hex.d.ts +16 -0
  126. package/dist/lib/syntax/color/hex.js +27 -31
  127. package/dist/lib/syntax/color/hsl.d.ts +20 -0
  128. package/dist/lib/syntax/color/hsl.js +5 -12
  129. package/dist/lib/syntax/color/hsv.d.ts +2 -0
  130. package/dist/lib/syntax/color/hwb.d.ts +21 -0
  131. package/dist/lib/syntax/color/hwb.js +8 -21
  132. package/dist/lib/syntax/color/lab.d.ts +25 -0
  133. package/dist/lib/syntax/color/lab.js +20 -21
  134. package/dist/lib/syntax/color/lch.d.ts +23 -0
  135. package/dist/lib/syntax/color/lch.js +13 -15
  136. package/dist/lib/syntax/color/oklab.d.ts +22 -0
  137. package/dist/lib/syntax/color/oklab.js +20 -39
  138. package/dist/lib/syntax/color/oklch.d.ts +20 -0
  139. package/dist/lib/syntax/color/oklch.js +14 -16
  140. package/dist/lib/syntax/color/p3.d.ts +6 -0
  141. package/dist/lib/syntax/color/p3.js +0 -8
  142. package/dist/lib/syntax/color/prophotorgb.d.ts +2 -0
  143. package/dist/lib/syntax/color/rec2020.d.ts +2 -0
  144. package/dist/lib/syntax/color/rec2020.js +9 -13
  145. package/dist/lib/syntax/color/relativecolor.d.ts +13 -0
  146. package/dist/lib/syntax/color/relativecolor.js +68 -41
  147. package/dist/lib/syntax/color/rgb.d.ts +20 -0
  148. package/dist/lib/syntax/color/rgb.js +14 -18
  149. package/dist/lib/syntax/color/srgb.d.ts +23 -0
  150. package/dist/lib/syntax/color/srgb.js +27 -26
  151. package/dist/lib/syntax/color/utils/components.d.ts +2 -0
  152. package/dist/lib/syntax/color/utils/components.js +30 -14
  153. package/dist/lib/syntax/color/utils/distance.d.ts +18 -0
  154. package/dist/lib/syntax/color/utils/distance.js +1 -8
  155. package/dist/lib/syntax/color/utils/matrix.d.ts +6 -0
  156. package/dist/lib/syntax/color/xyz.d.ts +5 -0
  157. package/dist/lib/syntax/color/xyz.js +8 -20
  158. package/dist/lib/syntax/color/xyzd50.d.ts +4 -0
  159. package/dist/lib/syntax/color/xyzd50.js +6 -20
  160. package/dist/lib/syntax/constants.d.ts +67 -0
  161. package/dist/lib/syntax/constants.js +436 -0
  162. package/dist/lib/syntax/syntax.d.ts +38 -0
  163. package/dist/lib/syntax/syntax.js +533 -568
  164. package/dist/lib/validation/config.d.ts +14 -0
  165. package/dist/lib/validation/config.js +72 -33
  166. package/dist/lib/validation/config.json.js +1159 -74
  167. package/dist/lib/validation/json.d.ts +2 -0
  168. package/dist/lib/validation/match.d.ts +38 -0
  169. package/dist/lib/validation/match.js +2985 -0
  170. package/dist/lib/validation/parser/parse.d.ts +8 -0
  171. package/dist/lib/validation/parser/parse.js +684 -935
  172. package/dist/lib/validation/parser/typedef.d.ts +95 -0
  173. package/dist/lib/validation/parser/typedef.js +100 -0
  174. package/dist/lib/validation/utils/list.d.ts +4 -0
  175. package/dist/lib/validation/utils/list.js +4 -11
  176. package/dist/lib/validation/utils/whitespace.d.ts +2 -0
  177. package/dist/lib/validation/utils/whitespace.js +2 -8
  178. package/dist/node.d.ts +207 -0
  179. package/dist/node.js +42 -39
  180. package/dist/web.d.ts +169 -0
  181. package/dist/web.js +38 -33
  182. package/package.json +15 -12
  183. package/playground/index.html +1328 -0
  184. package/playground/sw.js +55 -0
  185. package/playground/tree.js +176 -0
  186. package/dist/lib/syntax/color/utils/constants.js +0 -214
  187. package/dist/lib/syntax/utils.js +0 -70
  188. package/dist/lib/validation/at-rules/container.js +0 -342
  189. package/dist/lib/validation/at-rules/counter-style.js +0 -90
  190. package/dist/lib/validation/at-rules/custom-media.js +0 -50
  191. package/dist/lib/validation/at-rules/document.js +0 -89
  192. package/dist/lib/validation/at-rules/else.js +0 -5
  193. package/dist/lib/validation/at-rules/font-feature-values.js +0 -63
  194. package/dist/lib/validation/at-rules/import.js +0 -150
  195. package/dist/lib/validation/at-rules/keyframes.js +0 -67
  196. package/dist/lib/validation/at-rules/layer.js +0 -41
  197. package/dist/lib/validation/at-rules/media.js +0 -255
  198. package/dist/lib/validation/at-rules/namespace.js +0 -81
  199. package/dist/lib/validation/at-rules/page-margin-box.js +0 -64
  200. package/dist/lib/validation/at-rules/page.js +0 -100
  201. package/dist/lib/validation/at-rules/supports.js +0 -295
  202. package/dist/lib/validation/at-rules/when.js +0 -185
  203. package/dist/lib/validation/atrule.js +0 -184
  204. package/dist/lib/validation/selector.js +0 -36
  205. package/dist/lib/validation/syntax.js +0 -1073
  206. package/dist/lib/validation/syntaxes/complex-selector-list.js +0 -27
  207. package/dist/lib/validation/syntaxes/complex-selector.js +0 -52
  208. package/dist/lib/validation/syntaxes/compound-selector.js +0 -196
  209. package/dist/lib/validation/syntaxes/family-name.js +0 -57
  210. package/dist/lib/validation/syntaxes/keyframe-selector.js +0 -36
  211. package/dist/lib/validation/syntaxes/layer-name.js +0 -57
  212. package/dist/lib/validation/syntaxes/relative-selector-list.js +0 -31
  213. package/dist/lib/validation/syntaxes/relative-selector.js +0 -38
  214. package/dist/lib/validation/syntaxes/selector-list.js +0 -5
  215. package/dist/lib/validation/syntaxes/selector.js +0 -5
  216. package/dist/lib/validation/syntaxes/url.js +0 -40
@@ -0,0 +1,10 @@
1
+ import type { AstNode } from "../../@types/index.d.ts";
2
+ import type { Token } from "../../@types/token.d.ts";
3
+ /**
4
+ *
5
+ * @param node he nod to clone
6
+ * @param cloneChildren deep clone
7
+ * @param cloneMap a map of existing children as keys and their clones as values
8
+ * @returns
9
+ */
10
+ export declare function cloneNode(node: AstNode, cloneChildren?: boolean, cloneMap?: Map<Token | AstNode, Token | AstNode> | null): AstNode;
@@ -0,0 +1,45 @@
1
+ import { EnumToken } from './types.js';
2
+
3
+ /**
4
+ *
5
+ * @param node he nod to clone
6
+ * @param cloneChildren deep clone
7
+ * @param cloneMap a map of existing children as keys and their clones as values
8
+ * @returns
9
+ */
10
+ function cloneNode(node, cloneChildren = false, cloneMap = null) {
11
+ const checkNode = node.typ == EnumToken.DeclarationNodeType ? "val" : "chi";
12
+ const clone = {};
13
+ const properties = {};
14
+ cloneMap?.set?.(node, clone);
15
+ for (const [name, value] of Object.entries(Object.getOwnPropertyDescriptors(node))) {
16
+ // @ts-expect-error
17
+ if (value.value == null || typeof value.value != "object" || name == "parent") {
18
+ // @ts-expect-error
19
+ properties[name] = { ...value };
20
+ // @ts-expect-error
21
+ }
22
+ else if (Array.isArray(value.value)) {
23
+ // @ts-expect-error
24
+ properties[name] = {
25
+ // @ts-expect-error
26
+ ...value,
27
+ value: !cloneChildren && name == checkNode
28
+ ? []
29
+ : // @ts-expect-error
30
+ value.value.map((c) => {
31
+ const newObj = cloneNode(c, cloneChildren, cloneMap);
32
+ cloneMap?.set?.(c, newObj);
33
+ return newObj;
34
+ }),
35
+ };
36
+ }
37
+ else {
38
+ // @ts-expect-error
39
+ properties[name] = { ...value, value: cloneNode(value.value, clone) };
40
+ }
41
+ }
42
+ return Object.defineProperties(clone, properties);
43
+ }
44
+
45
+ export { cloneNode };
@@ -0,0 +1,14 @@
1
+ import type { AstAtRule, AstNode, AstRule, AstStyleSheet } from "../../@types/index.d.ts";
2
+ /**
3
+ * expand css nesting ast nodes
4
+ * @param ast
5
+ *
6
+ * @private
7
+ */
8
+ export declare function expand(ast: AstStyleSheet | AstAtRule | AstRule): AstNode;
9
+ /**
10
+ * replace compound selector
11
+ * @param input
12
+ * @param replace
13
+ */
14
+ export declare function replaceCompound(input: string, replace: string): string;
@@ -1,12 +1,9 @@
1
- import { splitRule, combinators } from './minify.js';
1
+ import { splitRule } from './minify.js';
2
+ import { combinators } from '../syntax/constants.js';
2
3
  import { parseString } from '../parser/parse.js';
3
- import '../parser/tokenize.js';
4
- import '../parser/utils/config.js';
5
- import { EnumToken } from './types.js';
6
4
  import { walkValues } from './walk.js';
7
5
  import { renderToken } from '../renderer/render.js';
8
- import '../renderer/sourcemap/lib/encode.js';
9
- import '../syntax/color/utils/constants.js';
6
+ import { EnumToken } from './types.js';
10
7
 
11
8
  /**
12
9
  * expand css nesting ast nodes
@@ -18,11 +15,11 @@ function expand(ast) {
18
15
  const result = { ...ast, chi: [] };
19
16
  for (let i = 0; i < ast.chi.length; i++) {
20
17
  const node = ast.chi[i];
21
- if (node.typ == EnumToken.RuleNodeType) {
18
+ if (node.typ === EnumToken.RuleNodeType) {
22
19
  // @ts-ignore
23
20
  result.chi.push(...expandRule(node));
24
21
  }
25
- else if (node.typ == EnumToken.AtRuleNodeType && 'chi' in node) {
22
+ else if (node.typ == EnumToken.AtRuleNodeType && "chi" in node) {
26
23
  let hasRule = false;
27
24
  let j = node.chi.length;
28
25
  while (j--) {
@@ -50,20 +47,23 @@ function expandRule(node) {
50
47
  for (; i < ast.chi.length; i++) {
51
48
  if (ast.chi[i].typ == EnumToken.RuleNodeType) {
52
49
  const rule = ast.chi[i];
53
- if (!rule.sel.includes('&')) {
50
+ if (!rule.sel.includes("&")) {
54
51
  const selRule = splitRule(rule.sel);
55
- const arSelf = splitRule(ast.sel).filter((r) => r.every((t) => t != ':before' && t != ':after' && !t.startsWith('::'))).reduce((acc, curr) => acc.concat([curr.join('')]), []).join(',');
52
+ const arSelf = splitRule(ast.sel)
53
+ .filter((r) => r.every((t) => t != ":before" && t != ":after" && !t.startsWith("::")))
54
+ .reduce((acc, curr) => acc.concat([curr.join("")]), [])
55
+ .join(",");
56
56
  if (arSelf.length == 0) {
57
57
  ast.chi.splice(i--, 1);
58
58
  continue;
59
59
  }
60
- //
61
- selRule.forEach(arr => combinators.includes(arr[0].charAt(0)) ? arr.unshift(arSelf) : arr.unshift(arSelf, ' '));
62
- rule.sel = selRule.reduce((acc, curr) => {
63
- acc.push(curr.join(''));
60
+ selRule.forEach((arr) => combinators.includes(arr[0].charAt(0)) ? arr.unshift(arSelf) : arr.unshift(arSelf, " "));
61
+ rule.sel = selRule
62
+ .reduce((acc, curr) => {
63
+ acc.push(curr.join(""));
64
64
  return acc;
65
- }, []).join(',');
66
- // }
65
+ }, [])
66
+ .join(",");
67
67
  }
68
68
  else {
69
69
  let childSelectorCompound = [];
@@ -71,22 +71,22 @@ function expandRule(node) {
71
71
  let withoutCompound = [];
72
72
  // pseudo elements cannot be used with '&'
73
73
  // https://www.w3.org/TR/css-nesting-1/#example-7145ff1e
74
- const rules = splitRule(ast.sel).filter((r) => r.every((t) => t != ':before' && t != ':after' && !t.startsWith('::')));
75
- const parentSelector = !node.sel.includes('&');
74
+ const rules = splitRule(ast.sel).filter((r) => r.every((t) => t != ":before" && t != ":after" && !t.startsWith("::")));
75
+ const parentSelector = !node.sel.includes("&");
76
76
  if (rules.length == 0) {
77
77
  ast.chi.splice(i--, 1);
78
78
  continue;
79
79
  }
80
- for (const sel of (rule.raw ?? splitRule(rule.sel))) {
81
- const s = sel.join('');
82
- if (s.includes('&') || parentSelector) {
83
- if (s.indexOf('&', 1) == -1) {
84
- if (s.at(0) == '&') {
85
- if (s.at(1) == ' ') {
80
+ for (const sel of rule.raw ?? splitRule(rule.sel)) {
81
+ const s = sel.join("");
82
+ if (s.includes("&") || parentSelector) {
83
+ if (s.indexOf("&", 1) == -1) {
84
+ if (s.at(0) == "&") {
85
+ if (s.at(1) == " ") {
86
86
  childSelectorCompound.push(s.slice(2));
87
87
  }
88
88
  else {
89
- if (s == '&' || parentSelector) {
89
+ if (s == "&" || parentSelector) {
90
90
  withCompound.push(s);
91
91
  }
92
92
  }
@@ -101,29 +101,48 @@ function expandRule(node) {
101
101
  }
102
102
  }
103
103
  const selectors = [];
104
- const selector = rules.length > 1 ? ':is(' + rules.map(a => a.join('')).join(',') + ')' : rules[0].join('');
104
+ const selector = rules.length > 1 ? ":is(" + rules.map((a) => a.join("")).join(",") + ")" : rules[0].join("");
105
105
  if (childSelectorCompound.length > 0) {
106
106
  if (childSelectorCompound.length == 1) {
107
- selectors.push(replaceCompound('& ' + childSelectorCompound[0].trim(), selector));
107
+ selectors.push(replaceCompound("& " + childSelectorCompound[0].trim(), selector));
108
108
  }
109
109
  else {
110
- selectors.push(replaceCompound('& :is(' + childSelectorCompound.reduce((acc, curr) => acc + (acc.length > 0 ? ',' : '') + curr.trim(), '') + ')', selector));
110
+ selectors.push(replaceCompound("& :is(" +
111
+ childSelectorCompound.reduce((acc, curr) => acc + (acc.length > 0 ? "," : "") + curr.trim(), "") +
112
+ ")", selector));
111
113
  }
112
114
  }
113
115
  if (withCompound.length > 0) {
114
- if (withCompound.every((t) => t[0] == '&' && t.indexOf('&', 1) == -1)) {
115
- withoutCompound.push(...withCompound.map(t => t.slice(1)));
116
+ if (withCompound.every((t) => t[0] == "&" && t.indexOf("&", 1) == -1)) {
117
+ withoutCompound.push(...withCompound.map((t) => t.slice(1)));
116
118
  withCompound.length = 0;
117
119
  }
118
120
  }
119
121
  if (withoutCompound.length > 0) {
120
122
  if (withoutCompound.length == 1) {
121
- const useIs = rules.length == 1 && selector.match(/^[a-zA-Z.:]/) != null && selector.includes(' ') && withoutCompound.length == 1 && withoutCompound[0].match(/^[a-zA-Z]+$/) != null;
122
- const compound = useIs ? ':is(&)' : '&';
123
- selectors.push(replaceCompound(rules.length == 1 ? (useIs ? withoutCompound[0] + ':is(&)' : (selector.match(/^[.:]/) && withoutCompound[0].match(/^[a-zA-Z]+$/) ? withoutCompound[0] + compound : compound + withoutCompound[0])) : (withoutCompound[0].match(/^[a-zA-Z:]+$/) ? withoutCompound[0].trim() + compound : '&' + (withoutCompound[0].match(/^\S+$/) ? withoutCompound[0].trim() : ':is(' + withoutCompound[0].trim() + ')')), selector));
123
+ const useIs = rules.length == 1 &&
124
+ selector.match(/^[a-zA-Z.:]/) != null &&
125
+ selector.includes(" ") &&
126
+ withoutCompound.length == 1 &&
127
+ withoutCompound[0].match(/^[a-zA-Z]+$/) != null;
128
+ const compound = useIs ? ":is(&)" : "&";
129
+ selectors.push(replaceCompound(rules.length == 1
130
+ ? useIs
131
+ ? withoutCompound[0] + ":is(&)"
132
+ : selector.match(/^[.:]/) && withoutCompound[0].match(/^[a-zA-Z]+$/)
133
+ ? withoutCompound[0] + compound
134
+ : compound + withoutCompound[0]
135
+ : withoutCompound[0].match(/^[a-zA-Z:]+$/)
136
+ ? withoutCompound[0].trim() + compound
137
+ : "&" +
138
+ (withoutCompound[0].match(/^\S+$/)
139
+ ? withoutCompound[0].trim()
140
+ : ":is(" + withoutCompound[0].trim() + ")"), selector));
124
141
  }
125
142
  else {
126
- selectors.push(replaceCompound('&:is(' + withoutCompound.reduce((acc, curr) => acc + (acc.length > 0 ? ',' : '') + curr.trim(), '') + ')', selector));
143
+ selectors.push(replaceCompound("&:is(" +
144
+ withoutCompound.reduce((acc, curr) => acc + (acc.length > 0 ? "," : "") + curr.trim(), "") +
145
+ ")", selector));
127
146
  }
128
147
  }
129
148
  if (withCompound.length > 0) {
@@ -131,7 +150,7 @@ function expandRule(node) {
131
150
  selectors.push(replaceCompound(withCompound[0], selector));
132
151
  }
133
152
  }
134
- rule.sel = selectors.reduce((acc, curr) => curr.length == 0 ? acc : acc + (acc.length > 0 ? ',' : '') + curr, '');
153
+ rule.sel = selectors.reduce((acc, curr) => (curr.length == 0 ? acc : acc + (acc.length > 0 ? "," : "") + curr), "");
135
154
  }
136
155
  ast.chi.splice(i--, 1);
137
156
  result.push(...expandRule(rule));
@@ -139,11 +158,13 @@ function expandRule(node) {
139
158
  else if (ast.chi[i].typ == EnumToken.AtRuleNodeType) {
140
159
  let astAtRule = ast.chi[i];
141
160
  const values = [];
142
- if (astAtRule.nam == 'scope') {
143
- if (astAtRule.val.includes('&')) {
161
+ if (astAtRule.nam === "scope") {
162
+ if (astAtRule.val.includes("&")) {
144
163
  astAtRule.val = replaceCompound(astAtRule.val, ast.sel);
145
164
  }
146
- const slice = astAtRule.chi.slice().filter(t => t.typ == EnumToken.RuleNodeType && t.sel.includes('&'));
165
+ const slice = astAtRule.chi
166
+ .slice()
167
+ .filter((t) => t.typ == EnumToken.RuleNodeType && t.sel.includes("&"));
147
168
  if (slice.length > 0) {
148
169
  expandRule({ ...node, chi: astAtRule.chi.slice() });
149
170
  }
@@ -154,13 +175,13 @@ function expandRule(node) {
154
175
  // @ts-ignore
155
176
  astAtRule.chi.length = 0;
156
177
  for (const r of expandRule(clone)) {
157
- if (r.typ == EnumToken.AtRuleNodeType && 'chi' in r) {
158
- if (astAtRule.val !== '' && r.val !== '') {
159
- if (astAtRule.nam == 'media' && r.nam == 'media') {
160
- r.val = astAtRule.val + ' and ' + r.val;
178
+ if (r.typ == EnumToken.AtRuleNodeType && "chi" in r) {
179
+ if (astAtRule.val !== "" && r.val !== "") {
180
+ if (astAtRule.nam === "media" && r.nam === "media") {
181
+ r.val = astAtRule.val + " and " + r.val;
161
182
  }
162
- else if (astAtRule.nam == 'layer' && r.nam == 'layer') {
163
- r.val = astAtRule.val + '.' + r.val;
183
+ else if (astAtRule.nam == "layer" && r.nam == "layer") {
184
+ r.val = astAtRule.val + "." + r.val;
164
185
  }
165
186
  }
166
187
  // @ts-ignore
@@ -190,38 +211,42 @@ function replaceCompound(input, replace) {
190
211
  const tokens = parseString(input);
191
212
  let replacement = null;
192
213
  for (const t of walkValues(tokens)) {
193
- if (t.value.typ == EnumToken.LiteralTokenType) {
194
- if (t.value.val == '&') {
195
- if (tokens.length == 2) {
196
- if (replacement == null) {
197
- replacement = parseString(replace);
198
- }
199
- t.value.val = replaceCompoundLiteral(t.value.val, replace);
200
- // }
201
- continue;
214
+ if (t.value.typ == EnumToken.NestingSelectorTokenType) {
215
+ if (tokens.length == 2) {
216
+ if (replacement == null) {
217
+ replacement = parseString(replace);
202
218
  }
203
- const rule = splitRule(replace);
204
- t.value.val = rule.length > 1 ? ':is(' + replace + ')' : replace;
219
+ Object.assign(t.value, {
220
+ typ: EnumToken.LiteralTokenType,
221
+ val: replaceCompoundLiteral(t.value.val, replace),
222
+ });
223
+ continue;
205
224
  }
225
+ const rule = splitRule(replace);
226
+ Object.assign(t.value, {
227
+ typ: EnumToken.LiteralTokenType,
228
+ val: rule.length > 1 ? ":is(" + replace + ")" : replace,
229
+ });
206
230
  }
207
231
  }
208
- return tokens.reduce((acc, curr) => acc + renderToken(curr), '');
232
+ return tokens.reduce((acc, curr) => acc + renderToken(curr), "");
209
233
  }
210
234
  function replaceCompoundLiteral(selector, replace) {
211
- const tokens = [''];
235
+ const tokens = [""];
212
236
  let i = 0;
213
237
  for (; i < selector.length; i++) {
214
- if (selector.charAt(i) == '&') {
215
- tokens.push('&');
216
- tokens.push('');
238
+ if (selector.charAt(i) == "&") {
239
+ tokens.push("&", "");
217
240
  }
218
241
  }
219
- return tokens.sort((a, b) => {
220
- if (a == '&') {
242
+ return tokens
243
+ .sort((a, b) => {
244
+ if (a == "&") {
221
245
  return 1;
222
246
  }
223
- return b == '&' ? -1 : 0;
224
- }).reduce((acc, curr) => acc + (curr == '&' ? replace : curr), '');
247
+ return b == "&" ? -1 : 0;
248
+ })
249
+ .reduce((acc, curr) => acc + (curr == "&" ? replace : curr), "");
225
250
  }
226
251
 
227
252
  export { expand, replaceCompound };
@@ -0,0 +1,10 @@
1
+ import type { AstAtRule, AstNode, AstRule, ParserOptions } from "../../../@types/index.d.ts";
2
+ import { EnumToken } from "../types.ts";
3
+ import { FeatureWalkMode } from "./type.ts";
4
+ export declare class ComputeCalcExpressionFeature {
5
+ accept: Set<EnumToken>;
6
+ get ordering(): number;
7
+ get processMode(): FeatureWalkMode;
8
+ static register(options: ParserOptions): void;
9
+ run(ast: AstRule | AstAtRule): AstNode | null;
10
+ }
@@ -2,13 +2,8 @@ import { EnumToken } from '../types.js';
2
2
  import { walkValues, WalkerEvent, WalkerOptionEnum } from '../walk.js';
3
3
  import { evaluate } from '../math/expression.js';
4
4
  import { renderToken } from '../../renderer/render.js';
5
- import '../../renderer/sourcemap/lib/encode.js';
6
- import { mathFuncs } from '../../syntax/syntax.js';
7
- import '../minify.js';
8
- import '../../parser/parse.js';
9
- import '../../parser/tokenize.js';
10
- import '../../parser/utils/config.js';
11
5
  import { FeatureWalkMode } from './type.js';
6
+ import { mathFuncs } from '../../syntax/constants.js';
12
7
 
13
8
  class ComputeCalcExpressionFeature {
14
9
  accept = new Set([EnumToken.RuleNodeType, EnumToken.AtRuleNodeType]);
@@ -25,14 +20,14 @@ class ComputeCalcExpressionFeature {
25
20
  }
26
21
  }
27
22
  run(ast) {
28
- if (!('chi' in ast)) {
23
+ if (!("chi" in ast)) {
29
24
  return null;
30
25
  }
31
26
  for (const node of ast.chi) {
32
27
  if (node.typ != EnumToken.DeclarationNodeType) {
33
28
  continue;
34
29
  }
35
- const set = new Set;
30
+ const set = new Set();
36
31
  for (const { value, parent } of walkValues(node.val, node, {
37
32
  event: WalkerEvent.Enter,
38
33
  // @ts-ignore
@@ -42,20 +37,36 @@ class ComputeCalcExpressionFeature {
42
37
  parent.typ == EnumToken.DeclarationNodeType &&
43
38
  // @ts-ignore
44
39
  parent.val.length == 1 &&
45
- node.typ == EnumToken.FunctionTokenType &&
40
+ (node.typ === EnumToken.MathFunctionTokenType || node.typ === EnumToken.FunctionTokenType) &&
46
41
  mathFuncs.includes(node.val) &&
47
42
  node.chi.length == 1 &&
48
43
  node.chi[0].typ == EnumToken.IdenTokenType) {
49
44
  return WalkerOptionEnum.Ignore;
50
45
  }
51
- if ((node.typ == EnumToken.FunctionTokenType && node.val == 'var') || (!mathFuncs.includes(parent.val) && [EnumToken.ColorTokenType, EnumToken.DeclarationNodeType, EnumToken.RuleNodeType, EnumToken.AtRuleNodeType, EnumToken.StyleSheetNodeType].includes(parent?.typ))) {
46
+ if ((node.typ === EnumToken.WildCardFunctionTokenType && node.val == "var") ||
47
+ (!mathFuncs.includes(parent.val) &&
48
+ [
49
+ EnumToken.MathFunctionTokenType,
50
+ EnumToken.ColorTokenType,
51
+ EnumToken.DeclarationNodeType,
52
+ EnumToken.RuleNodeType,
53
+ EnumToken.AtRuleNodeType,
54
+ EnumToken.StyleSheetNodeType,
55
+ ].includes(parent?.typ))) {
52
56
  return null;
53
57
  }
54
58
  // @ts-ignore
55
- const slice = (node.typ == EnumToken.FunctionTokenType ? node.chi : (node.typ == EnumToken.DeclarationNodeType ? node.val : node.chi))?.slice();
56
- if (slice != null && node.typ == EnumToken.FunctionTokenType && mathFuncs.includes(node.val)) {
59
+ const slice = (node.typ == EnumToken.FunctionTokenType || node.typ == EnumToken.MathFunctionTokenType
60
+ ? node.chi
61
+ : node.typ == EnumToken.DeclarationNodeType
62
+ ? node.val
63
+ : node.chi)?.slice();
64
+ if (slice != null &&
65
+ (node.typ === EnumToken.MathFunctionTokenType ||
66
+ (node.typ == EnumToken.FunctionTokenType &&
67
+ mathFuncs.includes(node.val)))) {
57
68
  // @ts-ignore
58
- const key = 'chi' in node ? 'chi' : 'val';
69
+ const key = "chi" in node ? "chi" : "val";
59
70
  const str1 = renderToken({ ...node, [key]: slice });
60
71
  const str2 = renderToken(node); // values.reduce((acc: string, curr: Token): string => acc + renderToken(curr), '');
61
72
  if (str1.length <= str2.length) {
@@ -65,25 +76,52 @@ class ComputeCalcExpressionFeature {
65
76
  return WalkerOptionEnum.Ignore;
66
77
  }
67
78
  return null;
68
- }
79
+ },
69
80
  })) {
70
- if (value != null && value.typ == EnumToken.FunctionTokenType && mathFuncs.includes(value.val)) {
81
+ if (value != null &&
82
+ (value.typ === EnumToken.MathFunctionTokenType ||
83
+ (value.typ == EnumToken.FunctionTokenType && mathFuncs.includes(value.val)))) {
71
84
  if (!set.has(value)) {
72
85
  set.add(value);
73
86
  if (parent != null) {
74
87
  // @ts-ignore
75
- const cp = value.typ == EnumToken.FunctionTokenType && mathFuncs.includes(value.val) && value.val != 'calc' ? [value] : (value.typ == EnumToken.DeclarationNodeType ? value.val : value.chi);
88
+ const cp = (value.typ === EnumToken.MathFunctionTokenType ||
89
+ (value.typ == EnumToken.FunctionTokenType &&
90
+ mathFuncs.includes(value.val))) &&
91
+ value.val != "calc"
92
+ ? [value]
93
+ : value.typ == EnumToken.DeclarationNodeType
94
+ ? value.val
95
+ : value.chi;
76
96
  const values = evaluate(cp);
97
+ // fix a + -b to a - b
98
+ for (const { value } of walkValues(values)) {
99
+ if (value.typ === EnumToken.BinaryExpressionTokenType &&
100
+ value.op === EnumToken.Add &&
101
+ Math.sign(value.r.val) == -1) {
102
+ value.op = EnumToken.Sub;
103
+ // @ts-expect-error
104
+ value.r.val *= -1;
105
+ }
106
+ }
77
107
  // @ts-ignore
78
108
  const children = parent.typ == EnumToken.DeclarationNodeType ? parent.val : parent.chi;
79
109
  if (values.length == 1 && values[0].typ != EnumToken.BinaryExpressionTokenType) {
80
110
  for (let i = 0; i < children.length; i++) {
81
111
  if (children[i] == value) {
82
- children.splice(i, 1, !(parent.typ == EnumToken.FunctionTokenType && parent.val == 'calc') && (typeof values[0].val != 'number' && !(values[0].typ == EnumToken.FunctionTokenType && mathFuncs.includes(values[0].val))) ? {
83
- typ: EnumToken.FunctionTokenType,
84
- val: 'calc',
85
- chi: values
86
- } : values[0]);
112
+ children.splice(i, 1, !(parent.typ === EnumToken.MathFunctionTokenType ||
113
+ (parent.typ == EnumToken.FunctionTokenType &&
114
+ parent.val == "calc")) &&
115
+ typeof values[0].val != "number" &&
116
+ !(values[0].typ == EnumToken.MathFunctionTokenType ||
117
+ (values[0].typ == EnumToken.FunctionTokenType &&
118
+ mathFuncs.includes(values[0].val)))
119
+ ? {
120
+ typ: EnumToken.MathFunctionTokenType,
121
+ val: "calc",
122
+ chi: values,
123
+ }
124
+ : values[0]);
87
125
  break;
88
126
  }
89
127
  }
@@ -92,9 +130,9 @@ class ComputeCalcExpressionFeature {
92
130
  for (let i = 0; i < children.length; i++) {
93
131
  if (children[i] == value) {
94
132
  children.splice(i, 1, {
95
- typ: EnumToken.FunctionTokenType,
96
- val: 'calc',
97
- chi: values
133
+ typ: EnumToken.MathFunctionTokenType,
134
+ val: "calc",
135
+ chi: values,
98
136
  });
99
137
  break;
100
138
  }
@@ -0,0 +1,10 @@
1
+ import type { AstDeclaration, AstNode, ParserOptions } from "../../../@types/index.d.ts";
2
+ import { EnumToken } from "../types.ts";
3
+ import { FeatureWalkMode } from "./type.ts";
4
+ export declare class ExpandIfFeature {
5
+ accept: Set<EnumToken>;
6
+ get ordering(): number;
7
+ get processMode(): FeatureWalkMode;
8
+ static register(options: ParserOptions): void;
9
+ run(declaration: AstDeclaration): AstNode | null;
10
+ }