@tbela99/css-parser 1.0.0 → 1.1.1-alpha4

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 (87) hide show
  1. package/CHANGELOG.md +269 -0
  2. package/README.md +16 -11
  3. package/dist/index-umd-web.js +3805 -1894
  4. package/dist/index.cjs +3806 -1895
  5. package/dist/index.d.ts +184 -57
  6. package/dist/lib/ast/expand.js +2 -1
  7. package/dist/lib/ast/features/calc.js +12 -1
  8. package/dist/lib/ast/features/inlinecssvariables.js +47 -24
  9. package/dist/lib/ast/features/prefix.js +117 -86
  10. package/dist/lib/ast/features/shorthand.js +29 -6
  11. package/dist/lib/ast/features/transform.js +10 -3
  12. package/dist/lib/ast/features/type.js +7 -0
  13. package/dist/lib/ast/math/expression.js +7 -1
  14. package/dist/lib/ast/math/math.js +6 -0
  15. package/dist/lib/ast/minify.js +165 -77
  16. package/dist/lib/ast/transform/compute.js +1 -0
  17. package/dist/lib/ast/transform/matrix.js +1 -0
  18. package/dist/lib/ast/types.js +26 -15
  19. package/dist/lib/ast/utils/utils.js +104 -0
  20. package/dist/lib/ast/walk.js +33 -7
  21. package/dist/lib/fs/resolve.js +10 -0
  22. package/dist/lib/parser/declaration/list.js +48 -45
  23. package/dist/lib/parser/declaration/map.js +1 -0
  24. package/dist/lib/parser/declaration/set.js +2 -1
  25. package/dist/lib/parser/parse.js +350 -279
  26. package/dist/lib/parser/tokenize.js +147 -72
  27. package/dist/lib/parser/utils/declaration.js +4 -3
  28. package/dist/lib/parser/utils/type.js +2 -1
  29. package/dist/lib/renderer/color/a98rgb.js +2 -1
  30. package/dist/lib/renderer/color/color-mix.js +10 -7
  31. package/dist/lib/renderer/color/color.js +171 -153
  32. package/dist/lib/renderer/color/hex.js +2 -1
  33. package/dist/lib/renderer/color/hsl.js +2 -1
  34. package/dist/lib/renderer/color/hwb.js +2 -1
  35. package/dist/lib/renderer/color/lab.js +2 -1
  36. package/dist/lib/renderer/color/lch.js +2 -1
  37. package/dist/lib/renderer/color/oklab.js +2 -1
  38. package/dist/lib/renderer/color/oklch.js +2 -1
  39. package/dist/lib/renderer/color/p3.js +2 -1
  40. package/dist/lib/renderer/color/rec2020.js +2 -1
  41. package/dist/lib/renderer/color/relativecolor.js +17 -11
  42. package/dist/lib/renderer/color/rgb.js +4 -3
  43. package/dist/lib/renderer/color/srgb.js +18 -17
  44. package/dist/lib/renderer/color/utils/components.js +6 -5
  45. package/dist/lib/renderer/color/utils/constants.js +47 -3
  46. package/dist/lib/renderer/color/xyz.js +2 -1
  47. package/dist/lib/renderer/color/xyzd50.js +2 -1
  48. package/dist/lib/renderer/render.js +48 -20
  49. package/dist/lib/syntax/syntax.js +257 -140
  50. package/dist/lib/validation/at-rules/container.js +75 -97
  51. package/dist/lib/validation/at-rules/counter-style.js +9 -8
  52. package/dist/lib/validation/at-rules/custom-media.js +13 -15
  53. package/dist/lib/validation/at-rules/document.js +22 -27
  54. package/dist/lib/validation/at-rules/font-feature-values.js +8 -8
  55. package/dist/lib/validation/at-rules/import.js +30 -81
  56. package/dist/lib/validation/at-rules/keyframes.js +18 -22
  57. package/dist/lib/validation/at-rules/layer.js +5 -5
  58. package/dist/lib/validation/at-rules/media.js +42 -52
  59. package/dist/lib/validation/at-rules/namespace.js +19 -23
  60. package/dist/lib/validation/at-rules/page-margin-box.js +15 -18
  61. package/dist/lib/validation/at-rules/page.js +8 -7
  62. package/dist/lib/validation/at-rules/supports.js +73 -82
  63. package/dist/lib/validation/at-rules/when.js +32 -36
  64. package/dist/lib/validation/atrule.js +15 -14
  65. package/dist/lib/validation/config.js +24 -1
  66. package/dist/lib/validation/config.json.js +611 -111
  67. package/dist/lib/validation/parser/parse.js +206 -212
  68. package/dist/lib/validation/parser/types.js +1 -1
  69. package/dist/lib/validation/selector.js +3 -3
  70. package/dist/lib/validation/syntax.js +984 -0
  71. package/dist/lib/validation/syntaxes/complex-selector-list.js +10 -11
  72. package/dist/lib/validation/syntaxes/complex-selector.js +10 -11
  73. package/dist/lib/validation/syntaxes/compound-selector.js +40 -50
  74. package/dist/lib/validation/syntaxes/family-name.js +9 -8
  75. package/dist/lib/validation/syntaxes/keyframe-block-list.js +4 -3
  76. package/dist/lib/validation/syntaxes/keyframe-selector.js +15 -18
  77. package/dist/lib/validation/syntaxes/layer-name.js +6 -5
  78. package/dist/lib/validation/syntaxes/relative-selector-list.js +7 -6
  79. package/dist/lib/validation/syntaxes/relative-selector.js +2 -1
  80. package/dist/lib/validation/syntaxes/url.js +18 -22
  81. package/dist/lib/validation/utils/list.js +2 -1
  82. package/dist/lib/validation/utils/whitespace.js +2 -1
  83. package/dist/node/index.js +4 -2
  84. package/dist/node/load.js +5 -0
  85. package/dist/web/index.js +4 -2
  86. package/dist/web/load.js +5 -0
  87. package/package.json +14 -13
