@tbela99/css-parser 0.7.0 → 0.8.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 (82) hide show
  1. package/README.md +142 -81
  2. package/dist/index-umd-web.js +7027 -51519
  3. package/dist/index.cjs +7022 -51515
  4. package/dist/index.d.ts +189 -60
  5. package/dist/lib/ast/expand.js +87 -2
  6. package/dist/lib/ast/features/calc.js +76 -12
  7. package/dist/lib/ast/features/inlinecssvariables.js +6 -1
  8. package/dist/lib/ast/features/prefix.js +17 -9
  9. package/dist/lib/ast/features/shorthand.js +1 -0
  10. package/dist/lib/ast/math/expression.js +299 -11
  11. package/dist/lib/ast/math/math.js +7 -1
  12. package/dist/lib/ast/minify.js +1 -1
  13. package/dist/lib/ast/types.js +58 -49
  14. package/dist/lib/ast/walk.js +80 -18
  15. package/dist/lib/parser/declaration/list.js +1 -0
  16. package/dist/lib/parser/declaration/map.js +1 -0
  17. package/dist/lib/parser/declaration/set.js +1 -0
  18. package/dist/lib/parser/parse.js +285 -72
  19. package/dist/lib/parser/tokenize.js +23 -3
  20. package/dist/lib/parser/utils/declaration.js +2 -2
  21. package/dist/lib/parser/utils/type.js +6 -6
  22. package/dist/lib/renderer/color/a98rgb.js +1 -0
  23. package/dist/lib/renderer/color/color.js +1 -0
  24. package/dist/lib/renderer/color/colormix.js +1 -0
  25. package/dist/lib/renderer/color/hex.js +1 -0
  26. package/dist/lib/renderer/color/hsl.js +1 -0
  27. package/dist/lib/renderer/color/hwb.js +1 -0
  28. package/dist/lib/renderer/color/lab.js +1 -0
  29. package/dist/lib/renderer/color/lch.js +1 -0
  30. package/dist/lib/renderer/color/oklab.js +1 -0
  31. package/dist/lib/renderer/color/oklch.js +1 -0
  32. package/dist/lib/renderer/color/p3.js +1 -0
  33. package/dist/lib/renderer/color/prophotoRgb.js +56 -0
  34. package/dist/lib/renderer/color/rec2020.js +1 -0
  35. package/dist/lib/renderer/color/relativecolor.js +52 -28
  36. package/dist/lib/renderer/color/rgb.js +1 -0
  37. package/dist/lib/renderer/color/srgb.js +1 -0
  38. package/dist/lib/renderer/color/utils/components.js +1 -0
  39. package/dist/lib/renderer/color/utils/constants.js +1 -0
  40. package/dist/lib/renderer/color/xyz.js +1 -0
  41. package/dist/lib/renderer/color/xyzd50.js +1 -0
  42. package/dist/lib/renderer/render.js +28 -6
  43. package/dist/lib/syntax/syntax.js +27 -4
  44. package/dist/lib/validation/at-rules/counter-style.js +78 -0
  45. package/dist/lib/validation/at-rules/document.js +114 -0
  46. package/dist/lib/validation/at-rules/font-feature-values.js +49 -0
  47. package/dist/lib/validation/at-rules/import.js +196 -0
  48. package/dist/lib/validation/at-rules/keyframes.js +70 -0
  49. package/dist/lib/validation/at-rules/layer.js +27 -0
  50. package/dist/lib/validation/at-rules/media.js +166 -0
  51. package/dist/lib/validation/at-rules/namespace.js +85 -0
  52. package/dist/lib/validation/at-rules/page-margin-box.js +56 -0
  53. package/dist/lib/validation/at-rules/page.js +88 -0
  54. package/dist/lib/validation/at-rules/supports.js +262 -0
  55. package/dist/lib/validation/atrule.js +172 -0
  56. package/dist/lib/validation/config.js +30 -2
  57. package/dist/lib/validation/config.json.js +1560 -50902
  58. package/dist/lib/validation/declaration.js +72 -0
  59. package/dist/lib/validation/parser/parse.js +1059 -7
  60. package/dist/lib/validation/parser/types.js +27 -12
  61. package/dist/lib/validation/selector.js +23 -444
  62. package/dist/lib/validation/syntax.js +1429 -0
  63. package/dist/lib/validation/syntaxes/complex-selector-list.js +41 -0
  64. package/dist/lib/validation/syntaxes/complex-selector.js +283 -0
  65. package/dist/lib/validation/syntaxes/family-name.js +91 -0
  66. package/dist/lib/validation/syntaxes/keyframe-block-list.js +27 -0
  67. package/dist/lib/validation/syntaxes/keyframe-selector.js +137 -0
  68. package/dist/lib/validation/syntaxes/layer-name.js +67 -0
  69. package/dist/lib/validation/syntaxes/relative-selector-list.js +27 -0
  70. package/dist/lib/validation/syntaxes/relative-selector.js +36 -0
  71. package/dist/lib/validation/syntaxes/selector-list.js +5 -0
  72. package/dist/lib/validation/syntaxes/selector.js +5 -0
  73. package/dist/lib/validation/syntaxes/url.js +75 -0
  74. package/dist/lib/validation/utils/list.js +24 -0
  75. package/dist/lib/validation/utils/whitespace.js +22 -0
  76. package/dist/node/index.js +13 -0
  77. package/dist/web/index.js +13 -0
  78. package/dist/web/load.js +1 -0
  79. package/package.json +17 -15
  80. package/dist/lib/ast/utils/minifyfeature.js +0 -9
  81. package/dist/lib/iterable/weakset.js +0 -58
  82. package/dist/lib/parser/utils/syntax.js +0 -450
