@tbela99/css-parser 0.9.1 → 1.0.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 (58) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +15 -8
  3. package/dist/index-umd-web.js +1815 -498
  4. package/dist/index.cjs +1816 -499
  5. package/dist/index.d.ts +46 -14
  6. package/dist/lib/ast/features/calc.js +7 -10
  7. package/dist/lib/ast/features/index.js +1 -0
  8. package/dist/lib/ast/features/inlinecssvariables.js +0 -5
  9. package/dist/lib/ast/features/prefix.js +2 -7
  10. package/dist/lib/ast/features/shorthand.js +6 -9
  11. package/dist/lib/ast/features/transform.js +60 -0
  12. package/dist/lib/ast/math/expression.js +14 -10
  13. package/dist/lib/ast/math/math.js +14 -2
  14. package/dist/lib/ast/minify.js +46 -5
  15. package/dist/lib/ast/transform/compute.js +336 -0
  16. package/dist/lib/ast/transform/convert.js +33 -0
  17. package/dist/lib/ast/transform/matrix.js +111 -0
  18. package/dist/lib/ast/transform/minify.js +296 -0
  19. package/dist/lib/ast/transform/perspective.js +10 -0
  20. package/dist/lib/ast/transform/rotate.js +40 -0
  21. package/dist/lib/ast/transform/scale.js +32 -0
  22. package/dist/lib/ast/transform/skew.js +23 -0
  23. package/dist/lib/ast/transform/translate.js +32 -0
  24. package/dist/lib/ast/transform/utils.js +198 -0
  25. package/dist/lib/ast/types.js +1 -0
  26. package/dist/lib/ast/walk.js +23 -17
  27. package/dist/lib/parser/parse.js +109 -88
  28. package/dist/lib/parser/utils/declaration.js +1 -1
  29. package/dist/lib/renderer/color/{colormix.js → color-mix.js} +6 -0
  30. package/dist/lib/renderer/color/color.js +94 -18
  31. package/dist/lib/renderer/color/hex.js +17 -7
  32. package/dist/lib/renderer/color/hsl.js +7 -2
  33. package/dist/lib/renderer/color/lab.js +8 -0
  34. package/dist/lib/renderer/color/lch.js +8 -0
  35. package/dist/lib/renderer/color/oklab.js +8 -0
  36. package/dist/lib/renderer/color/oklch.js +8 -0
  37. package/dist/lib/renderer/color/relativecolor.js +10 -21
  38. package/dist/lib/renderer/color/rgb.js +10 -7
  39. package/dist/lib/renderer/color/srgb.js +30 -6
  40. package/dist/lib/renderer/color/utils/components.js +13 -2
  41. package/dist/lib/renderer/render.js +67 -30
  42. package/dist/lib/syntax/syntax.js +74 -56
  43. package/dist/lib/validation/at-rules/container.js +6 -6
  44. package/dist/lib/validation/at-rules/document.js +1 -1
  45. package/dist/lib/validation/at-rules/keyframes.js +1 -1
  46. package/dist/lib/validation/at-rules/media.js +0 -1
  47. package/dist/lib/validation/atrule.js +0 -4
  48. package/dist/lib/validation/selector.js +5 -2
  49. package/dist/lib/validation/syntaxes/keyframe-block-list.js +2 -2
  50. package/dist/lib/validation/syntaxes/keyframe-selector.js +11 -90
  51. package/dist/lib/validation/syntaxes/relative-selector.js +15 -14
  52. package/dist/lib/validation/utils/list.js +18 -1
  53. package/dist/node/load.js +1 -1
  54. package/package.json +12 -12
  55. package/dist/lib/renderer/color/prophotoRgb.js +0 -56
  56. package/dist/lib/validation/declaration.js +0 -94
  57. package/dist/lib/validation/syntax.js +0 -1509
  58. package/dist/lib/validation/syntaxes/image.js +0 -29
@@ -67,25 +67,35 @@ function rgb2hex(token) {
67
67
  return value;
68
68
  }
69
69
  function hsl2hex(token) {
70
- return `${hsl2rgb(token).reduce(toHexString, '#')}`;
70
+ const t = hsl2rgb(token);
71
+ return t == null ? null : `${t.reduce(toHexString, '#')}`;
71
72
  }
