@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,12 +1,7 @@
1
1
  import { ValidationTokenEnum } from './types.js';
2
- import '../../ast/types.js';
3
- import '../../ast/minify.js';
4
- import '../../parser/parse.js';
5
- import '../../parser/utils/config.js';
6
- import '../../renderer/color/utils/constants.js';
7
- import '../../renderer/sourcemap/lib/encode.js';
2
+ import { isIdent, isPseudo } from '../../syntax/syntax.js';
8
3
 
9
- [
4
+ const skipped = [
10
5
  ValidationTokenEnum.Star,
11
6
  ValidationTokenEnum.HashMark,
12
7
  ValidationTokenEnum.AtLeastOnce,
@@ -14,3 +9,1060 @@ import '../../renderer/sourcemap/lib/encode.js';
14
9
  ValidationTokenEnum.QuestionMark,
15
10
  ValidationTokenEnum.OpenCurlyBrace
16
11
  ];
12
+ const objectProperties = {
13
+ enumerable: false,
14
+ writable: true,
15
+ configurable: true
16
+ };
17
+ // syntaxes: keyword | <'property'> | <function>
18
+ // "none | [ [<dashed-ident> || <try-tactic>] | inset-area( <'inset-area'> ) ]#"
19
+ // ""
20
+ // : "<outline-radius>{1,4} [ / <outline-radius>{1,4} ]?
21
+ // ""
22
+ // false | true
23
+ // [ <mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> || [ <box> | border | padding | content | text ] || [ <box> | border | padding | content ] ]#
24
+ // false | true | green | pipe
25
+ // keyword | <'property'> | <function>
26
+ // [<dashed-ident> || <try-tactic>]
27
+ // [ <mask-reference> || <position> [ / <bg-size> ]? || <repeat-style> || [ <box> | border | padding | content | text ] || [ <box> | border | padding | content ] ]#
28
+ // none | [ [<dashed-ident> || <try-tactic>] | inset-area( <'inset-area'> ) ]
29
+ function* tokenize(syntax, position = { ind: 0, lin: 1, col: 0 }, currentPosition = {
30
+ ind: -1,
31
+ lin: 1,
32
+ col: 0
33
+ }) {
34
+ let i = -1;
35
+ let buffer = '';
36
+ while (++i < syntax.length) {
37
+ let chr = syntax.charAt(i);
38
+ move(currentPosition, chr);
39
+ switch (chr) {
40
+ case '\\':
41
+ if (buffer.length > 0) {
42
+ yield getTokenType(buffer, position, currentPosition);
43
+ buffer = '';
44
+ }
45
+ buffer += chr;
46
+ chr = syntax.charAt(++i);
47
+ buffer += chr;
48
+ move(currentPosition, chr);
49
+ break;
50
+ case ';':
51
+ if (buffer.length > 0) {
52
+ yield getTokenType(buffer, position, currentPosition);
53
+ buffer = '';
54
+ }
55
+ yield getTokenType(chr, position, currentPosition);
56
+ buffer = '';
57
+ break;
58
+ case ':':
59
+ if (isIdent(buffer)) {
60
+ yield Object.defineProperty({
61
+ typ: ValidationTokenEnum.DeclarationNameToken,
62
+ val: buffer
63
+ }, 'pos', { ...objectProperties, value: { ...position } });
64
+ buffer = '';
65
+ move(currentPosition, chr);
66
+ break;
67
+ }
68
+ buffer += chr;
69
+ break;
70
+ case '"':
71
+ case "'":
72
+ if (buffer.length > 0) {
73
+ yield getTokenType(buffer, position, currentPosition);
74
+ buffer = '';
75
+ }
76
+ buffer += chr;
77
+ while (i + 1 < syntax.length) {
78
+ chr = syntax.charAt(++i);
79
+ buffer += chr;
80
+ move(currentPosition, chr);
81
+ if (chr == '\\') {
82
+ chr = syntax.charAt(++i);
83
+ buffer += chr;
84
+ move(currentPosition, chr);
85
+ continue;
86
+ }
87
+ if (chr == buffer.charAt(0)) {
88
+ break;
89
+ }
90
+ }
91
+ // check for type "<property>" or "<'property'>"
92
+ if (buffer.at(1) == '<' && buffer.at(-2) == '>') {
93
+ yield Object.defineProperty({
94
+ typ: ValidationTokenEnum.Character,
95
+ val: chr
96
+ }, 'pos', { ...objectProperties, value: { ...position } });
97
+ position = { ...currentPosition };
98
+ move(currentPosition, chr);
99
+ buffer = buffer.slice(1, -1);
100
+ yield* tokenize(buffer, position, currentPosition);
101
+ yield Object.defineProperty({
102
+ typ: ValidationTokenEnum.Character,
103
+ val: chr
104
+ }, 'pos', { ...objectProperties, value: { ...position } });
105
+ position = { ...currentPosition };
106
+ move(currentPosition, chr);
107
+ buffer = '';
108
+ break;
109
+ }
110
+ yield getTokenType(buffer, position, currentPosition);
111
+ buffer = '';
112
+ break;
113
+ case '<':
114
+ buffer += chr;
115
+ while (i + 1 < syntax.length) {
116
+ chr = syntax.charAt(++i);
117
+ buffer += chr;
118
+ move(currentPosition, chr);
119
+ if (chr == '>') {
120
+ break;
121
+ }
122
+ }
123
+ yield getTokenType(buffer, position, currentPosition);
124
+ buffer = '';
125
+ break;
126
+ case ' ':
127
+ case '\t':
128
+ case '\n':
129
+ case '\r':
130
+ case '\f':
131
+ case '|':
132
+ case '#':
133
+ case '+':
134
+ case ',':
135
+ case '[':
136
+ case ']':
137
+ case '(':
138
+ case ')':
139
+ case '*':
140
+ case '{':
141
+ case '}':
142
+ case '?':
143
+ case '!':
144
+ case '&':
145
+ if (buffer.length > 0) {
146
+ yield getTokenType(buffer, position, currentPosition);
147
+ }
148
+ if (chr == '|' || chr == '&') {
149
+ if (syntax.charAt(i + 1) == chr) {
150
+ move(currentPosition, chr);
151
+ yield getTokenType(chr + chr, position, currentPosition);
152
+ i++;
153
+ buffer = '';
154
+ continue;
155
+ }
156
+ }
157
+ Object.assign(position, currentPosition);
158
+ yield getTokenType(chr, position, currentPosition);
159
+ buffer = '';
160
+ break;
161
+ default:
162
+ buffer += chr;
163
+ break;
164
+ }
165
+ }
166
+ if (buffer.length > 0) {
167
+ yield getTokenType(buffer, position, currentPosition);
168
+ }
169
+ }
170
+ function parseSyntax(syntax) {
171
+ const root = Object.defineProperty({
172
+ typ: ValidationTokenEnum.Root,
173
+ chi: []
174
+ }, 'pos', { ...objectProperties, value: { ind: 0, lin: 1, col: 0 } });
175
+ // return minify(doParseSyntax(syntaxes, tokenize(syntaxes), root)) as ValidationRootToken;
176
+ return minify(doParseSyntax(syntax, tokenize(syntax), root));
177
+ }
178
+ function matchParens(syntax, iterator) {
179
+ let item;
180
+ let func = null;
181
+ let items = [];
182
+ let match = 0;
183
+ while ((item = iterator.next()) && !item.done) {
184
+ switch (item.value.typ) {
185
+ case ValidationTokenEnum.OpenParenthesis:
186
+ if (match > 0) {
187
+ func.chi.push(item.value);
188
+ }
189
+ else if (match == 0) {
190
+ func = items.at(-1);
191
+ if (func == null) {
192
+ func = Object.defineProperty({
193
+ typ: ValidationTokenEnum.Parens,
194
+ val: '',
195
+ chi: []
196
+ }, 'pos', { ...objectProperties, value: item.value.pos });
197
+ items.push(func);
198
+ }
199
+ else {
200
+ // @ts-ignore
201
+ func.typ = func.typ == ValidationTokenEnum.PseudoClassToken ? ValidationTokenEnum.PseudoClassFunctionToken : ValidationTokenEnum.Function;
202
+ func.chi = [];
203
+ }
204
+ }
205
+ match++;
206
+ break;
207
+ case ValidationTokenEnum.CloseParenthesis:
208
+ match--;
209
+ if (match > 0) {
210
+ func.chi.push(item.value);
211
+ }
212
+ break;
213
+ default:
214
+ if (match > 0) {
215
+ func.chi.push(item.value);
216
+ }
217
+ else {
218
+ items.push(item.value);
219
+ }
220
+ break;
221
+ }
222
+ }
223
+ for (const item of items) {
224
+ if ('chi' in item) {
225
+ // @ts-ignore
226
+ item.chi = matchParens(syntax, item.chi[Symbol.iterator]());
227
+ }
228
+ }
229
+ return items;
230
+ }
231
+ function matchBrackets(syntax, iterator) {
232
+ let item;
233
+ let bracket = null;
234
+ let items = [];
235
+ let match = 0;
236
+ while ((item = iterator.next()) && !item.done) {
237
+ switch (item.value.typ) {
238
+ case ValidationTokenEnum.OpenBracket:
239
+ if (match > 0) {
240
+ bracket.chi.push(item.value);
241
+ }
242
+ else if (match == 0) {
243
+ bracket = Object.defineProperty({
244
+ typ: ValidationTokenEnum.Bracket,
245
+ chi: []
246
+ }, 'pos', { ...objectProperties, value: item.value.pos });
247
+ items.push(bracket);
248
+ }
249
+ match++;
250
+ break;
251
+ case ValidationTokenEnum.CloseBracket:
252
+ match--;
253
+ if (match > 0) {
254
+ bracket.chi.push(item.value);
255
+ }
256
+ break;
257
+ default:
258
+ if (match > 0) {
259
+ bracket.chi.push(item.value);
260
+ }
261
+ else {
262
+ items.push(item.value);
263
+ }
264
+ break;
265
+ }
266
+ }
267
+ for (const item of items) {
268
+ if ('chi' in item) {
269
+ // @ts-ignore
270
+ item.chi = matchBrackets(syntax, item.chi[Symbol.iterator]());
271
+ }
272
+ }
273
+ return items;
274
+ }
275
+ function matchCurlBraces(syntax, iterator) {
276
+ let item;
277
+ let block = null;
278
+ let items = [];
279
+ let match = 0;
280
+ while ((item = iterator.next()) && !item.done) {
281
+ switch (item.value.typ) {
282
+ case ValidationTokenEnum.OpenCurlyBrace:
283
+ if (match > 0) {
284
+ block.chi.push(item.value);
285
+ }
286
+ else if (match == 0) {
287
+ block = Object.defineProperty({
288
+ typ: ValidationTokenEnum.Block,
289
+ chi: []
290
+ }, 'pos', { ...objectProperties, value: item.value.pos });
291
+ items.push(block);
292
+ }
293
+ match++;
294
+ break;
295
+ case ValidationTokenEnum.CloseCurlyBrace:
296
+ match--;
297
+ if (match > 0) {
298
+ block.chi.push(item.value);
299
+ }
300
+ break;
301
+ default:
302
+ if (match > 0) {
303
+ block.chi.push(item.value);
304
+ }
305
+ else {
306
+ items.push(item.value);
307
+ }
308
+ break;
309
+ }
310
+ }
311
+ let it;
312
+ let i = 0;
313
+ for (; i < items.length; i++) {
314
+ it = items[i];
315
+ if (i > 0 && it.typ == ValidationTokenEnum.Block && it.chi[0]?.typ == ValidationTokenEnum.Number) {
316
+ items[i - 1].occurence = {
317
+ min: +it.chi[0].val,
318
+ max: +(it.chi[2] ?? it.chi[0]).val
319
+ };
320
+ items.splice(i--, 1);
321
+ continue;
322
+ }
323
+ if ('chi' in it) {
324
+ // @ts-ignore
325
+ it.chi = matchBrackets(syntax, it.chi[Symbol.iterator]());
326
+ }
327
+ }
328
+ return items;
329
+ }
330
+ function matchAtRule(syntax, iterator) {
331
+ const children = [];
332
+ let item;
333
+ let token = null;
334
+ while ((item = iterator.next()) && !item.done) {
335
+ if (item.value.typ == ValidationTokenEnum.AtRule || item.value.typ == ValidationTokenEnum.AtRuleDefinition) {
336
+ token = Object.defineProperty({
337
+ ...item.value,
338
+ typ: ValidationTokenEnum.AtRuleDefinition
339
+ }, 'pos', { ...objectProperties, value: item.value.pos });
340
+ children.push(token);
341
+ item = iterator.next();
342
+ if (item.done) {
343
+ // @ts-ignore
344
+ token.typ = ValidationTokenEnum.AtRule;
345
+ break;
346
+ }
347
+ if (item.value.typ != ValidationTokenEnum.Whitespace) {
348
+ console.error('unexpected token', item.value);
349
+ }
350
+ item = iterator.next();
351
+ if (item.done) {
352
+ break;
353
+ }
354
+ if (item.value.typ == ValidationTokenEnum.Pipe) {
355
+ // @ts-ignore
356
+ token.typ = ValidationTokenEnum.AtRule;
357
+ children.push(item.value);
358
+ continue;
359
+ }
360
+ if (item.value.typ != ValidationTokenEnum.OpenCurlyBrace) {
361
+ if (!('prelude' in token)) {
362
+ token.prelude = [];
363
+ }
364
+ token.prelude.push(item.value);
365
+ }
366
+ let braces = 0;
367
+ let previousItem = item.value;
368
+ while ((item = iterator.next()) && !item.done) {
369
+ if (item.value.typ == ValidationTokenEnum.DeclarationNameToken) {
370
+ iterator.next();
371
+ const t = Object.defineProperty({
372
+ typ: ValidationTokenEnum.DeclarationDefinitionToken,
373
+ nam: item.value.val,
374
+ val: iterator.next().value
375
+ }, 'pos', {
376
+ ...objectProperties,
377
+ value: item.value.pos
378
+ });
379
+ if (braces > 0) {
380
+ token.chi.push(t);
381
+ }
382
+ else {
383
+ token.prelude.push(t);
384
+ }
385
+ previousItem = t;
386
+ continue;
387
+ }
388
+ if (item.value.typ == ValidationTokenEnum.OpenCurlyBrace) {
389
+ previousItem = item.value;
390
+ continue;
391
+ }
392
+ if (item.value.typ == ValidationTokenEnum.Whitespace && previousItem?.typ == ValidationTokenEnum.OpenCurlyBrace) {
393
+ braces++;
394
+ if (braces == 1) {
395
+ previousItem = item.value;
396
+ continue;
397
+ }
398
+ }
399
+ if (previousItem?.typ == ValidationTokenEnum.Whitespace && item.value.typ == ValidationTokenEnum.CloseCurlyBrace) {
400
+ braces--;
401
+ if (braces == 0) {
402
+ break;
403
+ }
404
+ }
405
+ if (braces == 0) {
406
+ if (!('prelude' in token)) {
407
+ token.prelude = [];
408
+ }
409
+ token.prelude.push(item.value);
410
+ }
411
+ else {
412
+ if (!('chi' in token)) {
413
+ token.chi = [];
414
+ }
415
+ token.chi.push(item.value);
416
+ }
417
+ previousItem = item.value;
418
+ }
419
+ if ('prelude' in token) {
420
+ if (token?.prelude?.length == 1 && token.prelude[0].typ == ValidationTokenEnum.Whitespace) {
421
+ delete token.prelude;
422
+ }
423
+ else {
424
+ const t = { typ: ValidationTokenEnum.Root, chi: token.prelude };
425
+ doParseSyntax(syntax, t.chi[Symbol.iterator](), t);
426
+ token.prelude = t.chi;
427
+ minify(token.prelude);
428
+ }
429
+ }
430
+ // @ts-ignore
431
+ if (token?.chi?.length > 0) {
432
+ minify(doParseSyntax(syntax, token.chi[Symbol.iterator](), token));
433
+ }
434
+ }
435
+ else {
436
+ children.push(item.value);
437
+ }
438
+ }
439
+ return children;
440
+ }
441
+ function matchToken(syntax, iterator, validationToken) {
442
+ let children = [];
443
+ let item;
444
+ let token = null;
445
+ let i;
446
+ if (validationToken == ValidationTokenEnum.Ampersand) {
447
+ // @ts-ignore
448
+ children = [...iterator];
449
+ let offsetL;
450
+ let offsetR;
451
+ for (i = 0; i < children.length; i++) {
452
+ if (children[i].typ == ValidationTokenEnum.Ampersand) {
453
+ offsetR = i + 1;
454
+ offsetL = i - 1;
455
+ while (offsetR < children.length - 1 && children[offsetR].typ == ValidationTokenEnum.Whitespace) {
456
+ offsetR++;
457
+ }
458
+ while (offsetR + 1 < children.length && skipped.includes(children[offsetR + 1].typ)) {
459
+ offsetR++;
460
+ }
461
+ while (offsetL > 0 && (children[offsetL].typ == ValidationTokenEnum.Whitespace || skipped.includes(children[offsetL].typ))) {
462
+ offsetL--;
463
+ }
464
+ token = Object.defineProperty({
465
+ typ: ValidationTokenEnum.AmpersandToken,
466
+ l: children.slice(offsetL, i),
467
+ r: children.slice(i + 1, offsetR + 1)
468
+ }, 'pos', { ...objectProperties, value: children[i].pos });
469
+ i = offsetL;
470
+ children.splice(offsetL, offsetR - offsetL + 1, token);
471
+ }
472
+ else if ('chi' in children[i]) {
473
+ // @ts-ignore
474
+ children[i].chi = matchToken(syntax, children[i].chi[Symbol.iterator](), validationToken);
475
+ }
476
+ else if ('l' in children[i]) {
477
+ // @ts-ignore
478
+ children[i].l = matchToken(syntax, children[i].l[Symbol.iterator](), validationToken);
479
+ // @ts-ignore
480
+ children[i].r = matchToken(syntax, children[i].r[Symbol.iterator](), validationToken);
481
+ }
482
+ }
483
+ return children;
484
+ }
485
+ while ((item = iterator.next()) && !item.done) {
486
+ if (item.value.typ == validationToken) {
487
+ if (item.value.typ == ValidationTokenEnum.Pipe) {
488
+ token = Object.defineProperty({
489
+ typ: ValidationTokenEnum.PipeToken,
490
+ chi: [matchToken(syntax, children.slice()[Symbol.iterator](), validationToken)], //.concat(matchToken(syntaxes, children.slice()[Symbol.iterator]() as Iterator<ValidationTokenIteratorValue>, validationToken), matchToken(syntaxes, iterator, validationToken)),
491
+ // @ts-ignore
492
+ // l: matchToken(syntaxes, children.slice()[Symbol.iterator](), validationToken),
493
+ // r: matchToken(syntaxes, iterator, validationToken)
494
+ }, 'pos', {
495
+ ...objectProperties,
496
+ value: item.value.pos
497
+ });
498
+ children.length = 0;
499
+ while ((item = iterator.next()) && !item.done) {
500
+ if (item.value.typ == ValidationTokenEnum.Pipe) {
501
+ token.chi.push(matchToken(syntax, children.slice()[Symbol.iterator](), validationToken));
502
+ children.length = 0;
503
+ }
504
+ else {
505
+ children.push(item.value);
506
+ }
507
+ }
508
+ if (children.length > 0) {
509
+ token.chi.push(matchToken(syntax, children.slice()[Symbol.iterator](), validationToken));
510
+ }
511
+ token.chi.sort((a, b) => {
512
+ if (a.some((t) => t.isList)) {
513
+ return -1;
514
+ }
515
+ if (b.some((t) => t.isList)) {
516
+ return 1;
517
+ }
518
+ if (a.some((t) => t.occurence != null)) {
519
+ return -1;
520
+ }
521
+ if (b.some((t) => t.occurence != null)) {
522
+ return -1;
523
+ }
524
+ if (a.some((t) => t.isRepeatableGroup)) {
525
+ return -1;
526
+ }
527
+ if (b.some((t) => t.isRepeatableGroup)) {
528
+ return 1;
529
+ }
530
+ if (a.some((t) => t.isRepeatable)) {
531
+ return -1;
532
+ }
533
+ if (b.some((t) => t.isRepeatable)) {
534
+ return 1;
535
+ }
536
+ if (a.some((t) => t.isOptional)) {
537
+ return 1;
538
+ }
539
+ if (b.some((t) => t.isOptional)) {
540
+ return -1;
541
+ }
542
+ return 0;
543
+ });
544
+ children = [token];
545
+ }
546
+ else {
547
+ token = Object.defineProperty({
548
+ typ: ValidationTokenEnum.ColumnToken,
549
+ l: matchToken(syntax, children.slice()[Symbol.iterator](), validationToken),
550
+ r: matchToken(syntax, iterator, validationToken)
551
+ }, 'pos', {
552
+ ...objectProperties,
553
+ value: item.value.pos
554
+ });
555
+ }
556
+ children.length = 0;
557
+ children.push(token);
558
+ while ((item = iterator.next()) && !item.done) {
559
+ children.push(item.value);
560
+ if ('chi' in item.value) {
561
+ // @ts-ignore
562
+ item.value.chi = matchToken(syntax, item.value.chi[Symbol.iterator](), validationToken);
563
+ }
564
+ else if ('l' in item.value) {
565
+ // @ts-ignore
566
+ item.value.l = matchToken(syntax, item.value.l[Symbol.iterator](), validationToken);
567
+ // @ts-ignore
568
+ item.value.r = matchToken(syntax, item.value.r[Symbol.iterator](), validationToken);
569
+ }
570
+ }
571
+ // @ts-ignore
572
+ return children;
573
+ }
574
+ else {
575
+ children.push(item.value);
576
+ if ('chi' in item.value) {
577
+ // @ts-ignore
578
+ item.value.chi = matchToken(syntax, item.value.chi[Symbol.iterator](), validationToken);
579
+ }
580
+ else if ('l' in item.value) {
581
+ // @ts-ignore
582
+ item.value.l = matchToken(syntax, item.value.l[Symbol.iterator](), validationToken);
583
+ // @ts-ignore
584
+ item.value.r = matchToken(syntax, item.value.r[Symbol.iterator](), validationToken);
585
+ }
586
+ }
587
+ }
588
+ return children;
589
+ }
590
+ function parseTokens(syntax, iterator) {
591
+ const items = [];
592
+ let item;
593
+ let i;
594
+ while ((item = iterator.next()) && !item.done) {
595
+ if (Array.isArray(item.value)) {
596
+ // @ts-ignore
597
+ item.value = parseTokens(syntax, item.value[Symbol.iterator]());
598
+ }
599
+ switch (item.value.typ) {
600
+ case ValidationTokenEnum.Star:
601
+ case ValidationTokenEnum.HashMark:
602
+ case ValidationTokenEnum.AtLeastOnce:
603
+ case ValidationTokenEnum.Exclamation:
604
+ case ValidationTokenEnum.QuestionMark:
605
+ case ValidationTokenEnum.OpenCurlyBrace:
606
+ i = items.length;
607
+ while (i--) {
608
+ if (items[i].typ != ValidationTokenEnum.Whitespace) {
609
+ break;
610
+ }
611
+ }
612
+ if (item.value.typ == ValidationTokenEnum.Exclamation) {
613
+ items[i].isRepeatableGroup = true;
614
+ }
615
+ else if (item.value.typ == ValidationTokenEnum.QuestionMark) {
616
+ items[i].isOptional = true;
617
+ }
618
+ else if (item.value.typ == ValidationTokenEnum.Star) {
619
+ items[i].isRepeatable = true;
620
+ }
621
+ else if (item.value.typ == ValidationTokenEnum.AtLeastOnce) {
622
+ items[i].atLeastOnce = true;
623
+ }
624
+ else if (item.value.typ == ValidationTokenEnum.HashMark) {
625
+ items[i].isList = true;
626
+ }
627
+ else if (item.value.typ == ValidationTokenEnum.OpenCurlyBrace) {
628
+ items[i].occurence = {
629
+ min: 0,
630
+ max: 0
631
+ };
632
+ while ((item = iterator.next()) && !item.done) {
633
+ if (item.value.typ == ValidationTokenEnum.Number) {
634
+ // @ts-ignore
635
+ if (items[i].occurence.min == 0) {
636
+ // @ts-ignore
637
+ items[i].occurence.min = +item.value.val;
638
+ }
639
+ else {
640
+ // @ts-ignore
641
+ items[i].occurence.max = +item.value.val;
642
+ }
643
+ }
644
+ if (item.value.typ == ValidationTokenEnum.CloseCurlyBrace) {
645
+ break;
646
+ }
647
+ }
648
+ }
649
+ break;
650
+ case ValidationTokenEnum.Pipe:
651
+ item.value.chi = item.value.chi.map((t) => parseTokens(syntax, t[Symbol.iterator]()));
652
+ items.push(item.value);
653
+ break;
654
+ default:
655
+ items.push(item.value);
656
+ break;
657
+ }
658
+ }
659
+ for (i = 0; i < items.length; i++) {
660
+ if ('chi' in items[i]) {
661
+ // @ts-ignore
662
+ items[i].chi = parseTokens(syntax, items[i].chi[Symbol.iterator]());
663
+ }
664
+ else if ('l' in items[i]) {
665
+ // @ts-ignore
666
+ items[i].l = parseTokens(syntax, items[i].l[Symbol.iterator]());
667
+ // @ts-ignore
668
+ items[i].r = parseTokens(syntax, items[i].r[Symbol.iterator]());
669
+ }
670
+ if (items[i].isOptional || items[i].isRepeatable) {
671
+ if (i <= 1) {
672
+ let k = i;
673
+ while (++k < items.length) {
674
+ if (items[k].typ == ValidationTokenEnum.Whitespace) {
675
+ continue;
676
+ }
677
+ if (items[k].typ == ValidationTokenEnum.Comma) {
678
+ items.splice(i, k - i + 1, Object.defineProperty({
679
+ typ: ValidationTokenEnum.Bracket,
680
+ chi: items.slice(i, k + 1)
681
+ }, 'pos', { ...objectProperties, value: items[i].pos }));
682
+ }
683
+ break;
684
+ }
685
+ }
686
+ else {
687
+ let k = i;
688
+ while (--k > 0) {
689
+ if (items[k].typ == ValidationTokenEnum.Whitespace) {
690
+ continue;
691
+ }
692
+ if (items[k].typ == ValidationTokenEnum.Comma) {
693
+ items.splice(k, i - k + 1, Object.defineProperty({
694
+ typ: ValidationTokenEnum.Bracket,
695
+ chi: items.slice(k, i + 1)
696
+ }, 'pos', { ...objectProperties, value: items[k].pos }));
697
+ i = k - 1;
698
+ }
699
+ break;
700
+ }
701
+ }
702
+ }
703
+ }
704
+ return items;
705
+ }
706
+ function doParseSyntax(syntax, iterator, context) {
707
+ context.chi = matchParens(syntax, iterator);
708
+ // @ts-ignore
709
+ context.chi = matchAtRule(syntax, context.chi[Symbol.iterator]());
710
+ // @ts-ignore
711
+ context.chi = matchBrackets(syntax, context.chi[Symbol.iterator]());
712
+ // @ts-ignore
713
+ context.chi = matchCurlBraces(syntax, context.chi[Symbol.iterator]());
714
+ // @ts-ignore
715
+ context.chi = matchToken(syntax, context.chi[Symbol.iterator](), ValidationTokenEnum.Column);
716
+ // @ts-ignore
717
+ context.chi = matchToken(syntax, context.chi[Symbol.iterator](), ValidationTokenEnum.Pipe);
718
+ // @ts-ignore
719
+ context.chi = parseTokens(syntax, context.chi[Symbol.iterator]());
720
+ // @ts-ignore
721
+ context.chi = matchToken(syntax, context.chi[Symbol.iterator](), ValidationTokenEnum.Ampersand);
722
+ return context;
723
+ }
724
+ function getTokenType(token, position, currentPosition) {
725
+ const pos = { ...position };
726
+ Object.assign(position, currentPosition);
727
+ if (token.charAt(0) == '"' || token.charAt(0) == "'") {
728
+ return Object.defineProperty({
729
+ typ: ValidationTokenEnum.StringToken,
730
+ val: token
731
+ }, 'pos', { ...objectProperties, value: pos });
732
+ }
733
+ if (token == ';') {
734
+ return Object.defineProperty({
735
+ typ: ValidationTokenEnum.SemiColon
736
+ }, 'pos', { ...objectProperties, value: pos });
737
+ }
738
+ if (token.match(/^\s+$/)) {
739
+ return Object.defineProperty({
740
+ typ: ValidationTokenEnum.Whitespace,
741
+ }, 'pos', { ...objectProperties, value: pos });
742
+ }
743
+ if (token.match(/^\d+$/)) {
744
+ return Object.defineProperty({
745
+ typ: ValidationTokenEnum.Number,
746
+ val: Number(token)
747
+ }, 'pos', { ...objectProperties, value: pos });
748
+ }
749
+ if (isPseudo(token)) {
750
+ return Object.defineProperty({
751
+ typ: ValidationTokenEnum.PseudoClassToken,
752
+ val: token
753
+ }, 'pos', { ...objectProperties, value: pos });
754
+ }
755
+ if (token == '!') {
756
+ return Object.defineProperty({
757
+ typ: ValidationTokenEnum.Exclamation
758
+ }, 'pos', { ...objectProperties, value: pos });
759
+ }
760
+ if (token == '#') {
761
+ return Object.defineProperty({
762
+ typ: ValidationTokenEnum.HashMark
763
+ }, 'pos', { ...objectProperties, value: pos });
764
+ }
765
+ if (token == '/') {
766
+ return Object.defineProperty({
767
+ typ: ValidationTokenEnum.Separator
768
+ }, 'pos', { ...objectProperties, value: pos });
769
+ }
770
+ if (token == '+') {
771
+ return Object.defineProperty({
772
+ typ: ValidationTokenEnum.AtLeastOnce
773
+ }, 'pos', { ...objectProperties, value: pos });
774
+ }
775
+ if (token == '|') {
776
+ return Object.defineProperty({
777
+ typ: ValidationTokenEnum.Pipe
778
+ }, 'pos', { ...objectProperties, value: pos });
779
+ }
780
+ if (token == '&&') {
781
+ return Object.defineProperty({
782
+ typ: ValidationTokenEnum.Ampersand
783
+ }, 'pos', { ...objectProperties, value: pos });
784
+ }
785
+ if (token == '||') {
786
+ return Object.defineProperty({
787
+ typ: ValidationTokenEnum.Column
788
+ }, 'pos', { ...objectProperties, value: pos });
789
+ }
790
+ if (token == ',') {
791
+ return Object.defineProperty({
792
+ typ: ValidationTokenEnum.Comma
793
+ }, 'pos', { ...objectProperties, value: pos });
794
+ }
795
+ if (token == '[') {
796
+ return Object.defineProperty({
797
+ typ: ValidationTokenEnum.OpenBracket
798
+ }, 'pos', { ...objectProperties, value: pos });
799
+ }
800
+ if (token == ']') {
801
+ return Object.defineProperty({
802
+ typ: ValidationTokenEnum.CloseBracket
803
+ }, 'pos', { ...objectProperties, value: pos });
804
+ }
805
+ if (token == '(') {
806
+ return Object.defineProperty({
807
+ typ: ValidationTokenEnum.OpenParenthesis
808
+ }, 'pos', { ...objectProperties, value: pos });
809
+ }
810
+ if (token == ')') {
811
+ return Object.defineProperty({
812
+ typ: ValidationTokenEnum.CloseParenthesis
813
+ }, 'pos', { ...objectProperties, value: pos });
814
+ }
815
+ if (token == '{') {
816
+ return Object.defineProperty({
817
+ typ: ValidationTokenEnum.OpenCurlyBrace
818
+ }, 'pos', { ...objectProperties, value: pos });
819
+ }
820
+ if (token == '}') {
821
+ return Object.defineProperty({
822
+ typ: ValidationTokenEnum.CloseCurlyBrace
823
+ }, 'pos', { ...objectProperties, value: pos });
824
+ }
825
+ if (token == '*') {
826
+ return Object.defineProperty({
827
+ typ: ValidationTokenEnum.Star
828
+ }, 'pos', { ...objectProperties, value: pos });
829
+ }
830
+ if (token == '?') {
831
+ return Object.defineProperty({
832
+ typ: ValidationTokenEnum.QuestionMark
833
+ }, 'pos', { ...objectProperties, value: pos });
834
+ }
835
+ if (token.startsWith("<'")) {
836
+ return Object.defineProperty({
837
+ typ: ValidationTokenEnum.DeclarationType,
838
+ val: token.slice(2, -2)
839
+ }, 'pos', { ...objectProperties, value: pos });
840
+ }
841
+ if (token.startsWith('<')) {
842
+ // <number [1,1000]>
843
+ // <length [0,∞]>
844
+ let match = token.match(/<([a-z0-9-]+)(\s+\[([0-9]+),(([0-9]+)|∞)\])?>/);
845
+ if (match == null) {
846
+ let match = token.match(/<([a-zA-Z0-9-]+)\(\)>/);
847
+ if (match != null) {
848
+ return Object.defineProperty({
849
+ typ: ValidationTokenEnum.ValidationFunctionDefinition,
850
+ val: match[1]
851
+ }, 'pos', { ...objectProperties, value: pos });
852
+ }
853
+ throw new Error('invalid token at position: ' + position.lin + ':' + position.col + ' ' + token);
854
+ }
855
+ if (match[2] != null) {
856
+ return Object.defineProperty({
857
+ typ: ValidationTokenEnum.PropertyType,
858
+ val: match[1],
859
+ range: [+match[3], match[4] == '∞' ? Infinity : +match[4]]
860
+ }, 'pos', { ...objectProperties, value: pos });
861
+ }
862
+ return Object.defineProperty({
863
+ typ: ValidationTokenEnum.PropertyType,
864
+ val: token.slice(1, -1)
865
+ }, 'pos', { ...objectProperties, value: pos });
866
+ }
867
+ if (token.startsWith('@') && isIdent(token.slice(1))) {
868
+ return Object.defineProperty({
869
+ typ: ValidationTokenEnum.AtRule,
870
+ val: token.slice(1)
871
+ }, 'pos', { ...objectProperties, value: pos });
872
+ }
873
+ return Object.defineProperty({
874
+ typ: ValidationTokenEnum.Keyword,
875
+ val: token
876
+ }, 'pos', { ...objectProperties, value: pos });
877
+ }
878
+ function move(position, chr) {
879
+ for (const c of chr) {
880
+ position.col++;
881
+ position.ind += c.length;
882
+ }
883
+ return position;
884
+ }
885
+ function renderSyntax(token, parent) {
886
+ let glue;
887
+ switch (token.typ) {
888
+ case ValidationTokenEnum.Root:
889
+ return token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '');
890
+ case ValidationTokenEnum.Whitespace:
891
+ return ' ';
892
+ case ValidationTokenEnum.ValidationFunctionDefinition:
893
+ return '<' + token.val + '()>';
894
+ case ValidationTokenEnum.HashMark:
895
+ return '#';
896
+ case ValidationTokenEnum.Pipe:
897
+ return '|';
898
+ case ValidationTokenEnum.Column:
899
+ return '||';
900
+ case ValidationTokenEnum.PipeToken:
901
+ return token.chi.reduce((acc, curr) => acc + (acc.trim().length > 0 ? '|' : '') + curr.reduce((acc, curr) => acc + renderSyntax(curr), ''), '');
902
+ case ValidationTokenEnum.ColumnToken:
903
+ case ValidationTokenEnum.AmpersandToken:
904
+ glue = token.typ == ValidationTokenEnum.ColumnToken ? '||' : '&&';
905
+ return token.l.reduce((acc, curr) => acc + renderSyntax(curr), '') +
906
+ glue +
907
+ token.r.reduce((acc, curr) => acc + renderSyntax(curr), '');
908
+ case ValidationTokenEnum.Function:
909
+ case ValidationTokenEnum.PseudoClassFunctionToken:
910
+ case ValidationTokenEnum.Parens:
911
+ return token.val + '(' + token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '') + ')' + renderAttributes(token);
912
+ case ValidationTokenEnum.Comma:
913
+ return ',';
914
+ case ValidationTokenEnum.Keyword:
915
+ return token.val + renderAttributes(token);
916
+ case ValidationTokenEnum.OpenBracket:
917
+ return '[';
918
+ case ValidationTokenEnum.Ampersand:
919
+ return '&&';
920
+ case ValidationTokenEnum.QuestionMark:
921
+ return '?';
922
+ case ValidationTokenEnum.Separator:
923
+ return '/';
924
+ case ValidationTokenEnum.Bracket:
925
+ return '[' + token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '') + ']' + renderAttributes(token);
926
+ case ValidationTokenEnum.PropertyType:
927
+ return '<' + token.val + '>' + renderAttributes(token);
928
+ case ValidationTokenEnum.DeclarationType:
929
+ return "<'" + token.val + "'>" + renderAttributes(token);
930
+ case ValidationTokenEnum.Number:
931
+ case ValidationTokenEnum.PseudoClassToken:
932
+ case ValidationTokenEnum.StringToken:
933
+ return token.val + '';
934
+ case ValidationTokenEnum.SemiColon:
935
+ return ';';
936
+ case ValidationTokenEnum.AtRule:
937
+ return '@' + token.val;
938
+ case ValidationTokenEnum.AtRuleDefinition:
939
+ return '@' + token.val +
940
+ (token.prelude == null ? '' : ' ' + token.prelude.reduce((acc, curr) => acc + renderSyntax(curr), '')) +
941
+ (token.chi == null ? '' : ' {\n' + token.chi.reduce((acc, curr) => acc + renderSyntax(curr), '')).slice(1, -1) + '\n}';
942
+ case ValidationTokenEnum.Block:
943
+ return '{' + token.chi.reduce((acc, t) => acc + renderSyntax(t), '') + '}';
944
+ default:
945
+ throw new Error('Unhandled token: ' + JSON.stringify({ token }));
946
+ }
947
+ }
948
+ function renderAttributes(token) {
949
+ let result = '';
950
+ if (token.isList) {
951
+ result += '#';
952
+ }
953
+ if (token.isOptional) {
954
+ result += '?';
955
+ }
956
+ if (token.isRepeatableGroup) {
957
+ result += '!';
958
+ }
959
+ if (token.isRepeatable) {
960
+ result += '*';
961
+ }
962
+ if (token.atLeastOnce) {
963
+ result += '+';
964
+ }
965
+ if (token.occurence != null) {
966
+ if (token.occurence.max == 0 || token.occurence.max == token.occurence.min || Number.isNaN(token.occurence.max)) {
967
+ result += '{' + token.occurence.min + '}';
968
+ }
969
+ else {
970
+ result += '{' + token.occurence.min + ',' + token.occurence.max + '}';
971
+ }
972
+ }
973
+ return result;
974
+ }
975
+ function minify(ast) {
976
+ if (Array.isArray(ast)) {
977
+ // @ts-ignore
978
+ while (ast.length > 0 && ast[0].typ == ValidationTokenEnum.Whitespace) {
979
+ // @ts-ignore
980
+ ast.shift();
981
+ }
982
+ while (ast.length > 0 && ast.at(-1).typ == ValidationTokenEnum.Whitespace) {
983
+ ast.pop();
984
+ }
985
+ for (let i = 0; i < ast.length; i++) {
986
+ // if ([ValidationTokenEnum.ColumnToken, ValidationTokenEnum.PipeToken, ValidationTokenEnum.AmpersandToken].includes(ast[i].typ)) {
987
+ // for (const j of (ast[i] as ValidationPipeToken | ValidationColumnToken | ValidationAmpersandToken).l) {
988
+ minify(ast[i]);
989
+ // }
990
+ // for (const j of (ast[i] as ValidationPipeToken | ValidationColumnToken | ValidationAmpersandToken).r) {
991
+ //
992
+ // minify(j);
993
+ // }
994
+ // } else
995
+ // if ('chi' in ast[i]) {
996
+ //
997
+ // minify((ast[i] as ValidationFunctionToken | ValidationBracketToken).chi as ValidationToken[]);
998
+ //
999
+ // } else
1000
+ if (ast[i].typ == ValidationTokenEnum.Whitespace && ast[i + 1]?.typ == ValidationTokenEnum.Whitespace) {
1001
+ ast.splice(i + 1, 1);
1002
+ i--;
1003
+ continue;
1004
+ }
1005
+ if (ast[i].typ == ValidationTokenEnum.Separator) {
1006
+ if (ast[i + 1]?.typ == ValidationTokenEnum.Whitespace) {
1007
+ ast.splice(i + 1, 1);
1008
+ }
1009
+ if (ast[i - 1]?.typ == ValidationTokenEnum.Whitespace) {
1010
+ ast.splice(--i, 1);
1011
+ }
1012
+ }
1013
+ }
1014
+ return ast;
1015
+ }
1016
+ // else {
1017
+ // if ([ValidationTokenEnum.ColumnToken, ValidationTokenEnum.PipeToken, ValidationTokenEnum.AmpersandToken].includes(ast.typ)) {
1018
+ // for (const j of (ast as ValidationPipeToken | ValidationColumnToken | ValidationAmpersandToken).l) {
1019
+ if ('l' in ast) {
1020
+ minify(ast.l);
1021
+ }
1022
+ // }
1023
+ // for (const j of (ast as ValidationPipeToken | ValidationColumnToken | ValidationAmpersandToken).r) {
1024
+ if ('r' in ast) {
1025
+ minify(ast.r);
1026
+ }
1027
+ if ('chi' in ast) {
1028
+ minify(ast.chi);
1029
+ }
1030
+ if ('prelude' in ast) {
1031
+ minify(ast.prelude);
1032
+ }
1033
+ return ast;
1034
+ }
1035
+ function* walkValidationToken(token, parent, callback) {
1036
+ if (Array.isArray(token)) {
1037
+ for (const child of token) {
1038
+ yield* walkValidationToken(child, parent);
1039
+ }
1040
+ return;
1041
+ }
1042
+ yield { token, parent };
1043
+ if ('prelude' in token) {
1044
+ for (const child of token.prelude) {
1045
+ yield* walkValidationToken(child, token);
1046
+ }
1047
+ }
1048
+ if ('chi' in token) {
1049
+ // @ts-ignore
1050
+ for (const child of token.chi) {
1051
+ yield* walkValidationToken(child, token);
1052
+ }
1053
+ }
1054
+ if ('l' in token) {
1055
+ // @ts-ignore
1056
+ for (const child of token.l) {
1057
+ yield* walkValidationToken(child, token);
1058
+ }
1059
+ }
1060
+ if ('r' in token) {
1061
+ // @ts-ignore
1062
+ for (const child of token.r) {
1063
+ yield* walkValidationToken(child, token);
1064
+ }
1065
+ }
1066
+ }
1067
+
1068
+ export { parseSyntax, renderSyntax, walkValidationToken };