@tbela99/css-parser 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/.editorconfig +484 -0
  2. package/README.md +13 -8
  3. package/dist/index-umd-web.js +2451 -2554
  4. package/dist/index.cjs +2605 -2708
  5. package/dist/index.d.ts +73 -23
  6. package/dist/lib/ast/expand.js +29 -4
  7. package/dist/lib/ast/math/expression.js +1 -1
  8. package/dist/lib/ast/minify.js +31 -17
  9. package/dist/lib/ast/types.js +2 -0
  10. package/dist/lib/ast/walk.js +12 -0
  11. package/dist/lib/parser/declaration/map.js +59 -52
  12. package/dist/lib/parser/declaration/set.js +0 -12
  13. package/dist/lib/parser/parse.js +204 -139
  14. package/dist/lib/parser/tokenize.js +15 -3
  15. package/dist/lib/renderer/color/color.js +2 -2
  16. package/dist/lib/renderer/color/hex.js +1 -1
  17. package/dist/lib/renderer/color/hsl.js +1 -1
  18. package/dist/lib/renderer/color/hwb.js +2 -2
  19. package/dist/lib/renderer/color/lab.js +3 -2
  20. package/dist/lib/renderer/color/lch.js +1 -1
  21. package/dist/lib/renderer/color/oklab.js +2 -2
  22. package/dist/lib/renderer/color/oklch.js +1 -1
  23. package/dist/lib/renderer/color/p3.js +1 -1
  24. package/dist/lib/renderer/color/prophotoRgb.js +2 -2
  25. package/dist/lib/renderer/color/prophotorgb.js +2 -2
  26. package/dist/lib/renderer/color/rgb.js +1 -1
  27. package/dist/lib/renderer/color/srgb.js +2 -2
  28. package/dist/lib/renderer/color/utils/constants.js +1 -1
  29. package/dist/lib/renderer/color/xyz.js +2 -18
  30. package/dist/lib/renderer/color/xyzd50.js +20 -2
  31. package/dist/lib/renderer/render.js +37 -8
  32. package/dist/lib/renderer/sourcemap/sourcemap.js +1 -1
  33. package/dist/lib/syntax/syntax.js +337 -1
  34. package/dist/lib/validation/at-rules/container.js +353 -0
  35. package/dist/lib/validation/at-rules/counter-style.js +2 -2
  36. package/dist/lib/validation/at-rules/custom-media.js +52 -0
  37. package/dist/lib/validation/at-rules/document.js +40 -60
  38. package/dist/lib/validation/at-rules/else.js +5 -0
  39. package/dist/lib/validation/at-rules/font-feature-values.js +3 -0
  40. package/dist/lib/validation/at-rules/import.js +64 -59
  41. package/dist/lib/validation/at-rules/layer.js +3 -0
  42. package/dist/lib/validation/at-rules/media.js +118 -29
  43. package/dist/lib/validation/at-rules/supports.js +51 -20
  44. package/dist/lib/validation/at-rules/when.js +178 -0
  45. package/dist/lib/validation/atrule.js +25 -10
  46. package/dist/lib/validation/config.js +20 -15
  47. package/dist/lib/validation/config.json.js +242 -74
  48. package/dist/lib/validation/declaration.js +32 -10
  49. package/dist/lib/validation/parser/parse.js +87 -103
  50. package/dist/lib/validation/parser/types.js +2 -2
  51. package/dist/lib/validation/selector.js +6 -3
  52. package/dist/lib/validation/syntax.js +86 -6
  53. package/dist/lib/validation/syntaxes/complex-selector-list.js +16 -12
  54. package/dist/lib/validation/syntaxes/complex-selector.js +17 -247
  55. package/dist/lib/validation/syntaxes/compound-selector.js +226 -0
  56. package/dist/lib/validation/syntaxes/image.js +29 -0
  57. package/dist/lib/validation/syntaxes/keyframe-block-list.js +1 -1
  58. package/dist/lib/validation/syntaxes/keyframe-selector.js +1 -1
  59. package/dist/lib/validation/syntaxes/layer-name.js +5 -16
  60. package/dist/lib/validation/syntaxes/relative-selector-list.js +43 -13
  61. package/dist/lib/validation/utils/list.js +2 -2
  62. package/dist/node/index.js +1 -1
  63. package/dist/web/index.js +1 -1
  64. package/package.json +10 -9