72
73
  function hwb2hex(token) {
73
- return `${hwb2rgb(token).reduce(toHexString, '#')}`;
74
+ const t = hwb2rgb(token);
75
+ return t == null ? null : `${t.reduce(toHexString, '#')}`;
74
76
  }
75
77
  function cmyk2hex(token) {
76
- return `#${cmyk2rgb(token).reduce(toHexString, '')}`;
78
+ const t = cmyk2rgb(token);
79
+ return t == null ? null : `#${t.reduce(toHexString, '')}`;
77
80
  }
78
81
  function oklab2hex(token) {
79
- return `${oklab2rgb(token).reduce(toHexString, '#')}`;
82
+ const t = oklab2rgb(token);
83
+ return t == null ? null : `${t.reduce(toHexString, '#')}`;
80
84
  }
81
85
  function oklch2hex(token) {
82
- return `${oklch2rgb(token).reduce(toHexString, '#')}`;
86
+ const value = oklch2rgb(token);
87
+ if (value == null) {
88
+ return null;
89
+ }
90
+ return `${value.reduce(toHexString, '#')}`;
83
91
  }
84
92
  function lab2hex(token) {
85
- return `${lab2rgb(token).reduce(toHexString, '#')}`;
93
+ const t = lab2rgb(token);
94
+ return t == null ? null : `${t.reduce(toHexString, '#')}`;
86
95
  }
87
96
  function lch2hex(token) {
88
- return `${lch2rgb(token).reduce(toHexString, '#')}`;
97
+ const t = lch2rgb(token);
98
+ return t == null ? null : `${t.reduce(toHexString, '#')}`;
89
99
  }
