@tbela99/css-parser 0.9.1 → 1.1.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 (99) hide show
  1. package/CHANGELOG.md +265 -0
  2. package/LICENSE.md +1 -1
  3. package/README.md +29 -17
  4. package/dist/index-umd-web.js +7461 -4360
  5. package/dist/index.cjs +8608 -5507
  6. package/dist/index.d.ts +203 -61
  7. package/dist/lib/ast/expand.js +2 -1
  8. package/dist/lib/ast/features/calc.js +19 -11
  9. package/dist/lib/ast/features/index.js +1 -0
  10. package/dist/lib/ast/features/inlinecssvariables.js +47 -29
  11. package/dist/lib/ast/features/prefix.js +117 -91
  12. package/dist/lib/ast/features/shorthand.js +34 -14
  13. package/dist/lib/ast/features/transform.js +67 -0
  14. package/dist/lib/ast/features/type.js +7 -0
  15. package/dist/lib/ast/math/expression.js +20 -10
  16. package/dist/lib/ast/math/math.js +20 -2
  17. package/dist/lib/ast/minify.js +209 -80
  18. package/dist/lib/ast/transform/compute.js +337 -0
  19. package/dist/lib/ast/transform/convert.js +33 -0
  20. package/dist/lib/ast/transform/matrix.js +112 -0
  21. package/dist/lib/ast/transform/minify.js +296 -0
  22. package/dist/lib/ast/transform/perspective.js +10 -0
  23. package/dist/lib/ast/transform/rotate.js +40 -0
  24. package/dist/lib/ast/transform/scale.js +32 -0
  25. package/dist/lib/ast/transform/skew.js +23 -0
  26. package/dist/lib/ast/transform/translate.js +32 -0
  27. package/dist/lib/ast/transform/utils.js +198 -0
  28. package/dist/lib/ast/types.js +18 -15
  29. package/dist/lib/ast/walk.js +54 -22
  30. package/dist/lib/fs/resolve.js +10 -0
  31. package/dist/lib/parser/declaration/list.js +48 -45
  32. package/dist/lib/parser/declaration/map.js +1 -0
  33. package/dist/lib/parser/declaration/set.js +2 -1
  34. package/dist/lib/parser/parse.js +449 -340
  35. package/dist/lib/parser/tokenize.js +147 -72
  36. package/dist/lib/parser/utils/declaration.js +5 -4
  37. package/dist/lib/parser/utils/type.js +2 -1
  38. package/dist/lib/renderer/color/a98rgb.js +2 -1
  39. package/dist/lib/renderer/color/{colormix.js → color-mix.js} +16 -7
  40. package/dist/lib/renderer/color/color.js +264 -170
  41. package/dist/lib/renderer/color/hex.js +19 -8
  42. package/dist/lib/renderer/color/hsl.js +9 -3
  43. package/dist/lib/renderer/color/hwb.js +2 -1
  44. package/dist/lib/renderer/color/lab.js +10 -1
  45. package/dist/lib/renderer/color/lch.js +10 -1
  46. package/dist/lib/renderer/color/oklab.js +10 -1
  47. package/dist/lib/renderer/color/oklch.js +10 -1
  48. package/dist/lib/renderer/color/p3.js +2 -1
  49. package/dist/lib/renderer/color/rec2020.js +2 -1
  50. package/dist/lib/renderer/color/relativecolor.js +27 -32
  51. package/dist/lib/renderer/color/rgb.js +14 -10
  52. package/dist/lib/renderer/color/srgb.js +48 -23
  53. package/dist/lib/renderer/color/utils/components.js +18 -6
  54. package/dist/lib/renderer/color/utils/constants.js +47 -3
  55. package/dist/lib/renderer/color/xyz.js +2 -1
  56. package/dist/lib/renderer/color/xyzd50.js +2 -1
  57. package/dist/lib/renderer/render.js +108 -43
  58. package/dist/lib/syntax/syntax.js +267 -136
  59. package/dist/lib/validation/at-rules/container.js +81 -103
  60. package/dist/lib/validation/at-rules/counter-style.js +9 -8
  61. package/dist/lib/validation/at-rules/custom-media.js +13 -15
  62. package/dist/lib/validation/at-rules/document.js +22 -27
  63. package/dist/lib/validation/at-rules/font-feature-values.js +8 -8
  64. package/dist/lib/validation/at-rules/import.js +30 -81
  65. package/dist/lib/validation/at-rules/keyframes.js +19 -23
  66. package/dist/lib/validation/at-rules/layer.js +5 -5
  67. package/dist/lib/validation/at-rules/media.js +42 -53
  68. package/dist/lib/validation/at-rules/namespace.js +19 -23
  69. package/dist/lib/validation/at-rules/page-margin-box.js +15 -18
  70. package/dist/lib/validation/at-rules/page.js +8 -7
  71. package/dist/lib/validation/at-rules/supports.js +73 -82
  72. package/dist/lib/validation/at-rules/when.js +32 -36
  73. package/dist/lib/validation/atrule.js +15 -18
  74. package/dist/lib/validation/config.js +24 -1
  75. package/dist/lib/validation/config.json.js +563 -63
  76. package/dist/lib/validation/parser/parse.js +196 -185
  77. package/dist/lib/validation/parser/types.js +1 -1
  78. package/dist/lib/validation/selector.js +8 -5
  79. package/dist/lib/validation/syntax.js +724 -1405
  80. package/dist/lib/validation/syntaxes/complex-selector-list.js +10 -11
  81. package/dist/lib/validation/syntaxes/complex-selector.js +10 -11
  82. package/dist/lib/validation/syntaxes/compound-selector.js +40 -50
  83. package/dist/lib/validation/syntaxes/family-name.js +9 -8
  84. package/dist/lib/validation/syntaxes/keyframe-block-list.js +6 -5
  85. package/dist/lib/validation/syntaxes/keyframe-selector.js +23 -105
  86. package/dist/lib/validation/syntaxes/layer-name.js +6 -5
  87. package/dist/lib/validation/syntaxes/relative-selector-list.js +7 -6
  88. package/dist/lib/validation/syntaxes/relative-selector.js +17 -15
  89. package/dist/lib/validation/syntaxes/url.js +18 -22
  90. package/dist/lib/validation/utils/list.js +20 -2
  91. package/dist/lib/validation/utils/whitespace.js +2 -1
  92. package/dist/node/index.js +4 -2
  93. package/dist/node/load.js +6 -1
  94. package/dist/web/index.js +4 -2
  95. package/dist/web/load.js +5 -0
  96. package/package.json +16 -15
  97. package/dist/lib/renderer/color/prophotoRgb.js +0 -56
  98. package/dist/lib/validation/declaration.js +0 -94
  99. package/dist/lib/validation/syntaxes/image.js +0 -29