@@ -1,3 +1,4 @@
1
+ const specialValues = ['inherit', 'initial', 'unset', 'revert', 'revert-layer'];
1
2
  var ValidationTokenEnum;
2
3
  (function (ValidationTokenEnum) {
3
4
  ValidationTokenEnum[ValidationTokenEnum["Root"] = 0] = "Root";
@@ -23,17 +24,31 @@ var ValidationTokenEnum;
23
24
  ValidationTokenEnum[ValidationTokenEnum["Whitespace"] = 20] = "Whitespace";
24
25
  ValidationTokenEnum[ValidationTokenEnum["Parenthesis"] = 21] = "Parenthesis";
25
26
  ValidationTokenEnum[ValidationTokenEnum["Bracket"] = 22] = "Bracket";
26
- ValidationTokenEnum[ValidationTokenEnum["AtLeastOnce"] = 23] = "AtLeastOnce";
27
- ValidationTokenEnum[ValidationTokenEnum["Separator"] = 24] = "Separator";
28
- ValidationTokenEnum[ValidationTokenEnum["Exclamation"] = 25] = "Exclamation";
29
- ValidationTokenEnum[ValidationTokenEnum["Ampersand"] = 26] = "Ampersand";
30
- ValidationTokenEnum[ValidationTokenEnum["PipeToken"] = 27] = "PipeToken";
31
- ValidationTokenEnum[ValidationTokenEnum["ColumnToken"] = 28] = "ColumnToken";
32
- ValidationTokenEnum[ValidationTokenEnum["AmpersandToken"] = 29] = "AmpersandToken";
33
- ValidationTokenEnum[ValidationTokenEnum["Parens"] = 30] = "Parens";
34
- ValidationTokenEnum[ValidationTokenEnum["PseudoClassToken"] = 31] = "PseudoClassToken";
35
- ValidationTokenEnum[ValidationTokenEnum["PseudoClassFunctionToken"] = 32] = "PseudoClassFunctionToken";
36
- ValidationTokenEnum[ValidationTokenEnum["StringToken"] = 33] = "StringToken";
27
+ ValidationTokenEnum[ValidationTokenEnum["Block"] = 23] = "Block";
28
+ ValidationTokenEnum[ValidationTokenEnum["AtLeastOnce"] = 24] = "AtLeastOnce";
29
+ ValidationTokenEnum[ValidationTokenEnum["Separator"] = 25] = "Separator";
30
+ ValidationTokenEnum[ValidationTokenEnum["Exclamation"] = 26] = "Exclamation";
31
+ ValidationTokenEnum[ValidationTokenEnum["Ampersand"] = 27] = "Ampersand";
32
+ ValidationTokenEnum[ValidationTokenEnum["PipeToken"] = 28] = "PipeToken";
33
+ ValidationTokenEnum[ValidationTokenEnum["ColumnToken"] = 29] = "ColumnToken";
34
+ ValidationTokenEnum[ValidationTokenEnum["AmpersandToken"] = 30] = "AmpersandToken";
35
+ ValidationTokenEnum[ValidationTokenEnum["Parens"] = 31] = "Parens";
36
+ ValidationTokenEnum[ValidationTokenEnum["PseudoClassToken"] = 32] = "PseudoClassToken";
37
+ ValidationTokenEnum[ValidationTokenEnum["PseudoClassFunctionToken"] = 33] = "PseudoClassFunctionToken";
38
+ ValidationTokenEnum[ValidationTokenEnum["StringToken"] = 34] = "StringToken";
39
+ ValidationTokenEnum[ValidationTokenEnum["AtRuleDefinition"] = 35] = "AtRuleDefinition";
40
+ ValidationTokenEnum[ValidationTokenEnum["DeclarationNameToken"] = 36] = "DeclarationNameToken";
41
+ ValidationTokenEnum[ValidationTokenEnum["DeclarationDefinitionToken"] = 37] = "DeclarationDefinitionToken";
42
+ ValidationTokenEnum[ValidationTokenEnum["SemiColon"] = 38] = "SemiColon";
43
+ ValidationTokenEnum[ValidationTokenEnum["Character"] = 39] = "Character";
37
44
  })(ValidationTokenEnum || (ValidationTokenEnum = {}));