90
100
  function srgb2hexvalues(r, g, b, alpha) {
91
101
  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'), '#');
@@ -17,6 +17,9 @@ function hex2hsl(token) {
17
17
  }
18
18
  function rgb2hsl(token) {
19
19
  const chi = getComponents(token);
20
+ if (chi == null) {
21
+ return null;
22
+ }
20
23
  // @ts-ignore
21
24
  let t = chi[0];
22
25
  // @ts-ignore
@@ -75,12 +78,14 @@ function lch2hsl(token) {
75
78
  return rgb2hslvalues(...lch2rgb(token));
76
79
  }
77
80
  function oklab2hsl(token) {
81
+ const t = oklab2rgb(token);
78
82
  // @ts-ignore
79
- return rgb2hslvalues(...oklab2rgb(token));
83
+ return t == null ? null : rgb2hslvalues(...t);
80
84
  }
81
85
  function oklch2hsl(token) {
86
+ const t = oklch2rgb(token);
82
87
  // @ts-ignore
83
- return rgb2hslvalues(...oklch2rgb(token));
88
+ return t == null ? null : rgb2hslvalues(...t);
84
89
  }
85
90
  function rgb2hslvalues(r, g, b, a = null) {
86
91
  return srgb2hsl(r / 255, g / 255, b / 255, a);
@@ -87,6 +87,14 @@ function lch2labvalues(l, c, h, a = null) {
87
87
  }
88
88
  function getLABComponents(token) {
89
89
  const components = getComponents(token);
90
+ if (components == null) {
91
+ return null;
92
+ }
93
+ for (let i = 0; i < components.length; i++) {
94
+ if (![EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.AngleTokenType, EnumToken.IdenTokenType].includes(components[i].typ)) {
95
+ return [];
96
+ }
97
+ }
90
98
  // @ts-ignore
91
99
  let t = components[0];
92
100
  // @ts-ignore
@@ -59,6 +59,14 @@ function xyz2lchvalues(x, y, z, alpha) {
59
59
  }
60
60
  function getLCHComponents(token) {
61
61
  const components = getComponents(token);
62
+ if (components == null) {
63
+ return null;
64
+ }
65
+ for (let i = 0; i < components.length; i++) {
66
+ if (![EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.AngleTokenType, EnumToken.IdenTokenType].includes(components[i].typ)) {
67
+ return null;
68
+ }
69
+ }
62
70
  // @ts-ignore
63
71
  let t = components[0];
64
72
  // @ts-ignore
@@ -52,6 +52,14 @@ function srgb2oklab(r, g, blue, alpha) {
52
52
  }
53
53
  function getOKLABComponents(token) {
54
54
  const components = getComponents(token);
55
+ if (components == null) {
56
+ return null;
57
+ }
58
+ for (let i = 0; i < components.length; i++) {
59
+ if (![EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.AngleTokenType, EnumToken.IdenTokenType].includes(components[i].typ)) {
60
+ return null;
61
+ }
62
+ }
55
63
  // @ts-ignore
56
64
  let t = components[0];
57
65
  // @ts-ignore
@@ -44,6 +44,14 @@ function srgb2oklch(r, g, blue, alpha) {
44
44
  }
45
45
  function getOKLCHComponents(token) {
46
46
  const components = getComponents(token);
47
+ if (components == null) {
48
+ return null;
49
+ }
50
+ for (let i = 0; i < components.length; i++) {
51
+ if (![EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.AngleTokenType, EnumToken.IdenTokenType].includes(components[i].typ)) {
52
+ return [];
53
+ }
54
+ }
47
55
  // @ts-ignore
48
56
  let t = components[0];
49
57
  // @ts-ignore
@@ -142,30 +142,19 @@ function computeComponentValue(expr, converted, values) {
142
142
  return expr;
143
143
  }
144
144
  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;
145
+ for (const { value: val, parent: pr } of walkValues([parent])) {
146
+ if (val.typ == value.typ && val.val == value.val) {
147
+ if (pr.typ == EnumToken.BinaryExpressionTokenType) {
148
+ if (pr.l == val) {
149
+ pr.l = newValue;
163
150
  }
164
- else if (parent.chi[i].r == value) {
165
- parent.chi[i].r = newValue;
166
- break;
151
+ else {
152
+ pr.r = newValue;
167
153
  }
168
154
  }
155
+ else {
156
+ pr.chi.splice(pr.chi.indexOf(val), 1, newValue);
157
+ }
169
158
  }
170
159
  }
171
160
  }
@@ -21,26 +21,29 @@ function hex2rgb(token) {
21
21
  return rgb;
22
22
  }
23
23
  function hwb2rgb(token) {
24
- return hwb2srgb(token).map(srgb2rgb);
24
+ return hwb2srgb(token)?.map?.(srgb2rgb) ?? null;
25
25
  }
26
26
  function hsl2rgb(token) {
27
- let { h, s, l, a } = hslvalues(token);
27
+ let { h, s, l, a } = hslvalues(token) ?? {};
28
+ if (h == null || s == null || l == null) {
29
+ return null;
30
+ }
28
31
  return hsl2srgbvalues(h, s, l, a).map((t) => minmax(Math.round(t * 255), 0, 255));
29
32
  }
30
33
  function cmyk2rgb(token) {
31
- return cmyk2srgb(token).map(srgb2rgb);
34
+ return cmyk2srgb(token)?.map?.(srgb2rgb) ?? null;
32
35
  }
33
36
  function oklab2rgb(token) {
34
- return oklab2srgb(token).map(srgb2rgb);
37
+ return oklab2srgb(token)?.map?.(srgb2rgb) ?? null;
35
38
  }
36
39
  function oklch2rgb(token) {
37
- return oklch2srgb(token).map(srgb2rgb);
40
+ return oklch2srgb(token)?.map?.(srgb2rgb) ?? null;
38
41
  }
39
42
  function lab2rgb(token) {
40
- return lab2srgb(token).map(srgb2rgb);
43
+ return lab2srgb(token)?.map?.(srgb2rgb) ?? null;
41
44
  }
42
45
  function lch2rgb(token) {
43
- return lch2srgb(token).map(srgb2rgb);
46
+ return lch2srgb(token)?.map?.(srgb2rgb) ?? null;
44
47
  }
45
48
 
46
49
  export { cmyk2rgb, hex2rgb, hsl2rgb, hwb2rgb, lab2rgb, lch2rgb, oklab2rgb, oklch2rgb, srgb2rgb };
@@ -44,7 +44,7 @@ function srgbvalues(token) {
44
44
  return null;
45
45
  }
46
46
  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);
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) ?? null;
48
48
  }
49
49
  function hex2srgb(token) {
50
50
  const value = expandHexValue(token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : token.val);
@@ -59,7 +59,10 @@ function xyz2srgb(x, y, z) {
59
59
  return lsrgb2srgbvalues(...XYZ_to_lin_sRGB(x, y, z));
60
60
  }
61
61
  function hwb2srgb(token) {
62
- const { h: hue, s: white, l: black, a: alpha } = hslvalues(token);
62
+ const { h: hue, s: white, l: black, a: alpha } = hslvalues(token) ?? {};
63
+ if (hue == null || white == null || black == null) {
64
+ return [];
65
+ }
63
66
  const rgb = hsl2srgbvalues(hue, 1, .5);
64
67
  for (let i = 0; i < 3; i++) {
65
68
  rgb[i] *= (1 - white - black);
@@ -71,11 +74,17 @@ function hwb2srgb(token) {
71
74
  return rgb;
72
75
  }
73
76
  function hsl2srgb(token) {
74
- let { h, s, l, a } = hslvalues(token);
77
+ let { h, s, l, a } = hslvalues(token) ?? {};
78
+ if (h == null || s == null || l == null) {
79
+ return null;
80
+ }
75
81
  return hsl2srgbvalues(h, s, l, a);
76
82
  }
77
83
  function cmyk2srgb(token) {
78
84
  const components = getComponents(token);
85
+ if (components == null) {
86
+ return null;
87
+ }
79
88
  // @ts-ignore
80
89
  let t = components[0];
81
90
  // @ts-ignore
@@ -107,7 +116,10 @@ function cmyk2srgb(token) {
107
116
  return rgb;
108
117
  }
109
118
  function oklab2srgb(token) {
110
- const [l, a, b, alpha] = getOKLABComponents(token);
119
+ const [l, a, b, alpha] = getOKLABComponents(token) ?? [];
120
+ if (l == null || a == null || b == null) {
121
+ return null;
122
+ }
111
123
  const rgb = OKLab_to_sRGB(l, a, b);
112
124
  if (alpha != null && alpha != 1) {
113
125
  rgb.push(alpha);
@@ -115,7 +127,10 @@ function oklab2srgb(token) {
115
127
  return rgb;
116
128
  }
117
129
  function oklch2srgb(token) {
118
- const [l, c, h, alpha] = getOKLCHComponents(token);
130
+ const [l, c, h, alpha] = getOKLCHComponents(token) ?? [];
131
+ if (l == null || c == null || h == null) {
132
+ return null;
133
+ }
119
134
  // @ts-ignore
120
135
  const rgb = OKLab_to_sRGB(...lch2labvalues(l, c, h));
121
136
  if (alpha != 1) {
@@ -125,6 +140,9 @@ function oklch2srgb(token) {
125
140
  }
126
141
  function hslvalues(token) {
127
142
  const components = getComponents(token);
143
+ if (components == null) {
144
+ return null;
145
+ }
128
146
  let t;
129
147
  // @ts-ignore
130
148
  let h = getAngle(components[0]);
@@ -199,7 +217,10 @@ function hsl2srgbvalues(h, s, l, a = null) {
199
217
  return values;
200
218
  }
201
219
  function lab2srgb(token) {
202
- const [l, a, b, alpha] = getLABComponents(token);
220
+ const [l, a, b, alpha] = getLABComponents(token) ?? [];
221
+ if (l == null || a == null || b == null) {
222
+ return null;
223
+ }
203
224
  const rgb = Lab_to_sRGB(l, a, b);
204
225
  if (alpha != null && alpha != 1) {
205
226
  rgb.push(alpha);
@@ -209,6 +230,9 @@ function lab2srgb(token) {
209
230
  function lch2srgb(token) {
210
231
  // @ts-ignore
211
232
  const [l, a, b, alpha] = lch2labvalues(...getLCHComponents(token));
233
+ if (l == null || a == null || b == null) {
234
+ return null;
235
+ }
212
236
  // https://www.w3.org/TR/css-color-4/#lab-to-lch
213
237
  const rgb = Lab_to_sRGB(l, a, b);
214
238
  if (alpha != 1) {
@@ -15,8 +15,19 @@ function getComponents(token) {
15
15
  return { typ: EnumToken.Number, val: parseInt(t, 16).toString() };
16
16
  });
17
17
  }
18
- return token.chi
19
- .filter((t) => ![EnumToken.LiteralTokenType, EnumToken.CommentTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType].includes(t.typ));
18
+ const result = [];
19
+ for (const child of (token.chi)) {
20
+ if ([
21
+ EnumToken.LiteralTokenType, EnumToken.CommentTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType
22
+ ].includes(child.typ)) {
23
+ continue;
24
+ }
25
+ if (child.typ == EnumToken.ColorTokenType && child.val == 'currentcolor') {
26
+ return null;
27
+ }
28
+ result.push(child);
29
+ }
30
+ return result;
20
31
  }
21
32
 
22
33
  export { getComponents };
@@ -2,11 +2,11 @@ import { getAngle, color2srgbvalues, clamp } from './color/color.js';
2
2
  import { colorFuncColorSpace, COLORS_NAMES } from './color/utils/constants.js';
3
3
  import { getComponents } from './color/utils/components.js';
4
4
  import { reduceHexValue, srgb2hexvalues, rgb2hex, hsl2hex, hwb2hex, cmyk2hex, oklab2hex, oklch2hex, lab2hex, lch2hex } from './color/hex.js';
5
- import { EnumToken } from '../ast/types.js';
5
+ import { EnumToken, funcLike } from '../ast/types.js';
6
6
  import '../ast/minify.js';
7
7
  import '../ast/walk.js';
8
8
  import { expand } from '../ast/expand.js';
9
- import { colorMix } from './color/colormix.js';
9
+ import { colorMix } from './color/color-mix.js';
10
10
  import { parseRelativeColor } from './color/relativecolor.js';
11
11
  import { SourceMap } from './sourcemap/sourcemap.js';
12
12
  import { isColor, pseudoElements, mathFuncs, isNewLine } from '../syntax/syntax.js';
@@ -109,7 +109,7 @@ function doRender(data, options = {}) {
109
109
  return result;
110
110
  }
111
111
  function updateSourceMap(node, options, cache, sourcemap, position, str) {
112
- if ([EnumToken.RuleNodeType, EnumToken.AtRuleNodeType, EnumToken.KeyFrameRuleNodeType].includes(node.typ)) {
112
+ if ([EnumToken.RuleNodeType, EnumToken.AtRuleNodeType, EnumToken.KeyFrameRuleNodeType, EnumToken.KeyframeAtRuleNodeType].includes(node.typ)) {
113
113
  let src = node.loc?.src ?? '';
114
114
  let output = options.output ?? '';
115
115
  if (!(src in cache)) {
@@ -152,7 +152,7 @@ function renderAstNode(data, options, sourcemap, position, errors, reducer, cach
152
152
  const indentSub = indents[level + 1];
153
153
  switch (data.typ) {
154
154
  case EnumToken.DeclarationNodeType:
155
- return `${data.nam}:${options.indent}${data.val.reduce(reducer, '')}`;
155
+ return `${data.nam}:${options.indent}${(options.minify ? filterValues(data.val) : data.val).reduce(reducer, '')}`;
156
156
  case EnumToken.CommentNodeType:
157
157
  case EnumToken.CDOCOMMNodeType:
158
158
  if (data.val.startsWith('/*# sourceMappingURL=')) {
@@ -181,7 +181,8 @@ function renderAstNode(data, options, sourcemap, position, errors, reducer, cach
181
181
  case EnumToken.AtRuleNodeType:
182
182
  case EnumToken.RuleNodeType:
183
183
  case EnumToken.KeyFrameRuleNodeType:
184
- if (data.typ == EnumToken.AtRuleNodeType && !('chi' in data)) {
184
+ case EnumToken.KeyframeAtRuleNodeType:
185
+ if ([EnumToken.AtRuleNodeType, EnumToken.KeyframeAtRuleNodeType].includes(data.typ) && !('chi' in data)) {
185
186
  return `${indent}@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val};`;
186
187
  }
187
188
  // @ts-ignore
@@ -191,7 +192,7 @@ function renderAstNode(data, options, sourcemap, position, errors, reducer, cach
191
192
  str = options.removeComments && (!options.preserveLicense || !node.val.startsWith('/*!')) ? '' : node.val;
192
193
  }
193
194
  else if (node.typ == EnumToken.DeclarationNodeType) {
194
- if (node.val.length == 0) {
195
+ if (!node.nam.startsWith('--') && node.val.length == 0) {
195
196
  // @ts-ignore
196
197
  errors.push({
197
198
  action: 'ignore',
@@ -200,7 +201,7 @@ function renderAstNode(data, options, sourcemap, position, errors, reducer, cach
200
201
  });
201
202
  return '';
202
203
  }
203
- str = `${node.nam}:${options.indent}${node.val.reduce(reducer, '').trimEnd()};`;
204
+ str = `${node.nam}:${options.indent}${(options.minify ? filterValues(node.val) : node.val).reduce(reducer, '').trimEnd()};`;
204
205
  }
205
206
  else if (node.typ == EnumToken.AtRuleNodeType && !('chi' in node)) {
206
207
  str = `${data.val === '' ? '' : options.indent || ' '}${data.val};`;
@@ -222,7 +223,7 @@ function renderAstNode(data, options, sourcemap, position, errors, reducer, cach
222
223
  if (children.endsWith(';')) {
223
224
  children = children.slice(0, -1);
224
225
  }
225
- if (data.typ == EnumToken.AtRuleNodeType) {
226
+ if ([EnumToken.AtRuleNodeType, EnumToken.KeyframeAtRuleNodeType].includes(data.typ)) {
226
227
  return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
227
228
  }
228
229
  return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
@@ -258,20 +259,25 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
258
259
  if (isColor(token)) {
259
260
  // @ts-ignore
260
261
  token.typ = EnumToken.ColorTokenType;
262
+ // @ts-ignore
261
263
  if (token.chi[0].typ == EnumToken.IdenTokenType && token.chi[0].val == 'from') {
262
264
  // @ts-ignore
263
265
  token.cal = 'rel';
264
266
  }
265
- else if (token.val == 'color-mix' && token.chi[0].typ == EnumToken.IdenTokenType && token.chi[0].val == 'in') {
266
- // @ts-ignore
267
- token.cal = 'mix';
268
- }
269
- else {
270
- if (token.val == 'color') {
267
+ else { // @ts-ignore
268
+ if (token.val == 'color-mix' && token.chi[0].typ == EnumToken.IdenTokenType && token.chi[0].val == 'in') {
271
269
  // @ts-ignore
272
- token.cal = 'col';
270
+ token.cal = 'mix';
271
+ }
272
+ else {
273
+ // @ts-ignore
274
+ if (token.val == 'color') {
275
+ // @ts-ignore
276
+ token.cal = 'col';
277
+ }
278
+ // @ts-ignore
279
+ token.chi = token.chi.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommaTokenType, EnumToken.CommentTokenType].includes(t.typ));
273
280
  }
274
- token.chi = token.chi.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommaTokenType, EnumToken.CommentTokenType].includes(t.typ));
275
281
  }
276
282
  }
277
283
  }
@@ -338,22 +344,36 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
338
344
  if (value != null) {
339
345
  token = value;
340
346
  }
347
+ else if (!token.chi.some(t => t.typ == EnumToken.CommaTokenType)) {
348
+ token.chi = children.reduce((acc, curr, index) => {
349
+ if (acc.length > 0) {
350
+ acc.push({ typ: EnumToken.CommaTokenType });
351
+ }
352
+ acc.push(...curr);
353
+ return acc;
354
+ }, []);
355
+ }
341
356
  }
342
357
  if (token.cal == 'rel' && ['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch', 'color'].includes(token.val)) {
343
358
  const chi = getComponents(token);
344
359
  const offset = token.val == 'color' ? 2 : 1;
345
- // @ts-ignore
346
- const color = chi[1];
347
- const components = parseRelativeColor(token.val == 'color' ? chi[offset].val : token.val, color, chi[offset + 1], chi[offset + 2], chi[offset + 3], chi[offset + 4]);
348
- if (components != null) {
349
- token.chi = [...(token.val == 'color' ? [chi[offset]] : []), ...Object.values(components)];
350
- delete token.cal;
360
+ if (chi != null) {
361
+ // @ts-ignore
362
+ const color = chi[1];
363
+ const components = parseRelativeColor(token.val == 'color' ? chi[offset].val : token.val, color, chi[offset + 1], chi[offset + 2], chi[offset + 3], chi[offset + 4]);
364
+ if (components != null) {
365
+ token.chi = [...(token.val == 'color' ? [chi[offset]] : []), ...Object.values(components)];
366
+ delete token.cal;
367
+ }
351
368
  }
352
369
  }
353
370
  if (token.val == 'color') {
354
371
  if (token.chi[0].typ == EnumToken.IdenTokenType && colorFuncColorSpace.includes(token.chi[0].val.toLowerCase())) {
355
- // @ts-ignore
356
- return reduceHexValue(srgb2hexvalues(...color2srgbvalues(token)));
372
+ const values = color2srgbvalues(token);
373
+ if (Array.isArray(values) && values.every(t => !Number.isNaN(t))) {
374
+ // @ts-ignore
375
+ return reduceHexValue(srgb2hexvalues(...values));
376
+ }
357
377
  }
358
378
  }
359
379
  if (token.cal != null) {
@@ -410,7 +430,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
410
430
  else if (token.val == 'lch') {
411
431
  value = lch2hex(token);
412
432
  }
413
- if (value !== '') {
433
+ if (value !== '' && value != null) {
414
434
  return reduceHexValue(value);
415
435
  }
416
436
  }
@@ -600,7 +620,11 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
600
620
  if (!('original' in token)) {
601
621
  // do not modify original token
602
622
  token = { ...token };
603
- Object.defineProperty(token, 'original', { enumerable: false, writable: false, value: token.val });
623
+ Object.defineProperty(token, 'original', {
624
+ enumerable: false,
625
+ writable: false,
626
+ value: token.val
627
+ });
604
628
  }
605
629
  // @ts-ignore
606
630
  if (!(token.original in cache)) {
@@ -633,7 +657,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
633
657
  case EnumToken.InvalidClassSelectorTokenType:
634
658
  return token.val;
635
659
  case EnumToken.DeclarationNodeType:
636
- return token.nam + ':' + token.val.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
660
+ return token.nam + ':' + (options.minify ? filterValues(token.val) : token.val).reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
637
661
  case EnumToken.MediaQueryConditionTokenType:
638
662
  return renderToken(token.l, options, cache, reducer, errors) + renderToken(token.op, options, cache, reducer, errors) + token.r.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
639
663
  case EnumToken.MediaFeatureTokenType:
@@ -646,11 +670,24 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
646
670
  return 'and';
647
671
  case EnumToken.MediaFeatureOrTokenType:
648
672
  return 'or';
649
- default:
650
- throw new Error(`render: unexpected token ${JSON.stringify(token, null, 1)}`);
673
+ // default:
674
+ //
675
+ // throw new Error(`render: unexpected token ${JSON.stringify(token, null, 1)}`);
651
676
  }
652
677
  errors?.push({ action: 'ignore', message: `render: unexpected token ${JSON.stringify(token, null, 1)}` });
653
678
  return '';
654
679
  }
680
+ function filterValues(values) {
681
+ let i = 0;
682
+ for (; i < values.length; i++) {
683
+ if (values[i].typ == EnumToken.ImportantTokenType && values[i - 1]?.typ == EnumToken.WhitespaceTokenType) {
684
+ values.splice(i - 1, 1);
685
+ }
686
+ else if (funcLike.includes(values[i].typ) && !['var', 'calc'].includes(values[i].val) && values[i + 1]?.typ == EnumToken.WhitespaceTokenType) {
687
+ values.splice(i + 1, 1);
688
+ }
689
+ }
690
+ return values;
691
+ }
655
692
 
656
- export { colorsFunc, doRender, reduceNumber, renderToken };
693
+ export { colorsFunc, doRender, filterValues, reduceNumber, renderToken };