@tbela99/css-parser 1.4.1 → 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 +168 -4
  7. package/README.md +82 -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 +24393 -18479
  12. package/dist/index.cjs +27430 -21519
  13. package/dist/index.d.ts +1403 -933
  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 +543 -215
  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 +53 -47
  180. package/dist/web.d.ts +169 -0
  181. package/dist/web.js +50 -41
  182. package/package.json +18 -13
  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
@@ -1,123 +1,601 @@
1
- import { EnumToken } from '../../ast/types.js';
2
- import '../../ast/minify.js';
1
+ import { EnumToken, ColorType, ValidationLevel } from '../../ast/types.js';
2
+ import { definedPropertySettings, tokensfuncDefMap, COLORS_NAMES, nonStandardColors, systemColors, deprecatedSystemColors, tokensMap, trimTokenSpace } from '../../syntax/constants.js';
3
+ import { renamedStandardProperties, isColor, parseColor, isWhiteSpace, isValue } from '../../syntax/syntax.js';
4
+ import { getSyntaxRule, getParsedSyntax } from '../../validation/config.js';
5
+ import { trimArray, matchAllSyntax, createValidationContext } from '../../validation/match.js';
6
+ import { ValidationSyntaxGroupEnum, ValidationTokenEnum } from '../../validation/parser/typedef.js';
3
7
  import { walkValues } from '../../ast/walk.js';
4
- import '../parse.js';
5
- import '../tokenize.js';
6
- import './config.js';
7
- import { isWhiteSpace } from '../../syntax/syntax.js';
8
- import '../../syntax/color/utils/constants.js';
9
- import '../../renderer/sourcemap/lib/encode.js';
8
+ import { equalsIgnoreCase } from './text.js';
9
+ import { buildExpression } from '../../ast/math/expression.js';
10
+ import { splitTokenList } from '../../validation/utils/list.js';
10
11
 
