@tbela99/css-parser 1.1.1 → 1.2.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 (101) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +53 -6
  3. package/dist/index-umd-web.js +4195 -3363
  4. package/dist/index.cjs +4199 -3367
  5. package/dist/index.d.ts +42 -31
  6. package/dist/lib/ast/expand.js +81 -65
  7. package/dist/lib/ast/features/calc.js +37 -35
  8. package/dist/lib/ast/features/inlinecssvariables.js +25 -17
  9. package/dist/lib/ast/features/prefix.js +22 -19
  10. package/dist/lib/ast/features/shorthand.js +1 -1
  11. package/dist/lib/ast/features/transform.js +17 -2
  12. package/dist/lib/ast/math/expression.js +184 -159
  13. package/dist/lib/ast/math/math.js +22 -20
  14. package/dist/lib/ast/minify.js +249 -199
  15. package/dist/lib/ast/transform/compute.js +48 -38
  16. package/dist/lib/ast/transform/matrix.js +6 -5
  17. package/dist/lib/ast/transform/minify.js +31 -34
  18. package/dist/lib/ast/transform/utils.js +76 -16
  19. package/dist/lib/ast/types.js +32 -1
  20. package/dist/lib/fs/resolve.js +1 -14
  21. package/dist/lib/parser/declaration/list.js +1 -1
  22. package/dist/lib/parser/declaration/map.js +1 -1
  23. package/dist/lib/parser/declaration/set.js +1 -1
  24. package/dist/lib/parser/parse.js +19 -95
  25. package/dist/lib/parser/tokenize.js +1 -13
  26. package/dist/lib/parser/utils/declaration.js +1 -1
  27. package/dist/lib/parser/utils/type.js +1 -1
  28. package/dist/lib/renderer/render.js +44 -168
  29. package/dist/lib/{renderer → syntax}/color/a98rgb.js +2 -2
  30. package/dist/lib/syntax/color/cmyk.js +104 -0
  31. package/dist/lib/{renderer → syntax}/color/color-mix.js +20 -21
  32. package/dist/lib/syntax/color/color.js +581 -0
  33. package/dist/lib/syntax/color/hex.js +179 -0
  34. package/dist/lib/syntax/color/hsl.js +201 -0
  35. package/dist/lib/syntax/color/hwb.js +185 -0
  36. package/dist/lib/syntax/color/lab.js +262 -0
  37. package/dist/lib/syntax/color/lch.js +194 -0
  38. package/dist/lib/syntax/color/oklab.js +237 -0
  39. package/dist/lib/syntax/color/oklch.js +166 -0
  40. package/dist/lib/{renderer → syntax}/color/p3.js +3 -3
  41. package/dist/lib/{renderer → syntax}/color/rec2020.js +11 -11
  42. package/dist/lib/{renderer → syntax}/color/relativecolor.js +53 -40
  43. package/dist/lib/syntax/color/rgb.js +140 -0
  44. package/dist/lib/{renderer → syntax}/color/srgb.js +58 -46
  45. package/dist/lib/{renderer → syntax}/color/utils/components.js +7 -7
  46. package/dist/lib/{renderer → syntax}/color/utils/constants.js +6 -33
  47. package/dist/lib/syntax/color/utils/distance.js +30 -0
  48. package/dist/lib/{renderer → syntax}/color/xyz.js +27 -14
  49. package/dist/lib/{renderer → syntax}/color/xyzd50.js +8 -8
  50. package/dist/lib/syntax/syntax.js +77 -67
  51. package/dist/lib/syntax/utils.js +70 -0
  52. package/dist/lib/validation/at-rules/container.js +1 -1
  53. package/dist/lib/validation/at-rules/counter-style.js +1 -1
  54. package/dist/lib/validation/at-rules/custom-media.js +1 -1
  55. package/dist/lib/validation/at-rules/document.js +1 -1
  56. package/dist/lib/validation/at-rules/font-feature-values.js +2 -2
  57. package/dist/lib/validation/at-rules/import.js +1 -1
  58. package/dist/lib/validation/at-rules/keyframes.js +14 -13
  59. package/dist/lib/validation/at-rules/layer.js +1 -1
  60. package/dist/lib/validation/at-rules/media.js +1 -1
  61. package/dist/lib/validation/at-rules/namespace.js +1 -1
  62. package/dist/lib/validation/at-rules/page-margin-box.js +1 -1
  63. package/dist/lib/validation/at-rules/page.js +1 -1
  64. package/dist/lib/validation/at-rules/supports.js +1 -1
  65. package/dist/lib/validation/at-rules/when.js +1 -1
  66. package/dist/lib/validation/atrule.js +2 -2
  67. package/dist/lib/validation/config.js +4 -3
  68. package/dist/lib/validation/config.json.js +1 -1
  69. package/dist/lib/validation/parser/parse.js +12 -7
  70. package/dist/lib/validation/selector.js +9 -8
  71. package/dist/lib/validation/syntax.js +170 -120
  72. package/dist/lib/validation/syntaxes/complex-selector-list.js +13 -19
  73. package/dist/lib/validation/syntaxes/complex-selector.js +1 -1
  74. package/dist/lib/validation/syntaxes/compound-selector.js +5 -24
  75. package/dist/lib/validation/syntaxes/family-name.js +36 -39
  76. package/dist/lib/validation/syntaxes/keyframe-selector.js +14 -22
  77. package/dist/lib/validation/syntaxes/layer-name.js +1 -1
  78. package/dist/lib/validation/syntaxes/relative-selector-list.js +27 -25
  79. package/dist/lib/validation/syntaxes/relative-selector.js +1 -1
  80. package/dist/lib/validation/syntaxes/url.js +35 -33
  81. package/dist/lib/validation/utils/list.js +10 -9
  82. package/dist/lib/validation/utils/whitespace.js +1 -1
  83. package/dist/node/index.js +4 -2
  84. package/dist/web/index.js +4 -2
  85. package/package.json +4 -4
  86. package/.editorconfig +0 -484
  87. package/dist/lib/ast/transform/convert.js +0 -33
  88. package/dist/lib/ast/utils/utils.js +0 -104
  89. package/dist/lib/renderer/color/color.js +0 -654
  90. package/dist/lib/renderer/color/hex.js +0 -105
  91. package/dist/lib/renderer/color/hsl.js +0 -125
  92. package/dist/lib/renderer/color/hwb.js +0 -103
  93. package/dist/lib/renderer/color/lab.js +0 -148
  94. package/dist/lib/renderer/color/lch.js +0 -90
  95. package/dist/lib/renderer/color/oklab.js +0 -131
  96. package/dist/lib/renderer/color/oklch.js +0 -75
  97. package/dist/lib/renderer/color/rgb.js +0 -50
  98. package/dist/lib/validation/syntaxes/keyframe-block-list.js +0 -28
  99. package/dist/lib/{renderer → syntax}/color/hsv.js +0 -0
  100. package/dist/lib/{renderer → syntax}/color/prophotorgb.js +1 -1
  101. /package/dist/lib/{renderer → syntax}/color/utils/matrix.js +0 -0