@@ -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
@@ -19,17 +21,46 @@ const dimensionUnits = new Set([
19
21
  const fontFormat = ['collection', 'embedded-opentype', 'opentype', 'svg', 'truetype', 'woff', 'woff2'];
20
22
  const colorFontTech = ['color-colrv0', 'color-colrv1', 'color-svg', 'color-sbix', 'color-cbdt'];
21
23
  const fontFeaturesTech = ['features-opentype', 'features-aat', 'features-graphite', 'incremental-patch', 'incremental-range', 'incremental-auto', 'variations', 'palettes'];
24
+ const transformFunctions = [
25
+ 'translate', 'scale', 'rotate', 'skew', 'perspective',
26
+ 'translateX', 'translateY', 'translateZ',
27
+ 'scaleX', 'scaleY', 'scaleZ',
28
+ 'rotateX', 'rotateY', 'rotateZ',
29
+ 'skewX', 'skewY',
30
+ 'rotate3d', 'translate3d', 'scale3d', 'matrix', 'matrix3d'
31
+ ];
22
32
  // https://drafts.csswg.org/mediaqueries/#media-types
23
33
  const mediaTypes = ['all', 'print', 'screen',
24
34
  /* deprecated */
25
35
  'aural', 'braille', 'embossed', 'handheld', 'projection', 'tty', 'tv', 'speech'];
26
36
  // https://www.w3.org/TR/css-values-4/#math-function
27
- 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'];
28
39
  const pseudoElements = [':before', ':after', ':first-line', ':first-letter'];
29
- const webkitPseudoAliasMap = {
30
- '-webkit-autofill': 'autofill',
31
- '-webkit-any': 'is',
32
- '-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
+ '-ms-grid-columns': 'grid-template-columns',
44
+ '-ms-grid-rows': 'grid-template-rows',
45
+ '-ms-grid-row': 'grid-row-start',
46
+ '-ms-grid-column': 'grid-column-start',
47
+ '-ms-grid-row-align': 'align-self',
48
+ '-ms-grid-row-span': 'grid-row-end',
49
+ '-ms-grid-column-span': 'grid-column-end',
50
+ '-ms-grid-column-align': 'justify-self',
51
+ ':-ms-input-placeholder': '::placeholder',
52
+ '::-ms-input-placeholder': '::placeholder',
53
+ ':-moz-any()': ':is',
54
+ '-moz-user-modify': 'user-modify',
55
+ '-moz-background-clip': 'background-clip',
56
+ '-moz-background-origin': 'background-origin',
57
+ '-ms-input-placeholder': 'placeholder',
58
+ ':-webkit-autofill': ':autofill',
59
+ ':-webkit-any()': ':is',
60
+ '::-webkit-input-placeholder': '::placeholder',
61
+ '::-webkit-file-upload-button': '::file-selector-button',
62
+ '::-moz-placeholder': '::placeholder',
63
+ ':-webkit-any-link': ':any-link',
33
64
  '-webkit-border-after': 'border-block-end',
34
65
  '-webkit-border-after-color': 'border-block-end-color',
35
66
  '-webkit-border-after-style': 'border-block-end-style',
@@ -66,7 +97,75 @@ const webkitPseudoAliasMap = {
66
97
  '-webkit-padding-end': 'padding-inline-end',
67
98
  '-webkit-padding-start': 'padding-inline-start',
68
99
  '-webkit-min-device-pixel-ratio': 'min-resolution',
69
- '-webkit-max-device-pixel-ratio': 'max-resolution'
100
+ '-webkit-max-device-pixel-ratio': 'max-resolution',
101
+ '-webkit-font-smoothing': 'font-smooth',
102
+ '-webkit-line-clamp': 'line-clamp',
103
+ ':-webkit-autofill-strong-password': ':autofill',
104
+ ':-webkit-full-page-media': ':fullscreen',
105
+ ':-webkit-full-screen': ':fullscreen',
106
+ ':-webkit-full-screen-ancestor': ':fullscreen',
107
+ ':-webkit-full-screen-document': ':fullscreen',
108
+ ':-webkit-full-screen-controls-hidden': ':fullscreen',
109
+ '-moz-background-inline-policy': 'box-decoration-break',
110
+ '-moz-background-size': 'background-size',
111
+ '-moz-border-end': 'border-inline-end',
112
+ '-moz-border-end-color': 'border-inline-end-color',
113
+ '-moz-border-end-style': 'border-inline-end-style',
114
+ '-moz-border-end-width': 'border-inline-end-width',
115
+ '-moz-border-image': 'border-inline-end-width',
116
+ '-moz-border-start': 'border-inline-start',
117
+ '-moz-border-start-color': 'border-inline-start-color',
118
+ '-moz-border-start-style': 'border-inline-start-style',
119
+ '-moz-border-start-width': 'border-inline-start-width',
120
+ '-moz-column-count': 'column-count',
121
+ '-moz-column-fill': 'column-fill',
122
+ '-moz-column-gap': 'column-gap',
123
+ '-moz-column-width': 'column-width',
124
+ '-moz-column-rule': 'column-rule',
125
+ '-moz-column-rule-width': 'column-rule-width',
126
+ '-moz-column-rule-style': 'column-rule-style',
127
+ '-moz-column-rule-color': 'column-rule-color',
128
+ '-moz-margin-end': 'margin-inline-end',
129
+ '-moz-margin-start': 'margin-inline-start',
130
+ '-moz-opacity': 'opacity',
131
+ '-moz-outline': 'outline',
132
+ '-moz-outline-color': 'outline-color',
133
+ '-moz-outline-offset': 'outline-offset',
134
+ '-moz-outline-style': 'outline-style',
135
+ '-moz-outline-width': 'outline-width',
136
+ '-moz-padding-end': 'padding-inline-end',
137
+ '-moz-padding-start': 'padding-inline-start',
138
+ '-moz-tab-size': 'tab-size',
139
+ '-moz-text-align-last': 'text-align-last',
140
+ '-moz-text-decoration-color': 'text-decoration-color',
141
+ '-moz-text-decoration-line': 'text-decoration-line',
142
+ '-moz-text-decoration-style': 'text-decoration-style',
143
+ '-moz-transition': 'transition',
144
+ '-moz-transition-delay': 'transition-delay',
145
+ '-moz-transition-duration': 'transition-duration',
146
+ '-moz-transition-property': 'transition-property',
147
+ '-moz-transition-timing-function': 'transition-timing-function',
148
+ '-moz-user-select': 'user-select',
149
+ '-moz-initial': 'initial',
150
+ '-moz-linear-gradient()': 'linear-gradient',
151
+ '-moz-radial-gradient()': 'radial-gradient',
152
+ '-moz-element()': 'element',
153
+ '-moz-crisp-edges': 'crisp-edges',
154
+ '-moz-calc()': 'calc',
155
+ '-moz-min-content': 'min-content',
156
+ '-moz-fit-content': 'fit-content',
157
+ '-moz-max-content': 'max-content',
158
+ '-moz-available': 'stretch',
159
+ ':-moz-any-link': ':any-link',
160
+ ':-moz-full-screen': ':fullscreen',
161
+ ':-moz-full-screen-ancestor': ':fullscreen',
162
+ ':-moz-placeholder': ':placeholder-shown',
163
+ ':-moz-read-only': ':read-only',
164
+ ':-moz-read-write': ':read-write',
165
+ ':-moz-submit-invalid': ':invalid',
166
+ ':-moz-ui-invalid': ':user-invalid',
167
+ ':-moz-ui-valid': ':user-valid',
168
+ '::-moz-selection': '::selection',
70
169
  };
71
170
  // https://developer.mozilla.org/en-US/docs/Web/CSS/WebKit_Extensions
72
171
  // https://developer.mozilla.org/en-US/docs/Web/CSS/::-webkit-scrollbar
@@ -400,148 +499,205 @@ function isHueInterpolationMethod(token) {
400
499
  }
401
500
  return ['shorter', 'longer', 'increasing', 'decreasing'].includes(token.val);
402
501
  }
502
+ function isIdentColor(token) {
503
+ return token.typ == EnumToken.ColorTokenType && [ColorKind.SYS, ColorKind.DPSYS, ColorKind.LIT].includes(token.kin) && isIdent(token.val);
504
+ }
403
505
  function isColor(token) {
404
- if (token.typ == EnumToken.ColorTokenType) {
405
- return true;
406
- }
407
506
  if (token.typ == EnumToken.IdenTokenType) {
408
507
  // named color
409
508
  return token.val.toLowerCase() in COLORS_NAMES;
410
509
  }
411
510
  let isLegacySyntax = false;
412
- if (token.typ == EnumToken.FunctionTokenType && token.chi.length > 0 && colorsFunc.includes(token.val)) {
413
- if (token.val == 'light-dark') {
414
- const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
415
- if (children.length != 2) {
416
- return false;
417
- }
418
- if (isColor(children[0]) && isColor(children[1])) {
419
- return true;
420
- }
511
+ if (token.typ == EnumToken.FunctionTokenType) {
512
+ if (!colorsFunc.includes(token.val.toLowerCase())) {
513
+ return false;
421
514
  }
422
- if (token.val == 'color') {
423
- const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
424
- const isRelative = children[0].typ == EnumToken.IdenTokenType && children[0].val == 'from';
425
- if (children.length < 4 || children.length > 8) {
426
- return false;
427
- }
428
- if (!isRelative && !isColorspace(children[0])) {
429
- return false;
430
- }
431
- for (let i = 1; i < children.length - 2; i++) {
432
- if (children[i].typ == EnumToken.IdenTokenType) {
433
- if (children[i].val != 'none' &&
434
- !(isRelative && ['alpha', 'r', 'g', 'b', 'x', 'y', 'z'].includes(children[i].val) || isColorspace(children[i]))) {
435
- return false;
436
- }
437
- }
438
- if (children[i].typ == EnumToken.FunctionTokenType && !mathFuncs.includes(children[i].val)) {
515
+ if (token.chi.length > 0) {
516
+ // @ts-ignore
517
+ if (token.val == 'light-dark') {
518
+ // @ts-ignore
519
+ const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
520
+ if (children.length != 2) {
439
521
  return false;
440
522
  }
523
+ if (isColor(children[0]) && isColor(children[1])) {
524
+ return true;
525
+ }
441
526
  }
442
- if (children.length == 4 || (isRelative && children.length == 6)) {
443
- return true;
527
+ // adding numbers and percentages is disallowed
528
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/lch#defining_relative_color_output_channel_components
529
+ // @ts-ignore
530
+ for (const { value } of walkValues(token.chi, null, (node) => funcLike.includes(node.typ) ? WalkerOptionEnum.IgnoreChildren : null)) {
531
+ if (funcLike.includes(value.typ)) {
532
+ for (const { value: val } of walkValues([buildExpression(value.chi)])) {
533
+ if (val.typ == EnumToken.BinaryExpressionTokenType &&
534
+ (val.l.typ == EnumToken.PercentageTokenType || val.r.typ == EnumToken.PercentageTokenType) &&
535
+ ((val.r.typ == EnumToken.PercentageTokenType && val.op == EnumToken.Div) ||
536
+ ((val.op == EnumToken.Add || val.op == EnumToken.Sub) &&
537
+ val.l.typ != val.r.typ))) {
538
+ return false;
539
+ }
540
+ }
541
+ }
444
542
  }
445
- if (children.length == 8 || children.length == 6) {
446
- const sep = children.at(-2);
447
- const alpha = children.at(-1);
543
+ // @ts-ignore
544
+ if (token.val == 'color') {
448
545
  // @ts-ignore
449
- if ((children.length > 6 || !isRelative) && sep.typ != EnumToken.LiteralTokenType || sep.val != '/') {
546
+ const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
547
+ const isRelative = children[0].typ == EnumToken.IdenTokenType && children[0].val == 'from';
548
+ if (children.length < 4 || children.length > 8) {
450
549
  return false;
451
550
  }
452
- if (alpha.typ == EnumToken.IdenTokenType && alpha.val != 'none') {
551
+ if (!isRelative && !isColorspace(children[0])) {
453
552
  return false;
454
553
  }
455
- else {
456
- // @ts-ignore
457
- if (alpha.typ == EnumToken.PercentageTokenType) {
458
- if (+alpha.val < 0 || +alpha.val > 100) {
459
- return false;
460
- }
461
- }
462
- else if (alpha.typ == EnumToken.NumberTokenType) {
463
- if (+alpha.val < 0 || +alpha.val > 1) {
554
+ for (let i = 1; i < children.length - 2; i++) {
555
+ if (children[i].typ == EnumToken.IdenTokenType) {
556
+ if (children[i].val != 'none' &&
557
+ !(isRelative && ['alpha', 'r', 'g', 'b', 'x', 'y', 'z'].includes(children[i].val) || isColorspace(children[i]))) {
464
558
  return false;
465
559
  }
466
560
  }
467
- }
468
- }
469
- return true;
470
- }
471
- else if (token.val == 'color-mix') {
472
- const children = token.chi.reduce((acc, t) => {
473
- if (t.typ == EnumToken.CommaTokenType) {
474
- acc.push([]);
475
- }
476
- else {
477
- if (![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)) {
478
- acc[acc.length - 1].push(t);
561
+ if (children[i].typ == EnumToken.FunctionTokenType && !mathFuncs.includes(children[i].val)) {
562
+ return false;
479
563
  }
480
564
  }
481
- return acc;
482
- }, [[]]);
483
- if (children.length == 3) {
484
- if (children[0].length > 3 ||
485
- children[0][0].typ != EnumToken.IdenTokenType ||
486
- children[0][0].val != 'in' ||
487
- !isColorspace(children[0][1]) ||
488
- (children[0].length == 3 && !isHueInterpolationMethod(children[0][2])) ||
489
- children[1].length > 2 ||
490
- children[1][0].typ != EnumToken.ColorTokenType ||
491
- children[2].length > 2 ||
492
- children[2][0].typ != EnumToken.ColorTokenType) {
493
- return false;
565
+ if (children.length == 4 || (isRelative && children.length == 6)) {
566
+ return true;
494
567
  }
495
- if (children[1].length == 2) {
496
- if (!(children[1][1].typ == EnumToken.PercentageTokenType || (children[1][1].typ == EnumToken.NumberTokenType && children[1][1].val == '0'))) {
568
+ if (children.length == 8 || children.length == 6) {
569
+ const sep = children.at(-2);
570
+ const alpha = children.at(-1);
571
+ // @ts-ignore
572
+ if ((children.length > 6 || !isRelative) && sep.typ != EnumToken.LiteralTokenType || sep.val != '/') {
497
573
  return false;
498
574
  }
499
- }
500
- if (children[2].length == 2) {
501
- if (!(children[2][1].typ == EnumToken.PercentageTokenType || (children[2][1].typ == EnumToken.NumberTokenType && children[2][1].val == '0'))) {
575
+ if (alpha.typ == EnumToken.IdenTokenType && alpha.val != 'none') {
502
576
  return false;
503
577
  }
578
+ else {
579
+ // @ts-ignore
580
+ if (alpha.typ == EnumToken.PercentageTokenType) {
581
+ if (+alpha.val < 0 || +alpha.val > 100) {
582
+ return false;
583
+ }
584
+ }
585
+ else if (alpha.typ == EnumToken.NumberTokenType) {
586
+ if (+alpha.val < 0 || +alpha.val > 1) {
587
+ return false;
588
+ }
589
+ }
590
+ }
504
591
  }
505
592
  return true;
506
593
  }
507
- return false;
508
- }
509
- else {
510
- const keywords = ['from', 'none'];
511
- if (['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch'].includes(token.val)) {
512
- keywords.push('alpha', ...token.val.slice(-3).split(''));
513
- }
514
- // @ts-ignore
515
- for (const v of token.chi) {
516
- if (v.typ == EnumToken.CommaTokenType) {
517
- isLegacySyntax = true;
594
+ else { // @ts-ignore
595
+ if (token.val == 'color-mix') {
596
+ // @ts-ignore
597
+ const children = token.chi.reduce((acc, t) => {
598
+ if (t.typ == EnumToken.CommaTokenType) {
599
+ acc.push([]);
600
+ }
601
+ else {
602
+ if (![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)) {
603
+ acc[acc.length - 1].push(t);
604
+ }
605
+ }
606
+ return acc;
607
+ }, [[]]);
608
+ if (children.length == 3) {
609
+ if (children[0].length > 3 ||
610
+ children[0][0].typ != EnumToken.IdenTokenType ||
611
+ children[0][0].val != 'in' ||
612
+ !isColorspace(children[0][1]) ||
613
+ (children[0].length == 3 && !isHueInterpolationMethod(children[0][2])) ||
614
+ children[1].length > 2 ||
615
+ children[1][0].typ != EnumToken.ColorTokenType ||
616
+ children[2].length > 2 ||
617
+ children[2][0].typ != EnumToken.ColorTokenType) {
618
+ return false;
619
+ }
620
+ if (children[1].length == 2) {
621
+ if (!(children[1][1].typ == EnumToken.PercentageTokenType || (children[1][1].typ == EnumToken.NumberTokenType && children[1][1].val == '0'))) {
622
+ return false;
623
+ }
624
+ }
625
+ if (children[2].length == 2) {
626
+ if (!(children[2][1].typ == EnumToken.PercentageTokenType || (children[2][1].typ == EnumToken.NumberTokenType && children[2][1].val == '0'))) {
627
+ return false;
628
+ }
629
+ }
630
+ return true;
631
+ }
632
+ return false;
518
633
  }
519
- if (v.typ == EnumToken.IdenTokenType) {
520
- if (!(keywords.includes(v.val) || v.val.toLowerCase() in COLORS_NAMES)) {
521
- return false;
634
+ else {
635
+ const keywords = ['from', 'none'];
636
+ // @ts-ignore
637
+ if (['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch'].includes(token.val)) {
638
+ // @ts-ignore
639
+ keywords.push('alpha', ...token.val.slice(-3).split(''));
522
640
  }
523
- if (keywords.includes(v.val)) {
524
- if (isLegacySyntax) {
525
- return false;
641
+ // @ts-ignore
642
+ for (const v of token.chi) {
643
+ if (v.typ == EnumToken.CommaTokenType) {
644
+ isLegacySyntax = true;
645
+ }
646
+ if (v.typ == EnumToken.IdenTokenType) {
647
+ if (!(keywords.includes(v.val) || v.val.toLowerCase() in COLORS_NAMES)) {
648
+ return false;
649
+ }
650
+ if (keywords.includes(v.val)) {
651
+ if (isLegacySyntax) {
652
+ return false;
653
+ }
654
+ // @ts-ignore
655
+ if (v.val == 'from' && ['rgba', 'hsla'].includes(token.val)) {
656
+ return false;
657
+ }
658
+ }
659
+ continue;
660
+ }
661
+ if (v.typ == EnumToken.FunctionTokenType && (mathFuncs.includes(v.val) || v.val == 'var' || colorsFunc.includes(v.val))) {
662
+ continue;
526
663
  }
527
- if (v.val == 'from' && ['rgba', 'hsla'].includes(token.val)) {
664
+ if (![EnumToken.ColorTokenType, EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType].includes(v.typ)) {
528
665
  return false;
529
666
  }
530
667
  }
531
- continue;
532
- }
533
- if (v.typ == EnumToken.FunctionTokenType && (mathFuncs.includes(v.val) || v.val == 'var' || colorsFunc.includes(v.val))) {
534
- continue;
535
- }
536
- if (![EnumToken.ColorTokenType, EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType].includes(v.typ)) {
537
- return false;
538
668
  }
539
669
  }
670
+ return true;
540
671
  }
541
- return true;
542
672
  }
543
673
  return false;
544
674
  }
675
+ function parseColor(token) {
676
+ // @ts-ignore
677
+ token.typ = EnumToken.ColorTokenType;
678
+ // @ts-ignore
679
+ token.kin = ColorKind[token.val.replaceAll('-', '_').toUpperCase()];
680
+ // @ts-ignore
681
+ if (token.chi[0].typ == EnumToken.IdenTokenType) {
682
+ // @ts-ignore
683
+ if (token.chi[0].val == 'from') {
684
+ // @ts-ignore
685
+ token.cal = 'rel';
686
+ }
687
+ // @ts-ignore
688
+ else if (token.val == 'color-mix' && token.chi[0].val == 'in') {
689
+ // @ts-ignore
690
+ token.cal = 'mix';
691
+ }
692
+ else { // @ts-ignore
693
+ if (token.val == 'color') {
694
+ // @ts-ignore
695
+ token.cal = 'col';
696
+ }
697
+ }
698
+ }
699
+ return token;
700
+ }
545
701
  function isLetter(codepoint) {
546
702
  // lowercase
547
703
  return (codepoint >= 0x61 && codepoint <= 0x7a) ||
@@ -771,31 +927,6 @@ function isHexColor(name) {
771
927
  }
772
928
  return true;
773
929
  }
774
- /*
775
- export function isHexDigit(name: string): boolean {
776
-
777
- if (name.length || name.length > 6) {
778
-
779
- return false;
780
- }
781
-
782
- for (let chr of name) {
783
-
784
- let codepoint = <number>chr.charCodeAt(0);
785
-
786
- if (!isDigit(codepoint) &&
787
- // A F
788
- !(codepoint >= 0x41 && codepoint <= 0x46) &&
789
- // a f
790
- !(codepoint >= 0x61 && codepoint <= 0x66)) {
791
-
792
- return false;
793
- }
794
- }
795
-
796
- return true;
797
- }
798
- */
799
930
  function isFunction(name) {
800
931
  return name.endsWith('(') && isIdent(name.slice(0, -1));
801
932
  }
@@ -812,4 +943,4 @@ function isWhiteSpace(codepoint) {
812
943
  codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
813
944
  }
814
945
 
815
- 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, webkitExtensions, webkitPseudoAliasMap };
946
+ 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 };