@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,1073 +0,0 @@
1
- import { ValidationTokenEnum, renderSyntax } from './parser/parse.js';
2
- import { SyntaxValidationResult, EnumToken, ColorType } from '../ast/types.js';
3
- import '../ast/minify.js';
4
- import '../ast/walk.js';
5
- import '../parser/parse.js';
6
- import '../parser/tokenize.js';
7
- import '../parser/utils/config.js';
8
- import { wildCardFuncs, isIdentColor, mathFuncs, isColor } from '../syntax/syntax.js';
9
- import { renderToken } from '../renderer/render.js';
10
- import '../renderer/sourcemap/lib/encode.js';
11
- import { getSyntaxConfig, getParsedSyntax, getSyntax } from './config.js';
12
- import './syntaxes/complex-selector.js';
13
- import { funcLike, colorsFunc } from '../syntax/color/utils/constants.js';
14
- import '../../types.js';
15
- import '../ast/features/type.js';
16
-
17
- const config = getSyntaxConfig();
18
- // @ts-ignore
19
- const allValues = getSyntaxConfig()["declarations" /* ValidationSyntaxGroupEnum.Declarations */].all.syntax.trim().split(/[\s|]+/g);
20
- /**
21
- * Check if a node is allowed as child in a given context
22
- * @param node
23
- * @param context
24
- */
25
- function isNodeAllowedInContext(node, context) {
26
- if (node.typ == EnumToken.CommentNodeType || context == null) {
27
- return true;
28
- }
29
- switch (context?.typ) {
30
- case EnumToken.StyleSheetNodeType:
31
- case EnumToken.RuleNodeType:
32
- return node.typ == EnumToken.RuleNodeType ||
33
- node.typ == EnumToken.AtRuleNodeType ||
34
- node.typ == EnumToken.KeyframesAtRuleNodeType ||
35
- (node.typ == EnumToken.DeclarationNodeType && context.typ == EnumToken.RuleNodeType) ||
36
- (node.typ == EnumToken.CDOCOMMNodeType && context.typ == EnumToken.StyleSheetNodeType);
37
- case EnumToken.KeyframesAtRuleNodeType:
38
- return node.typ == EnumToken.KeyFramesRuleNodeType;
39
- case EnumToken.KeyFramesRuleNodeType:
40
- return node.typ == EnumToken.DeclarationNodeType;
41
- case EnumToken.AtRuleNodeType:
42
- // @ts-ignore
43
- const syntax = getParsedSyntax("atRules" /* ValidationSyntaxGroupEnum.AtRules */, '@' + context.nam)?.[0].chi ?? null;
44
- //
45
- if (syntax == null) {
46
- // console.error(`syntax: Not found ${ValidationSyntaxGroupEnum.AtRules}@${(context as AstAtRule).nam}`);
47
- return true;
48
- }
49
- const stack = syntax.slice();
50
- for (const child of stack) {
51
- if (Array.isArray(child)) {
52
- stack.push(...child);
53
- continue;
54
- }
55
- if ('chi' in child && Array.isArray(child.chi)) {
56
- stack.push(...child.chi);
57
- continue;
58
- }
59
- // @ts-ignore
60
- if (child.l != null) {
61
- // @ts-ignore
62
- stack.push(child.l);
63
- // @ts-ignore
64
- if (child.r != null) {
65
- // @ts-ignore
66
- stack.push(...(Array.isArray(child.r) ? child.r : [child.r]));
67
- }
68
- continue;
69
- }
70
- if (node.typ == EnumToken.DeclarationNodeType) {
71
- if (child.typ == ValidationTokenEnum.DeclarationDefinitionToken) {
72
- if (node.nam == child.nam) {
73
- return true;
74
- }
75
- }
76
- }
77
- if (child.typ == ValidationTokenEnum.PropertyType) {
78
- if (['group-rule-body', 'block-contents', 'rule-list', 'stylesheet'].includes(child.val)) {
79
- if ((node.typ == EnumToken.RuleNodeType ||
80
- node.typ == EnumToken.AtRuleNodeType ||
81
- node.typ == EnumToken.KeyframesAtRuleNodeType)) {
82
- return true;
83
- }
84
- if (node.typ == EnumToken.DeclarationNodeType) {
85
- let parent = node.parent;
86
- while (parent != null) {
87
- if (parent.parent?.typ == EnumToken.RuleNodeType) {
88
- return true;
89
- }
90
- parent = parent.parent;
91
- }
92
- }
93
- }
94
- if (['declaration-list', 'feature-value-declaration'].includes(child.val) && node.typ == EnumToken.DeclarationNodeType) {
95
- return true;
96
- }
97
- if (child.val == 'page-body' && (node.typ == EnumToken.DeclarationNodeType || (node.typ == EnumToken.AtRuleNodeType && [
98
- 'top-left-corner', 'top-left', 'top-center', 'top-right', 'top-right-corner',
99
- 'bottom-left-corner', 'bottom-left', 'bottom-center', 'bottom-right', 'bottom-right-corner',
100
- 'left-top', 'left-middle', 'left-bottom', 'right-top', 'right-middle', 'right-bottom'
101
- ].includes(node.nam)))) {
102
- return true;
103
- }
104
- if (child.val == 'feature-value-block-list' &&
105
- (node.typ == EnumToken.AtRuleNodeType && ['stylistic', 'historical-forms', 'styleset', 'character-variant', 'swash', 'ornaments', 'annotation'].includes(node.nam))) {
106
- return true;
107
- }
108
- if (['feature-value-declaration-list', 'feature-value-declaration'].includes(child.val) && node.typ == EnumToken.DeclarationNodeType) {
109
- return true;
110
- }
111
- if (child.val == 'page-body') {
112
- if (node.typ == EnumToken.DeclarationNodeType) {
113
- return true;
114
- }
115
- }
116
- // console.error(`isNodeAllowedInContext: Not found ${(child as ValidationPropertyToken).val}`, {
117
- // child,
118
- // node
119
- // });
120
- }
121
- }
122
- break;
123
- }
124
- return false;
125
- }
126
- /**
127
- * Create a syntax validation context from a list of tokens
128
- * @param input
129
- */
130
- function createContext(input) {
131
- const values = input.slice();
132
- const result = values.filter(token => token.typ != EnumToken.CommentTokenType).slice();
133
- return {
134
- index: -1,
135
- get length() {
136
- return this.index < 0 ? result.length : this.index > result.length ? 0 : result.length - this.index;
137
- },
138
- peek() {
139
- let index = this.index + 1;
140
- if (index >= result.length) {
141
- return null;
142
- }
143
- if (result[index]?.typ == EnumToken.WhitespaceTokenType) {
144
- index++;
145
- }
146
- return result[index] ?? null;
147
- },
148
- update(context) {
149
- // @ts-ignore
150
- const newIndex = result.indexOf(context.current());
151
- if (newIndex > this.index) {
152
- this.index = newIndex;
153
- }
154
- },
155
- consume(token, howMany) {
156
- let newIndex = result.indexOf(token, this.index + 1);
157
- howMany ??= 0;
158
- let splice = 1;
159
- result.splice(this.index + 1, 0, ...result.splice(newIndex, splice + howMany));
160
- this.index += howMany + splice;
161
- return true;
162
- },
163
- done() {
164
- return this.index + 1 >= result.length;
165
- },
166
- current() {
167
- return result[this.index] ?? null;
168
- },
169
- next() {
170
- let index = this.index + 1;
171
- if (index >= result.length) {
172
- return null;
173
- }
174
- if (result[index]?.typ == EnumToken.WhitespaceTokenType) {
175
- index++;
176
- }
177
- this.index = index;
178
- return result[this.index] ?? null;
179
- },
180
- slice() {
181
- return result.slice(this.index + 1);
182
- },
183
- clone() {
184
- const context = createContext(result.slice());
185
- context.index = this.index;
186
- return context;
187
- }
188
- };
189
- }
190
- /**
191
- * Evaluate the validity of the syntax of a node
192
- * @param node
193
- * @param parent
194
- * @param options
195
- */
196
- function evaluateSyntax(node, parent, options) {
197
- if (node.validSyntax) {
198
- return {
199
- valid: SyntaxValidationResult.Valid,
200
- node,
201
- syntax: null,
202
- error: '',
203
- context: []
204
- };
205
- }
206
- let ast;
207
- let result;
208
- switch (node.typ) {
209
- case EnumToken.DeclarationNodeType:
210
- if (node.nam.startsWith('--')) {
211
- break;
212
- }
213
- let token = null;
214
- let values = node.val.slice();
215
- ast = getParsedSyntax("declarations" /* ValidationSyntaxGroupEnum.Declarations */, node.nam);
216
- while (values.length > 0) {
217
- token = values.at(-1);
218
- if (token.typ == EnumToken.WhitespaceTokenType || token.typ == EnumToken.CommentTokenType) {
219
- values.pop();
220
- }
221
- else {
222
- if (token.typ == EnumToken.ImportantTokenType) {
223
- values.pop();
224
- if (values.at(-1)?.typ == EnumToken.WhitespaceTokenType) {
225
- values.pop();
226
- }
227
- }
228
- break;
229
- }
230
- }
231
- if (ast == null) {
232
- if (parent?.typ == EnumToken.AtRuleNodeType) {
233
- ast = (getParsedSyntax("atRules" /* ValidationSyntaxGroupEnum.AtRules */, ['@' + parent.nam, 'descriptors', node.nam]));
234
- if (ast == null) {
235
- ast = (getParsedSyntax("atRules" /* ValidationSyntaxGroupEnum.AtRules */, ['@' + parent.nam, 'descriptors', node.nam]) ?? getParsedSyntax("atRules" /* ValidationSyntaxGroupEnum.AtRules */, '@' + parent.nam))?.[0]?.chi;
236
- values = [{ ...node, val: values }];
237
- }
238
- }
239
- }
240
- if (ast != null) {
241
- result = doEvaluateSyntax(ast, createContext(values), { ...options, visited: new WeakMap() });
242
- if (result.valid == SyntaxValidationResult.Valid && !result.context.done()) {
243
- let token = null;
244
- if ((token = result.context.next()) != null) {
245
- return {
246
- ...result,
247
- valid: SyntaxValidationResult.Drop,
248
- node: token,
249
- syntax: getSyntax("declarations" /* ValidationSyntaxGroupEnum.Declarations */, node.nam),
250
- error: `unexpected token: '${renderToken(token)}'`,
251
- };
252
- }
253
- }
254
- return {
255
- ...result,
256
- syntax: getSyntax("declarations" /* ValidationSyntaxGroupEnum.Declarations */, node.nam)
257
- };
258
- }
259
- break;
260
- }
261
- return {
262
- valid: SyntaxValidationResult.Valid,
263
- node,
264
- syntax: null,
265
- error: ''
266
- };
267
- }
268
- function clearVisited(token, syntax, key, options) {
269
- options.visited.get(token)?.get?.(key)?.delete(syntax);
270
- }
271
- function isVisited(token, syntax, key, options) {
272
- if (options.visited.get(token)?.get?.(key)?.has(syntax)) {
273
- return true;
274
- }
275
- if (!options.visited.has(token)) {
276
- options.visited.set(token, new Map());
277
- }
278
- if (!options.visited.get(token).has(key)) {
279
- options.visited.get(token).set(key, new Set());
280
- }
281
- options.visited.get(token).get(key).add(syntax);
282
- return false;
283
- }
284
- // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Values_and_Units/Value_definition_syntax
285
- function doEvaluateSyntax(syntaxes, context, options) {
286
- let syntax;
287
- let i = 0;
288
- let result;
289
- let tmpResult;
290
- let token = null;
291
- if (context.done()) {
292
- const success = syntaxes.some(s => s.isOptional || s.isRepeatable || s.isRepeatableGroup);
293
- return {
294
- valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
295
- node: null,
296
- syntax: null,
297
- error: '',
298
- context
299
- };
300
- }
301
- for (; i < syntaxes.length; i++) {
302
- syntax = syntaxes[i];
303
- if (context.done()) {
304
- if (syntax.typ == ValidationTokenEnum.Whitespace || syntax.isOptional || syntax.isRepeatable) {
305
- continue;
306
- }
307
- break;
308
- }
309
- token = context.peek();
310
- // if var() is the last token, then match the remaining syntax and return
311
- if (context.length == 1 && token.typ == EnumToken.FunctionTokenType && 'var' === token.val?.toLowerCase?.()) {
312
- return doEvaluateSyntax(getParsedSyntax("functions" /* ValidationSyntaxGroupEnum.Functions */, 'var')?.[0]?.chi ?? [], createContext(token.chi), options);
313
- }
314
- if (syntax.typ == ValidationTokenEnum.Whitespace) {
315
- if (context.peek()?.typ == EnumToken.WhitespaceTokenType) {
316
- context.next();
317
- }
318
- continue;
319
- }
320
- else if (options.isList !== false && syntax.isList) {
321
- result = matchList(syntax, context, options);
322
- }
323
- else if (options.isRepeatable !== false && syntax.isRepeatable) {
324
- tmpResult = matchRepeatable(syntax, context, options);
325
- if (tmpResult.valid == SyntaxValidationResult.Valid) {
326
- result = tmpResult;
327
- }
328
- else {
329
- continue;
330
- }
331
- }
332
- else if (options.occurrence !== false && syntax.occurence != null) {
333
- result = matchOccurence(syntax, context, options);
334
- }
335
- else if (options.atLeastOnce !== false && syntax.atLeastOnce) {
336
- result = matchAtLeastOnce(syntax, context, options);
337
- }
338
- else {
339
- if (isVisited(token, syntax, 'doEvaluateSyntax', options)) {
340
- return {
341
- valid: SyntaxValidationResult.Drop,
342
- node: token,
343
- syntax,
344
- error: `cyclic dependency: ${renderSyntax(syntax)}`,
345
- context
346
- };
347
- }
348
- result = match(syntax, context, options);
349
- if (result.valid == SyntaxValidationResult.Valid) {
350
- clearVisited(token, syntax, 'doEvaluateSyntax', options);
351
- }
352
- }
353
- if (result.valid == SyntaxValidationResult.Drop) {
354
- if (syntax.isOptional) {
355
- continue;
356
- }
357
- return result;
358
- }
359
- context.update(result.context);
360
- }
361
- // @ts-ignore
362
- return result ?? {
363
- valid: SyntaxValidationResult.Valid,
364
- node: null,
365
- syntax: syntaxes[i - 1],
366
- error: '',
367
- context
368
- };
369
- }
370
- function matchAtLeastOnce(syntax, context, options) {
371
- let success = false;
372
- let result;
373
- while (!context.done()) {
374
- result = match(syntax, context.clone(), { ...options, atLeastOnce: false });
375
- if (result.valid == SyntaxValidationResult.Valid) {
376
- success = true;
377
- context.update(result.context);
378
- continue;
379
- }
380
- break;
381
- }
382
- return {
383
- valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
384
- node: context.peek(),
385
- syntax,
386
- error: success ? '' : `could not match syntax: ${renderSyntax(syntax)}`,
387
- context
388
- };
389
- }
390
- function matchRepeatable(syntax, context, options) {
391
- let result;
392
- while (!context.done()) {
393
- result = match(syntax, context.clone(), { ...options, isRepeatable: false });
394
- if (result.valid == SyntaxValidationResult.Valid) {
395
- context.update(result.context);
396
- continue;
397
- }
398
- break;
399
- }
400
- return {
401
- valid: SyntaxValidationResult.Valid,
402
- node: null,
403
- syntax,
404
- error: '',
405
- context
406
- };
407
- }
408
- function matchList(syntax, context, options) {
409
- let success;
410
- let result;
411
- let count = 0;
412
- let con = context.clone();
413
- let tokens = [];
414
- while (!con.done()) {
415
- while (!con.done() && con.peek()?.typ != EnumToken.CommaTokenType) {
416
- tokens.push(con.next());
417
- }
418
- result = doEvaluateSyntax([syntax], createContext(tokens), {
419
- ...options,
420
- isList: false,
421
- occurrence: false
422
- });
423
- if (result.valid == SyntaxValidationResult.Valid) {
424
- context = con.clone();
425
- count++;
426
- // pop comma
427
- if (con.done() || con.peek()?.typ != EnumToken.CommaTokenType) {
428
- break;
429
- }
430
- con.next();
431
- tokens.length = 0;
432
- }
433
- else {
434
- break;
435
- }
436
- }
437
- success = count > 0;
438
- if (success && syntax.occurence != null) {
439
- success = count >= syntax.occurence.min;
440
- if (success && syntax.occurence.max != null) {
441
- success = count <= syntax.occurence.max;
442
- }
443
- }
444
- return {
445
- valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
446
- node: context.peek(),
447
- syntax,
448
- error: '',
449
- context
450
- };
451
- }
452
- function matchOccurence(syntax, context, options) {
453
- let counter = 0;
454
- let result;
455
- do {
456
- result = match(syntax, context.clone(), { ...options, occurrence: false });
457
- if (result.valid == SyntaxValidationResult.Drop) {
458
- break;
459
- }
460
- counter++;
461
- context.update(result.context);
462
- } while (result.valid == SyntaxValidationResult.Valid && !context.done());
463
- let sucesss = counter >= syntax.occurence.min;
464
- if (sucesss && syntax.occurence.max != null) {
465
- if (Number.isFinite(syntax.occurence.max)) {
466
- sucesss = sucesss && counter <= syntax.occurence.max;
467
- }
468
- }
469
- return {
470
- valid: sucesss ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
471
- node: context.peek(),
472
- syntax,
473
- error: sucesss ? '' : `expected ${renderSyntax(syntax)} ${syntax.occurence.min} to ${syntax.occurence.max} occurences, got ${counter}`,
474
- context
475
- };
476
- }
477
- function match(syntax, context, options) {
478
- let success = false;
479
- let result;
480
- let token = context.peek();
481
- switch (syntax.typ) {
482
- case ValidationTokenEnum.PipeToken:
483
- return someOf(syntax.chi, context, options);
484
- case ValidationTokenEnum.Bracket:
485
- return doEvaluateSyntax(syntax.chi, context, options);
486
- case ValidationTokenEnum.AmpersandToken:
487
- return allOf(flatten(syntax), context, options);
488
- case ValidationTokenEnum.ColumnToken: {
489
- let result = anyOf(flatten(syntax), context, options);
490
- if (result.valid == SyntaxValidationResult.Valid) {
491
- return result;
492
- }
493
- return {
494
- valid: SyntaxValidationResult.Drop,
495
- node: context.peek(),
496
- syntax,
497
- error: `expected '${ValidationTokenEnum[syntax.typ].toLowerCase()}', got '${context.done() ? null : renderToken(context.peek())}'`,
498
- context
499
- };
500
- }
501
- }
502
- if (syntax.typ != ValidationTokenEnum.PropertyType && (token?.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val))) {
503
- const result = doEvaluateSyntax(getParsedSyntax("functions" /* ValidationSyntaxGroupEnum.Functions */, token.val)?.[0]?.chi ?? [], createContext(token.chi), {
504
- ...options,
505
- isRepeatable: null,
506
- isList: null,
507
- occurrence: null,
508
- atLeastOnce: null
509
- });
510
- if (result.valid == SyntaxValidationResult.Valid) {
511
- context.next();
512
- }
513
- return { ...result, context };
514
- }
515
- switch (syntax.typ) {
516
- case ValidationTokenEnum.Keyword:
517
- success = (token.typ == EnumToken.IdenTokenType || token.typ == EnumToken.DashedIdenTokenType || isIdentColor(token)) &&
518
- (token.val == syntax.val ||
519
- syntax.val.toLowerCase() === token.val?.toLowerCase?.() ||
520
- // config.declarations.all
521
- allValues.includes(token.val.toLowerCase()));
522
- if (success) {
523
- context.next();
524
- return {
525
- valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
526
- node: token,
527
- syntax,
528
- error: success ? '' : `expected keyword: '${syntax.val}', got ${renderToken(token)}`,
529
- context
530
- };
531
- }
532
- break;
533
- case ValidationTokenEnum.PropertyType:
534
- return matchPropertyType(syntax, context, options);
535
- case ValidationTokenEnum.ValidationFunctionDefinition:
536
- token = context.peek();
537
- if (token.typ == EnumToken.ParensTokenType || !funcLike.concat(EnumToken.ColorTokenType).includes(token.typ) || (!('chi' in token))) {
538
- return {
539
- valid: SyntaxValidationResult.Drop,
540
- node: context.next(),
541
- syntax,
542
- error: `expected function or color token, got ${renderToken(token)}`,
543
- context
544
- };
545
- }
546
- result = match(getParsedSyntax("syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */, syntax.val + '()')?.[0], context, options);
547
- if (result.valid == SyntaxValidationResult.Valid) {
548
- context.next();
549
- result.context = context;
550
- return result;
551
- }
552
- break;
553
- case ValidationTokenEnum.DeclarationType:
554
- return doEvaluateSyntax(getParsedSyntax("declarations" /* ValidationSyntaxGroupEnum.Declarations */, syntax.val), context, {
555
- ...options,
556
- isRepeatable: null,
557
- isList: null,
558
- occurrence: null,
559
- atLeastOnce: null
560
- });
561
- case ValidationTokenEnum.Comma:
562
- success = context.peek()?.typ == EnumToken.CommaTokenType;
563
- if (success) {
564
- context.next();
565
- }
566
- break;
567
- case ValidationTokenEnum.Separator:
568
- {
569
- const token = context.peek();
570
- success = token?.typ == EnumToken.LiteralTokenType && token.val == '/';
571
- if (success) {
572
- context.next();
573
- }
574
- }
575
- break;
576
- default:
577
- token = context.peek();
578
- if (!wildCardFuncs.includes(syntax.val) && syntax.val != token.val) {
579
- break;
580
- }
581
- if (syntax.typ == ValidationTokenEnum.Function) {
582
- success = funcLike.includes(token.typ) && syntax.val.toLowerCase() === token.val?.toLowerCase?.() && doEvaluateSyntax(syntax.chi, createContext(token.chi), options).valid == SyntaxValidationResult.Valid;
583
- if (success) {
584
- context.next();
585
- }
586
- break;
587
- }
588
- if (token.typ != EnumToken.ParensTokenType && funcLike.includes(token.typ)) {
589
- success = doEvaluateSyntax(syntax.chi, createContext(token.chi), {
590
- ...options,
591
- isRepeatable: null,
592
- isList: null,
593
- occurrence: null,
594
- atLeastOnce: null
595
- }).valid == SyntaxValidationResult.Valid;
596
- if (success) {
597
- context.next();
598
- }
599
- break;
600
- }
601
- }
602
- if (!success && token.typ == EnumToken.IdenTokenType && allValues.includes(token.val.toLowerCase())) {
603
- success = true;
604
- context.next();
605
- }
606
- return {
607
- valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
608
- node: context.peek(),
609
- syntax,
610
- error: success ? '' : `expected '${ValidationTokenEnum[syntax.typ].toLowerCase()}', got '${renderToken(context.peek())}'`,
611
- context
612
- };
613
- }
614
- function matchPropertyType(syntax, context, options) {
615
- if (![
616
- 'color',
617
- 'integer',
618
- 'bg-position',
619
- 'composes-selector',
620
- 'length-percentage', 'flex', 'calc-sum', 'color',
621
- 'color-base', 'system-color', 'deprecated-system-color',
622
- 'pseudo-class-selector', 'pseudo-element-selector', 'feature-value-declaration'
623
- ].includes(syntax.val)) {
624
- if (syntax.val in config["syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */]) {
625
- return doEvaluateSyntax(getParsedSyntax("syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */, syntax.val), context, {
626
- ...options,
627
- isRepeatable: null,
628
- isList: null,
629
- occurrence: null,
630
- atLeastOnce: null
631
- });
632
- }
633
- }
634
- let success = true;
635
- let token = context.peek();
636
- if ((token?.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val))) {
637
- const result = doEvaluateSyntax(getParsedSyntax("functions" /* ValidationSyntaxGroupEnum.Functions */, token.val)?.[0]?.chi ?? [], createContext(token.chi), {
638
- ...options,
639
- isRepeatable: null,
640
- isList: null,
641
- occurrence: null,
642
- atLeastOnce: null
643
- });
644
- if (result.valid == SyntaxValidationResult.Valid) {
645
- context.next();
646
- }
647
- return { ...result, context };
648
- }
649
- switch (syntax.val) {
650
- case 'composes-selector':
651
- success = token.typ == EnumToken.ComposesSelectorNodeType;
652
- break;
653
- case 'bg-position': {
654
- let val;
655
- let keyworkMatchCount = 0;
656
- let lengthMatchCount = 0;
657
- let functionMatchCount = 0;
658
- let isBGX = false;
659
- let isBGY = false;
660
- while (token != null && keyworkMatchCount + lengthMatchCount + functionMatchCount < 3) {
661
- // match one value: keyword or length
662
- success = (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
663
- if (success) {
664
- functionMatchCount++;
665
- context.next();
666
- token = context.peek();
667
- continue;
668
- }
669
- if (token.typ == EnumToken.WhitespaceTokenType) {
670
- context.next();
671
- token = context.peek();
672
- continue;
673
- }
674
- if (token.typ == EnumToken.IdenTokenType) {
675
- val = token.val.toLowerCase();
676
- success = ['left', 'center', 'right', 'top', 'center', 'bottom'].includes(val);
677
- if (!success) {
678
- break;
679
- }
680
- keyworkMatchCount++;
681
- if (keyworkMatchCount > 2) {
682
- return {
683
- valid: SyntaxValidationResult.Drop,
684
- node: token,
685
- syntax,
686
- error: `expected <length-percentage>`,
687
- context
688
- };
689
- }
690
- if (val == 'left' || val == 'right') {
691
- if (isBGX) {
692
- return {
693
- valid: SyntaxValidationResult.Drop,
694
- node: token,
695
- syntax,
696
- error: `top | bottom | <length-percentage>`,
697
- context
698
- };
699
- }
700
- isBGX = true;
701
- }
702
- if (val == 'top' || val == 'bottom') {
703
- if (isBGY) {
704
- return {
705
- valid: SyntaxValidationResult.Drop,
706
- node: token,
707
- syntax,
708
- error: `expected left | right | <length-percentage>`,
709
- context
710
- };
711
- }
712
- isBGY = true;
713
- }
714
- context.next();
715
- token = context.peek();
716
- continue;
717
- }
718
- success = token.typ == EnumToken.LengthTokenType || token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0);
719
- if (!success) {
720
- break;
721
- }
722
- lengthMatchCount++;
723
- context.next();
724
- token = context.peek();
725
- }
726
- if (keyworkMatchCount + lengthMatchCount + functionMatchCount == 0) {
727
- return {
728
- valid: SyntaxValidationResult.Drop,
729
- node: token,
730
- syntax,
731
- error: `expected <bg-position>`,
732
- context
733
- };
734
- }
735
- return {
736
- valid: SyntaxValidationResult.Valid,
737
- node: token,
738
- syntax,
739
- error: '',
740
- context
741
- };
742
- }
743
- case 'calc-sum':
744
- success = (token.typ == EnumToken.FunctionTokenType && mathFuncs.includes(token.val)) ||
745
- // @ts-ignore
746
- (token.typ == EnumToken.IdenTokenType && typeof Math[token.val.toUpperCase()] == 'number') ||
747
- [EnumToken.BinaryExpressionTokenType, EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.DimensionTokenType, EnumToken.LengthTokenType, EnumToken.AngleTokenType, EnumToken.TimeTokenType, EnumToken.ResolutionTokenType, EnumToken.FrequencyTokenType].includes(token.typ);
748
- break;
749
- case 'declaration':
750
- {
751
- success = token.typ == EnumToken.DeclarationNodeType;
752
- if (success) {
753
- success = evaluateSyntax(token, null, options).valid == SyntaxValidationResult.Valid;
754
- }
755
- }
756
- break;
757
- case 'declaration-value':
758
- while (!context.done()) {
759
- context.next();
760
- }
761
- success = true;
762
- break;
763
- case 'url-token':
764
- success = token.typ == EnumToken.UrlTokenTokenType || token.typ == EnumToken.StringTokenType || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
765
- break;
766
- case 'ident':
767
- case 'ident-token':
768
- case 'custom-ident':
769
- success = token.typ == EnumToken.IdenTokenType || token.typ == EnumToken.DashedIdenTokenType || isIdentColor(token);
770
- break;
771
- case 'dashed-ident':
772
- case 'custom-property-name':
773
- success = token.typ == EnumToken.DashedIdenTokenType;
774
- break;
775
- case 'system-color':
776
- success = (token.typ == EnumToken.ColorTokenType && token.kin == ColorType.SYS) || (token.typ == EnumToken.IdenTokenType && 'currentcolor' === token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
777
- break;
778
- case 'deprecated-system-color':
779
- success = (token.typ == EnumToken.ColorTokenType && token.kin == ColorType.DPSYS) || (token.typ == EnumToken.IdenTokenType && 'currentcolor' === token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
780
- break;
781
- case 'color':
782
- case 'color-base':
783
- success = token.typ == EnumToken.ColorTokenType ||
784
- (token.typ == EnumToken.IdenTokenType && 'currentcolor' === token.val.toLowerCase()) ||
785
- (token.typ == EnumToken.IdenTokenType && 'transparent' === token.val.toLowerCase()) ||
786
- (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val) ||
787
- isColor(token));
788
- if (!success && token.typ == EnumToken.FunctionTokenType && colorsFunc.includes(token.val)) {
789
- success = doEvaluateSyntax(getParsedSyntax("functions" /* ValidationSyntaxGroupEnum.Functions */, token.val)?.[0]?.chi, createContext(token.chi), {
790
- ...options,
791
- isRepeatable: null,
792
- isList: null,
793
- occurrence: null,
794
- atLeastOnce: null
795
- }).valid == SyntaxValidationResult.Valid;
796
- }
797
- break;
798
- case 'hex-color':
799
- success = (token.typ == EnumToken.ColorTokenType && token.kin == ColorType.HEX) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
800
- break;
801
- case 'feature-value-declaration':
802
- {
803
- let hasNumber = false;
804
- success = token.typ == EnumToken.DeclarationNodeType && token.val.length > 0 && token.val.every((val) => {
805
- if (val.typ == EnumToken.WhitespaceTokenType || val.typ == EnumToken.CommentTokenType) {
806
- return true;
807
- }
808
- const success = (val.typ == EnumToken.NumberTokenType && Number.isInteger(+val.val) && val.val > 0) || (val.typ == EnumToken.FunctionTokenType && mathFuncs.includes(val.val.toLowerCase()) || (val.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(val.val)));
809
- if (success) {
810
- hasNumber = true;
811
- }
812
- if ('range' in syntax) {
813
- return success && +val.val >= +syntax.range[0] && +val.val <= +syntax.range[1];
814
- }
815
- return success;
816
- }) && hasNumber;
817
- }
818
- break;
819
- case 'integer':
820
- success = (token.typ == EnumToken.NumberTokenType && /^[+-]?\d+$/.test(token.val.toString())) || (token.typ == EnumToken.FunctionTokenType && mathFuncs.includes(token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val)));
821
- if ('range' in syntax) {
822
- success = success && +token.val >= +syntax.range[0] && +token.val <= +syntax.range[1];
823
- }
824
- break;
825
- case 'dimension':
826
- success = [
827
- EnumToken.DimensionTokenType,
828
- EnumToken.LengthTokenType,
829
- EnumToken.AngleTokenType,
830
- EnumToken.TimeTokenType,
831
- EnumToken.ResolutionTokenType,
832
- EnumToken.FrequencyTokenType
833
- ].includes(token.typ) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
834
- break;
835
- case 'flex':
836
- success = token.typ == EnumToken.FlexTokenType || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
837
- break;
838
- case 'number':
839
- case 'number-token':
840
- success = token.typ == EnumToken.NumberTokenType;
841
- if (success && 'range' in syntax) {
842
- success = +token.val >= +syntax.range[0] && (syntax.range[1] == null || +token.val <= +syntax.range[1]);
843
- }
844
- break;
845
- case 'angle':
846
- success = token.typ == EnumToken.AngleTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
847
- break;
848
- case 'length':
849
- success = token.typ == EnumToken.LengthTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
850
- break;
851
- case 'percentage':
852
- success = token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
853
- break;
854
- case 'length-percentage':
855
- success = token.typ == EnumToken.LengthTokenType || token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
856
- break;
857
- case 'resolution':
858
- success = token.typ == EnumToken.ResolutionTokenType || token.typ == EnumToken.PercentageTokenType || (token.typ == EnumToken.NumberTokenType && token.val == 0) || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
859
- break;
860
- case 'hash-token':
861
- success = token.typ == EnumToken.HashTokenType;
862
- break;
863
- case 'string':
864
- success = token.typ == EnumToken.StringTokenType || token.typ == EnumToken.UrlTokenTokenType || token.typ == EnumToken.HashTokenType || token.typ == EnumToken.IdenTokenType || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
865
- break;
866
- case 'time':
867
- success = token.typ == EnumToken.TimeTokenType || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
868
- break;
869
- case 'zero':
870
- success = token.val == 0 || (token.typ == EnumToken.FunctionTokenType && token.val == 'calc');
871
- break;
872
- case 'pseudo-element-selector':
873
- success = token.typ == EnumToken.PseudoElementTokenType;
874
- break;
875
- case 'pseudo-class-selector':
876
- success = token.typ == EnumToken.PseudoClassTokenType || token.typ == EnumToken.PseudoClassFuncTokenType;
877
- if (success) {
878
- success = token.val + (token.typ == EnumToken.PseudoClassTokenType ? '' : '()') in config["selectors" /* ValidationSyntaxGroupEnum.Selectors */];
879
- if (success && token.typ == EnumToken.PseudoClassFuncTokenType) {
880
- success = doEvaluateSyntax(getParsedSyntax("selectors" /* ValidationSyntaxGroupEnum.Selectors */, token.val + '()')?.[0]?.chi ?? [], createContext(token.chi), {
881
- ...options,
882
- isRepeatable: null,
883
- isList: null,
884
- occurrence: null,
885
- atLeastOnce: null
886
- }).valid == SyntaxValidationResult.Valid;
887
- }
888
- }
889
- break;
890
- }
891
- if (!success &&
892
- token.typ == EnumToken.FunctionTokenType &&
893
- ['length-percentage', 'length', 'number', 'number-token', 'angle', 'percentage', 'dimension'].includes(syntax.val)) {
894
- if (!success) {
895
- success = mathFuncs.includes(token.val.toLowerCase()) &&
896
- doEvaluateSyntax(getParsedSyntax("syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */, token.val + '()')?.[0]?.chi ?? [], createContext(token.chi), {
897
- ...options,
898
- isRepeatable: null,
899
- isList: null,
900
- occurrence: null,
901
- atLeastOnce: null
902
- }).valid == SyntaxValidationResult.Valid;
903
- }
904
- }
905
- if (!success && token.typ == EnumToken.IdenTokenType) {
906
- success = allValues.includes(token.val.toLowerCase());
907
- }
908
- if (success) {
909
- context.next();
910
- }
911
- return {
912
- valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
913
- node: token,
914
- syntax,
915
- error: success ? '' : `expected '${syntax.val}', got ${renderToken(token)}`,
916
- context
917
- };
918
- }
919
- function someOf(syntaxes, context, options) {
920
- let result;
921
- let i;
922
- let success = false;
923
- const matched = [];
924
- for (i = 0; i < syntaxes.length; i++) {
925
- result = doEvaluateSyntax(syntaxes[i], context.clone(), options);
926
- if (result.valid == SyntaxValidationResult.Valid) {
927
- success = true;
928
- if (result.context.done()) {
929
- return result;
930
- }
931
- matched.push(result);
932
- }
933
- }
934
- if (matched.length > 0) {
935
- // pick the best match
936
- matched.sort((a, b) => a.context.done() ? -1 : b.context.done() ? 1 : b.context.index - a.context.index);
937
- }
938
- return matched[0] ?? {
939
- valid: SyntaxValidationResult.Drop,
940
- node: context.peek(),
941
- syntax: null,
942
- error: success ? '' : `could not match syntax: ${syntaxes.reduce((acc, curr) => acc + (acc.length > 0 ? ' | ' : '') + curr.reduce((acc, curr) => acc + renderSyntax(curr), ''), '')}`,
943
- context
944
- };
945
- }
946
- function anyOf(syntaxes, context, options) {
947
- let result;
948
- let i;
949
- let success = false;
950
- for (i = 0; i < syntaxes.length; i++) {
951
- result = doEvaluateSyntax(syntaxes[i], context.clone(), options);
952
- if (result.valid == SyntaxValidationResult.Valid) {
953
- success = true;
954
- context.update(result.context);
955
- if (result.context.done()) {
956
- return result;
957
- }
958
- syntaxes.splice(i, 1);
959
- i = -1;
960
- }
961
- }
962
- return {
963
- valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
964
- node: context.peek(),
965
- syntax: null,
966
- error: success ? '' : `could not match syntax: ${syntaxes.reduce((acc, curr) => acc + '[' + curr.reduce((acc, curr) => acc + renderSyntax(curr), '') + ']', '')}`,
967
- context
968
- };
969
- }
970
- function allOf(syntax, context, options) {
971
- let result;
972
- let i;
973
- let slice = context.slice();
974
- const vars = [];
975
- const tokens = [];
976
- const repeatable = [];
977
- // match optional syntax first
978
- // <length>{2,3}&&<color>? => <color>?&&<length>{2,3}
979
- for (i = 0; i < syntax.length; i++) {
980
- if (syntax[i].length == 1 && syntax[i][0].occurence != null) {
981
- repeatable.push(syntax[i]);
982
- syntax.splice(i--, 1);
983
- }
984
- }
985
- if (repeatable.length > 0) {
986
- syntax.push(...repeatable);
987
- }
988
- // sort tokens -> wildCard -> last
989
- // 1px var(...) 2px => 1px 2px var(...)
990
- for (i = 0; i < slice.length; i++) {
991
- if (slice[i].typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(slice[i].val.toLowerCase())) {
992
- vars.push(slice[i]);
993
- continue;
994
- }
995
- if (slice[i].typ == EnumToken.CommaTokenType || (slice[i].typ == EnumToken.LiteralTokenType && slice[i].val == '/')) {
996
- tokens.push(...vars);
997
- vars.length = 0;
998
- }
999
- tokens.push(slice[i]);
1000
- }
1001
- if (vars.length > 0) {
1002
- tokens.push(...vars);
1003
- }
1004
- const con = createContext(tokens);
1005
- let cp;
1006
- let j;
1007
- for (i = 0; i < syntax.length; i++) {
1008
- if (syntax[i].length == 1 && syntax[i][0].isOptional) {
1009
- j = 0;
1010
- cp = con.clone();
1011
- slice = cp.slice();
1012
- if (cp.done()) {
1013
- syntax.splice(i, 1);
1014
- i = -1;
1015
- continue;
1016
- }
1017
- while (!cp.done()) {
1018
- result = doEvaluateSyntax(syntax[i], cp.clone(), { ...options, isOptional: false });
1019
- if (result.valid == SyntaxValidationResult.Valid) {
1020
- let end = slice.indexOf(cp.current());
1021
- if (end == -1) {
1022
- end = 0;
1023
- }
1024
- else {
1025
- end -= j - 1;
1026
- }
1027
- con.consume(slice[j], end < 0 ? 0 : end);
1028
- break;
1029
- }
1030
- cp.next();
1031
- j++;
1032
- }
1033
- // @ts-ignore
1034
- if (result?.valid == SyntaxValidationResult.Valid || (syntax[i].length == 1 && syntax[i][0].isOptional)) {
1035
- syntax.splice(i, 1);
1036
- i = -1;
1037
- }
1038
- continue;
1039
- }
1040
- result = doEvaluateSyntax(syntax[i], con.clone(), options);
1041
- if (result.valid == SyntaxValidationResult.Valid) {
1042
- con.update(result.context);
1043
- syntax.splice(i, 1);
1044
- i = -1;
1045
- }
1046
- }
1047
- const success = syntax.length == 0;
1048
- return {
1049
- valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
1050
- node: context.peek(),
1051
- syntax: syntax?.[0]?.[0] ?? null,
1052
- error: `could not match syntax: ${syntax.reduce((acc, curr) => acc + '[' + curr.reduce((acc, curr) => acc + renderSyntax(curr), '') + ']', '')}`,
1053
- context: success ? con : context
1054
- };
1055
- }
1056
- function flatten(syntax) {
1057
- const stack = [syntax.l, syntax.r];
1058
- const data = [];
1059
- let s;
1060
- let i = 0;
1061
- for (; i < stack.length; i++) {
1062
- if (stack[i].length == 1 && stack[i][0].typ == syntax.typ) {
1063
- s = stack[i][0];
1064
- stack.splice(i--, 1, s.l, s.r);
1065
- }
1066
- else {
1067
- data.push(stack[i]);
1068
- }
1069
- }
1070
- return data;
1071
- }
1072
-
1073
- export { createContext, doEvaluateSyntax, evaluateSyntax, isNodeAllowedInContext };