45
+ var ValidationSyntaxGroupEnum;
46
+ (function (ValidationSyntaxGroupEnum) {
47
+ ValidationSyntaxGroupEnum["Declarations"] = "declarations";
48
+ ValidationSyntaxGroupEnum["Functions"] = "functions";
49
+ ValidationSyntaxGroupEnum["Syntaxes"] = "syntaxes";
50
+ ValidationSyntaxGroupEnum["Selectors"] = "selectors";
51
+ ValidationSyntaxGroupEnum["AtRules"] = "atRules";
52
+ })(ValidationSyntaxGroupEnum || (ValidationSyntaxGroupEnum = {}));
38
53
 
39
- export { ValidationTokenEnum };
54
+ export { ValidationSyntaxGroupEnum, ValidationTokenEnum, specialValues };
@@ -1,459 +1,38 @@
1
- import { EnumToken, ValidationLevel } from '../ast/types.js';
1
+ import { EnumToken } from '../ast/types.js';
2
2
  import '../ast/minify.js';
3
+ import '../ast/walk.js';
3
4
  import '../parser/parse.js';
4
5
  import '../renderer/color/utils/constants.js';
5
6
  import '../renderer/sourcemap/lib/encode.js';
6
7
  import '../parser/utils/config.js';
7
- import { getConfig } from './config.js';
8
+ import { validateRelativeSelectorList } from './syntaxes/relative-selector-list.js';
9
+ import './syntaxes/complex-selector.js';
10
+ import { validateKeyframeBlockList } from './syntaxes/keyframe-block-list.js';
11
+ import { validateSelectorList } from './syntaxes/selector-list.js';
8
12
 
