@tbela99/css-parser 0.7.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/.editorconfig +484 -0
  2. package/README.md +140 -84
  3. package/dist/index-umd-web.js +8461 -51655
  4. package/dist/index.cjs +8437 -51636
  5. package/dist/index.d.ts +220 -68
  6. package/dist/lib/ast/expand.js +46 -9
  7. package/dist/lib/ast/features/calc.js +76 -12
  8. package/dist/lib/ast/features/inlinecssvariables.js +6 -1
  9. package/dist/lib/ast/features/prefix.js +17 -9
  10. package/dist/lib/ast/features/shorthand.js +1 -0
  11. package/dist/lib/ast/math/expression.js +299 -11
  12. package/dist/lib/ast/math/math.js +7 -1
  13. package/dist/lib/ast/minify.js +30 -16
  14. package/dist/lib/ast/types.js +59 -49
  15. package/dist/lib/ast/walk.js +92 -18
  16. package/dist/lib/parser/declaration/list.js +1 -0
  17. package/dist/lib/parser/declaration/map.js +60 -52
  18. package/dist/lib/parser/declaration/set.js +1 -12
  19. package/dist/lib/parser/parse.js +371 -119
  20. package/dist/lib/parser/tokenize.js +31 -6
  21. package/dist/lib/parser/utils/declaration.js +2 -2
  22. package/dist/lib/parser/utils/type.js +6 -6
  23. package/dist/lib/renderer/color/a98rgb.js +1 -0
  24. package/dist/lib/renderer/color/color.js +1 -0
  25. package/dist/lib/renderer/color/colormix.js +1 -0
  26. package/dist/lib/renderer/color/hex.js +2 -1
  27. package/dist/lib/renderer/color/hsl.js +2 -1
  28. package/dist/lib/renderer/color/hwb.js +3 -2
  29. package/dist/lib/renderer/color/lab.js +2 -1
  30. package/dist/lib/renderer/color/lch.js +2 -1
  31. package/dist/lib/renderer/color/oklab.js +3 -2
  32. package/dist/lib/renderer/color/oklch.js +2 -1
  33. package/dist/lib/renderer/color/p3.js +2 -1
  34. package/dist/lib/renderer/color/prophotoRgb.js +56 -0
  35. package/dist/lib/renderer/color/prophotorgb.js +1 -1
  36. package/dist/lib/renderer/color/rec2020.js +1 -0
  37. package/dist/lib/renderer/color/relativecolor.js +52 -28
  38. package/dist/lib/renderer/color/rgb.js +2 -1
  39. package/dist/lib/renderer/color/srgb.js +3 -2
  40. package/dist/lib/renderer/color/utils/components.js +1 -0
  41. package/dist/lib/renderer/color/utils/constants.js +2 -1
  42. package/dist/lib/renderer/color/xyz.js +2 -1
  43. package/dist/lib/renderer/color/xyzd50.js +1 -0
  44. package/dist/lib/renderer/render.js +62 -12
  45. package/dist/lib/syntax/syntax.js +362 -4
  46. package/dist/lib/validation/at-rules/container.js +353 -0
  47. package/dist/lib/validation/at-rules/counter-style.js +78 -0
  48. package/dist/lib/validation/at-rules/custom-media.js +52 -0
  49. package/dist/lib/validation/at-rules/document.js +114 -0
  50. package/dist/lib/validation/at-rules/else.js +5 -0
  51. package/dist/lib/validation/at-rules/font-feature-values.js +52 -0
  52. package/dist/lib/validation/at-rules/import.js +199 -0
  53. package/dist/lib/validation/at-rules/keyframes.js +70 -0
  54. package/dist/lib/validation/at-rules/layer.js +30 -0
  55. package/dist/lib/validation/at-rules/media.js +254 -0
  56. package/dist/lib/validation/at-rules/namespace.js +85 -0
  57. package/dist/lib/validation/at-rules/page-margin-box.js +56 -0
  58. package/dist/lib/validation/at-rules/page.js +88 -0
  59. package/dist/lib/validation/at-rules/supports.js +262 -0
  60. package/dist/lib/validation/at-rules/when.js +178 -0
  61. package/dist/lib/validation/atrule.js +187 -0
  62. package/dist/lib/validation/config.js +35 -2
  63. package/dist/lib/validation/config.json.js +1683 -50905
  64. package/dist/lib/validation/declaration.js +102 -0
  65. package/dist/lib/validation/parser/parse.js +1137 -7
  66. package/dist/lib/validation/parser/types.js +28 -12
  67. package/dist/lib/validation/selector.js +26 -444
  68. package/dist/lib/validation/syntax.js +1475 -0
  69. package/dist/lib/validation/syntaxes/complex-selector-list.js +45 -0
  70. package/dist/lib/validation/syntaxes/complex-selector.js +53 -0
  71. package/dist/lib/validation/syntaxes/compound-selector.js +226 -0
  72. package/dist/lib/validation/syntaxes/family-name.js +91 -0
  73. package/dist/lib/validation/syntaxes/image.js +29 -0
  74. package/dist/lib/validation/syntaxes/keyframe-block-list.js +27 -0
  75. package/dist/lib/validation/syntaxes/keyframe-selector.js +137 -0
  76. package/dist/lib/validation/syntaxes/layer-name.js +67 -0
  77. package/dist/lib/validation/syntaxes/relative-selector-list.js +57 -0
  78. package/dist/lib/validation/syntaxes/relative-selector.js +36 -0
  79. package/dist/lib/validation/syntaxes/selector-list.js +5 -0
  80. package/dist/lib/validation/syntaxes/selector.js +5 -0
  81. package/dist/lib/validation/syntaxes/url.js +75 -0
  82. package/dist/lib/validation/utils/list.js +24 -0
  83. package/dist/lib/validation/utils/whitespace.js +22 -0
  84. package/dist/node/index.js +5 -5
  85. package/dist/web/index.js +5 -1
  86. package/dist/web/load.js +1 -0
  87. package/package.json +16 -14
  88. package/dist/lib/ast/utils/minifyfeature.js +0 -9
  89. package/dist/lib/iterable/weakset.js +0 -58
  90. package/dist/lib/parser/utils/syntax.js +0 -450