@@ -1,12 +1,12 @@
1
- import { isColor, parseColor, isIdent, mediaTypes, isDimension, parseDimension, isPseudo, pseudoElements, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isHexColor, isHash, isIdentStart, isIdentColor, mathFuncs } from '../syntax/syntax.js';
2
- import './utils/config.js';
3
- import { EnumToken, ValidationLevel, SyntaxValidationResult } from '../ast/types.js';
1
+ import { isIdentStart, isIdent, isIdentColor, mathFuncs, isColor, parseColor, isPseudo, pseudoElements, isAtKeyword, isFunction, isNumber, isPercentage, isFlex, isDimension, parseDimension, isHexColor, isHash, mediaTypes } from '../syntax/syntax.js';
2
+ import { EnumToken, ColorType, ValidationLevel, SyntaxValidationResult } from '../ast/types.js';
4
3
  import { minify, definedPropertySettings, combinators } from '../ast/minify.js';
5
4
  import { walkValues, walk, WalkerOptionEnum } from '../ast/walk.js';
6
5
  import { expand } from '../ast/expand.js';
6
+ import './utils/config.js';
7
7
  import { parseDeclarationNode } from './utils/declaration.js';
8
8
  import { renderToken } from '../renderer/render.js';
9
- import { funcLike, ColorKind, COLORS_NAMES, systemColors, deprecatedSystemColors, colorsFunc } from '../renderer/color/utils/constants.js';
9
+ import { funcLike, timingFunc, timelineFunc, COLORS_NAMES, systemColors, deprecatedSystemColors, colorsFunc } from '../syntax/color/utils/constants.js';
10
10
  import { buildExpression } from '../ast/math/expression.js';
11
11
  import { tokenize } from './tokenize.js';
12
12
  import '../validation/config.js';
@@ -234,7 +234,6 @@ async function doParse(iterator, options = {}) {
234
234
  }
235
235
  }
236
236
  catch (error) {
237
- // console.error(error);
238
237
  // @ts-ignore
239
238
  errors.push({ action: 'ignore', message: 'doParse: ' + error.message, error });
240
239
  }
@@ -485,7 +484,7 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
485
484
  }
486
485
  const t = parseAtRulePrelude(parseTokens(tokens, { minify: options.minify }), atRule);
487
486
  const raw = t.reduce((acc, curr) => {
488
- acc.push(renderToken(curr, { removeComments: true }));
487
+ acc.push(renderToken(curr, { removeComments: true, convertColor: false }));
489
488
  return acc;
490
489
  }, []);
491
490
  const nam = renderToken(atRule, { removeComments: true });
@@ -507,7 +506,6 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
507
506
  node.loc = loc;
508
507
  node.loc.end = { ...map.get(delim).end };
509
508
  }
510
- // if (options.validation) {
511
509
  let isValid = true;