9
- const expressions = [
10
- EnumToken.DelimTokenType, EnumToken.IncludeMatchTokenType, EnumToken.DashMatchTokenType,
11
- EnumToken.StartMatchTokenType, EnumToken.EndMatchTokenType, EnumToken.ContainMatchTokenType
12
- ];
13
- const selectorTokens = [
14
- EnumToken.IdenTokenType, EnumToken.ClassSelectorTokenType, EnumToken.AttrTokenType,
15
- EnumToken.PseudoClassTokenType, EnumToken.PseudoClassFuncTokenType, EnumToken.HashTokenType,
16
- EnumToken.UniversalSelectorTokenType
17
- ];
18
- const combinatorTokens = [
19
- EnumToken.ChildCombinatorTokenType, EnumToken.NextSiblingCombinatorTokenType,
20
- EnumToken.SubsequentSiblingCombinatorTokenType
21
- ];
22
13
  function validateSelector(selector, options, root) {
23
- if (selector.length == 0) {
24
- return {
25
- valid: ValidationLevel.Drop,
26
- node: null,
27
- error: 'The selector is empty.'
28
- };
14
+ if (root == null) {
15
+ return validateRelativeSelectorList(selector, root);
29
16
  }
30
- return doValidateSelector(selector, options, root);
31
- }
32
- function doValidateSelector(selector, options, root) {
33
- let result;
34
- if (combinatorTokens.includes(selector[0].typ)) {
35
- if (root == null || root.typ == EnumToken.StyleSheetNodeType) {
36
- return {
37
- valid: ValidationLevel.Drop,
38
- node: null,
39
- error: 'The selector cannot start with a combinator.'
40
- };
41
- }
42
- selector = selector.slice(1);
43
- }
44
- while ((selector?.length ?? 0) > 0) {
45
- result = validateSimpleSelector(selector, options, root);
46
- if (result.valid == ValidationLevel.Drop) {
47
- return {
48
- valid: ValidationLevel.Drop,
49
- node: result.nodes[0] ?? null,
50
- error: result.error
51
- };
52
- }
53
- if (result.nodes.length == 0) {
54
- return {
55
- valid: result.valid,
56
- node: result.nodes[0] ?? null,
57
- error: result.error
58
- };
59
- }
60
- selector = result.nodes;
61
- result = validateCombinator(selector);
62
- if (result.valid == ValidationLevel.Drop) {
63
- while (result.valid == ValidationLevel.Drop && selector.length > 0) {
64
- if (selector[0].typ == EnumToken.CommaTokenType) {
65
- selector = consumeWhitespace(selector.slice(1));
66
- if (selector.length == 0) {
67
- return {
68
- valid: ValidationLevel.Drop,
69
- node: selector[0],
70
- error: 'unexpected token'
71
- };
72
- }
73
- if (selector.length > 0 && combinatorTokens.includes(selector[0].typ)) {
74
- if (root == null || root.typ == EnumToken.StyleSheetNodeType) {
75
- return {
76
- valid: ValidationLevel.Drop,
77
- node: selector[0],
78
- error: 'Unexpected token'
79
- };
80
- }
81
- selector = selector.slice(1);
82
- }
83
- result = validateSimpleSelector(selector, options, root);
84
- if (result.valid == ValidationLevel.Drop) {
85
- return {
86
- valid: ValidationLevel.Drop,
87
- node: null,
88
- error: 'Invalid selector'
89
- };
90
- }
91
- if (result.nodes.length == 0) {
92
- return {
93
- valid: result.valid,
94
- node: null,
95
- error: result.error
96
- };
97
- }
98
- selector = result.nodes;
99
- result = validateCombinator(selector);
100
- if (result.nodes.length == 0) {
101
- return {
102
- valid: result.valid,
103
- node: null,
104
- error: result.error
105
- };
106
- }
107
- selector = result.nodes;
108
- }
109
- else {
110
- break;
111
- }
112
- }
113
- }
114
- else {
115
- selector = result.nodes;
116
- }
117
- }
118
- return {
119
- valid: ValidationLevel.Valid,
120
- node: null,
121
- error: ''
122
- };
123
- }
124
- function consumeWhitespace(selector) {
125
- let i = 0;
126
- while (i < selector.length &&
127
- (selector[i].typ == EnumToken.WhitespaceTokenType ||
128
- selector[i].typ == EnumToken.CommentTokenType)) {
129
- i++;
130
- }
131
- return selector.slice(i);
132
- }
133
- function validateSimpleSelector(selector, options, root) {
134
- let i = 0;
135
- if (i >= selector.length) {
136
- return {
137
- valid: ValidationLevel.Valid,
138
- nodes: selector.slice(i),
139
- error: 'empty selector'
140
- };
141
- }
142
- if (root?.typ == EnumToken.AtRuleNodeType && null != root.nam.match(/(-[a-zA-Z]+-)?keyframes/)) {
143
- while (i < selector.length) {
144
- if ([EnumToken.PercentageTokenType, EnumToken.CommentTokenType].includes(selector[i].typ)) {
145
- i++;
146
- continue;
147
- }
148
- if ((selector[i].typ == EnumToken.IdenTokenType && ['from', 'to'].includes(selector[i].val))) {
149
- i++;
150
- continue;
151
- }
152
- if (selector[i].typ == EnumToken.CommaTokenType) {
153
- break;
154
- }
155
- return {
156
- valid: ValidationLevel.Drop,
157
- nodes: selector.slice(i),
158
- error: 'invalid selector'
159
- };
160
- }
161
- return {
162
- valid: ValidationLevel.Valid,
163
- nodes: selector.slice(i),
164
- error: 'empty selector'
165
- };
166
- }
167
- while (i < selector.length && [EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(selector[i].typ)) {
168
- i++;
169
- }
170
- if (i >= selector.length) {
171
- return {
172
- valid: ValidationLevel.Valid,
173
- nodes: selector.slice(i),
174
- error: 'empty selector'
175
- };
176
- }
177
- if (selectorTokens.includes(selector[i].typ)) {
178
- let result;
179
- if (selector[i].typ == EnumToken.PseudoClassTokenType) {
180
- result = validatePseudoClass(selector[i], options);
181
- if (result.valid != ValidationLevel.Valid) {
182
- return result;
183
- }
184
- }
185
- if (selector[i].typ == EnumToken.PseudoClassFuncTokenType) {
186
- result = validatePseudoClassFunction(selector[i], options);
187
- if (result.valid != ValidationLevel.Valid) {
188
- return result;
189
- }
190
- }
191
- if (selector[i].typ == EnumToken.AttrTokenType) {
192
- result = validateAttributeSelector(selector[i], options);
193
- if (result.valid != ValidationLevel.Valid) {
194
- return result;
195
- }
196
- }
197
- return {
198
- valid: ValidationLevel.Valid,
199
- nodes: selector.slice(i + 1),
200
- error: ''
201
- };
202
- }
203
- if (selector[i].typ == EnumToken.LiteralTokenType && selector[i].val.startsWith('\\')) {
204
- return {
205
- valid: ValidationLevel.Valid,
206
- nodes: selector.slice(i + 1),
207
- error: ''
208
- };
209
- }
210
- if (selector[i].typ == EnumToken.NestingSelectorTokenType && root != null && root.typ != EnumToken.StyleSheetNodeType) {
211
- return {
212
- valid: ValidationLevel.Valid,
213
- nodes: selector.slice(i + 1),
214
- error: 'Compound selector not allowed here'
215
- };
216
- }
217
- return {
218
- valid: ValidationLevel.Drop,
219
- nodes: selector.slice(i + 1, 1),
220
- error: 'unexpected token'
221
- };
222
- }
223
- function validatePseudoClass(selector, options) {
224
- const name = selector.val.slice(selector.val[1] == ':' ? 2 : 1);
225
- if (name.match(/^-[a-zA-Z]+-/) || selector.val == ':before' || selector.val == ':after') {
226
- return {
227
- valid: ValidationLevel.Valid,
228
- nodes: [selector],
229
- error: ''
230
- };
231
- }
232
- const config = getConfig();
233
- const isValid = selector.val in config.selectors;
234
- return {
235
- valid: isValid || !options.validation ? ValidationLevel.Valid : ValidationLevel.Drop,
236
- nodes: [selector],
237
- error: isValid ? '' : 'invalid selector'
238
- };
239
- }
240
- function validatePseudoClassFunction(selector, options) {
241
- const name = selector.val.slice(1);
242
- if (name.match(/^-[a-zA-Z]+-/)) {
243
- const isValid = name == '-webkit-any' || name == '-moz-any';
244
- return {
245
- valid: isValid ? ValidationLevel.Valid : ValidationLevel.Drop,
246
- nodes: [selector],
247
- error: isValid ? '' : 'invalid pseudo class'
248
- };
249
- }
250
- const config = getConfig();
251
- if (selector.val in config.selectors) {
252
- if (!('chi' in config.selectors[selector.val].ast[0])) {
253
- return {
254
- valid: !options.validation ? ValidationLevel.Valid : ValidationLevel.Drop,
255
- nodes: [selector],
256
- error: ''
257
- };
258
- }
259
- }
260
- else if (!(selector.val + '()' in config.selectors)) {
261
- return {
262
- valid: !options.validation ? ValidationLevel.Valid : ValidationLevel.Drop,
263
- nodes: [selector],
264
- error: ''
265
- };
17
+ // @ts-ignore
18
+ if (root.typ == EnumToken.AtRuleNodeType && root.nam.match(/^(-[a-z]+-)?keyframes$/)) {
19
+ return validateKeyframeBlockList(selector, root);
266
20
  }
267
- // TODO: validate params
268
- return {
269
- valid: ValidationLevel.Valid,
270
- nodes: [selector],
271
- error: ''
272
- };
273
- }
274
- function validateAttributeSelector(selector, options) {
275
- let i = 0;
276
- let isMatchExpression = false;
277
- let expression;
278
- while (i < selector.chi.length) {
279
- if ([EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(selector.chi[i].typ)) {
280
- i++;
281
- continue;
282
- }
283
- if (EnumToken.IdenTokenType == selector.chi[i].typ ||
284
- EnumToken.MatchExpressionTokenType == selector.chi[i].typ ||
285
- EnumToken.NameSpaceAttributeTokenType == selector.chi[i].typ) {
286
- isMatchExpression = EnumToken.MatchExpressionTokenType == selector.chi[i].typ;
287
- if (isMatchExpression) {
288
- expression = selector.chi[i];
21
+ let isNested = root.typ == EnumToken.RuleNodeType ? 1 : 0;
22
+ let currentRoot = root.parent;
23
+ while (currentRoot != null && isNested == 0) {
24
+ if (currentRoot.typ == EnumToken.RuleNodeType) {
25
+ isNested++;
26
+ if (isNested > 0) {
27
+ // @ts-ignore
28
+ return validateRelativeSelectorList(selector, root, { nestedSelector: true });
289
29
  }
290
- if (EnumToken.NameSpaceAttributeTokenType == selector.chi[i].typ) {
291
- if (selector.chi[i].r.typ != EnumToken.IdenTokenType) {
292
- return {
293
- valid: ValidationLevel.Drop,
294
- nodes: [selector],
295
- error: 'identifier expected'
296
- };
297
- }
298
- if (selector.chi[i].l != null) {
299
- // @ts-ignore
300
- if (selector.chi[i].l.typ != EnumToken.IdenTokenType &&
301
- // @ts-ignore
302
- selector.chi[i].l.typ != EnumToken.LiteralTokenType) {
303
- return {
304
- valid: ValidationLevel.Drop,
305
- nodes: [selector],
306
- error: 'invalid namespace prefix'
307
- };
308
- }
309
- if (
310
- // @ts-ignore
311
- selector.chi[i].l.typ == EnumToken.LiteralTokenType &&
312
- selector.chi[i].l.val != '*') {
313
- return {
314
- valid: ValidationLevel.Drop,
315
- nodes: [selector],
316
- error: 'exoected universal selector or namespace prefix'
317
- };
318
- }
319
- }
320
- }
321
- i++;
322
- break;
323
- }
324
- return {
325
- valid: ValidationLevel.Drop,
326
- nodes: [selector],
327
- error: 'invalid selector'
328
- };
329
- }
330
- if (!isMatchExpression) {
331
- while (i < selector.chi.length) {
332
- if ([EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(selector.chi[i].typ)) {
333
- i++;
334
- continue;
335
- }
336
- break;
337
30
  }
338
- if (i < selector.chi.length) {
339
- if (!expressions.includes(selector.chi[i].typ)) {
340
- return {
341
- valid: ValidationLevel.Drop,
342
- nodes: [selector],
343
- error: 'invalid selector'
344
- };
345
- }
346
- i++;
347
- while (i < selector.chi.length) {
348
- if ([EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(selector.chi[i].typ)) {
349
- i++;
350
- continue;
351
- }
352
- break;
353
- }
354
- if (i >= selector.chi.length || ![EnumToken.IdenTokenType, EnumToken.StringTokenType].includes(selector.chi[i].typ)) {
355
- return {
356
- valid: ValidationLevel.Drop,
357
- nodes: [selector],
358
- error: 'expected identifier or string'
359
- };
360
- }
361
- i++;
362
- }
363
- }
364
- else {
365
- if (expression.l.typ != EnumToken.IdenTokenType ||
366
- ![EnumToken.IdenTokenType, EnumToken.StringTokenType].includes(expression.r.typ) ||
367
- !expressions.includes(expression.op)) {
368
- return {
369
- valid: ValidationLevel.Drop,
370
- nodes: [selector],
371
- error: 'expected identifier or string'
372
- };
373
- }
374
- }
375
- if (i < selector.chi.length) {
376
- let hasWhitespace = false;
377
- while (i < selector.chi.length) {
378
- if ([EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(selector.chi[i].typ)) {
379
- if (!hasWhitespace) {
380
- hasWhitespace = selector.chi[i].typ == EnumToken.WhitespaceTokenType;
381
- }
382
- i++;
383
- continue;
384
- }
385
- break;
386
- }
387
- // @ts-ignore
388
- if (!hasWhitespace || i >= selector.chi.length || selector.chi[i].typ != EnumToken.IdenTokenType || !['i', 's'].includes(selector.chi[i].val)) {
389
- const valid = !options.validation && selector.chi[i].typ == EnumToken.IdenTokenType && selector.chi[i].val.match(/^[a-z]$/);
390
- return {
391
- valid: valid ? ValidationLevel.Valid : ValidationLevel.Drop,
392
- nodes: [selector],
393
- error: valid ? '' : 'invalid attribute selector'
394
- };
395
- }
396
- i++;
397
- while (i < selector.chi.length) {
398
- if (![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(selector.chi[i].typ)) {
399
- return {
400
- valid: ValidationLevel.Drop,
401
- nodes: [selector],
402
- error: 'invalid attribute selector'
403
- };
404
- }
405
- i++;
406
- }
407
- }
408
- return {
409
- valid: ValidationLevel.Valid,
410
- nodes: [selector],
411
- error: ''
412
- };
413
- }
414
- function validateCombinator(selector, options, root) {
415
- selector = consumeWhitespace(selector);
416
- if (selector.length == 0) {
417
- return {
418
- valid: ValidationLevel.Drop,
419
- nodes: selector,
420
- error: 'expecting combinator'
421
- };
422
- }
423
- const combinatorTypes = [
424
- EnumToken.ChildCombinatorTokenType,
425
- EnumToken.DescendantCombinatorTokenType,
426
- EnumToken.NextSiblingCombinatorTokenType,
427
- EnumToken.SubsequentSiblingCombinatorTokenType,
428
- EnumToken.ColumnCombinatorTokenType
429
- ];
430
- if (!combinatorTypes.includes(selector[0].typ)) {
431
- return {
432
- valid: ValidationLevel.Drop,
433
- nodes: selector,
434
- error: 'Expecting combinator'
435
- };
436
- }
437
- selector = consumeWhitespace(selector.slice(1));
438
- if (selector.length == 0) {
439
- return {
440
- valid: ValidationLevel.Drop,
441
- nodes: selector,
442
- error: 'Unexpected combinator'
443
- };
444
- }
445
- if (combinatorTypes.includes(selector[0].typ)) {
446
- return {
447
- valid: ValidationLevel.Drop,
448
- nodes: selector,
449
- error: 'Unexpected combinator'
450
- };
31
+ currentRoot = currentRoot.parent;
451
32
  }
452
- return {
453
- valid: ValidationLevel.Valid,
454
- nodes: selector,
455
- error: ''
456
- };
33
+ const nestedSelector = isNested > 0;
34
+ // @ts-ignore
35
+ return nestedSelector ? validateRelativeSelectorList(selector, root, { nestedSelector }) : validateSelectorList(selector, root, { nestedSelector });
457
36
  }
458
37
 
459
38
  export { validateSelector };