@@ -1,4 +1,5 @@
1
1
  import { consumeWhitespace } from '../utils/whitespace.js';
2
+ import { splitTokenList } from '../utils/list.js';
2
3
  import { EnumToken, ValidationLevel } from '../../ast/types.js';
3
4
  import '../../ast/minify.js';
4
5
  import '../../ast/walk.js';
@@ -6,9 +7,11 @@ import '../../parser/parse.js';
6
7
  import '../../renderer/color/utils/constants.js';
7
8
  import '../../renderer/sourcemap/lib/encode.js';
8
9
  import '../../parser/utils/config.js';
10
+ import { validateCompoundSelector } from './compound-selector.js';
9
11
 
10
12
  const combinatorsTokens = [EnumToken.ChildCombinatorTokenType, EnumToken.ColumnCombinatorTokenType,
11
- EnumToken.DescendantCombinatorTokenType, EnumToken.NextSiblingCombinatorTokenType, EnumToken.SubsequentSiblingCombinatorTokenType];
13
+ // EnumToken.DescendantCombinatorTokenType,
14
+ EnumToken.NextSiblingCombinatorTokenType, EnumToken.SubsequentSiblingCombinatorTokenType];
12
15
  // <compound-selector> [ <combinator>? <compound-selector> ]*
13
16
  function validateComplexSelector(tokens, root, options) {
14
17
  // [ <type-selector>? <subclass-selector>* [ <pseudo-element-selector> <pseudo-class-selector>* ]* ]!
@@ -25,257 +28,24 @@ function validateComplexSelector(tokens, root, options) {
25
28
  tokens
26
29
  };
27
30
  }