512
510
  if (node.nam == 'else') {
513
511
  const prev = getLastNode(context);
@@ -544,6 +542,7 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
544
542
  else {
545
543
  node.val = node.tokens.reduce((acc, curr) => acc + renderToken(curr, {
546
544
  minify: false,
545
+ convertColor: false,
547
546
  removeComments: true
548
547
  }), '');
549
548
  }
@@ -675,7 +674,7 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
675
674
  if (name == null && [EnumToken.IdenTokenType, EnumToken.DashedIdenTokenType].includes(tokens[i].typ)) {
676
675
  name = tokens.slice(0, i + 1);
677
676
  }
678
- else if (name == null && tokens[i].typ == EnumToken.ColorTokenType && [ColorKind.SYS, ColorKind.DPSYS].includes(tokens[i].kin)) {
677
+ else if (name == null && tokens[i].typ == EnumToken.ColorTokenType && [ColorType.SYS, ColorType.DPSYS].includes(tokens[i].kin)) {
679
678
  name = tokens.slice(0, i + 1);
680
679
  tokens[i].typ = EnumToken.IdenTokenType;
681
680
  }
@@ -784,12 +783,11 @@ function parseNode(results, context, options, errors, src, map, rawTokens) {
784
783
  value: valid.valid == SyntaxValidationResult.Valid
785
784
  });
786
785
  if (valid.valid == SyntaxValidationResult.Drop) {
787
- // console.error({result, valid});
788
- // console.error(JSON.stringify({result, options, valid}, null, 1));
789
786
  errors.push({
790
787
  action: 'drop',
791
788
  message: valid.error,
792
789
  syntax: valid.syntax,
790
+ node: valid.node,
793
791
  location: map.get(valid.node) ?? valid.node?.loc ?? result.loc ?? location
794
792
  });
795
793
  if (!options.lenient) {
@@ -950,10 +948,7 @@ function parseAtRulePrelude(tokens, atRule) {
950
948
  break;
951
949
  }
952
950
  if (valueIndex == -1) {
953
- // @ts-ignore
954
- // value.chi[nameIndex].typ = EnumToken.MediaFeatureTokenType;
955
951
  continue;
956
- // return tokens;
957
952
  }
958
953
  for (i = nameIndex + 1; i < value.chi.length; i++) {
959
954
  if ([
@@ -965,7 +960,7 @@ function parseAtRulePrelude(tokens, atRule) {
965
960
  const node = value.chi.splice(nameIndex, 1)[0];
966
961
  // 'background'
967
962
  // @ts-ignore
968
- if (node.typ == EnumToken.ColorTokenType && node.kin == ColorKind.DPSYS) {
963
+ if (node.typ == EnumToken.ColorTokenType && node.kin == ColorType.DPSYS) {
969
964
  // @ts-ignore
970
965
  delete node.kin;
971
966
  node.typ = EnumToken.IdenTokenType;
@@ -992,7 +987,7 @@ function parseAtRulePrelude(tokens, atRule) {
992
987
  * @param tokens
993
988
  */
994
989
  function parseSelector(tokens) {
995
- for (const { value, previousValue, nextValue, parent } of walkValues(tokens)) {
990
+ for (const { value, parent } of walkValues(tokens)) {
996
991
  if (value.typ == EnumToken.CommentTokenType ||
997
992
  value.typ == EnumToken.WhitespaceTokenType ||
998
993
  value.typ == EnumToken.CommaTokenType ||
@@ -1005,43 +1000,6 @@ function parseSelector(tokens) {
1005
1000
  // @ts-ignore
1006
1001
  value.typ = EnumToken.ChildCombinatorTokenType;
1007
1002
  }
1008
- // @ts-ignore
1009
- else if (value.typ == EnumToken.WhitespaceTokenType) {
1010
- if (nextValue != null && nextValue.typ == EnumToken.LiteralTokenType) {
1011
- if (['>', '+', '~'].includes(nextValue.val)) {
1012
- switch (value.val) {
1013
- case '>':
1014
- // @ts-ignore
1015
- nextValue.typ = EnumToken.ChildCombinatorTokenType;
1016
- break;
1017
- case '+':
1018
- // @ts-ignore
1019
- nextValue.typ = EnumToken.NextSiblingCombinatorTokenType;
1020
- break;
1021
- case '~':
1022
- // @ts-ignore
1023
- nextValue.typ = EnumToken.SubsequentSiblingCombinatorTokenType;
1024
- break;
1025
- }
1026
- // @ts-ignore
1027
- delete nextValue.val;
1028
- continue;
1029
- }
1030
- }
1031
- if (previousValue != null && [
1032
- EnumToken.ChildCombinatorTokenType,
1033
- EnumToken.DescendantCombinatorTokenType,
1034
- EnumToken.NextSiblingCombinatorTokenType,
1035
- EnumToken.SubsequentSiblingCombinatorTokenType,
1036
- EnumToken.ColumnCombinatorTokenType,
1037
- EnumToken.NameSpaceAttributeTokenType,
1038
- EnumToken.CommaTokenType
1039
- ].includes(previousValue.typ)) {
1040
- continue;
1041
- }
1042
- // @ts-ignore
1043
- value.typ = EnumToken.DescendantCombinatorTokenType;
1044
- }
1045
1003
  else if (value.typ == EnumToken.LiteralTokenType) {
1046
1004
  if (value.val.charAt(0) == '&') {
1047
1005
  // @ts-ignore
@@ -1059,12 +1017,7 @@ function parseSelector(tokens) {
1059
1017
  value.typ = EnumToken.ClassSelectorTokenType;
1060
1018
  }
1061
1019
  }
1062
- // @ts-ignore
1063
- if (value.typ == EnumToken.DelimTokenType) {
1064
- // @ts-ignore
1065
- value.typ = EnumToken.NextSiblingCombinatorTokenType;
1066
- }
1067
- else if (['*', '>', '+', '~'].includes(value.val)) {
1020
+ if (['*', '>', '+', '~'].includes(value.val)) {
1068
1021
  switch (value.val) {
1069
1022
  case '*':
1070
1023
  // @ts-ignore
@@ -1084,13 +1037,12 @@ function parseSelector(tokens) {
1084
1037
  break;
1085
1038
  }
1086
1039
  // @ts-ignore
1087
- // @ts-ignore
1088
1040
  delete value.val;
1089
1041
  }
1090
1042
  }
1091
1043
  else if (value.typ == EnumToken.ColorTokenType) {
1092
- if (value.kin == ColorKind.LIT || value.kin == ColorKind.HEX || value.kin == ColorKind.SYS || value.kin == ColorKind.DPSYS) {
1093
- if (value.kin == ColorKind.HEX) {
1044
+ if (value.kin == ColorType.LIT || value.kin == ColorType.HEX || value.kin == ColorType.SYS || value.kin == ColorType.DPSYS) {
1045
+ if (value.kin == ColorType.HEX) {
1094
1046
  if (!isIdent(value.val.slice(1))) {
1095
1047
  continue;
1096
1048
  }
@@ -1130,10 +1082,6 @@ function parseSelector(tokens) {
1130
1082
  }
1131
1083
  return tokens;
1132
1084
  }
1133
- // export async function parseDeclarations(src: string, options: ParserOptions = {}): Promise<AstDeclaration[]> {
1134
- //
1135
- // return doParse(`.x{${src}`, options).then((result: ParseResult) => <AstDeclaration[]>(<AstRule>result.ast.chi[0]).chi.filter(t => t.typ == EnumToken.DeclarationNodeType));
1136
- // }
1137
1085
  /**
1138
1086
  * parse css string
1139
1087
  * @param src
@@ -1223,14 +1171,14 @@ function getTokenType(val, hint) {
1223
1171
  chi: []
1224
1172
  };
1225
1173
  }
1226
- if (['ease', 'ease-in', 'ease-out', 'ease-in-out', 'linear', 'step-start', 'step-end', 'steps', 'cubic-bezier'].includes(val)) {
1174
+ if (timingFunc.includes(val.toLowerCase())) {
1227
1175
  return {
1228
1176
  typ: EnumToken.TimingFunctionTokenType,
1229
1177
  val,
1230
1178
  chi: []
1231
1179
  };
1232
1180
  }
1233
- if (['view', 'scroll'].includes(val)) {
1181
+ if (timelineFunc.includes(val)) {
1234
1182
  return {
1235
1183
  typ: EnumToken.TimelineFunctionTokenType,
1236
1184
  val,
@@ -1269,7 +1217,7 @@ function getTokenType(val, hint) {
1269
1217
  return {
1270
1218
  typ: EnumToken.ColorTokenType,
1271
1219
  val: v,
1272
- kin: ColorKind.LIT
1220
+ kin: ColorType.LIT
1273
1221
  };
1274
1222
  }
1275
1223
  if (isIdent(val)) {
@@ -1277,14 +1225,14 @@ function getTokenType(val, hint) {
1277
1225
  return {
1278
1226
  typ: EnumToken.ColorTokenType,
1279
1227
  val,
1280
- kin: ColorKind.SYS
1228
+ kin: ColorType.SYS
1281
1229
  };
1282
1230
  }
1283
1231
  if (deprecatedSystemColors.has(v)) {
1284
1232
  return {
1285
1233
  typ: EnumToken.ColorTokenType,
1286
1234
  val,
1287
- kin: ColorKind.DPSYS
1235
+ kin: ColorType.DPSYS
1288
1236
  };
1289
1237
  }
1290
1238
  return {
@@ -1296,7 +1244,7 @@ function getTokenType(val, hint) {
1296
1244
  return {
1297
1245
  typ: EnumToken.ColorTokenType,
1298
1246
  val,
1299
- kin: ColorKind.HEX
1247
+ kin: ColorType.HEX
1300
1248
  };
1301
1249
  }
1302
1250
  if (val.charAt(0) == '#' && isHash(val)) {
@@ -1373,7 +1321,6 @@ function parseTokens(tokens, options = {}) {
1373
1321
  }
1374
1322
  // @ts-ignore
1375
1323
  if (attr.chi.length > 1) {
1376
- /*(<AttrToken>t).chi =*/
1377
1324
  // @ts-ignore
1378
1325
  parseTokens(attr.chi, t.typ);
1379
1326
  }
@@ -1593,7 +1540,6 @@ function parseTokens(tokens, options = {}) {
1593
1540
  // @ts-ignore
1594
1541
  if (t.chi.length > 0) {
1595
1542
  if (t.typ == EnumToken.PseudoClassFuncTokenType && t.val == ':is' && options.minify) {
1596
- //
1597
1543
  const count = t.chi.filter((t) => t.typ != EnumToken.CommentTokenType).length;
1598
1544
  if (count == 1 ||
1599
1545
  (i == 0 &&
@@ -1604,28 +1550,6 @@ function parseTokens(tokens, options = {}) {
1604
1550
  }
1605
1551
  }
1606
1552
  }
1607
- continue;
1608
- }
1609
- if (options.parseColor) {
1610
- if (t.typ == EnumToken.IdenTokenType) {
1611
- // named color
1612
- const value = t.val.toLowerCase();
1613
- if (value in COLORS_NAMES) {
1614
- Object.assign(t, {
1615
- typ: EnumToken.ColorTokenType,
1616
- val: COLORS_NAMES[value].length < value.length ? COLORS_NAMES[value] : value,
1617
- kin: ColorKind.HEX
1618
- });
1619
- }
1620
- continue;
1621
- }
1622
- if (t.typ == EnumToken.HashTokenType && isHexColor(t.val)) {
1623
- // hex color
1624
- // @ts-ignore
1625
- t.typ = EnumToken.ColorTokenType;
1626
- // @ts-ignore
1627
- t.kin = ColorKind.HEX;
1628
- }
1629
1553
  }
1630
1554
  }
1631
1555
  return tokens;
@@ -4,7 +4,7 @@ import '../ast/walk.js';
4
4
  import './parse.js';
5
5
  import './utils/config.js';
6
6
  import { isWhiteSpace, isIdentStart, isIdent, isNewLine, isDigit, isNonPrintable } from '../syntax/syntax.js';
7
- import '../renderer/color/utils/constants.js';
7
+ import '../syntax/color/utils/constants.js';
8
8
  import '../renderer/sourcemap/lib/encode.js';
9
9
 
10
10
  var TokenMap;
@@ -92,11 +92,6 @@ function* consumeString(quoteStr, buffer, parseInfo) {
92
92
  }
93
93
  break;
94
94
  }
95
- if (i == 1) {
96
- buffer += value + sequence[i];
97
- next(parseInfo, 2);
98
- continue;
99
- }
100
95
  if (escapeSequence.trimEnd().length > 0) {
101
96
  const codepoint = parseInt(escapeSequence, 16);
102
97
  if (codepoint == 0 ||
@@ -119,7 +114,6 @@ function* consumeString(quoteStr, buffer, parseInfo) {
119
114
  buffer += value;
120
115
  yield pushToken(buffer, parseInfo, hasNewLine ? EnumToken.BadStringTokenType : EnumToken.StringTokenType);
121
116
  next(parseInfo);
122
- // i += value.length;
123
117
  buffer = '';
124
118
  return;
125
119
  }
@@ -161,15 +155,9 @@ function prev(parseInfo, count = 1) {
161
155
  function next(parseInfo, count = 1) {
162
156
  let char = '';
163
157
  let chr = '';
164
- if (count < 0) {
165
- return '';
166
- }
167
158
  while (count-- && (chr = parseInfo.stream.charAt(parseInfo.currentPosition.ind + 1))) {
168
159
  char += chr;
169
160
  const codepoint = parseInfo.stream.charCodeAt(++parseInfo.currentPosition.ind);
170
- if (isNaN(codepoint)) {
171
- return char;
172
- }
173
161
  if (isNewLine(codepoint)) {
174
162
  parseInfo.currentPosition.lin++;
175
163
  parseInfo.currentPosition.col = 0;
@@ -5,7 +5,7 @@ import '../parse.js';
5
5
  import '../tokenize.js';
6
6
  import './config.js';
7
7
  import { isWhiteSpace } from '../../syntax/syntax.js';
8
- import '../../renderer/color/utils/constants.js';
8
+ import '../../syntax/color/utils/constants.js';
9
9
  import '../../renderer/sourcemap/lib/encode.js';
10
10
 
11
11
  function parseDeclarationNode(node, errors, location) {
@@ -5,7 +5,7 @@ import '../parse.js';
5
5
  import '../tokenize.js';
6
6
  import './config.js';
7
7
  import { mathFuncs } from '../../syntax/syntax.js';
8
- import '../../renderer/color/utils/constants.js';
8
+ import '../../syntax/color/utils/constants.js';
9
9
  import '../../renderer/sourcemap/lib/encode.js';
10
10
 
11
11
  function matchType(val, properties) {
@@ -1,33 +1,13 @@
1
- import { getAngle, color2srgbvalues, clamp } from './color/color.js';
2
- import { colorsFunc, ColorKind, colorFuncColorSpace, COLORS_NAMES, funcLike } from './color/utils/constants.js';
3
- import { getComponents } from './color/utils/components.js';
4
- import { reduceHexValue, srgb2hexvalues, rgb2hex, hsl2hex, hwb2hex, cmyk2hex, oklab2hex, oklch2hex, lab2hex, lch2hex } from './color/hex.js';
5
- import { EnumToken } from '../ast/types.js';
1
+ import { getAngle, convertColor } from '../syntax/color/color.js';
2
+ import { colorsFunc, funcLike } from '../syntax/color/utils/constants.js';
3
+ import { EnumToken, ColorType } from '../ast/types.js';
6
4
  import '../ast/minify.js';
7
5
  import '../ast/walk.js';
8
6
  import { expand } from '../ast/expand.js';
9
- import { colorMix } from './color/color-mix.js';
10
- import { parseRelativeColor } from './color/relativecolor.js';
11
- import { SourceMap } from './sourcemap/sourcemap.js';
12
7
  import { isColor, pseudoElements, mathFuncs, isNewLine } from '../syntax/syntax.js';
8
+ import { minifyNumber } from '../syntax/utils.js';
9
+ import { SourceMap } from './sourcemap/sourcemap.js';
13
10
 
14
- function reduceNumber(val) {
15
- val = String(+val);
16
- if (val === '0') {
17
- return '0';
18
- }
19
- const chr = val.charAt(0);
20
- if (chr == '-') {
21
- const slice = val.slice(0, 2);
22
- if (slice == '-0') {
23
- return val.length == 2 ? '0' : '-' + val.slice(2);
24
- }
25
- }
26
- if (chr == '0') {
27
- return val.slice(1);
28
- }
29
- return val;
30
- }
31
11
  function update(position, str) {
32
12
  let i = 0;
33
13
  for (; i < str.length; i++) {
@@ -236,10 +216,8 @@ function renderAstNode(data, options, sourcemap, position, errors, reducer, cach
236
216
  case EnumToken.InvalidDeclarationNodeType:
237
217
  case EnumToken.InvalidRuleTokenType:
238
218
  case EnumToken.InvalidAtRuleTokenType:
239
- return '';
240
219
  default:
241
- // return renderToken(data as Token, options, cache, reducer, errors);
242
- throw new Error(`render: unexpected token ${JSON.stringify(data, null, 1)}`);
220
+ return '';
243
221
  }
244
222
  }
245
223
  /**
@@ -315,7 +293,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
315
293
  case EnumToken.FractionTokenType:
316
294
  const fraction = renderToken(token.l) + '/' + renderToken(token.r);
317
295
  if (+token.r.val != 0) {
318
- const value = reduceNumber(+token.l.val / +token.r.val);
296
+ const value = minifyNumber(+token.l.val / +token.r.val);
319
297
  if (value.length <= fraction.length) {
320
298
  return value;
321
299
  }
@@ -331,143 +309,41 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
331
309
  case EnumToken.Div:
332
310
  return '/';
333
311
  case EnumToken.ColorTokenType:
334
- if (token.kin == ColorKind.LIGHT_DARK || ('chi' in token && !options.convertColor)) {
312
+ if (token.kin == ColorType.LIGHT_DARK || ('chi' in token && options.convertColor === false)) {
335
313
  return token.val + '(' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache), '') + ')';
336
314
  }
337
- if (options.convertColor) {
338
- if (token.cal == 'mix' && token.val == 'color-mix') {
339
- const children = token.chi.reduce((acc, t) => {
340
- if (t.typ == EnumToken.ColorTokenType) {
341
- acc.push([t]);
342
- }
343
- else {
344
- if (![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType, EnumToken.CommaTokenType].includes(t.typ)) {
345
- acc[acc.length - 1].push(t);
346
- }
347
- }
348
- return acc;
349
- }, [[]]);
350
- const value = colorMix(children[0][1], children[0][2], children[1][0], children[1][1], children[2][0], children[2][1]);
351
- if (value != null) {
352
- token = value;
353
- }
354
- else if (!token.chi.some(t => t.typ == EnumToken.CommaTokenType)) {
355
- token.chi = children.reduce((acc, curr, index) => {
356
- if (acc.length > 0) {
357
- acc.push({ typ: EnumToken.CommaTokenType });
358
- }
359
- acc.push(...curr);
360
- return acc;
361
- }, []);
362
- }
363
- }
364
- if (token.cal == 'rel' && ['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch', 'color'].includes(token.val)) {
365
- const chi = getComponents(token);
366
- const offset = token.val == 'color' ? 2 : 1;
367
- if (chi != null) {
368
- // @ts-ignore
369
- const color = chi[1];
370
- const components = parseRelativeColor(token.val == 'color' ? chi[offset].val : token.val, color, chi[offset + 1], chi[offset + 2], chi[offset + 3], chi[offset + 4]);
371
- if (components != null) {
372
- token.chi = [...(token.val == 'color' ? [chi[offset]] : []), ...Object.values(components)];
373
- delete token.cal;
374
- }
375
- }
376
- }
377
- if (token.val == 'color') {
378
- if (token.chi[0].typ == EnumToken.IdenTokenType && colorFuncColorSpace.includes(token.chi[0].val.toLowerCase())) {
379
- const values = color2srgbvalues(token);
380
- if (Array.isArray(values) && values.every(t => !Number.isNaN(t))) {
381
- // @ts-ignore
382
- return reduceHexValue(srgb2hexvalues(...values));
383
- }
384
- }
385
- }
386
- if (token.cal != null) {
387
- let slice = false;
388
- if (token.cal == 'rel') {
389
- const last = token.chi.at(-1);
390
- if ((last.typ == EnumToken.NumberTokenType && last.val == '1') || (last.typ == EnumToken.IdenTokenType && last.val == 'none')) {
391
- const prev = token.chi.at(-2);
392
- if (prev.typ == EnumToken.LiteralTokenType && prev.val == '/') {
393
- slice = true;
394
- }
395
- }
396
- }
397
- return clamp(token).val + '(' + (slice ? token.chi.slice(0, -2) : token.chi).reduce((acc, curr) => {
398
- const val = renderToken(curr, options, cache);
399
- if (curr.typ == EnumToken.LiteralTokenType && curr.val == '/') {
400
- return acc.trimEnd() + '/';
401
- }
402
- if (curr.typ == EnumToken.CommaTokenType) {
403
- return acc.trimEnd() + ',';
404
- }
405
- if (curr.typ == EnumToken.WhitespaceTokenType) {
406
- const v = acc.at(-1);
407
- if (v == ' ' || v == ',' || v == '/') {
408
- return acc.trimEnd();
409
- }
410
- return acc.trimEnd() + ' ';
411
- }
412
- if (acc.length > 0) {
413
- return acc + (['/', ',', ' '].includes(acc.at(-1)) ? '' : ' ') + val;
414
- }
415
- return val;
416
- }, '') + ')';
417
- }
418
- if (token.kin == ColorKind.LIT && token.val.localeCompare('currentcolor', undefined, { sensitivity: 'base' }) == 0) {
419
- return 'currentcolor';
420
- }
421
- clamp(token);
422
- if (Array.isArray(token.chi) && token.chi.some((t) => t.typ == EnumToken.FunctionTokenType || (t.typ == EnumToken.ColorTokenType && Array.isArray(t.chi)))) {
423
- const replaceSemiColon = /^((rgba?)|(hsla?)|(hwb)|((ok)?lab)|((ok)?lch))$/i.test(token.val);
424
- return (token.val.endsWith('a') ? token.val.slice(0, -1) : token.val) + '(' + token.chi.reduce((acc, curr, index, array) => {
425
- if (curr.typ == EnumToken.Literal && curr.val == '/') {
426
- return acc.trimEnd() + '/';
427
- }
428
- if (curr.typ == EnumToken.CommaTokenType) {
429
- return acc.trimEnd() + (replaceSemiColon ? ' ' : ',');
430
- }
431
- if (curr.typ == EnumToken.WhitespaceTokenType) {
432
- return /[,\/\s]/.test(acc.at(-1)) ? acc.trimEnd() : acc.trimEnd() + ' ';
433
- }
434
- return acc + renderToken(curr, options, cache);
435
- }, '') + ')';
436
- }
437
- let value = token.kin == ColorKind.HEX ? token.val.toLowerCase() : (token.kin == ColorKind.LIT ? COLORS_NAMES[token.val.toLowerCase()] : '');
438
- if (token.val == 'rgb' || token.val == 'rgba') {
439
- value = rgb2hex(token);
440
- }
441
- else if (token.val == 'hsl' || token.val == 'hsla') {
442
- value = hsl2hex(token);
443
- }
444
- else if (token.val == 'hwb') {
445
- value = hwb2hex(token);
446
- }
447
- else if (token.val == 'device-cmyk') {
448
- value = cmyk2hex(token);
449
- }
450
- else if (token.val == 'oklab') {
451
- value = oklab2hex(token);
452
- }
453
- else if (token.val == 'oklch') {
454
- value = oklch2hex(token);
455
- }
456
- else if (token.val == 'lab') {
457
- value = lab2hex(token);
458
- }
459
- else if (token.val == 'lch') {
460
- value = lch2hex(token);
461
- }
462
- if (value !== '' && value != null) {
463
- return reduceHexValue(value);
315
+ if (options.convertColor !== false) {
316
+ const value = convertColor(token, typeof options.convertColor == 'boolean' ? ColorType.HEX : ColorType[ColorType[options.convertColor ?? 'HEX']?.toUpperCase?.().replaceAll?.('-', '_')] ?? ColorType.HEX);
317
+ //
318
+ if (value != null) {
319
+ token = value;
464
320
  }
465
321
  }
466
- if ([ColorKind.HEX, ColorKind.LIT, ColorKind.SYS, ColorKind.DPSYS].includes(token.kin)) {
322
+ if ([ColorType.HEX, ColorType.LIT, ColorType.SYS, ColorType.DPSYS].includes(token.kin)) {
467
323
  return token.val;
468
324
  }
469
325
  if (Array.isArray(token.chi)) {
470
- return (token.val.endsWith('a') ? token.val.slice(0, -1) : token.val) + '(' + token.chi.reduce((acc, curr) => acc + (acc.length > 0 && !(acc.endsWith('/') || curr.typ == EnumToken.LiteralTokenType) ? ' ' : '') + renderToken(curr, options, cache), '') + ')';
326
+ const isLegacy = ['rgb', 'rgba', 'hsl', 'hsla'].includes(token.val.toLowerCase());
327
+ const useAlpha = (['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'oklab', 'oklch', 'lab', 'lch'].includes(token.val.toLowerCase()) && token.chi.length == 4) ||
328
+ ('color'.localeCompare(token.val, undefined, { sensitivity: 'base' }) == 0 && token.chi.length == 5);
329
+ return (token.val.endsWith('a') ? token.val.slice(0, -1) : token.val) + '(' + token.chi.reduce((acc, curr, index, array) => {
330
+ if (/[,/]\s*$/.test(acc)) {
331
+ if (curr.typ == EnumToken.WhitespaceTokenType) {
332
+ return acc.trimEnd();
333
+ }
334
+ return acc.trimStart() + renderToken(curr, options, cache);
335
+ }
336
+ if (isLegacy && curr.typ == EnumToken.CommaTokenType) {
337
+ return acc.trimEnd() + ' ';
338
+ }
339
+ if (curr.typ == EnumToken.WhitespaceTokenType) {
340
+ return acc.trimEnd() + ' ';
341
+ }
342
+ if (curr.typ == EnumToken.CommaTokenType || (curr.typ == EnumToken.LiteralTokenType && curr.val == '/')) {
343
+ return acc.trimEnd() + (curr.typ == EnumToken.CommaTokenType ? ',' : '/');
344
+ }
345
+ return acc.trimEnd() + (useAlpha && index == array.length - 1 ? '/' : ' ') + renderToken(curr, options, cache);
346
+ }, '').trimStart() + ')';
471
347
  }
472
348
  case EnumToken.ParensTokenType:
473
349
  case EnumToken.FunctionTokenType:
@@ -554,7 +430,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
554
430
  case EnumToken.DimensionTokenType:
555
431
  case EnumToken.FrequencyTokenType:
556
432
  case EnumToken.ResolutionTokenType:
557
- let val = token.val.typ == EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : reduceNumber(token.val);
433
+ let val = token.val.typ == EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : minifyNumber(token.val);
558
434
  let unit = token.unit;
559
435
  if (token.typ == EnumToken.AngleTokenType && !val.includes('/')) {
560
436
  const angle = getAngle(token);
@@ -566,7 +442,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
566
442
  }
567
443
  switch (u) {
568
444
  case 'turn':
569
- v = reduceNumber(angle);
445
+ v = minifyNumber(angle);
570
446
  if (v.length + 4 < value.length) {
571
447
  val = v;
572
448
  unit = u;
@@ -574,7 +450,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
574
450
  }
575
451
  break;
576
452
  case 'deg':
577
- v = reduceNumber(angle * 360);
453
+ v = minifyNumber(angle * 360);
578
454
  if (v.length + 3 < value.length) {
579
455
  val = v;
580
456
  unit = u;
@@ -582,7 +458,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
582
458
  }
583
459
  break;
584
460
  case 'rad':
585
- v = reduceNumber(angle * (2 * Math.PI));
461
+ v = minifyNumber(angle * (2 * Math.PI));
586
462
  if (v.length + 3 < value.length) {
587
463
  val = v;
588
464
  unit = u;
@@ -590,7 +466,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
590
466
  }
591
467
  break;
592
468
  case 'grad':
593
- v = reduceNumber(angle * 400);
469
+ v = minifyNumber(angle * 400);
594
470
  if (v.length + 4 < value.length) {
595
471
  val = v;
596
472
  unit = u;
@@ -616,7 +492,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
616
492
  if (token.typ == EnumToken.TimeTokenType) {
617
493
  if (unit == 'ms') {
618
494
  // @ts-ignore
619
- const v = reduceNumber(val / 1000);
495
+ const v = minifyNumber(val / 1000);
620
496
  if (v.length + 1 <= val.length) {
621
497
  return v + 's';
622
498
  }
@@ -631,10 +507,10 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
631
507
  case EnumToken.FlexTokenType:
632
508
  case EnumToken.PercentageTokenType:
633
509
  const uni = token.typ == EnumToken.PercentageTokenType ? '%' : 'fr';
634
- const perc = token.val.typ == EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : reduceNumber(token.val);
510
+ const perc = token.val.typ == EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : minifyNumber(token.val);
635
511
  return options.minify && perc == '0' ? '0' : (perc.includes('/') ? perc.replace('/', uni + '/') : perc + uni);
636
512
  case EnumToken.NumberTokenType:
637
- return token.val.typ == EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : reduceNumber(token.val);
513
+ return token.val.typ == EnumToken.FractionTokenType ? renderToken(token.val, options, cache) : minifyNumber(token.val);
638
514
  case EnumToken.CommentTokenType:
639
515
  if (options.removeComments && (!options.preserveLicense || !token.val.startsWith('/*!'))) {
640
516
  return '';
@@ -718,4 +594,4 @@ function filterValues(values) {
718
594
  return values;
719
595
  }
720
596
 
721
- export { doRender, filterValues, reduceNumber, renderToken };
597
+ export { doRender, filterValues, renderToken };
@@ -8,7 +8,7 @@ import '../../parser/parse.js';
8
8
  import '../../parser/tokenize.js';
9
9
  import '../../parser/utils/config.js';
10
10
  import { srgb2xyz } from './xyz.js';
11
- import '../sourcemap/lib/encode.js';
11
+ import '../../renderer/sourcemap/lib/encode.js';
12
12
 
13
13
  function a98rgb2srgbvalues(r, g, b, a = null) {
14
14
  // @ts-ignore
@@ -16,7 +16,7 @@ function a98rgb2srgbvalues(r, g, b, a = null) {
16
16
  }
17
17
  function srgb2a98values(r, g, b, a = null) {
18
18
  // @ts-ignore
19
- return la98rgb2a98rgb(xyz2la98rgb(...srgb2xyz(r, g, b, a)));
19
+ return la98rgb2a98rgb(...xyz2la98rgb(...srgb2xyz(r, g, b, a)));
20
20
  }
21
21
  // a98-rgb functions
22
22
  function a98rgb2la98(r, g, b, a = null) {