11
- function parseDeclarationNode(node, errors, location) {
12
- while (node.val[0]?.typ == EnumToken.WhitespaceTokenType) {
13
- node.val.shift();
12
+ /**
13
+ *
14
+ * @param template
15
+ * @returns
16
+ */
17
+ function parseGridTemplate(template) {
18
+ let result = "";
19
+ let buffer = "";
20
+ for (let i = 0; i < template.length; i++) {
21
+ const char = template[i];
22
+ if (isWhiteSpace(char.charCodeAt(0))) {
23
+ while (i + 1 < template.length && isWhiteSpace(template[i + 1].charCodeAt(0))) {
24
+ i++;
25
+ }
26
+ result += buffer + " ";
27
+ buffer = "";
28
+ }
29
+ else if (char == ".") {
30
+ while (i + 1 < template.length && template[i + 1] == ".") {
31
+ i++;
32
+ }
33
+ if (isWhiteSpace(result.at(-1)?.charCodeAt(0))) {
34
+ result = result.slice(0, -1);
35
+ }
36
+ result += buffer + char;
37
+ buffer = "";
38
+ }
39
+ else {
40
+ buffer += char;
41
+ }
14
42
  }
15
- if (!node.nam.startsWith('--') && node.val.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)).length == 0) {
16
- errors.push({
17
- action: 'drop',
18
- message: 'doParse: invalid declaration',
19
- location
43
+ return buffer.length > 0 ? result + buffer : result;
44
+ }
45
+ /**
46
+ *
47
+ * @param tokens
48
+ * @returns
49
+ */
50
+ function isDeclarationValue(tokens) {
51
+ const stack = [];
52
+ let i = 0;
53
+ for (; i < tokens.length; i++) {
54
+ if (tokens[i].typ === EnumToken.WhitespaceTokenType || tokens[i].typ === EnumToken.CommentTokenType) {
55
+ continue;
56
+ }
57
+ else if (tokensfuncDefMap.has(tokens[i].typ) || tokens[i].typ === EnumToken.StartParensTokenType) {
58
+ stack.push(tokens[i]);
59
+ }
60
+ else if (tokens[i].typ === EnumToken.CommaTokenType || tokens[i].typ === EnumToken.LiteralTokenType) {
61
+ stack.push(tokens[i]);
62
+ }
63
+ else if (isValue(tokens[i])) {
64
+ if (stack.at(-1)?.typ === EnumToken.LiteralTokenType) {
65
+ stack.pop();
66
+ }
67
+ }
68
+ else if (tokens[i].typ === EnumToken.EndParensTokenType) {
69
+ if (stack.at(-1)?.typ === EnumToken.StartParensTokenType || tokensfuncDefMap.has(stack.at(-1)?.typ)) {
70
+ stack.pop();
71
+ }
72
+ }
73
+ }
74
+ return {
75
+ success: stack.length === 0,
76
+ errors: stack.length > 0
77
+ ? [
78
+ {
79
+ action: "drop",
80
+ message: `unexpected declaration value at ${stack.at(-1)?.loc?.src}:${stack.at(-1)?.loc?.sta.lin}:${stack.at(-1)?.loc?.sta.col}`,
81
+ node: stack.at(-1),
82
+ location: stack.at(-1)?.loc,
83
+ },
84
+ ]
85
+ : [],
86
+ };
87
+ }
88
+ /**
89
+ * parse declaration
90
+ * @param tokens
91
+ * @param parent
92
+ * @param options
93
+ * @param errors
94
+ */
95
+ function parseDeclaration(tokens, parent, options, errors) {
96
+ const name = tokens.shift();
97
+ let i;
98
+ let rules = null;
99
+ let syntaxRules = null;
100
+ let success = true;
101
+ let validate = typeof options.validation === "boolean"
102
+ ? options.validation
103
+ : options.validation & ValidationLevel.Declaration;
104
+ if (renamedStandardProperties.has(name.val)) {
105
+ name.val = renamedStandardProperties.get(name.val);
106
+ }
107
+ for (i = 0; i < tokens.length; i++) {
108
+ const token = tokens[i];
109
+ if (token.typ == EnumToken.WhitespaceTokenType ||
110
+ token.typ == EnumToken.CommentTokenType ||
111
+ token.typ == EnumToken.InvalidCommentTokenType) {
112
+ continue;
113
+ }
114
+ break;
115
+ }
116
+ if ((name.typ !== EnumToken.IdenTokenType && name.typ !== EnumToken.DashedIdenTokenType) ||
117
+ tokens[i]?.typ !== EnumToken.ColonTokenType) {
118
+ return Object.defineProperty(Object.assign({
119
+ typ: EnumToken.RawNodeTokenType,
120
+ chi: tokens,
121
+ }), "loc", {
122
+ ...definedPropertySettings,
123
+ value: {
124
+ ...name.loc,
125
+ end: tokens[tokens.length - 1]?.loc?.end ?? name.loc.end,
126
+ },
20
127
  });
21
- return null;
22
128
  }
23
- if ('composes' == node.nam.toLowerCase()) {
24
- let left = [];
25
- let right = [];
26
- let current = 0;
27
- let hasFrom = 0;
28
- for (; current < node.val.length; current++) {
29
- if (EnumToken.WhitespaceTokenType == node.val[current].typ || EnumToken.CommentTokenType == node.val[current].typ) {
30
- if (!hasFrom) {
31
- left.push(node.val[current]);
129
+ tokens = trimArray(tokens.slice(i + 1));
130
+ for (i = 0; i < tokens.length; i++) {
131
+ const token = tokens[i];
132
+ if (token.typ == EnumToken.WhitespaceTokenType ||
133
+ token.typ == EnumToken.CommentTokenType ||
134
+ token.typ == EnumToken.InvalidCommentTokenType) {
135
+ continue;
136
+ }
137
+ if (tokens[i].typ === EnumToken.UrlFunctionTokenDefType) {
138
+ let k = i;
139
+ while (k < tokens.length) {
140
+ if (tokens[++k]?.typ === EnumToken.WhitespaceTokenType ||
141
+ tokens[k]?.typ === EnumToken.CommentTokenType) {
142
+ continue;
32
143
  }
33
- else {
34
- right.push(node.val[current]);
144
+ if (tokens[k]?.typ !== EnumToken.EndParensTokenType) {
145
+ break;
35
146
  }
36
- continue;
37
147
  }
38
- if (EnumToken.IdenTokenType == node.val[current].typ || EnumToken.DashedIdenTokenType == node.val[current].typ || EnumToken.StringTokenType == node.val[current].typ) {
39
- if (EnumToken.IdenTokenType == node.val[current].typ) {
40
- if ('from' == node.val[current].val) {
41
- if (hasFrom) {
42
- return null;
43
- }
44
- hasFrom++;
45
- continue;
148
+ if (tokens[k].typ === EnumToken.LiteralTokenType ||
149
+ tokens[k].typ === EnumToken.IdenTokenType ||
150
+ tokens[k].typ === EnumToken.DashedIdenTokenType ||
151
+ tokens[k].typ === EnumToken.HashTokenType ||
152
+ tokens[k].typ === EnumToken.ClassSelectorTokenType) {
153
+ let j = k;
154
+ let val = tokens[k].val;
155
+ while (j + 1 < tokens.length) {
156
+ if (tokens[++j].typ !== EnumToken.LiteralTokenType &&
157
+ tokens[j].typ !== EnumToken.IdenTokenType &&
158
+ tokens[j].typ !== EnumToken.DashedIdenTokenType &&
159
+ tokens[j].typ !== EnumToken.HashTokenType &&
160
+ tokens[j].typ !== EnumToken.ClassSelectorTokenType) {
161
+ break;
46
162
  }
163
+ val += tokens[j].val;
47
164
  }
48
- if (hasFrom) {
49
- right.push(node.val[current]);
165
+ Object.assign(tokens[k], {
166
+ typ: EnumToken.UrlTokenTokenType,
167
+ val,
168
+ });
169
+ tokens[k].loc.end = tokens[j].loc.end;
170
+ tokens.splice(k + 1, j - k - 1);
171
+ }
172
+ }
173
+ }
174
+ if (validate && name.typ === EnumToken.IdenTokenType) {
175
+ if (parent != null &&
176
+ (parent.typ == EnumToken.AtRuleNodeType || parent.typ === EnumToken.InvalidAtRuleNodeType) &&
177
+ parent.nam != "import" &&
178
+ parent.nam != "supports" &&
179
+ parent.nam != "media") {
180
+ // check @at-rule description
181
+ // pick up the syntax or reject immediately
182
+ // else do this
183
+ rules = getSyntaxRule(ValidationSyntaxGroupEnum.AtRules, "@" + parent.nam);
184
+ if (rules != null) {
185
+ const propertyDescriptors = rules.getPropertyDescriptors();
186
+ if (propertyDescriptors != null) {
187
+ syntaxRules = propertyDescriptors[name.val.toLowerCase()];
50
188
  }
51
189
  else {
52
- left.push(node.val[current]);
190
+ syntaxRules =
191
+ rules.acceptAnyDeclarations && rules.acceptAnyRules
192
+ ? getParsedSyntax(ValidationSyntaxGroupEnum.Declarations, name.val.toLowerCase())
193
+ : rules.getBlockRules();
194
+ if (syntaxRules == null) {
195
+ errors.push({
196
+ action: "drop",
197
+ message: "declaration not allowed in context",
198
+ node: name,
199
+ location: name.loc,
200
+ });
201
+ return Object.defineProperty(Object.assign(name, {
202
+ typ: EnumToken.InvalidDeclarationNodeType,
203
+ nam: name.val,
204
+ val: tokens,
205
+ }), "loc", {
206
+ ...definedPropertySettings,
207
+ value: {
208
+ ...name.loc,
209
+ end: tokens[tokens.length - 1].loc.end,
210
+ },
211
+ });
212
+ }
53
213
  }
54
- continue;
55
214
  }
56
- break;
57
215
  }
58
- if (hasFrom <= 1 && current > 0) {
59
- if (hasFrom == 0) {
60
- node.val.splice(0, left.length, {
61
- typ: EnumToken.ComposesSelectorNodeType,
62
- l: left,
63
- r: null
64
- });
216
+ // <declaration-list> or <declaration-rule-list>
217
+ // else
218
+ if (syntaxRules == null ||
219
+ (syntaxRules.length === 1 &&
220
+ syntaxRules[0].typ === ValidationTokenEnum.PropertyType &&
221
+ (syntaxRules[0].val === "declaration-list" ||
222
+ syntaxRules[0].val === "declaration-rule-list"))) {
223
+ if (parent?.typ === EnumToken.AtRuleNodeType &&
224
+ (parent.nam === "swash" ||
225
+ parent.nam === "annotation" ||
226
+ parent.nam === "ornaments" ||
227
+ parent.nam === "stylistic" ||
228
+ parent.nam === "historical-forms")) {
229
+ syntaxRules = getParsedSyntax(ValidationSyntaxGroupEnum.Syntaxes, "font-feature-custom-ident");
230
+ }
231
+ else if (parent?.typ === EnumToken.AtRuleNodeType && parent.nam === "styleset") {
232
+ syntaxRules = getParsedSyntax(ValidationSyntaxGroupEnum.Syntaxes, "font-feature-custom-ident-list");
233
+ }
234
+ else if (parent?.typ === EnumToken.AtRuleNodeType && parent.nam === "character-variant") {
235
+ syntaxRules = getParsedSyntax(ValidationSyntaxGroupEnum.Syntaxes, "font-feature-custom-ident-character-variant");
65
236
  }
66
237
  else {
67
- node.val.splice(0, current, {
68
- typ: EnumToken.ComposesSelectorNodeType,
69
- l: left,
70
- r: right.reduce((a, b) => {
71
- return a == null ? b : b.typ == EnumToken.WhitespaceTokenType || b.typ == EnumToken.CommentTokenType ? a : b;
72
- }, null)
238
+ syntaxRules = getParsedSyntax(ValidationSyntaxGroupEnum.Declarations, name.val.toLowerCase());
239
+ }
240
+ }
241
+ }
242
+ if (tokens.length === 0 && name.typ !== EnumToken.DashedIdenTokenType) {
243
+ errors.push({
244
+ action: "drop",
245
+ message: "declaration value missing",
246
+ node: name,
247
+ location: name.loc,
248
+ });
249
+ return Object.defineProperty(Object.assign(name, {
250
+ typ: EnumToken.InvalidDeclarationNodeType,
251
+ nam: name.val,
252
+ val: tokens,
253
+ }), "loc", {
254
+ ...definedPropertySettings,
255
+ value: {
256
+ ...name.loc,
257
+ end: tokens[tokens.length - 1]?.loc.end ?? name.loc.end,
258
+ },
259
+ });
260
+ }
261
+ const stack = [];
262
+ let result = null;
263
+ let token;
264
+ let index;
265
+ if (syntaxRules != null) {
266
+ const doNotValidate = options.validation === false || options.validation === ValidationLevel.None;
267
+ result = doNotValidate ? null : matchAllSyntax(syntaxRules, createValidationContext(tokens), options);
268
+ if (doNotValidate || result != null) {
269
+ success = doNotValidate || result?.success;
270
+ if (success) {
271
+ for (const { value } of walkValues(tokens)) {
272
+ if (value.typ === EnumToken.IdenTokenType && isColor(value)) {
273
+ parseColor(value);
274
+ }
275
+ else if (value.typ === EnumToken.ColorTokenType) {
276
+ if (isColor(value)) {
277
+ parseColor(value);
278
+ }
279
+ }
280
+ }
281
+ }
282
+ if (!doNotValidate && !result?.success && result.errors.length > 0) {
283
+ errors.push(...result.errors);
284
+ }
285
+ if (!doNotValidate && !(success || result.success)) {
286
+ return Object.defineProperty(Object.assign(name, {
287
+ typ: EnumToken.InvalidDeclarationNodeType,
288
+ nam: name.val,
289
+ val: tokens,
290
+ }), "loc", {
291
+ ...definedPropertySettings,
292
+ value: {
293
+ ...name.loc,
294
+ end: tokens[tokens.length - 1]?.loc.end ?? name.loc.end,
295
+ },
73
296
  });
74
297
  }
75
298
  }
76
299
  }
77
- for (const { value: val, parent } of walkValues(node.val, node)) {
78
- if (val.typ == EnumToken.AttrTokenType && val.chi.every((t) => [EnumToken.IdenTokenType, EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ))) {
79
- // @ts-ignore
80
- val.typ = EnumToken.IdenListTokenType;
300
+ for (i = 0; i < tokens.length; i++) {
301
+ token = tokens[i];
302
+ if (tokensfuncDefMap.has(token.typ) || token.typ == EnumToken.StartParensTokenType) {
303
+ stack.push(token);
304
+ continue;
81
305
  }
82
- else if (val.typ == EnumToken.StringTokenType && (node.nam == 'grid' || node.nam == 'grid-template-areas' || node.nam == 'grid-template-rows' || node.nam == 'grid-template-columns')) {
83
- val.val = val.val.at(0) + parseGridTemplate(val.val.slice(1, -1)) + val.val.at(-1);
84
- // @ts-ignore
85
- const array = parent?.chi ?? node.val;
86
- const index = array.indexOf(val);
87
- if (index > 0 && array[index - 1].typ == EnumToken.WhitespaceTokenType) {
88
- array.splice(index - 1, 1);
306
+ switch (token.typ) {
307
+ case EnumToken.IdenTokenType:
308
+ if (tokens[i + 1]?.typ == EnumToken.StartParensTokenType) {
309
+ Object.assign(token, {
310
+ typ: EnumToken.FunctionTokenDefType,
311
+ });
312
+ token.loc.end = tokens[i + 1].loc.end;
313
+ tokens.splice(i + 1, 1);
314
+ stack.push(token);
315
+ }
316
+ break;
317
+ case EnumToken.Literal:
318
+ if (token.val === "/" && stack.at(-1)?.typ == EnumToken.MathFunctionTokenDefType) {
319
+ Object.assign(token, {
320
+ typ: EnumToken.Div,
321
+ });
322
+ }
323
+ else if (token.val === "-" &&
324
+ stack.at(-1)?.typ == EnumToken.MathFunctionTokenDefType) {
325
+ Object.assign(token, {
326
+ typ: EnumToken.Sub,
327
+ });
328
+ }
329
+ break;
330
+ case EnumToken.Star:
331
+ case EnumToken.Plus:
332
+ Object.assign(token, {
333
+ typ: tokensMap.get(token.typ),
334
+ });
335
+ break;
336
+ case EnumToken.EndParensTokenType:
337
+ if (stack.length == 0) {
338
+ errors.push({
339
+ action: "drop",
340
+ message: "unbalanced parentheses",
341
+ node: token,
342
+ location: token.loc,
343
+ });
344
+ return Object.defineProperty(Object.assign(name, {
345
+ typ: EnumToken.InvalidDeclarationNodeType,
346
+ nam: name.val,
347
+ val: tokens,
348
+ }), "loc", {
349
+ ...definedPropertySettings,
350
+ value: {
351
+ ...name.loc,
352
+ end: tokens[tokens.length - 1]?.loc.end ?? name.loc.end,
353
+ },
354
+ });
355
+ }
356
+ if (stack.at(-1)?.typ === EnumToken.StartParensTokenType || tokensfuncDefMap.has(stack.at(-1)?.typ)) {
357
+ index = tokens.indexOf(stack.at(-1));
358
+ tokens.splice(i, 1);
359
+ Object.assign(tokens[index], {
360
+ typ: stack.at(-1)?.typ === EnumToken.StartParensTokenType
361
+ ? EnumToken.ParensTokenType
362
+ : tokensfuncDefMap.get(stack.at(-1)?.typ),
363
+ chi: trimArray(tokens.splice(index + 1, i - index - 1)),
364
+ });
365
+ if (tokens[index].typ === EnumToken.WildCardFunctionTokenType &&
366
+ equalsIgnoreCase(tokens[index].val, "if")) {
367
+ if (tokens[index].chi.at(-1)?.typ === EnumToken.SemiColonTokenType) {
368
+ tokens[index].chi.pop();
369
+ }
370
+ let foundElse = false;
371
+ tokens[index].chi = splitTokenList(tokens[index].chi, [EnumToken.SemiColonTokenType], true).reduce((acc, curr) => {
372
+ if (foundElse) {
373
+ // else already found
374
+ // ignore everything after else
375
+ // if(media(any-pointer: fine): 30px; else: 44px; media(any-pointer: fine): 23px); -> if(media(any-pointer: fine): 30px; else: 44px;);
376
+ return acc;
377
+ }
378
+ let index = -1;
379
+ while (++index < curr.length) {
380
+ if (curr[index].typ == EnumToken.IdenTokenType &&
381
+ equalsIgnoreCase("else", curr[index].val)) {
382
+ foundElse = true;
383
+ }
384
+ if (curr[index].typ === EnumToken.ColonTokenType) {
385
+ break;
386
+ }
387
+ }
388
+ if (foundElse && acc.length > 0) {
389
+ acc[acc.length - 1] = {
390
+ typ: EnumToken.IfElseConditionTokenType,
391
+ l: acc[acc.length - 1],
392
+ r: {
393
+ typ: EnumToken.IfConditionTokenType,
394
+ l: trimArray(curr.slice(0, index)),
395
+ r: trimArray(curr.slice(index + 1)),
396
+ },
397
+ };
398
+ }
399
+ else {
400
+ acc.push({
401
+ typ: EnumToken.IfConditionTokenType,
402
+ l: trimArray(curr.slice(0, index)),
403
+ r: trimArray(curr.slice(index + 1)),
404
+ });
405
+ }
406
+ return acc;
407
+ }, []);
408
+ }
409
+ else if (tokens[index].typ === EnumToken.UrlFunctionTokenType) {
410
+ let l = -1;
411
+ while (++l < tokens[index].chi.length) {
412
+ if (tokens[index].chi[l].typ === EnumToken.StringTokenType) {
413
+ break;
414
+ }
415
+ else if (tokens[index].chi[l].typ === EnumToken.IdenTokenType) {
416
+ let m = l + 1;
417
+ while (tokens[index].chi[m]?.typ === EnumToken.ClassSelectorTokenType) {
418
+ Object.assign(tokens[index].chi[l], {
419
+ typ: EnumToken.UrlTokenTokenType,
420
+ val: tokens[index].chi[l].val +
421
+ tokens[index].chi[m].val,
422
+ });
423
+ tokens[index].chi[l].loc.end = tokens[index].chi[m].loc.end;
424
+ tokens[index].chi.splice(m, 1);
425
+ }
426
+ break;
427
+ }
428
+ }
429
+ if (tokens[index].chi[l]?.typ === EnumToken.StringTokenType &&
430
+ /^[a-zA-Z0-0/_.-]+$/.test(tokens[index].chi[l].val.slice(1, -1))) {
431
+ Object.assign(tokens[index].chi[l], {
432
+ typ: EnumToken.UrlTokenTokenType,
433
+ val: tokens[index].chi[l].val.slice(1, -1),
434
+ });
435
+ }
436
+ }
437
+ i = index;
438
+ if (tokens[index].typ === EnumToken.MathFunctionTokenType &&
439
+ equalsIgnoreCase("calc", tokens[index].val)) {
440
+ tokens[index].chi = [buildExpression(tokens[index].chi)];
441
+ }
442
+ else if (tokens[index].typ === EnumToken.ColorTokenType) {
443
+ if (isColor(tokens[index])) {
444
+ parseColor(tokens[index]);
445
+ }
446
+ else {
447
+ success = false;
448
+ tokens[index].typ = EnumToken.FunctionTokenType;
449
+ errors.push({
450
+ action: "drop",
451
+ message: `invalid color at ${tokens[index].loc?.src}:${tokens[index].loc?.sta.lin}:${tokens[index].loc?.sta.col}`,
452
+ });
453
+ }
454
+ }
455
+ }
456
+ stack.pop();
457
+ break;
458
+ case EnumToken.IdenTokenType:
459
+ {
460
+ const val = token.val.toLowerCase();
461
+ if (val in COLORS_NAMES || val === "currentcolor") {
462
+ Object.assign(token, {
463
+ val,
464
+ typ: EnumToken.ColorTokenType,
465
+ kin: ColorType.LIT,
466
+ });
467
+ }
468
+ else if (nonStandardColors.has(val)) {
469
+ Object.assign(token, {
470
+ typ: EnumToken.ColorTokenType,
471
+ kin: ColorType.NON_STD,
472
+ });
473
+ }
474
+ else if (systemColors.has(val)) {
475
+ Object.assign(token, {
476
+ typ: EnumToken.ColorTokenType,
477
+ kin: ColorType.SYS,
478
+ });
479
+ }
480
+ else if (deprecatedSystemColors.has(val)) {
481
+ Object.assign(token, {
482
+ typ: EnumToken.ColorTokenType,
483
+ kin: ColorType.DPSYS,
484
+ });
485
+ }
486
+ }
487
+ break;
488
+ }
489
+ if (trimTokenSpace.has(token.typ)) {
490
+ if (tokens[i + 1]?.typ === EnumToken.WhitespaceTokenType) {
491
+ tokens.splice(i + 1, 1);
492
+ }
493
+ if (tokens[i - 1]?.typ == EnumToken.WhitespaceTokenType) {
494
+ tokens.splice(--i, 1);
89
495
  }
90
496
  }
91
497
  }
92
- return node;
93
- }
94
- function parseGridTemplate(template) {
95
- let result = '';
96
- let buffer = '';
97
- for (let i = 0; i < template.length; i++) {
98
- const char = template[i];
99
- if (isWhiteSpace(char.codePointAt(0))) {
100
- while (i + 1 < template.length && isWhiteSpace(template[i + 1].codePointAt(0))) {
101
- i++;
102
- }
103
- result += buffer + ' ';
104
- buffer = '';
498
+ if (stack.length > 0) {
499
+ errors.push({
500
+ action: "drop",
501
+ message: "unbalanced parenthesis",
502
+ node: stack[stack.length - 1],
503
+ location: stack[stack.length - 1].loc,
504
+ });
505
+ return Object.defineProperty(Object.assign(name, {
506
+ typ: EnumToken.InvalidDeclarationNodeType,
507
+ nam: name.val,
508
+ val: tokens,
509
+ }), "loc", {
510
+ ...definedPropertySettings,
511
+ value: {
512
+ ...name.loc,
513
+ end: tokens[tokens.length - 1].loc.end,
514
+ },
515
+ });
516
+ }
517
+ for (const { value } of walkValues(tokens)) {
518
+ if (value.typ === EnumToken.IdenTokenType && isColor(value)) {
519
+ parseColor(value);
105
520
  }
106
- else if (char == '.') {
107
- while (i + 1 < template.length && template[i + 1] == '.') {
108
- i++;
109
- }
110
- if (isWhiteSpace((result.at(-1)?.codePointAt(0)))) {
111
- result = result.slice(0, -1);
521
+ }
522
+ if (name.val === "grid" ||
523
+ name.val === "grid-template-areas" ||
524
+ name.val === "grid-template-rows" ||
525
+ name.val === "grid-template-columns") {
526
+ let i = 0;
527
+ for (; i < tokens.length; i++) {
528
+ if (tokens[i].typ === EnumToken.StringTokenType) {
529
+ if (/[\s.]/.test(tokens[i].val)) {
530
+ tokens[i].val = parseGridTemplate(tokens[i].val);
531
+ }
532
+ if (tokens[i + 1]?.typ === EnumToken.WhitespaceTokenType &&
533
+ tokens[i + 2]?.typ === EnumToken.StringTokenType) {
534
+ tokens.splice(i + 1, 1);
535
+ }
112
536
  }
113
- result += buffer + char;
114
- buffer = '';
115
537
  }
116
- else {
117
- buffer += char;
538
+ }
539
+ if (validate && syntaxRules == null && name.typ === EnumToken.IdenTokenType) {
540
+ const node = Object.defineProperty(Object.assign(name, {
541
+ typ: options.validation & ValidationLevel.Declaration
542
+ ? EnumToken.InvalidDeclarationNodeType
543
+ : EnumToken.DeclarationNodeType,
544
+ nam: name.val,
545
+ val: tokens,
546
+ }), "loc", {
547
+ ...definedPropertySettings,
548
+ value: {
549
+ ...name.loc,
550
+ end: tokens[tokens.length - 1]?.loc?.end ?? name.loc.end,
551
+ },
552
+ });
553
+ if (options.validation & ValidationLevel.Declaration) {
554
+ errors.push({
555
+ action: "drop",
556
+ message: "unknown declaration",
557
+ node: node,
558
+ location: node.loc,
559
+ });
118
560
  }
561
+ return node;
119
562
  }
120
- return buffer.length > 0 ? result + buffer : result;
563
+ if (equalsIgnoreCase("composes", name.val)) {
564
+ let index = -1;
565
+ for (let i = 0; i < tokens.length; i++) {
566
+ if (tokens[i].typ === EnumToken.IdenTokenType && equalsIgnoreCase("from", tokens[i].val)) {
567
+ index = i;
568
+ break;
569
+ }
570
+ }
571
+ const left = trimArray(index == -1 ? tokens : tokens.slice(0, index));
572
+ const right = index == -1 ? null : trimArray(tokens.slice(index + 1));
573
+ tokens = [
574
+ Object.defineProperty({
575
+ typ: EnumToken.ComposesSelectorNodeType,
576
+ l: left,
577
+ r: right?.[0] ?? null,
578
+ }, "loc", {
579
+ ...definedPropertySettings,
580
+ value: {
581
+ ...tokens[0].loc,
582
+ sta: left[0]?.loc?.sta,
583
+ end: index != -1 ? right[right.length - 1]?.loc?.end : left[left.length - 1].loc.end,
584
+ },
585
+ }),
586
+ ];
587
+ }
588
+ return Object.defineProperty(Object.assign(name, {
589
+ typ: success ? EnumToken.DeclarationNodeType : EnumToken.InvalidDeclarationNodeType,
590
+ nam: name.val,
591
+ val: tokens,
592
+ }), "loc", {
593
+ ...definedPropertySettings,
594
+ value: {
595
+ ...name.loc,
596
+ end: (tokens[tokens.length - 1] ?? name).loc.end,
597
+ },
598
+ });
121
599
  }
122
600
 
123
- export { parseDeclarationNode };
601
+ export { isDeclarationValue, parseDeclaration };