28
- while (tokens.length > 0) {
29
- if (combinatorsTokens.includes(tokens[0].typ)) {
30
- // @ts-ignore
31
- return {
32
- valid: ValidationLevel.Drop,
33
- matches: [],
34
- // @ts-ignore
35
- node: tokens[0],
36
- syntax: null,
37
- error: 'unexpected combinator',
38
- tokens
39
- };
40
- }
41
- if (tokens[0].typ == EnumToken.NestingSelectorTokenType) {
42
- if (!options?.nestedSelector) {
43
- // @ts-ignore
44
- return {
45
- valid: ValidationLevel.Drop,
46
- matches: [],
47
- // @ts-ignore
48
- node: tokens[0],
49
- syntax: null,
50
- error: 'nested selector not allowed',
51
- tokens
52
- };
53
- }
54
- while (tokens.length > 0 && tokens[0].typ == EnumToken.NestingSelectorTokenType) {
55
- tokens.shift();
56
- consumeWhitespace(tokens);
57
- }
58
- if (tokens.length == 0) {
59
- break;
60
- }
61
- }
62
- if (EnumToken.IdenTokenType == tokens[0].typ) {
63
- tokens.shift();
64
- consumeWhitespace(tokens);
65
- if (tokens.length == 0) {
66
- break;
67
- }
68
- }
69
- if (EnumToken.UniversalSelectorTokenType == tokens[0].typ) {
70
- tokens.shift();
71
- consumeWhitespace(tokens);
72
- }
73
- while (tokens.length > 0) {
74
- if (tokens[0].typ == EnumToken.PseudoClassFuncTokenType) {
75
- if (tokens[0].val.startsWith(':-webkit-')) {
76
- // @ts-ignore
77
- return {
78
- valid: ValidationLevel.Drop,
79
- matches: [],
80
- // @ts-ignore
81
- node: tokens[0],
82
- syntax: null,
83
- error: 'invalid pseudo-class',
84
- tokens
85
- };
86
- }
87
- }
88
- if ([
89
- EnumToken.ClassSelectorTokenType,
90
- EnumToken.HashTokenType,
91
- EnumToken.PseudoClassTokenType,
92
- EnumToken.PseudoClassFuncTokenType
93
- ].includes(tokens[0].typ)) {
94
- tokens.shift();
95
- consumeWhitespace(tokens);
96
- continue;
97
- }
98
- if (tokens[0].typ == EnumToken.NestingSelectorTokenType) {
99
- if (!options?.nestedSelector) {
100
- // @ts-ignore
101
- return {
102
- valid: ValidationLevel.Drop,
103
- matches: [],
104
- // @ts-ignore
105
- node: tokens[0],
106
- syntax: null,
107
- error: 'nested selector not allowed',
108
- tokens
109
- };
110
- }
111
- tokens.shift();
112
- consumeWhitespace(tokens);
113
- continue;
114
- }
115
- // validate namespace
116
- if (tokens[0].typ == EnumToken.NameSpaceAttributeTokenType) {
117
- if (!((tokens[0].l == null || tokens[0].l.typ == EnumToken.IdenTokenType || (tokens[0].l.typ == EnumToken.LiteralTokenType && tokens[0].l.val == '*')) &&
118
- tokens[0].r.typ == EnumToken.IdenTokenType)) {
119
- // @ts-ignore
120
- return {
121
- valid: ValidationLevel.Drop,
122
- matches: [],
123
- node: tokens[0],
124
- syntax: null,
125
- error: 'expecting wq-name',
126
- tokens
127
- };
128
- }
129
- tokens.shift();
130
- consumeWhitespace(tokens);
131
- continue;
132
- }
133
- // validate attribute
134
- else if (tokens[0].typ == EnumToken.AttrTokenType) {
135
- const children = tokens[0].chi.slice();
136
- consumeWhitespace(children);
137
- if (children.length == 0) {
138
- // @ts-ignore
139
- return {
140
- valid: ValidationLevel.Drop,
141
- matches: [],
142
- node: tokens[0],
143
- syntax: null,
144
- error: 'invalid attribute selector',
145
- tokens
146
- };
147
- }
148
- if (![
149
- EnumToken.IdenTokenType,
150
- EnumToken.NameSpaceAttributeTokenType,
151
- EnumToken.MatchExpressionTokenType
152
- ].includes(children[0].typ)) {
153
- // @ts-ignore
154
- return {
155
- valid: ValidationLevel.Drop,
156
- matches: [],
157
- node: tokens[0],
158
- syntax: null,
159
- error: 'invalid attribute selector',
160
- tokens
161
- };
162
- }
163
- if (children[0].typ == EnumToken.MatchExpressionTokenType) {
164
- if (![EnumToken.IdenTokenType,
165
- EnumToken.NameSpaceAttributeTokenType].includes(children[0].l.typ) ||
166
- ![
167
- EnumToken.EqualMatchTokenType, EnumToken.DashMatchTokenType,
168
- EnumToken.StartMatchTokenType, EnumToken.ContainMatchTokenType,
169
- EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType
170
- ].includes(children[0].op.typ) ||
171
- ![EnumToken.StringTokenType,
172
- EnumToken.IdenTokenType].includes(children[0].r.typ)) {
173
- // @ts-ignore
174
- return {
175
- valid: ValidationLevel.Drop,
176
- matches: [],
177
- node: tokens[0],
178
- syntax: null,
179
- error: 'invalid attribute selector',
180
- tokens
181
- };
182
- }
183
- if (children[0].attr != null && !['i', 's'].includes(children[0].attr)) {
184
- // @ts-ignore
185
- return {
186
- valid: ValidationLevel.Drop,
187
- matches: [],
188
- node: tokens[0],
189
- syntax: null,
190
- error: 'invalid attribute selector',
191
- tokens
192
- };
193
- }
194
- }
195
- children.shift();
196
- consumeWhitespace(children);
197
- if (children.length > 0) {
198
- // @ts-ignore
199
- return {
200
- valid: ValidationLevel.Drop,
201
- matches: [],
202
- node: children[0],
203
- syntax: null,
204
- error: 'unexpected token',
205
- tokens
206
- };
207
- }
208
- tokens.shift();
209
- consumeWhitespace(tokens);
210
- continue;
211
- }
212
- break;
213
- }
214
- if (tokens.length == 0) {
215
- break;
216
- }
217
- // combinator
218
- if (!combinatorsTokens.includes(tokens[0].typ)) {
219
- if (tokens[0].typ == EnumToken.NestingSelectorTokenType) {
220
- if (!options?.nestedSelector) {
221
- // @ts-ignore
222
- return {
223
- valid: ValidationLevel.Drop,
224
- matches: [],
225
- // @ts-ignore
226
- node: tokens[0],
227
- syntax: null,
228
- error: 'nested selector not allowed',
229
- tokens
230
- };
231
- }
232
- tokens.shift();
233
- consumeWhitespace(tokens);
234
- continue;
235
- }
236
- if (tokens.length > 0 &&
237
- [
238
- EnumToken.IdenTokenType,
239
- EnumToken.AttrTokenType,
240
- EnumToken.NameSpaceAttributeTokenType,
241
- EnumToken.ClassSelectorTokenType,
242
- EnumToken.HashTokenType,
243
- EnumToken.PseudoClassTokenType,
244
- EnumToken.PseudoClassFuncTokenType
245
- ].includes(tokens[0].typ)) {
246
- continue;
247
- }
248
- // @ts-ignore
249
- return {
250
- valid: ValidationLevel.Drop,
251
- matches: [],
252
- node: tokens[0],
253
- syntax: null,
254
- error: 'expecting combinator or subclass-selector',
255
- tokens
256
- };
257
- }
258
- const token = tokens.shift();
259
- consumeWhitespace(tokens);
260
- if (tokens.length == 0) {
261
- // @ts-ignore
262
- return {
263
- valid: ValidationLevel.Drop,
264
- matches: [],
265
- node: token,
266
- syntax: null,
267
- error: 'expected compound-selector',
268
- tokens
269
- };
31
+ // const config = getSyntaxConfig();
32
+ //
33
+ // let match: number = 0;
34
+ let result = null;
35
+ // const combinators: EnumToken[] = combinatorsTokens.filter((t: EnumToken) => t != EnumToken.DescendantCombinatorTokenType);
36
+ for (const t of splitTokenList(tokens, combinatorsTokens)) {
37
+ result = validateCompoundSelector(t, root, options);
38
+ if (result.valid == ValidationLevel.Drop) {
39
+ return result;
270
40
  }
271
41
  }
272
42
  // @ts-ignore
273
- return {
274
- valid: ValidationLevel.Valid,
43
+ return result ?? {
44
+ valid: ValidationLevel.Drop,
275
45
  matches: [],
276
- node: null,
46
+ node: root,
277
47
  syntax: null,
278
- error: '',
48
+ error: 'expecting compound-selector',
279
49
  tokens
280
50
  };
281
51
  }
@@ -0,0 +1,226 @@
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 { mozExtensions, webkitExtensions } 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 { getSyntaxConfig } from '../config.js';
11
+
12
+ function validateCompoundSelector(tokens, root, options) {
13
+ if (tokens.length == 0) {
14
+ // @ts-ignore
15
+ return {
16
+ valid: ValidationLevel.Drop,
17
+ matches: [],
18
+ // @ts-ignore
19
+ node: root,
20
+ // @ts-ignore
21
+ syntax: null,
22
+ error: 'expected selector',
23
+ tokens
24
+ };
25
+ }
26
+ tokens = tokens.slice();
27
+ consumeWhitespace(tokens);
28
+ const config = getSyntaxConfig();
29
+ let match = 0;
30
+ let length = tokens.length;
31
+ while (tokens.length > 0) {
32
+ while (tokens.length > 0 && tokens[0].typ == EnumToken.NestingSelectorTokenType) {
33
+ if (!options?.nestedSelector) {
34
+ // @ts-ignore
35
+ return {
36
+ valid: ValidationLevel.Drop,
37
+ matches: [],
38
+ // @ts-ignore
39
+ node: tokens[0],
40
+ syntax: null,
41
+ error: 'nested selector not allowed',
42
+ tokens
43
+ };
44
+ }
45
+ match++;
46
+ tokens.shift();
47
+ consumeWhitespace(tokens);
48
+ }
49
+ // <type-selector>
50
+ while (tokens.length > 0 &&
51
+ [
52
+ EnumToken.IdenTokenType,
53
+ EnumToken.NameSpaceAttributeTokenType,
54
+ EnumToken.ClassSelectorTokenType,
55
+ EnumToken.HashTokenType,
56
+ EnumToken.UniversalSelectorTokenType
57
+ ].includes(tokens[0].typ)) {
58
+ match++;
59
+ tokens.shift();
60
+ consumeWhitespace(tokens);
61
+ }
62
+ while (tokens.length > 0 && tokens[0].typ == EnumToken.PseudoClassFuncTokenType) {
63
+ if (!mozExtensions.has(tokens[0].val + '()') &&
64
+ !webkitExtensions.has(tokens[0].val + '()') &&
65
+ !((tokens[0].val + '()') in config.selectors)) {
66
+ if (!options?.lenient || /^(:?)-webkit-/.test(tokens[0].val)) {
67
+ // @ts-ignore
68
+ return {
69
+ valid: ValidationLevel.Drop,
70
+ matches: [],
71
+ // @ts-ignore
72
+ node: tokens[0],
73
+ syntax: null,
74
+ error: 'unknown pseudo-class: ' + tokens[0].val + '()',
75
+ tokens
76
+ };
77
+ }
78
+ }
79
+ match++;
80
+ tokens.shift();
81
+ consumeWhitespace(tokens);
82
+ }
83
+ while (tokens.length > 0 && (tokens[0].typ == EnumToken.PseudoElementTokenType || tokens[0].typ == EnumToken.PseudoClassTokenType)) {
84
+ const isPseudoElement = tokens[0].typ == EnumToken.PseudoElementTokenType;
85
+ if (
86
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/WebKit_Extensions#pseudo-elements
87
+ !(isPseudoElement && tokens[0].val.startsWith('::-webkit-')) &&
88
+ !mozExtensions.has(tokens[0].val) &&
89
+ !webkitExtensions.has(tokens[0].val) &&
90
+ !(tokens[0].val in config.selectors) &&
91
+ !(!isPseudoElement &&
92
+ (':' + tokens[0].val) in config.selectors)) {
93
+ if (!options?.lenient || /^(:?)-webkit-/.test(tokens[0].val)) {
94
+ // @ts-ignore
95
+ return {
96
+ valid: ValidationLevel.Drop,
97
+ matches: [],
98
+ // @ts-ignore
99
+ node: tokens[0],
100
+ syntax: null,
101
+ error: 'unknown pseudo-class: ' + tokens[0].val,
102
+ tokens
103
+ };
104
+ }
105
+ }
106
+ match++;
107
+ tokens.shift();
108
+ consumeWhitespace(tokens);
109
+ }
110
+ while (tokens.length > 0 && tokens[0].typ == EnumToken.AttrTokenType) {
111
+ const children = tokens[0].chi.slice();
112
+ consumeWhitespace(children);
113
+ if (children.length == 0) {
114
+ // @ts-ignore
115
+ return {
116
+ valid: ValidationLevel.Drop,
117
+ matches: [],
118
+ node: tokens[0],
119
+ syntax: null,
120
+ error: 'invalid attribute selector',
121
+ tokens
122
+ };
123
+ }
124
+ if (![
125
+ EnumToken.IdenTokenType,
126
+ EnumToken.NameSpaceAttributeTokenType,
127
+ EnumToken.MatchExpressionTokenType
128
+ ].includes(children[0].typ)) {
129
+ // @ts-ignore
130
+ return {
131
+ valid: ValidationLevel.Drop,
132
+ matches: [],
133
+ node: tokens[0],
134
+ syntax: null,
135
+ error: 'invalid attribute selector',
136
+ tokens
137
+ };
138
+ }
139
+ if (children[0].typ == EnumToken.MatchExpressionTokenType) {
140
+ if (children.length != 1) {
141
+ return {
142
+ valid: ValidationLevel.Drop,
143
+ matches: [],
144
+ node: tokens[0],
145
+ syntax: null,
146
+ error: 'invalid <attribute-selector>',
147
+ tokens
148
+ };
149
+ }
150
+ if (![
151
+ EnumToken.IdenTokenType,
152
+ EnumToken.NameSpaceAttributeTokenType
153
+ ].includes(children[0].l.typ) ||
154
+ ![
155
+ EnumToken.EqualMatchTokenType, EnumToken.DashMatchTokenType,
156
+ EnumToken.StartMatchTokenType, EnumToken.ContainMatchTokenType,
157
+ EnumToken.EndMatchTokenType, EnumToken.IncludeMatchTokenType
158
+ ].includes(children[0].op.typ) ||
159
+ ![
160
+ EnumToken.StringTokenType,
161
+ EnumToken.IdenTokenType
162
+ ].includes(children[0].r.typ)) {
163
+ // @ts-ignore
164
+ return {
165
+ valid: ValidationLevel.Drop,
166
+ matches: [],
167
+ node: tokens[0],
168
+ syntax: null,
169
+ error: 'invalid attribute selector',
170
+ tokens
171
+ };
172
+ }
173
+ if (children[0].attr != null && !['i', 's'].includes(children[0].attr)) {
174
+ // @ts-ignore
175
+ return {
176
+ valid: ValidationLevel.Drop,
177
+ matches: [],
178
+ node: tokens[0],
179
+ syntax: null,
180
+ error: 'invalid attribute selector',
181
+ tokens
182
+ };
183
+ }
184
+ }
185
+ match++;
186
+ tokens.shift();
187
+ consumeWhitespace(tokens);
188
+ }
189
+ if (length == tokens.length) {
190
+ return {
191
+ valid: ValidationLevel.Drop,
192
+ matches: [],
193
+ // @ts-ignore
194
+ node: tokens[0],
195
+ // @ts-ignore
196
+ syntax: null,
197
+ error: 'expected compound selector',
198
+ tokens
199
+ };
200
+ }
201
+ length = tokens.length;
202
+ }
203
+ return match == 0 ? {
204
+ valid: ValidationLevel.Drop,
205
+ matches: [],
206
+ // @ts-ignore
207
+ node: root,
208
+ // @ts-ignore
209
+ syntax: null,
210
+ error: 'expected compound selector',
211
+ tokens
212
+ } :
213
+ // @ts-ignore
214
+ {
215
+ valid: ValidationLevel.Valid,
216
+ matches: [],
217
+ // @ts-ignore
218
+ node: root,
219
+ // @ts-ignore
220
+ syntax: null,
221
+ error: null,
222
+ tokens
223
+ };
224
+ }
225
+
226
+ export { validateCompoundSelector };
@@ -0,0 +1,29 @@
1
+ import { EnumToken, ValidationLevel } 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 { validateSyntax } from '../syntax.js';
9
+ import { getParsedSyntax } from '../config.js';
10
+ import { validateURL } from './url.js';
11
+
12
+ function validateImage(token) {
13
+ if (token.typ == EnumToken.UrlFunctionTokenType) {
14
+ return validateURL(token);
15
+ }
16
+ if (token.typ == EnumToken.ImageFunctionTokenType) {
17
+ return validateSyntax(getParsedSyntax("syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */, token.val + '()'), token.chi);
18
+ }
19
+ return {
20
+ valid: ValidationLevel.Drop,
21
+ matches: [],
22
+ node: token,
23
+ syntax: 'image()',
24
+ error: 'expected <image> or <url>',
25
+ tokens: []
26
+ };
27
+ }
28
+
29
+ export { validateImage };
@@ -7,7 +7,7 @@ import '../../renderer/sourcemap/lib/encode.js';
7
7
  import '../../parser/utils/config.js';
8
8
  import { validateKeyframeSelector } from './keyframe-selector.js';
9
9
 
10
- function validateKeyframeBlockList(tokens, atRule) {
10
+ function validateKeyframeBlockList(tokens, atRule, options) {
11
11
  let i = 0;
12
12
  let j = 0;
13
13
  let result = null;
@@ -7,7 +7,7 @@ import '../../renderer/color/utils/constants.js';
7
7
  import '../../renderer/sourcemap/lib/encode.js';
8
8
  import '../../parser/utils/config.js';
9
9
 
10
- function validateKeyframeSelector(tokens, atRule) {
10
+ function validateKeyframeSelector(tokens, atRule, options) {
11
11
  consumeWhitespace(tokens);
12
12
  if (tokens.length == 0) {
13
13
  // @ts-ignore
@@ -15,7 +15,7 @@ function validateLayerName(tokens) {
15
15
  acc[acc.length - 1].push(curr);
16
16
  }
17
17
  return acc;
18
- }, [[]]).slice(1);
18
+ }, [[]]);
19
19
  for (let i = 0; i < slice.length; i++) {
20
20
  if (slice[i].length == 0) {
21
21
  // @ts-ignore
@@ -28,26 +28,15 @@ function validateLayerName(tokens) {
28
28
  tokens
29
29
  };
30
30
  }
31
- if (slice[i][0].typ != EnumToken.IdenTokenType) {
32
- // @ts-ignore
33
- return {
34
- valid: ValidationLevel.Drop,
35
- matches: tokens,
36
- node: slice[i][0],
37
- syntax: 'ident',
38
- error: 'expecting ident',
39
- tokens
40
- };
41
- }
42
- for (let j = 1; j < slice[i].length; j++) {
43
- if (slice[i][j].typ != EnumToken.ClassSelectorTokenType) {
31
+ for (let j = 0; j < slice[i].length; j++) {
32
+ if (slice[i][j].typ != EnumToken.IdenTokenType && slice[i][j].typ != EnumToken.ClassSelectorTokenType) {
44
33
  // @ts-ignore
45
34
  return {
46
35
  valid: ValidationLevel.Drop,
47
36
  matches: tokens,
48
37
  node: slice[i][j],
49
- syntax: 'layer-name',
50
- error: 'expecting class selector',
38
+ syntax: '<layer-name>',
39
+ error: 'expecting ident or class selector',
51
40
  tokens
52
41
  };
53
42
  }
@@ -1,4 +1,4 @@
1
- import { EnumToken, ValidationLevel } from '../../ast/types.js';
1
+ import { ValidationLevel } from '../../ast/types.js';
2
2
  import '../../ast/minify.js';
3
3
  import '../../ast/walk.js';
4
4
  import '../../parser/parse.js';
@@ -6,22 +6,52 @@ import '../../renderer/color/utils/constants.js';
6
6
  import '../../renderer/sourcemap/lib/encode.js';
7
7
  import '../../parser/utils/config.js';
8
8
  import { validateRelativeSelector } from './relative-selector.js';
9
+ import { consumeWhitespace } from '../utils/whitespace.js';
10
+ import { splitTokenList } from '../utils/list.js';
9
11
 
10
12
  function validateRelativeSelectorList(tokens, root, options) {
11
- let i = 0;
12
- let j = 0;
13
- let result = null;
14
- while (i + 1 < tokens.length) {
15
- if (tokens[++i].typ == EnumToken.CommaTokenType) {
16
- result = validateRelativeSelector(tokens.slice(j, i), root, options);
17
- if (result.valid == ValidationLevel.Drop) {
18
- return result;
19
- }
20
- j = i + 1;
21
- i = j;
13
+ tokens = tokens.slice();
14
+ consumeWhitespace(tokens);
15
+ if (tokens.length == 0) {
16
+ return {
17
+ valid: ValidationLevel.Drop,
18
+ matches: [],
19
+ // @ts-ignore
20
+ node: root,
21
+ // @ts-ignore
22
+ syntax: null,
23
+ error: 'expecting relative selector list',
24
+ tokens
25
+ };
26
+ }
27
+ for (const t of splitTokenList(tokens)) {
28
+ if (t.length == 0) {
29
+ return {
30
+ valid: ValidationLevel.Drop,
31
+ matches: [],
32
+ // @ts-ignore
33
+ node: root,
34
+ // @ts-ignore
35
+ syntax: null,
36
+ error: 'unexpected comma',
37
+ tokens
38
+ };
39
+ }
40
+ const result = validateRelativeSelector(t, root, options);
41
+ if (result.valid == ValidationLevel.Drop) {
42
+ return result;
22
43
  }
23
44
  }
24
- return validateRelativeSelector(i == j ? tokens.slice(i) : tokens.slice(j, i + 1), root, options);
45
+ return {
46
+ valid: ValidationLevel.Valid,
47
+ matches: [],
48
+ // @ts-ignore
49
+ node: root,
50
+ // @ts-ignore
51
+ syntax: null,
52
+ error: '',
53
+ tokens
54
+ };
25
55
  }
26
56
 
27
57
  export { validateRelativeSelectorList };