@@ -1,10 +1,12 @@
1
- import { colorsFunc } from '../renderer/render.js';
2
1
  import { EnumToken } from '../ast/types.js';
3
2
  import '../ast/minify.js';
4
- import '../ast/walk.js';
3
+ import { walkValues, WalkerOptionEnum } from '../ast/walk.js';
5
4
  import '../parser/parse.js';
5
+ import '../parser/tokenize.js';
6
6
  import '../parser/utils/config.js';
7
- import { COLORS_NAMES } from '../renderer/color/utils/constants.js';
7
+ import { COLORS_NAMES, colorsFunc, funcLike, ColorKind } from '../renderer/color/utils/constants.js';
8
+ import { buildExpression } from '../ast/math/expression.js';
9
+ import '../renderer/sourcemap/lib/encode.js';
8
10
 
9
11
  // https://www.w3.org/TR/CSS21/syndata.html#syntax
10
12
  // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
@@ -32,12 +34,36 @@ const mediaTypes = ['all', 'print', 'screen',
32
34
  /* deprecated */
33
35
  'aural', 'braille', 'embossed', 'handheld', 'projection', 'tty', 'tv', 'speech'];
34
36
  // https://www.w3.org/TR/css-values-4/#math-function
35
- const mathFuncs = ['calc', 'clamp', 'min', 'max', 'round', 'mod', 'rem', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2', 'pow', 'sqrt', 'hypot', 'log', 'exp', 'abs', 'sign'];
37
+ const mathFuncs = ['minmax', 'repeat', 'fit-content', 'calc', 'clamp', 'min', 'max', 'round', 'mod', 'rem', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2', 'pow', 'sqrt', 'hypot', 'log', 'exp', 'abs', 'sign'];
38
+ const wildCardFuncs = ['var', 'env'];
36
39
  const pseudoElements = [':before', ':after', ':first-line', ':first-letter'];
37
- const webkitPseudoAliasMap = {
38
- '-webkit-autofill': 'autofill',
39
- '-webkit-any': 'is',
40
- '-moz-any': 'is',
40
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/WebKit_Extensions
41
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/Mozilla_Extensions
42
+ const pseudoAliasMap = {
43
+ '-moz-center': 'center',
44
+ '-webkit-center': 'center',
45
+ '-ms-grid-columns': 'grid-template-columns',
46
+ '-ms-grid-rows': 'grid-template-rows',
47
+ '-ms-grid-row': 'grid-row-start',
48
+ '-ms-grid-column': 'grid-column-start',
49
+ '-ms-grid-row-align': 'align-self',
50
+ '-ms-grid-row-span': 'grid-row-end',
51
+ '-ms-grid-column-span': 'grid-column-end',
52
+ '-ms-grid-column-align': 'justify-self',
53
+ ':-ms-input-placeholder': '::placeholder',
54
+ '::-ms-input-placeholder': '::placeholder',
55
+ ':-moz-any()': ':is',
56
+ '-moz-user-modify': 'user-modify',
57
+ '-webkit-match-parent': 'match-parent',
58
+ '-moz-background-clip': 'background-clip',
59
+ '-moz-background-origin': 'background-origin',
60
+ '-ms-input-placeholder': 'placeholder',
61
+ ':-webkit-autofill': ':autofill',
62
+ ':-webkit-any()': ':is',
63
+ '::-webkit-input-placeholder': '::placeholder',
64
+ '::-webkit-file-upload-button': '::file-selector-button',
65
+ '::-moz-placeholder': '::placeholder',
66
+ ':-webkit-any-link': ':any-link',
41
67
  '-webkit-border-after': 'border-block-end',
42
68
  '-webkit-border-after-color': 'border-block-end-color',
43
69
  '-webkit-border-after-style': 'border-block-end-style',
@@ -74,7 +100,75 @@ const webkitPseudoAliasMap = {
74
100
  '-webkit-padding-end': 'padding-inline-end',
75
101
  '-webkit-padding-start': 'padding-inline-start',
76
102
  '-webkit-min-device-pixel-ratio': 'min-resolution',
77
- '-webkit-max-device-pixel-ratio': 'max-resolution'
103
+ '-webkit-max-device-pixel-ratio': 'max-resolution',
104
+ '-webkit-font-smoothing': 'font-smooth',
105
+ '-webkit-line-clamp': 'line-clamp',
106
+ ':-webkit-autofill-strong-password': ':autofill',
107
+ ':-webkit-full-page-media': ':fullscreen',
108
+ ':-webkit-full-screen': ':fullscreen',
109
+ ':-webkit-full-screen-ancestor': ':fullscreen',
110
+ ':-webkit-full-screen-document': ':fullscreen',
111
+ ':-webkit-full-screen-controls-hidden': ':fullscreen',
112
+ '-moz-background-inline-policy': 'box-decoration-break',
113
+ '-moz-background-size': 'background-size',
114
+ '-moz-border-end': 'border-inline-end',
115
+ '-moz-border-end-color': 'border-inline-end-color',
116
+ '-moz-border-end-style': 'border-inline-end-style',
117
+ '-moz-border-end-width': 'border-inline-end-width',
118
+ '-moz-border-image': 'border-inline-end-width',
119
+ '-moz-border-start': 'border-inline-start',
120
+ '-moz-border-start-color': 'border-inline-start-color',
121
+ '-moz-border-start-style': 'border-inline-start-style',
122
+ '-moz-border-start-width': 'border-inline-start-width',
123
+ '-moz-column-count': 'column-count',
124
+ '-moz-column-fill': 'column-fill',
125
+ '-moz-column-gap': 'column-gap',
126
+ '-moz-column-width': 'column-width',
127
+ '-moz-column-rule': 'column-rule',
128
+ '-moz-column-rule-width': 'column-rule-width',
129
+ '-moz-column-rule-style': 'column-rule-style',
130
+ '-moz-column-rule-color': 'column-rule-color',
131
+ '-moz-margin-end': 'margin-inline-end',
132
+ '-moz-margin-start': 'margin-inline-start',
133
+ '-moz-opacity': 'opacity',
134
+ '-moz-outline': 'outline',
135
+ '-moz-outline-color': 'outline-color',
136
+ '-moz-outline-offset': 'outline-offset',
137
+ '-moz-outline-style': 'outline-style',
138
+ '-moz-outline-width': 'outline-width',
139
+ '-moz-padding-end': 'padding-inline-end',
140
+ '-moz-padding-start': 'padding-inline-start',
141
+ '-moz-tab-size': 'tab-size',
142
+ '-moz-text-align-last': 'text-align-last',
143
+ '-moz-text-decoration-color': 'text-decoration-color',
144
+ '-moz-text-decoration-line': 'text-decoration-line',
145
+ '-moz-text-decoration-style': 'text-decoration-style',
146
+ '-moz-transition': 'transition',
147
+ '-moz-transition-delay': 'transition-delay',
148
+ '-moz-transition-duration': 'transition-duration',
149
+ '-moz-transition-property': 'transition-property',
150
+ '-moz-transition-timing-function': 'transition-timing-function',
151
+ '-moz-user-select': 'user-select',
152
+ '-moz-initial': 'initial',
153
+ '-moz-linear-gradient()': 'linear-gradient',
154
+ '-moz-radial-gradient()': 'radial-gradient',
155
+ '-moz-element()': 'element',
156
+ '-moz-crisp-edges': 'crisp-edges',
157
+ '-moz-calc()': 'calc',
158
+ '-moz-min-content': 'min-content',
159
+ '-moz-fit-content': 'fit-content',
160
+ '-moz-max-content': 'max-content',
161
+ '-moz-available': 'stretch',
162
+ ':-moz-any-link': ':any-link',
163
+ ':-moz-full-screen': ':fullscreen',
164
+ ':-moz-full-screen-ancestor': ':fullscreen',
165
+ ':-moz-placeholder': ':placeholder-shown',
166
+ ':-moz-read-only': ':read-only',
167
+ ':-moz-read-write': ':read-write',
168
+ ':-moz-submit-invalid': ':invalid',
169
+ ':-moz-ui-invalid': ':user-invalid',
170
+ ':-moz-ui-valid': ':user-valid',
171
+ '::-moz-selection': '::selection',
78
172
  };
79
173
  // https://developer.mozilla.org/en-US/docs/Web/CSS/WebKit_Extensions
80
174
  // https://developer.mozilla.org/en-US/docs/Web/CSS/::-webkit-scrollbar
@@ -117,6 +211,7 @@ const webkitExtensions = new Set([
117
211
  '-webkit-min-logical-height',
118
212
  '-webkit-min-logical-width',
119
213
  '-webkit-nbsp-mode',
214
+ '-webkit-match-parent',
120
215
  '-webkit-perspective-origin-x',
121
216
  '-webkit-perspective-origin-y',
122
217
  '-webkit-rtl-ordering',
@@ -408,158 +503,205 @@ function isHueInterpolationMethod(token) {
408
503
  }
409
504
  return ['shorter', 'longer', 'increasing', 'decreasing'].includes(token.val);
410
505
  }
506
+ function isIdentColor(token) {
507
+ return token.typ == EnumToken.ColorTokenType && [ColorKind.SYS, ColorKind.DPSYS, ColorKind.LIT].includes(token.kin) && isIdent(token.val);
508
+ }
411
509
  function isColor(token) {
412
- if (token.typ == EnumToken.ColorTokenType) {
413
- return true;
414
- }
415
510
  if (token.typ == EnumToken.IdenTokenType) {
416
511
  // named color
417
512
  return token.val.toLowerCase() in COLORS_NAMES;
418
513
  }
419
514
  let isLegacySyntax = false;
420
- if (token.typ == EnumToken.FunctionTokenType && token.chi.length > 0 && colorsFunc.includes(token.val)) {
421
- // @ts-ignore
422
- if (token.val == 'light-dark') {
423
- // @ts-ignore
424
- const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
425
- if (children.length != 2) {
426
- return false;
427
- }
428
- if (isColor(children[0]) && isColor(children[1])) {
429
- return true;
430
- }
515
+ if (token.typ == EnumToken.FunctionTokenType) {
516
+ if (!colorsFunc.includes(token.val.toLowerCase())) {
517
+ return false;
431
518
  }
432
- // @ts-ignore
433
- if (token.val == 'color') {
519
+ if (token.chi.length > 0) {
434
520
  // @ts-ignore
435
- const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
436
- const isRelative = children[0].typ == EnumToken.IdenTokenType && children[0].val == 'from';
437
- if (children.length < 4 || children.length > 8) {
438
- return false;
439
- }
440
- if (!isRelative && !isColorspace(children[0])) {
441
- return false;
442
- }
443
- for (let i = 1; i < children.length - 2; i++) {
444
- if (children[i].typ == EnumToken.IdenTokenType) {
445
- if (children[i].val != 'none' &&
446
- !(isRelative && ['alpha', 'r', 'g', 'b', 'x', 'y', 'z'].includes(children[i].val) || isColorspace(children[i]))) {
447
- return false;
448
- }
449
- }
450
- if (children[i].typ == EnumToken.FunctionTokenType && !mathFuncs.includes(children[i].val)) {
521
+ if (token.val == 'light-dark') {
522
+ // @ts-ignore
523
+ const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
524
+ if (children.length != 2) {
451
525
  return false;
452
526
  }
527
+ if (isColor(children[0]) && isColor(children[1])) {
528
+ return true;
529
+ }
453
530
  }
454
- if (children.length == 4 || (isRelative && children.length == 6)) {
455
- return true;
531
+ // adding numbers and percentages is disallowed
532
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/lch#defining_relative_color_output_channel_components
533
+ // @ts-ignore
534
+ for (const { value } of walkValues(token.chi, null, (node) => funcLike.includes(node.typ) ? WalkerOptionEnum.IgnoreChildren : null)) {
535
+ if (funcLike.includes(value.typ)) {
536
+ for (const { value: val } of walkValues([buildExpression(value.chi)])) {
537
+ if (val.typ == EnumToken.BinaryExpressionTokenType &&
538
+ (val.l.typ == EnumToken.PercentageTokenType || val.r.typ == EnumToken.PercentageTokenType) &&
539
+ ((val.r.typ == EnumToken.PercentageTokenType && val.op == EnumToken.Div) ||
540
+ ((val.op == EnumToken.Add || val.op == EnumToken.Sub) &&
541
+ val.l.typ != val.r.typ))) {
542
+ return false;
543
+ }
544
+ }
545
+ }
456
546
  }
457
- if (children.length == 8 || children.length == 6) {
458
- const sep = children.at(-2);
459
- const alpha = children.at(-1);
547
+ // @ts-ignore
548
+ if (token.val == 'color') {
460
549
  // @ts-ignore
461
- if ((children.length > 6 || !isRelative) && sep.typ != EnumToken.LiteralTokenType || sep.val != '/') {
550
+ const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
551
+ const isRelative = children[0].typ == EnumToken.IdenTokenType && children[0].val == 'from';
552
+ if (children.length < 4 || children.length > 8) {
462
553
  return false;
463
554
  }
464
- if (alpha.typ == EnumToken.IdenTokenType && alpha.val != 'none') {
555
+ if (!isRelative && !isColorspace(children[0])) {
465
556
  return false;
466
557
  }
467
- else {
468
- // @ts-ignore
469
- if (alpha.typ == EnumToken.PercentageTokenType) {
470
- if (+alpha.val < 0 || +alpha.val > 100) {
558
+ for (let i = 1; i < children.length - 2; i++) {
559
+ if (children[i].typ == EnumToken.IdenTokenType) {
560
+ if (children[i].val != 'none' &&
561
+ !(isRelative && ['alpha', 'r', 'g', 'b', 'x', 'y', 'z'].includes(children[i].val) || isColorspace(children[i]))) {
471
562
  return false;
472
563
  }
473
564
  }
474
- else if (alpha.typ == EnumToken.NumberTokenType) {
475
- if (+alpha.val < 0 || +alpha.val > 1) {
476
- return false;
477
- }
565
+ if (children[i].typ == EnumToken.FunctionTokenType && !mathFuncs.includes(children[i].val)) {
566
+ return false;
478
567
  }
479
568
  }
480
- }
481
- return true;
482
- }
483
- else { // @ts-ignore
484
- if (token.val == 'color-mix') {
485
- // @ts-ignore
486
- const children = token.chi.reduce((acc, t) => {
487
- if (t.typ == EnumToken.CommaTokenType) {
488
- acc.push([]);
489
- }
490
- else {
491
- if (![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)) {
492
- acc[acc.length - 1].push(t);
493
- }
569
+ if (children.length == 4 || (isRelative && children.length == 6)) {
570
+ return true;
571
+ }
572
+ if (children.length == 8 || children.length == 6) {
573
+ const sep = children.at(-2);
574
+ const alpha = children.at(-1);
575
+ // @ts-ignore
576
+ if ((children.length > 6 || !isRelative) && sep.typ != EnumToken.LiteralTokenType || sep.val != '/') {
577
+ return false;
494
578
  }
495
- return acc;
496
- }, [[]]);
497
- if (children.length == 3) {
498
- if (children[0].length > 3 ||
499
- children[0][0].typ != EnumToken.IdenTokenType ||
500
- children[0][0].val != 'in' ||
501
- !isColorspace(children[0][1]) ||
502
- (children[0].length == 3 && !isHueInterpolationMethod(children[0][2])) ||
503
- children[1].length > 2 ||
504
- children[1][0].typ != EnumToken.ColorTokenType ||
505
- children[2].length > 2 ||
506
- children[2][0].typ != EnumToken.ColorTokenType) {
579
+ if (alpha.typ == EnumToken.IdenTokenType && alpha.val != 'none') {
507
580
  return false;
508
581
  }
509
- if (children[1].length == 2) {
510
- if (!(children[1][1].typ == EnumToken.PercentageTokenType || (children[1][1].typ == EnumToken.NumberTokenType && children[1][1].val == '0'))) {
511
- return false;
582
+ else {
583
+ // @ts-ignore
584
+ if (alpha.typ == EnumToken.PercentageTokenType) {
585
+ if (+alpha.val < 0 || +alpha.val > 100) {
586
+ return false;
587
+ }
512
588
  }
513
- }
514
- if (children[2].length == 2) {
515
- if (!(children[2][1].typ == EnumToken.PercentageTokenType || (children[2][1].typ == EnumToken.NumberTokenType && children[2][1].val == '0'))) {
516
- return false;
589
+ else if (alpha.typ == EnumToken.NumberTokenType) {
590
+ if (+alpha.val < 0 || +alpha.val > 1) {
591
+ return false;
592
+ }
517
593
  }
518
594
  }
519
- return true;
520
595
  }
521
- return false;
596
+ return true;
522
597
  }
523
- else {
524
- const keywords = ['from', 'none'];
525
- // @ts-ignore
526
- if (['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch'].includes(token.val)) {
598
+ else { // @ts-ignore
599
+ if (token.val == 'color-mix') {
527
600
  // @ts-ignore
528
- keywords.push('alpha', ...token.val.slice(-3).split(''));
529
- }
530
- // @ts-ignore
531
- for (const v of token.chi) {
532
- if (v.typ == EnumToken.CommaTokenType) {
533
- isLegacySyntax = true;
534
- }
535
- if (v.typ == EnumToken.IdenTokenType) {
536
- if (!(keywords.includes(v.val) || v.val.toLowerCase() in COLORS_NAMES)) {
601
+ const children = token.chi.reduce((acc, t) => {
602
+ if (t.typ == EnumToken.CommaTokenType) {
603
+ acc.push([]);
604
+ }
605
+ else {
606
+ if (![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)) {
607
+ acc[acc.length - 1].push(t);
608
+ }
609
+ }
610
+ return acc;
611
+ }, [[]]);
612
+ if (children.length == 3) {
613
+ if (children[0].length > 3 ||
614
+ children[0][0].typ != EnumToken.IdenTokenType ||
615
+ children[0][0].val != 'in' ||
616
+ !isColorspace(children[0][1]) ||
617
+ (children[0].length == 3 && !isHueInterpolationMethod(children[0][2])) ||
618
+ children[1].length > 2 ||
619
+ children[1][0].typ != EnumToken.ColorTokenType ||
620
+ children[2].length > 2 ||
621
+ children[2][0].typ != EnumToken.ColorTokenType) {
537
622
  return false;
538
623
  }
539
- if (keywords.includes(v.val)) {
540
- if (isLegacySyntax) {
624
+ if (children[1].length == 2) {
625
+ if (!(children[1][1].typ == EnumToken.PercentageTokenType || (children[1][1].typ == EnumToken.NumberTokenType && children[1][1].val == '0'))) {
541
626
  return false;
542
627
  }
543
- // @ts-ignore
544
- if (v.val == 'from' && ['rgba', 'hsla'].includes(token.val)) {
628
+ }
629
+ if (children[2].length == 2) {
630
+ if (!(children[2][1].typ == EnumToken.PercentageTokenType || (children[2][1].typ == EnumToken.NumberTokenType && children[2][1].val == '0'))) {
545
631
  return false;
546
632
  }
547
633
  }
548
- continue;
634
+ return true;
549
635
  }
550
- if (v.typ == EnumToken.FunctionTokenType && (mathFuncs.includes(v.val) || v.val == 'var' || colorsFunc.includes(v.val))) {
551
- continue;
636
+ return false;
637
+ }
638
+ else {
639
+ const keywords = ['from', 'none'];
640
+ // @ts-ignore
641
+ if (['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch'].includes(token.val)) {
642
+ // @ts-ignore
643
+ keywords.push('alpha', ...token.val.slice(-3).split(''));
552
644
  }
553
- if (![EnumToken.ColorTokenType, EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType].includes(v.typ)) {
554
- return false;
645
+ // @ts-ignore
646
+ for (const v of token.chi) {
647
+ if (v.typ == EnumToken.CommaTokenType) {
648
+ isLegacySyntax = true;
649
+ }
650
+ if (v.typ == EnumToken.IdenTokenType) {
651
+ if (!(keywords.includes(v.val) || v.val.toLowerCase() in COLORS_NAMES)) {
652
+ return false;
653
+ }
654
+ if (keywords.includes(v.val)) {
655
+ if (isLegacySyntax) {
656
+ return false;
657
+ }
658
+ // @ts-ignore
659
+ if (v.val == 'from' && ['rgba', 'hsla'].includes(token.val)) {
660
+ return false;
661
+ }
662
+ }
663
+ continue;
664
+ }
665
+ if (v.typ == EnumToken.FunctionTokenType && (mathFuncs.includes(v.val) || v.val == 'var' || colorsFunc.includes(v.val))) {
666
+ continue;
667
+ }
668
+ if (![EnumToken.ColorTokenType, EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType].includes(v.typ)) {
669
+ return false;
670
+ }
555
671
  }
556
672
  }
557
673
  }
674
+ return true;
558
675
  }
559
- return true;
560
676
  }
561
677
  return false;
562
678
  }
679
+ function parseColor(token) {
680
+ // @ts-ignore
681
+ token.typ = EnumToken.ColorTokenType;
682
+ // @ts-ignore
683
+ token.kin = ColorKind[token.val.replaceAll('-', '_').toUpperCase()];
684
+ // @ts-ignore
685
+ if (token.chi[0].typ == EnumToken.IdenTokenType) {
686
+ // @ts-ignore
687
+ if (token.chi[0].val == 'from') {
688
+ // @ts-ignore
689
+ token.cal = 'rel';
690
+ }
691
+ // @ts-ignore
692
+ else if (token.val == 'color-mix' && token.chi[0].val == 'in') {
693
+ // @ts-ignore
694
+ token.cal = 'mix';
695
+ }
696
+ else { // @ts-ignore
697
+ if (token.val == 'color') {
698
+ // @ts-ignore
699
+ token.cal = 'col';
700
+ }
701
+ }
702
+ }
703
+ return token;
704
+ }
563
705
  function isLetter(codepoint) {
564
706
  // lowercase
565
707
  return (codepoint >= 0x61 && codepoint <= 0x7a) ||
@@ -789,31 +931,6 @@ function isHexColor(name) {
789
931
  }
790
932
  return true;
791
933
  }
792
- /*
793
- export function isHexDigit(name: string): boolean {
794
-
795
- if (name.length || name.length > 6) {
796
-
797
- return false;
798
- }
799
-
800
- for (let chr of name) {
801
-
802
- let codepoint = <number>chr.charCodeAt(0);
803
-
804
- if (!isDigit(codepoint) &&
805
- // A F
806
- !(codepoint >= 0x41 && codepoint <= 0x46) &&
807
- // a f
808
- !(codepoint >= 0x61 && codepoint <= 0x66)) {
809
-
810
- return false;
811
- }
812
- }
813
-
814
- return true;
815
- }
816
- */
817
934
  function isFunction(name) {
818
935
  return name.endsWith('(') && isIdent(name.slice(0, -1));
819
936
  }
@@ -830,4 +947,4 @@ function isWhiteSpace(codepoint) {
830
947
  codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
831
948
  }
832
949
 
833
- export { colorFontTech, fontFeaturesTech, fontFormat, isAngle, isAtKeyword, isColor, isColorspace, isDigit, isDimension, isFlex, isFrequency, isFunction, isHash, isHexColor, isHueInterpolationMethod, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPolarColorspace, isPseudo, isRectangularOrthogonalColorspace, isResolution, isTime, isWhiteSpace, mathFuncs, mediaTypes, mozExtensions, parseDimension, pseudoElements, transformFunctions, webkitExtensions, webkitPseudoAliasMap };
950
+ export { colorFontTech, fontFeaturesTech, fontFormat, isAngle, isAtKeyword, isColor, isColorspace, isDigit, isDimension, isFlex, isFrequency, isFunction, isHash, isHexColor, isHueInterpolationMethod, isIdent, isIdentCodepoint, isIdentColor, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPolarColorspace, isPseudo, isRectangularOrthogonalColorspace, isResolution, isTime, isWhiteSpace, mathFuncs, mediaTypes, mozExtensions, parseColor, parseDimension, pseudoAliasMap, pseudoElements, transformFunctions, webkitExtensions, wildCardFuncs };