@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
@@ -2,12 +2,13 @@ import { EnumToken } from '../../ast/types.js';
2
2
  import '../../ast/minify.js';
3
3
  import '../../ast/walk.js';
4
4
  import '../../parser/parse.js';
5
+ import '../../parser/tokenize.js';
6
+ import '../../parser/utils/config.js';
5
7
  import { minmax, getNumber } from './color.js';
6
8
  import { hsl2rgb, hwb2rgb, cmyk2rgb, oklab2rgb, oklch2rgb, lab2rgb, lch2rgb } from './rgb.js';
7
9
  import { NAMES_COLORS } from './utils/constants.js';
8
10
  import { getComponents } from './utils/components.js';
9
11
  import '../sourcemap/lib/encode.js';
10
- import '../../parser/utils/config.js';
11
12
 
12
13
  function toHexString(acc, value) {
13
14
  return acc + value.toString(16).padStart(2, '0');
@@ -67,25 +68,35 @@ function rgb2hex(token) {
67
68
  return value;
68
69
  }
69
70
  function hsl2hex(token) {
70
- return `${hsl2rgb(token).reduce(toHexString, '#')}`;
71
+ const t = hsl2rgb(token);
72
+ return t == null ? null : `${t.reduce(toHexString, '#')}`;
71
73
  }
72
74
  function hwb2hex(token) {
73
- return `${hwb2rgb(token).reduce(toHexString, '#')}`;
75
+ const t = hwb2rgb(token);
76
+ return t == null ? null : `${t.reduce(toHexString, '#')}`;
74
77
  }
75
78
  function cmyk2hex(token) {
76
- return `#${cmyk2rgb(token).reduce(toHexString, '')}`;
79
+ const t = cmyk2rgb(token);
80
+ return t == null ? null : `#${t.reduce(toHexString, '')}`;
77
81
  }
78
82
  function oklab2hex(token) {
79
- return `${oklab2rgb(token).reduce(toHexString, '#')}`;
83
+ const t = oklab2rgb(token);
84
+ return t == null ? null : `${t.reduce(toHexString, '#')}`;
80
85
  }
81
86
  function oklch2hex(token) {
82
- return `${oklch2rgb(token).reduce(toHexString, '#')}`;
87
+ const value = oklch2rgb(token);
88
+ if (value == null) {
89
+ return null;
90
+ }
91
+ return `${value.reduce(toHexString, '#')}`;
83
92
  }
84
93
  function lab2hex(token) {
85
- return `${lab2rgb(token).reduce(toHexString, '#')}`;
94
+ const t = lab2rgb(token);
95
+ return t == null ? null : `${t.reduce(toHexString, '#')}`;
86
96
  }
87
97
  function lch2hex(token) {
88
- return `${lch2rgb(token).reduce(toHexString, '#')}`;
98
+ const t = lch2rgb(token);
99
+ return t == null ? null : `${t.reduce(toHexString, '#')}`;
89
100
  }
90
101
  function srgb2hexvalues(r, g, b, alpha) {
91
102
  return [r, g, b].concat(alpha == null || alpha == 1 ? [] : [alpha]).reduce((acc, value) => acc + minmax(Math.round(255 * value), 0, 255).toString(16).padStart(2, '0'), '#');
@@ -7,9 +7,10 @@ import { EnumToken } from '../../ast/types.js';
7
7
  import '../../ast/minify.js';
8
8
  import '../../ast/walk.js';
9
9
  import '../../parser/parse.js';
10
+ import '../../parser/tokenize.js';
11
+ import '../../parser/utils/config.js';
10
12
  import { hslvalues } from './srgb.js';
11
13
  import '../sourcemap/lib/encode.js';
12
- import '../../parser/utils/config.js';
13
14
 
14
15
  function hex2hsl(token) {
15
16
  // @ts-ignore
@@ -17,6 +18,9 @@ function hex2hsl(token) {
17
18
  }
18
19
  function rgb2hsl(token) {
19
20
  const chi = getComponents(token);
21
+ if (chi == null) {
22
+ return null;
23
+ }
20
24
  // @ts-ignore
21
25
  let t = chi[0];
22
26
  // @ts-ignore
@@ -75,12 +79,14 @@ function lch2hsl(token) {
75
79
  return rgb2hslvalues(...lch2rgb(token));
76
80
  }
77
81
  function oklab2hsl(token) {
82
+ const t = oklab2rgb(token);
78
83
  // @ts-ignore
79
- return rgb2hslvalues(...oklab2rgb(token));
84
+ return t == null ? null : rgb2hslvalues(...t);
80
85
  }
81
86
  function oklch2hsl(token) {
87
+ const t = oklch2rgb(token);
82
88
  // @ts-ignore
83
- return rgb2hslvalues(...oklch2rgb(token));
89
+ return t == null ? null : rgb2hslvalues(...t);
84
90
  }
85
91
  function rgb2hslvalues(r, g, b, a = null) {
86
92
  return srgb2hsl(r / 255, g / 255, b / 255, a);
@@ -6,9 +6,10 @@ import { EnumToken } from '../../ast/types.js';
6
6
  import '../../ast/minify.js';
7
7
  import '../../ast/walk.js';
8
8
  import '../../parser/parse.js';
9
+ import '../../parser/tokenize.js';
10
+ import '../../parser/utils/config.js';
9
11
  import { lch2srgb, lab2srgb, oklch2srgb, oklab2srgb } from './srgb.js';
10
12
  import '../sourcemap/lib/encode.js';
11
- import '../../parser/utils/config.js';
12
13
 
13
14
  function rgb2hwb(token) {
14
15
  // @ts-ignore
@@ -9,9 +9,10 @@ import { EnumToken } from '../../ast/types.js';
9
9
  import '../../ast/minify.js';
10
10
  import '../../ast/walk.js';
11
11
  import '../../parser/parse.js';
12
+ import '../../parser/tokenize.js';
13
+ import '../../parser/utils/config.js';
12
14
  import { xyzd502srgb } from './xyzd50.js';
13
15
  import '../sourcemap/lib/encode.js';
14
- import '../../parser/utils/config.js';
15
16
 
16
17
  // L: 0% = 0.0, 100% = 100.0
17
18
  // for a and b: -100% = -125, 100% = 125
@@ -87,6 +88,14 @@ function lch2labvalues(l, c, h, a = null) {
87
88
  }
88
89
  function getLABComponents(token) {
89
90
  const components = getComponents(token);
91
+ if (components == null) {
92
+ return null;
93
+ }
94
+ for (let i = 0; i < components.length; i++) {
95
+ if (![EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.AngleTokenType, EnumToken.IdenTokenType].includes(components[i].typ)) {
96
+ return [];
97
+ }
98
+ }
90
99
  // @ts-ignore
91
100
  let t = components[0];
92
101
  // @ts-ignore
@@ -5,9 +5,10 @@ import { EnumToken } from '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
6
  import '../../ast/walk.js';
7
7
  import '../../parser/parse.js';
8
+ import '../../parser/tokenize.js';
9
+ import '../../parser/utils/config.js';
8
10
  import { srgb2lab, xyz2lab, oklch2lab, oklab2lab, getLABComponents, hwb2lab, hsl2lab, rgb2lab, hex2lab } from './lab.js';
9
11
  import '../sourcemap/lib/encode.js';
10
- import '../../parser/utils/config.js';
11
12
 
12
13
  function hex2lch(token) {
13
14
  // @ts-ignore
@@ -59,6 +60,14 @@ function xyz2lchvalues(x, y, z, alpha) {
59
60
  }
60
61
  function getLCHComponents(token) {
61
62
  const components = getComponents(token);
63
+ if (components == null) {
64
+ return null;
65
+ }
66
+ for (let i = 0; i < components.length; i++) {
67
+ if (![EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.AngleTokenType, EnumToken.IdenTokenType].includes(components[i].typ)) {
68
+ return null;
69
+ }
70
+ }
62
71
  // @ts-ignore
63
72
  let t = components[0];
64
73
  // @ts-ignore
@@ -7,10 +7,11 @@ import { EnumToken } from '../../ast/types.js';
7
7
  import '../../ast/minify.js';
8
8
  import '../../ast/walk.js';
9
9
  import '../../parser/parse.js';
10
+ import '../../parser/tokenize.js';
11
+ import '../../parser/utils/config.js';
10
12
  import { lch2labvalues } from './lab.js';
11
13
  import { getOKLCHComponents } from './oklch.js';
12
14
  import '../sourcemap/lib/encode.js';
13
- import '../../parser/utils/config.js';
14
15
 
15
16
  function hex2oklab(token) {
16
17
  // @ts-ignore
@@ -52,6 +53,14 @@ function srgb2oklab(r, g, blue, alpha) {
52
53
  }
53
54
  function getOKLABComponents(token) {
54
55
  const components = getComponents(token);
56
+ if (components == null) {
57
+ return null;
58
+ }
59
+ for (let i = 0; i < components.length; i++) {
60
+ if (![EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.AngleTokenType, EnumToken.IdenTokenType].includes(components[i].typ)) {
61
+ return null;
62
+ }
63
+ }
55
64
  // @ts-ignore
56
65
  let t = components[0];
57
66
  // @ts-ignore
@@ -5,10 +5,11 @@ import { EnumToken } from '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
6
  import '../../ast/walk.js';
7
7
  import '../../parser/parse.js';
8
+ import '../../parser/tokenize.js';
9
+ import '../../parser/utils/config.js';
8
10
  import { lab2lchvalues } from './lch.js';
9
11
  import { srgb2oklab, lch2oklab, getOKLABComponents, lab2oklab, hwb2oklab, hsl2oklab, rgb2oklab, hex2oklab } from './oklab.js';
10
12
  import '../sourcemap/lib/encode.js';
11
- import '../../parser/utils/config.js';
12
13
 
13
14
  function hex2oklch(token) {
14
15
  // @ts-ignore
@@ -44,6 +45,14 @@ function srgb2oklch(r, g, blue, alpha) {
44
45
  }
45
46
  function getOKLCHComponents(token) {
46
47
  const components = getComponents(token);
48
+ if (components == null) {
49
+ return null;
50
+ }
51
+ for (let i = 0; i < components.length; i++) {
52
+ if (![EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.AngleTokenType, EnumToken.IdenTokenType].includes(components[i].typ)) {
53
+ return [];
54
+ }
55
+ }
47
56
  // @ts-ignore
48
57
  let t = components[0];
49
58
  // @ts-ignore
@@ -5,9 +5,10 @@ import '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
6
  import '../../ast/walk.js';
7
7
  import '../../parser/parse.js';
8
+ import '../../parser/tokenize.js';
9
+ import '../../parser/utils/config.js';
8
10
  import { srgb2xyz } from './xyz.js';
9
11
  import '../sourcemap/lib/encode.js';
10
- import '../../parser/utils/config.js';
11
12
 
12
13
  function p32srgbvalues(r, g, b, alpha) {
13
14
  // @ts-ignore
@@ -5,9 +5,10 @@ import '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
6
  import '../../ast/walk.js';
7
7
  import '../../parser/parse.js';
8
+ import '../../parser/tokenize.js';
9
+ import '../../parser/utils/config.js';
8
10
  import { srgb2xyz } from './xyz.js';
9
11
  import '../sourcemap/lib/encode.js';
10
- import '../../parser/utils/config.js';
11
12
 
12
13
  function rec20202srgb(r, g, b, a) {
13
14
  // @ts-ignore
@@ -3,11 +3,12 @@ import { EnumToken } from '../../ast/types.js';
3
3
  import '../../ast/minify.js';
4
4
  import { walkValues } from '../../ast/walk.js';
5
5
  import '../../parser/parse.js';
6
- import { mathFuncs } from '../../syntax/syntax.js';
6
+ import '../../parser/tokenize.js';
7
7
  import '../../parser/utils/config.js';
8
+ import { mathFuncs } from '../../syntax/syntax.js';
8
9
  import { reduceNumber } from '../render.js';
10
+ import { ColorKind, colorRange } from './utils/constants.js';
9
11
  import { evaluateFunc, evaluate } from '../../ast/math/expression.js';
10
- import { colorRange } from './utils/constants.js';
11
12
 
12
13
  function parseRelativeColor(relativeKeys, original, rExp, gExp, bExp, aExp) {
13
14
  let r;
@@ -18,21 +19,23 @@ function parseRelativeColor(relativeKeys, original, rExp, gExp, bExp, aExp) {
18
19
  let values = {};
19
20
  // colorFuncColorSpace x,y,z or r,g,b
20
21
  const names = relativeKeys.startsWith('xyz') ? 'xyz' : relativeKeys.slice(-3);
21
- // @ts-ignore
22
- const converted = convert(original, relativeKeys);
22
+ const converted = convert(original, ColorKind[relativeKeys.toUpperCase().replaceAll('-', '_')]);
23
23
  if (converted == null) {
24
24
  return null;
25
25
  }
26
26
  const children = converted.chi.filter(t => ![EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType, EnumToken.CommentTokenType].includes(t.typ));
27
- [r, g, b, alpha] = converted.kin == 'color' ? children.slice(1) : children;
27
+ [r, g, b, alpha] = converted.kin == ColorKind.COLOR ? children.slice(1) : children;
28
28
  values = {
29
29
  [names[0]]: getValue(r, converted, names[0]),
30
30
  [names[1]]: getValue(g, converted, names[1]), // string,
31
31
  [names[2]]: getValue(b, converted, names[2]),
32
32
  // @ts-ignore
33
- alpha: alpha == null || (alpha.typ == EnumToken.IdenTokenType && alpha.val == 'none') ? {
33
+ alpha: alpha == null ? {
34
34
  typ: EnumToken.NumberTokenType,
35
35
  val: '1'
36
+ } : (alpha.typ == EnumToken.IdenTokenType && alpha.val == 'none') ? {
37
+ typ: EnumToken.NumberTokenType,
38
+ val: '0'
36
39
  } : (alpha.typ == EnumToken.PercentageTokenType ? {
37
40
  typ: EnumToken.NumberTokenType,
38
41
  val: String(getNumber(alpha))
@@ -43,9 +46,12 @@ function parseRelativeColor(relativeKeys, original, rExp, gExp, bExp, aExp) {
43
46
  [names[1]]: getValue(gExp, converted, names[1]),
44
47
  [names[2]]: getValue(bExp, converted, names[2]),
45
48
  // @ts-ignore
46
- alpha: getValue(aExp == null || (aExp.typ == EnumToken.IdenTokenType && aExp.val == 'none') ? {
49
+ alpha: getValue(aExp == null ? {
47
50
  typ: EnumToken.NumberTokenType,
48
51
  val: '1'
52
+ } : (aExp.typ == EnumToken.IdenTokenType && aExp.val == 'none') ? {
53
+ typ: EnumToken.NumberTokenType,
54
+ val: '0'
49
55
  } : aExp)
50
56
  };
51
57
  return computeComponentValue(keys, converted, values);
@@ -56,9 +62,10 @@ function getValue(t, converted, component) {
56
62
  }
57
63
  if (t.typ == EnumToken.PercentageTokenType) {
58
64
  let value = getNumber(t);
59
- if (converted.kin in colorRange) {
65
+ let colorSpace = ColorKind[converted.kin].toLowerCase().replaceAll('-', '_');
66
+ if (colorSpace in colorRange) {
60
67
  // @ts-ignore
61
- value *= colorRange[converted.kin][component].at(-1);
68
+ value *= colorRange[colorSpace][component].at(-1);
62
69
  }
63
70
  return {
64
71
  typ: EnumToken.NumberTokenType,
@@ -71,7 +78,6 @@ function computeComponentValue(expr, converted, values) {
71
78
  for (const object of [values, expr]) {
72
79
  if ('h' in object) {
73
80
  // normalize hue
74
- // @ts-ignore
75
81
  for (const k of walkValues([object.h])) {
76
82
  if (k.value.typ == EnumToken.AngleTokenType && k.value.unit == 'deg') {
77
83
  // @ts-ignore
@@ -142,32 +148,21 @@ function computeComponentValue(expr, converted, values) {
142
148
  return expr;
143
149
  }
144
150
  function replaceValue(parent, value, newValue) {
145
- if (parent.typ == EnumToken.BinaryExpressionTokenType) {
146
- if (parent.l == value) {
147
- parent.l = newValue;
148
- }
149
- else {
150
- parent.r = newValue;
151
- }
152
- }
153
- else {
154
- for (let i = 0; i < parent.chi.length; i++) {
155
- if (parent.chi[i] == value) {
156
- parent.chi.splice(i, 1, newValue);
157
- break;
158
- }
159
- if (parent.chi[i].typ == EnumToken.BinaryExpressionTokenType) {
160
- if (parent.chi[i].l == value) {
161
- parent.chi[i].l = newValue;
162
- break;
151
+ for (const { value: val, parent: pr } of walkValues([parent])) {
152
+ if (val.typ == value.typ && val.val == value.val) {
153
+ if (pr.typ == EnumToken.BinaryExpressionTokenType) {
154
+ if (pr.l == val) {
155
+ pr.l = newValue;
163
156
  }
164
- else if (parent.chi[i].r == value) {
165
- parent.chi[i].r = newValue;
166
- break;
157
+ else {
158
+ pr.r = newValue;
167
159
  }
168
160
  }
161
+ else {
162
+ pr.chi.splice(pr.chi.indexOf(val), 1, newValue);
163
+ }
169
164
  }
170
165
  }
171
166
  }
172
167
 
173
- export { parseRelativeColor };
168
+ export { parseRelativeColor, replaceValue };
@@ -1,19 +1,20 @@
1
1
  import { minmax } from './color.js';
2
- import { COLORS_NAMES } from './utils/constants.js';
2
+ import { COLORS_NAMES, ColorKind } from './utils/constants.js';
3
3
  import '../../ast/types.js';
4
4
  import '../../ast/minify.js';
5
5
  import '../../ast/walk.js';
6
6
  import '../../parser/parse.js';
7
+ import '../../parser/tokenize.js';
8
+ import '../../parser/utils/config.js';
7
9
  import { expandHexValue } from './hex.js';
8
10
  import { hslvalues, hsl2srgbvalues, hwb2srgb, cmyk2srgb, oklab2srgb, oklch2srgb, lab2srgb, lch2srgb } from './srgb.js';
9
11
  import '../sourcemap/lib/encode.js';
10
- import '../../parser/utils/config.js';
11
12
 
12
13
  function srgb2rgb(value) {
13
14
  return minmax(Math.round(value * 255), 0, 255);
14
15
  }
15
16
  function hex2rgb(token) {
16
- const value = expandHexValue(token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : token.val);
17
+ const value = expandHexValue(token.kin == ColorKind.LIT ? COLORS_NAMES[token.val.toLowerCase()] : token.val);
17
18
  const rgb = [];
18
19
  for (let i = 1; i < value.length; i += 2) {
19
20
  rgb.push(parseInt(value.slice(i, i + 2), 16));
@@ -21,26 +22,29 @@ function hex2rgb(token) {
21
22
  return rgb;
22
23
  }
23
24
  function hwb2rgb(token) {
24
- return hwb2srgb(token).map(srgb2rgb);
25
+ return hwb2srgb(token)?.map?.(srgb2rgb) ?? null;
25
26
  }
26
27
  function hsl2rgb(token) {
27
- let { h, s, l, a } = hslvalues(token);
28
+ let { h, s, l, a } = hslvalues(token) ?? {};
29
+ if (h == null || s == null || l == null) {
30
+ return null;
31
+ }
28
32
  return hsl2srgbvalues(h, s, l, a).map((t) => minmax(Math.round(t * 255), 0, 255));
29
33
  }
30
34
  function cmyk2rgb(token) {
31
- return cmyk2srgb(token).map(srgb2rgb);
35
+ return cmyk2srgb(token)?.map?.(srgb2rgb) ?? null;
32
36
  }
33
37
  function oklab2rgb(token) {
34
- return oklab2srgb(token).map(srgb2rgb);
38
+ return oklab2srgb(token)?.map?.(srgb2rgb) ?? null;
35
39
  }
36
40
  function oklch2rgb(token) {
37
- return oklch2srgb(token).map(srgb2rgb);
41
+ return oklch2srgb(token)?.map?.(srgb2rgb) ?? null;
38
42
  }
39
43
  function lab2rgb(token) {
40
- return lab2srgb(token).map(srgb2rgb);
44
+ return lab2srgb(token)?.map?.(srgb2rgb) ?? null;
41
45
  }
42
46
  function lch2rgb(token) {
43
- return lch2srgb(token).map(srgb2rgb);
47
+ return lch2srgb(token)?.map?.(srgb2rgb) ?? null;
44
48
  }
45
49
 
46
50
  export { cmyk2rgb, hex2rgb, hsl2rgb, hwb2rgb, lab2rgb, lch2rgb, oklab2rgb, oklch2rgb, srgb2rgb };
@@ -1,10 +1,12 @@
1
- import { COLORS_NAMES } from './utils/constants.js';
1
+ import { ColorKind, COLORS_NAMES } from './utils/constants.js';
2
2
  import { getComponents } from './utils/components.js';
3
3
  import { color2srgbvalues, getNumber, getAngle } from './color.js';
4
4
  import { EnumToken } from '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
6
  import '../../ast/walk.js';
7
7
  import '../../parser/parse.js';
8
+ import '../../parser/tokenize.js';
9
+ import '../../parser/utils/config.js';
8
10
  import { expandHexValue } from './hex.js';
9
11
  import { lch2labvalues, Lab_to_sRGB, getLABComponents } from './lab.js';
10
12
  import { OKLab_to_sRGB, getOKLABComponents } from './oklab.js';
@@ -12,42 +14,41 @@ import { getLCHComponents } from './lch.js';
12
14
  import { getOKLCHComponents } from './oklch.js';
13
15
  import { XYZ_to_lin_sRGB } from './xyz.js';
14
16
  import '../sourcemap/lib/encode.js';
15
- import '../../parser/utils/config.js';
16
17
 
17
18
  // from https://www.w3.org/TR/css-color-4/#color-conversion-code
18
19
  // srgb-linear -> srgb
19
20
  // 0 <= r, g, b <= 1
20
21
  function srgbvalues(token) {
21
22
  switch (token.kin) {
22
- case 'lit':
23
- case 'hex':
23
+ case ColorKind.LIT:
24
+ case ColorKind.HEX:
24
25
  return hex2srgb(token);
25
- case 'rgb':
26
- case 'rgba':
26
+ case ColorKind.RGB:
27
+ case ColorKind.RGBA:
27
28
  return rgb2srgb(token);
28
- case 'hsl':
29
- case 'hsla':
29
+ case ColorKind.HSL:
30
+ case ColorKind.HSLA:
30
31
  return hsl2srgb(token);
31
- case 'hwb':
32
+ case ColorKind.HWB:
32
33
  return hwb2srgb(token);
33
- case 'lab':
34
+ case ColorKind.LAB:
34
35
  return lab2srgb(token);
35
- case 'lch':
36
+ case ColorKind.LCH:
36
37
  return lch2srgb(token);
37
- case 'oklab':
38
+ case ColorKind.OKLAB:
38
39
  return oklab2srgb(token);
39
- case 'oklch':
40
+ case ColorKind.OKLCH:
40
41
  return oklch2srgb(token);
41
- case 'color':
42
+ case ColorKind.COLOR:
42
43
  return color2srgbvalues(token);
43
44
  }
44
45
  return null;
45
46
  }
46
47
  function rgb2srgb(token) {
47
- return getComponents(token).map((t, index) => index == 3 ? ((t.typ == EnumToken.IdenTokenType && t.val == 'none') ? 1 : getNumber(t)) : (t.typ == EnumToken.PercentageTokenType ? 255 : 1) * getNumber(t) / 255);
48
+ return getComponents(token)?.map?.((t, index) => index == 3 ? ((t.typ == EnumToken.IdenTokenType && t.val == 'none') ? 1 : getNumber(t)) : (t.typ == EnumToken.PercentageTokenType ? 255 : 1) * getNumber(t) / 255) ?? null;
48
49
  }
49
50
  function hex2srgb(token) {
50
- const value = expandHexValue(token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : token.val);
51
+ const value = expandHexValue(token.kin == ColorKind.LIT ? COLORS_NAMES[token.val.toLowerCase()] : token.val);
51
52
  const rgb = [];
52
53
  for (let i = 1; i < value.length; i += 2) {
53
54
  rgb.push(parseInt(value.slice(i, i + 2), 16) / 255);
@@ -59,7 +60,10 @@ function xyz2srgb(x, y, z) {
59
60
  return lsrgb2srgbvalues(...XYZ_to_lin_sRGB(x, y, z));
60
61
  }
61
62
  function hwb2srgb(token) {
62
- const { h: hue, s: white, l: black, a: alpha } = hslvalues(token);
63
+ const { h: hue, s: white, l: black, a: alpha } = hslvalues(token) ?? {};
64
+ if (hue == null || white == null || black == null) {
65
+ return [];
66
+ }
63
67
  const rgb = hsl2srgbvalues(hue, 1, .5);
64
68
  for (let i = 0; i < 3; i++) {
65
69
  rgb[i] *= (1 - white - black);
@@ -71,11 +75,17 @@ function hwb2srgb(token) {
71
75
  return rgb;
72
76
  }
73
77
  function hsl2srgb(token) {
74
- let { h, s, l, a } = hslvalues(token);
78
+ let { h, s, l, a } = hslvalues(token) ?? {};
79
+ if (h == null || s == null || l == null) {
80
+ return null;
81
+ }
75
82
  return hsl2srgbvalues(h, s, l, a);
76
83
  }
77
84
  function cmyk2srgb(token) {
78
85
  const components = getComponents(token);
86
+ if (components == null) {
87
+ return null;
88
+ }
79
89
  // @ts-ignore
80
90
  let t = components[0];
81
91
  // @ts-ignore
@@ -107,7 +117,10 @@ function cmyk2srgb(token) {
107
117
  return rgb;
108
118
  }
109
119
  function oklab2srgb(token) {
110
- const [l, a, b, alpha] = getOKLABComponents(token);
120
+ const [l, a, b, alpha] = getOKLABComponents(token) ?? [];
121
+ if (l == null || a == null || b == null) {
122
+ return null;
123
+ }
111
124
  const rgb = OKLab_to_sRGB(l, a, b);
112
125
  if (alpha != null && alpha != 1) {
113
126
  rgb.push(alpha);
@@ -115,7 +128,10 @@ function oklab2srgb(token) {
115
128
  return rgb;
116
129
  }
117
130
  function oklch2srgb(token) {
118
- const [l, c, h, alpha] = getOKLCHComponents(token);
131
+ const [l, c, h, alpha] = getOKLCHComponents(token) ?? [];
132
+ if (l == null || c == null || h == null) {
133
+ return null;
134
+ }
119
135
  // @ts-ignore
120
136
  const rgb = OKLab_to_sRGB(...lch2labvalues(l, c, h));
121
137
  if (alpha != 1) {
@@ -125,6 +141,9 @@ function oklch2srgb(token) {
125
141
  }
126
142
  function hslvalues(token) {
127
143
  const components = getComponents(token);
144
+ if (components == null) {
145
+ return null;
146
+ }
128
147
  let t;
129
148
  // @ts-ignore
130
149
  let h = getAngle(components[0]);
@@ -137,9 +156,9 @@ function hslvalues(token) {
137
156
  // @ts-ignore
138
157
  let l = getNumber(t);
139
158
  let a = null;
140
- if (token.chi?.length == 4) {
159
+ if (components.length == 4) {
141
160
  // @ts-ignore
142
- t = token.chi[3];
161
+ t = components[3];
143
162
  // @ts-ignore
144
163
  a = getNumber(t);
145
164
  }
@@ -199,7 +218,10 @@ function hsl2srgbvalues(h, s, l, a = null) {
199
218
  return values;
200
219
  }
201
220
  function lab2srgb(token) {
202
- const [l, a, b, alpha] = getLABComponents(token);
221
+ const [l, a, b, alpha] = getLABComponents(token) ?? [];
222
+ if (l == null || a == null || b == null) {
223
+ return null;
224
+ }
203
225
  const rgb = Lab_to_sRGB(l, a, b);
204
226
  if (alpha != null && alpha != 1) {
205
227
  rgb.push(alpha);
@@ -209,6 +231,9 @@ function lab2srgb(token) {
209
231
  function lch2srgb(token) {
210
232
  // @ts-ignore
211
233
  const [l, a, b, alpha] = lch2labvalues(...getLCHComponents(token));
234
+ if (l == null || a == null || b == null) {
235
+ return null;
236
+ }
212
237
  // https://www.w3.org/TR/css-color-4/#lab-to-lch
213
238
  const rgb = Lab_to_sRGB(l, a, b);
214
239
  if (alpha != 1) {
@@ -2,21 +2,33 @@ import { EnumToken } from '../../../ast/types.js';
2
2
  import '../../../ast/minify.js';
3
3
  import '../../../ast/walk.js';
4
4
  import '../../../parser/parse.js';
5
- import { COLORS_NAMES } from './constants.js';
5
+ import '../../../parser/tokenize.js';
6
+ import '../../../parser/utils/config.js';
7
+ import { ColorKind, COLORS_NAMES } from './constants.js';
6
8
  import { expandHexValue } from '../hex.js';
7
9
  import '../../sourcemap/lib/encode.js';
8
- import '../../../parser/utils/config.js';
9
10
 
10
11
  function getComponents(token) {
11
- if (token.kin == 'hex' || token.kin == 'lit') {
12
- const value = expandHexValue(token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : token.val);
12
+ if (token.kin == ColorKind.HEX || token.kin == ColorKind.LIT) {
13
+ const value = expandHexValue(token.kin == ColorKind.LIT ? COLORS_NAMES[token.val.toLowerCase()] : token.val);
13
14
  // @ts-ignore
14
15
  return value.slice(1).match(/([a-fA-F0-9]{2})/g).map((t) => {
15
16
  return { typ: EnumToken.Number, val: parseInt(t, 16).toString() };
16
17
  });
17
18
  }
18
- return token.chi
19
- .filter((t) => ![EnumToken.LiteralTokenType, EnumToken.CommentTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType].includes(t.typ));
19
+ const result = [];
20
+ for (const child of (token.chi)) {
21
+ if ([
22
+ EnumToken.LiteralTokenType, EnumToken.CommentTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType
23
+ ].includes(child.typ)) {
24
+ continue;
25
+ }
26
+ if (child.typ == EnumToken.ColorTokenType && child.val.localeCompare('currentcolor', undefined, { sensitivity: 'base' }) == 0) {
27
+ return null;
28
+ }
29
+ result.push(child);
30
+ }
31
+ return result;
20
32
  }
21
33
 
22
34
  export { getComponents };