@@ -0,0 +1,88 @@
1
+ import { ValidationLevel, EnumToken } from '../../ast/types.js';
2
+ import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
4
+ import '../../parser/parse.js';
5
+ import '../../renderer/color/utils/constants.js';
6
+ import '../../renderer/sourcemap/lib/encode.js';
7
+ import '../../parser/utils/config.js';
8
+ import { splitTokenList } from '../utils/list.js';
9
+
10
+ function validateAtRulePage(atRule, options, root) {
11
+ // media-query-list
12
+ if (!Array.isArray(atRule.tokens) || atRule.tokens.length == 0) {
13
+ // @ts-ignore
14
+ return {
15
+ valid: ValidationLevel.Valid,
16
+ matches: [],
17
+ node: null,
18
+ syntax: '@page',
19
+ error: '',
20
+ tokens: []
21
+ };
22
+ }
23
+ // page-selector-list
24
+ for (const tokens of splitTokenList(atRule.tokens)) {
25
+ if (tokens.length == 0) {
26
+ // @ts-ignore
27
+ return {
28
+ valid: ValidationLevel.Drop,
29
+ matches: [],
30
+ node: tokens[0] ?? atRule,
31
+ syntax: '@page',
32
+ error: 'unexpected token',
33
+ tokens: []
34
+ };
35
+ }
36
+ // <pseudo-page>+ | <ident> <pseudo-page>*
37
+ // ident pseudo-page* | pseudo-page+
38
+ if (tokens[0].typ == EnumToken.IdenTokenType) {
39
+ tokens.shift();
40
+ if (tokens.length == 0) {
41
+ continue;
42
+ }
43
+ // @ts-ignore
44
+ if (tokens[0].typ != EnumToken.WhitespaceTokenType) {
45
+ // @ts-ignore
46
+ return {
47
+ valid: ValidationLevel.Drop,
48
+ matches: [],
49
+ node: tokens[0] ?? atRule,
50
+ syntax: '@page',
51
+ error: 'unexpected token',
52
+ tokens: []
53
+ };
54
+ }
55
+ }
56
+ while (tokens.length > 0) {
57
+ if (tokens[0].typ == EnumToken.PseudoPageTokenType) {
58
+ tokens.shift();
59
+ if (tokens.length == 0) {
60
+ continue;
61
+ }
62
+ // @ts-ignore
63
+ if (tokens[0].typ != EnumToken.WhitespaceTokenType) {
64
+ // @ts-ignore
65
+ return {
66
+ valid: ValidationLevel.Drop,
67
+ matches: [],
68
+ node: tokens[0] ?? atRule,
69
+ syntax: '@page',
70
+ error: 'unexpected token',
71
+ tokens: []
72
+ };
73
+ }
74
+ }
75
+ }
76
+ }
77
+ // @ts-ignore
78
+ return {
79
+ valid: ValidationLevel.Valid,
80
+ matches: [],
81
+ node: atRule,
82
+ syntax: '@page',
83
+ error: '',
84
+ tokens: []
85
+ };
86
+ }
87
+
88
+ export { validateAtRulePage };
@@ -0,0 +1,262 @@
1
+ import { ValidationLevel, EnumToken } from '../../ast/types.js';
2
+ import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
4
+ import '../../parser/parse.js';
5
+ import { colorFontTech, fontFeaturesTech, fontFormat } from '../../syntax/syntax.js';
6
+ import '../../parser/utils/config.js';
7
+ import '../../renderer/color/utils/constants.js';
8
+ import '../../renderer/sourcemap/lib/encode.js';
9
+ import { consumeWhitespace } from '../utils/whitespace.js';
10
+ import { splitTokenList } from '../utils/list.js';
11
+ import { validateSyntax } from '../syntax.js';
12
+ import { getParsedSyntax } from '../config.js';
13
+
14
+ function validateAtRuleSupports(atRule, options, root) {
15
+ // media-query-list
16
+ if (!Array.isArray(atRule.tokens) || atRule.tokens.length == 0) {
17
+ // @ts-ignore
18
+ return {
19
+ valid: ValidationLevel.Drop,
20
+ matches: [],
21
+ node: atRule,
22
+ syntax: '@' + atRule.nam,
23
+ error: 'expected supports query list',
24
+ tokens: []
25
+ };
26
+ }
27
+ const result = validateAtRuleSupportsConditions(atRule, atRule.tokens);
28
+ if (result) {
29
+ if (result.node == null) {
30
+ result.node = atRule;
31
+ }
32
+ return result;
33
+ }
34
+ if (!('chi' in atRule)) {
35
+ // @ts-ignore
36
+ return {
37
+ valid: ValidationLevel.Drop,
38
+ matches: [],
39
+ node: atRule,
40
+ syntax: '@' + atRule.nam,
41
+ error: 'expected at-rule body',
42
+ tokens: []
43
+ };
44
+ }
45
+ // @ts-ignore
46
+ return {
47
+ valid: ValidationLevel.Valid,
48
+ matches: [],
49
+ node: atRule,
50
+ syntax: '@' + atRule.nam,
51
+ error: '',
52
+ tokens: []
53
+ };
54
+ }
55
+ function validateAtRuleSupportsConditions(atRule, tokenList) {
56
+ for (const tokens of splitTokenList(tokenList)) {
57
+ if (tokens.length == 0) {
58
+ // @ts-ignore
59
+ return {
60
+ valid: ValidationLevel.Drop,
61
+ matches: [],
62
+ node: tokens[0] ?? atRule,
63
+ syntax: '@' + atRule.nam,
64
+ error: 'unexpected token',
65
+ tokens: []
66
+ };
67
+ }
68
+ let previousToken = null;
69
+ let result = null;
70
+ while (tokens.length > 0) {
71
+ result = validateSupportCondition(atRule, tokens[0]);
72
+ // supports-condition
73
+ if (result == null || result.valid == ValidationLevel.Valid) {
74
+ previousToken = tokens[0];
75
+ tokens.shift();
76
+ }
77
+ else {
78
+ result = validateSupportFeature(tokens[0]);
79
+ if (result == null || result.valid == ValidationLevel.Valid) {
80
+ previousToken = tokens[0];
81
+ tokens.shift();
82
+ }
83
+ else {
84
+ return result;
85
+ }
86
+ }
87
+ if (tokens.length == 0) {
88
+ break;
89
+ }
90
+ if (!consumeWhitespace(tokens)) {
91
+ if (previousToken?.typ != EnumToken.ParensTokenType) {
92
+ // @ts-ignore
93
+ return {
94
+ valid: ValidationLevel.Drop,
95
+ matches: [],
96
+ node: tokens[0] ?? previousToken ?? atRule,
97
+ syntax: '@' + atRule.nam,
98
+ error: 'expected whitespace',
99
+ tokens: []
100
+ };
101
+ }
102
+ }
103
+ if (![EnumToken.MediaFeatureOrTokenType, EnumToken.MediaFeatureAndTokenType].includes(tokens[0].typ)) {
104
+ // @ts-ignore
105
+ return {
106
+ valid: ValidationLevel.Drop,
107
+ matches: [],
108
+ node: tokens[0] ?? atRule,
109
+ syntax: '@' + atRule.nam,
110
+ error: 'expected and/or',
111
+ tokens: []
112
+ };
113
+ }
114
+ if (tokens.length == 1) {
115
+ // @ts-ignore
116
+ return {
117
+ valid: ValidationLevel.Drop,
118
+ matches: [],
119
+ node: tokens[0] ?? atRule,
120
+ syntax: '@' + atRule.nam,
121
+ error: 'expected supports-condition',
122
+ tokens: []
123
+ };
124
+ }
125
+ tokens.shift();
126
+ if (!consumeWhitespace(tokens)) {
127
+ // @ts-ignore
128
+ return {
129
+ valid: ValidationLevel.Drop,
130
+ matches: [],
131
+ node: tokens[0] ?? atRule,
132
+ syntax: '@' + atRule.nam,
133
+ error: 'expected whitespace',
134
+ tokens: []
135
+ };
136
+ }
137
+ }
138
+ }
139
+ return null;
140
+ }
141
+ function validateSupportCondition(atRule, token) {
142
+ if (token.typ == EnumToken.MediaFeatureNotTokenType) {
143
+ return validateSupportCondition(atRule, token.val);
144
+ }
145
+ if (token.typ != EnumToken.ParensTokenType && !(['when', 'else'].includes(atRule.nam) && token.typ == EnumToken.FunctionTokenType && ['supports', 'font-format', 'font-tech'].includes(token.val))) {
146
+ // @ts-ignore
147
+ return {
148
+ valid: ValidationLevel.Drop,
149
+ matches: [],
150
+ node: token,
151
+ syntax: '@' + atRule.nam,
152
+ error: 'expected supports condition-in-parens',
153
+ tokens: []
154
+ };
155
+ }
156
+ const chi = token.chi.filter((t) => t.typ != EnumToken.CommentTokenType && t.typ != EnumToken.WhitespaceTokenType);
157
+ if (chi.length != 1) {
158
+ return validateAtRuleSupportsConditions(atRule, token.chi);
159
+ }
160
+ if (chi[0].typ == EnumToken.IdenTokenType) {
161
+ // @ts-ignore
162
+ return {
163
+ valid: ValidationLevel.Valid,
164
+ matches: [],
165
+ node: null,
166
+ syntax: '@' + atRule.nam,
167
+ error: '',
168
+ tokens: []
169
+ };
170
+ }
171
+ if (chi[0].typ == EnumToken.MediaFeatureNotTokenType) {
172
+ return validateSupportCondition(atRule, chi[0].val);
173
+ }
174
+ if (chi[0].typ == EnumToken.MediaQueryConditionTokenType) {
175
+ // @ts-ignore
176
+ return chi[0].l.typ == EnumToken.IdenTokenType && chi[0].op.typ == EnumToken.ColonTokenType ?
177
+ {
178
+ valid: ValidationLevel.Valid,
179
+ matches: [],
180
+ node: null,
181
+ syntax: 'supports-condition',
182
+ error: '',
183
+ tokens: []
184
+ } : {
185
+ valid: ValidationLevel.Drop,
186
+ matches: [],
187
+ node: token,
188
+ syntax: 'supports-condition',
189
+ error: 'expected supports condition-in-parens',
190
+ tokens: []
191
+ };
192
+ }
193
+ // @ts-ignore
194
+ return {
195
+ valid: ValidationLevel.Drop,
196
+ matches: [],
197
+ node: token,
198
+ syntax: 'supports-condition',
199
+ error: 'expected supports condition-in-parens',
200
+ tokens: []
201
+ };
202
+ }
203
+ function validateSupportFeature(token) {
204
+ if (token.typ == EnumToken.FunctionTokenType) {
205
+ if (token.val.localeCompare('selector', undefined, { sensitivity: 'base' }) == 0) {
206
+ return validateSyntax(getParsedSyntax("syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */, 'complex-selector'), token.chi);
207
+ }
208
+ if (token.val.localeCompare('font-tech', undefined, { sensitivity: 'base' }) == 0) {
209
+ const chi = token.chi.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ));
210
+ // @ts-ignore
211
+ return chi.length == 1 && chi[0].typ == EnumToken.IdenTokenType && colorFontTech.concat(fontFeaturesTech).some((t) => t.localeCompare(chi[0].val, undefined, { sensitivity: 'base' }) == 0) ?
212
+ {
213
+ valid: ValidationLevel.Valid,
214
+ matches: [],
215
+ node: token,
216
+ syntax: 'font-tech',
217
+ error: '',
218
+ tokens: []
219
+ } :
220
+ {
221
+ valid: ValidationLevel.Drop,
222
+ matches: [],
223
+ node: token,
224
+ syntax: 'font-tech',
225
+ error: 'expected font-tech',
226
+ tokens: []
227
+ };
228
+ }
229
+ if (token.val.localeCompare('font-format', undefined, { sensitivity: 'base' }) == 0) {
230
+ const chi = token.chi.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ));
231
+ // @ts-ignore
232
+ return chi.length == 1 && chi[0].typ == EnumToken.IdenTokenType && fontFormat.some((t) => t.localeCompare(chi[0].val, undefined, { sensitivity: 'base' }) == 0) ?
233
+ {
234
+ valid: ValidationLevel.Valid,
235
+ matches: [],
236
+ node: token,
237
+ syntax: 'font-format',
238
+ error: '',
239
+ tokens: []
240
+ } :
241
+ {
242
+ valid: ValidationLevel.Drop,
243
+ matches: [],
244
+ node: token,
245
+ syntax: 'font-format',
246
+ error: 'expected font-format',
247
+ tokens: []
248
+ };
249
+ }
250
+ }
251
+ // @ts-ignore
252
+ return {
253
+ valid: ValidationLevel.Drop,
254
+ matches: [],
255
+ node: token,
256
+ syntax: '@supports',
257
+ error: 'expected feature',
258
+ tokens: []
259
+ };
260
+ }
261
+
262
+ export { validateAtRuleSupports, validateAtRuleSupportsConditions, validateSupportCondition };
@@ -0,0 +1,178 @@
1
+ import { ValidationLevel, EnumToken } from '../../ast/types.js';
2
+ import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
4
+ import '../../parser/parse.js';
5
+ import '../../renderer/color/utils/constants.js';
6
+ import '../../renderer/sourcemap/lib/encode.js';
7
+ import '../../parser/utils/config.js';
8
+ import { consumeWhitespace } from '../utils/whitespace.js';
9
+ import { splitTokenList } from '../utils/list.js';
10
+ import { validateMediaFeature, validateMediaCondition } from './media.js';
11
+ import { validateSupportCondition } from './supports.js';
12
+
13
+ function validateAtRuleWhen(atRule, options, root) {
14
+ const slice = Array.isArray(atRule.tokens) ? atRule.tokens.slice() : [];
15
+ consumeWhitespace(slice);
16
+ if (slice.length == 0) {
17
+ // @ts-ignore
18
+ return {
19
+ valid: ValidationLevel.Valid,
20
+ matches: [],
21
+ node: atRule,
22
+ syntax: '@when',
23
+ error: '',
24
+ tokens: []
25
+ };
26
+ }
27
+ const result = validateAtRuleWhenQueryList(atRule.tokens, atRule);
28
+ if (result.valid == ValidationLevel.Drop) {
29
+ return result;
30
+ }
31
+ if (!('chi' in atRule)) {
32
+ // @ts-ignore
33
+ return {
34
+ valid: ValidationLevel.Drop,
35
+ matches: [],
36
+ node: atRule,
37
+ syntax: '@when',
38
+ error: 'expected at-rule body',
39
+ tokens: []
40
+ };
41
+ }
42
+ return {
43
+ valid: ValidationLevel.Valid,
44
+ matches: [],
45
+ node: atRule,
46
+ syntax: '@when',
47
+ error: '',
48
+ tokens: result.tokens
49
+ };
50
+ }
51
+ // media() = media( [ <mf-plain> | <mf-boolean> | <mf-range> ] )
52
+ // supports() = supports( <declaration> )
53
+ function validateAtRuleWhenQueryList(tokenList, atRule) {
54
+ const matched = [];
55
+ let result = null;
56
+ for (const split of splitTokenList(tokenList)) {
57
+ const match = [];
58
+ result = null;
59
+ consumeWhitespace(split);
60
+ if (split.length == 0) {
61
+ continue;
62
+ }
63
+ while (split.length > 0) {
64
+ if (split[0].typ != EnumToken.FunctionTokenType || !['media', 'supports', 'font-tech', 'font-format'].includes(split[0].val)) {
65
+ result = {
66
+ valid: ValidationLevel.Drop,
67
+ matches: [],
68
+ node: split[0] ?? atRule,
69
+ syntax: '@when',
70
+ error: 'unexpected token',
71
+ tokens: []
72
+ };
73
+ break;
74
+ }
75
+ const chi = split[0].chi.slice();
76
+ consumeWhitespace(chi);
77
+ if (split[0].val == 'media') {
78
+ // result = valida
79
+ if (chi.length != 1 || !(validateMediaFeature(chi[0]) || validateMediaCondition(split[0], atRule))) {
80
+ result = {
81
+ valid: ValidationLevel.Drop,
82
+ matches: [],
83
+ node: split[0] ?? atRule,
84
+ syntax: 'media( [ <mf-plain> | <mf-boolean> | <mf-range> ] )',
85
+ error: 'unexpected token',
86
+ tokens: []
87
+ };
88
+ break;
89
+ }
90
+ }
91
+ else if (['supports', 'font-tech', 'font-format'].includes(split[0].val)) {
92
+ // result = valida
93
+ if (!validateSupportCondition(atRule, split[0])) {
94
+ result = {
95
+ valid: ValidationLevel.Drop,
96
+ matches: [],
97
+ node: split[0] ?? atRule,
98
+ syntax: 'media( [ <mf-plain> | <mf-boolean> | <mf-range> ] )',
99
+ error: 'unexpected token',
100
+ tokens: []
101
+ };
102
+ break;
103
+ }
104
+ }
105
+ if (match.length > 0) {
106
+ match.push({ typ: EnumToken.WhitespaceTokenType });
107
+ }
108
+ match.push(split.shift());
109
+ consumeWhitespace(split);
110
+ if (split.length == 0) {
111
+ break;
112
+ }
113
+ if (![EnumToken.MediaFeatureAndTokenType, EnumToken.MediaFeatureOrTokenType].includes(split[0].typ)) {
114
+ result = {
115
+ valid: ValidationLevel.Drop,
116
+ matches: [],
117
+ node: split[0] ?? atRule,
118
+ syntax: '@when',
119
+ error: 'expecting and/or media-condition',
120
+ tokens: []
121
+ };
122
+ break;
123
+ }
124
+ if (match.length > 0) {
125
+ match.push({ typ: EnumToken.WhitespaceTokenType });
126
+ }
127
+ match.push(split.shift());
128
+ consumeWhitespace(split);
129
+ if (split.length == 0) {
130
+ result = {
131
+ valid: ValidationLevel.Drop,
132
+ matches: [],
133
+ node: split[0] ?? atRule,
134
+ syntax: '@when',
135
+ error: 'expecting media-condition',
136
+ tokens: []
137
+ };
138
+ break;
139
+ }
140
+ }
141
+ if (result == null && match.length > 0) {
142
+ matched.push(match);
143
+ }
144
+ }
145
+ if (result != null) {
146
+ return result;
147
+ }
148
+ if (matched.length == 0) {
149
+ return {
150
+ valid: ValidationLevel.Drop,
151
+ matches: [],
152
+ // @ts-ignore
153
+ node: result?.node ?? atRule,
154
+ syntax: '@when',
155
+ error: 'invalid at-rule body',
156
+ tokens: []
157
+ };
158
+ }
159
+ tokenList.length = 0;
160
+ for (const match of matched) {
161
+ if (tokenList.length > 0) {
162
+ tokenList.push({
163
+ typ: EnumToken.CommaTokenType
164
+ });
165
+ }
166
+ tokenList.push(...match);
167
+ }
168
+ return {
169
+ valid: ValidationLevel.Valid,
170
+ matches: [],
171
+ node: atRule,
172
+ syntax: '@when',
173
+ error: '',
174
+ tokens: tokenList
175
+ };
176
+ }
177
+
178
+ export { validateAtRuleWhen, validateAtRuleWhenQueryList };