@tbela99/css-parser 1.3.2 → 1.3.3

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.
@@ -336,7 +336,7 @@
336
336
  /**
337
337
  * keyframe rule node type
338
338
  */
339
- EnumToken[EnumToken["KeyFrameRuleNodeType"] = 73] = "KeyFrameRuleNodeType";
339
+ EnumToken[EnumToken["KeyFramesRuleNodeType"] = 73] = "KeyFramesRuleNodeType";
340
340
  /**
341
341
  * class selector token type
342
342
  */
@@ -416,7 +416,7 @@
416
416
  /**
417
417
  * keyframe at rule node type
418
418
  */
419
- EnumToken[EnumToken["KeyframeAtRuleNodeType"] = 93] = "KeyframeAtRuleNodeType";
419
+ EnumToken[EnumToken["KeyframesAtRuleNodeType"] = 93] = "KeyframesAtRuleNodeType";
420
420
  /**
421
421
  * invalid declaration node type
422
422
  */
@@ -951,12 +951,15 @@
951
951
  function lchToken(values) {
952
952
  values[2] = toPrecisionAngle(values[2]);
953
953
  const chi = [
954
- { typ: exports.EnumToken.NumberTokenType, val: values[0] },
955
- { typ: exports.EnumToken.NumberTokenType, val: values[1] },
954
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
955
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[1]) },
956
956
  { typ: exports.EnumToken.NumberTokenType, val: values[2] },
957
957
  ];
958
958
  if (values.length == 4) {
959
- chi.push({ typ: exports.EnumToken.LiteralTokenType, val: '/' }, { typ: exports.EnumToken.PercentageTokenType, val: values[3] * 100 });
959
+ chi.push({ typ: exports.EnumToken.LiteralTokenType, val: '/' }, {
960
+ typ: exports.EnumToken.PercentageTokenType,
961
+ val: values[3] * 100
962
+ });
960
963
  }
961
964
  return {
962
965
  typ: exports.EnumToken.ColorTokenType,
@@ -1219,8 +1222,8 @@
1219
1222
  function oklchToken(values) {
1220
1223
  values[2] = toPrecisionAngle(values[2]);
1221
1224
  const chi = [
1222
- { typ: exports.EnumToken.NumberTokenType, val: values[0] },
1223
- { typ: exports.EnumToken.NumberTokenType, val: values[1] },
1225
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
1226
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[1]) },
1224
1227
  { typ: exports.EnumToken.NumberTokenType, val: values[2] },
1225
1228
  ];
1226
1229
  if (values.length == 4) {
@@ -1262,16 +1265,28 @@
1262
1265
  return values == null ? null : srgb2oklch(...values);
1263
1266
  }
1264
1267
  function lab2oklchvalues(token) {
1268
+ const values = lab2oklabvalues(token);
1269
+ if (values == null) {
1270
+ return null;
1271
+ }
1265
1272
  // @ts-ignore
1266
- return labvalues2lchvalues(...lab2oklabvalues(token));
1273
+ return labvalues2lchvalues(...values);
1267
1274
  }
1268
1275
  function lch2oklchvalues(token) {
1276
+ const values = lch2oklabvalues(token);
1277
+ if (values == null) {
1278
+ return null;
1279
+ }
1269
1280
  // @ts-ignore
1270
- return labvalues2lchvalues(...lch2oklabvalues(token));
1281
+ return labvalues2lchvalues(...values);
1271
1282
  }
1272
1283
  function oklab2oklchvalues(token) {
1284
+ const values = getOKLABComponents(token);
1285
+ if (values == null) {
1286
+ return null;
1287
+ }
1273
1288
  // @ts-ignore
1274
- return labvalues2lchvalues(...getOKLABComponents(token));
1289
+ return labvalues2lchvalues(...values);
1275
1290
  }
1276
1291
  function srgb2oklch(r, g, blue, alpha) {
1277
1292
  // @ts-ignore
@@ -1371,9 +1386,9 @@
1371
1386
  }
1372
1387
  function oklabToken(values) {
1373
1388
  const chi = [
1374
- { typ: exports.EnumToken.NumberTokenType, val: values[0] },
1375
- { typ: exports.EnumToken.NumberTokenType, val: values[1] },
1376
- { typ: exports.EnumToken.NumberTokenType, val: values[2] },
1389
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
1390
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[1]) },
1391
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[2]) },
1377
1392
  ];
1378
1393
  if (values.length == 4) {
1379
1394
  chi.push({ typ: exports.EnumToken.LiteralTokenType, val: '/' }, {
@@ -1589,9 +1604,9 @@
1589
1604
  }
1590
1605
  function labToken(values) {
1591
1606
  const chi = [
1592
- { typ: exports.EnumToken.NumberTokenType, val: values[0] },
1593
- { typ: exports.EnumToken.NumberTokenType, val: values[1] },
1594
- { typ: exports.EnumToken.NumberTokenType, val: values[2] },
1607
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
1608
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[1]) },
1609
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[2]) },
1595
1610
  ];
1596
1611
  if (values.length == 4) {
1597
1612
  chi.push({ typ: exports.EnumToken.LiteralTokenType, val: '/' }, {
@@ -1992,7 +2007,7 @@
1992
2007
  return null;
1993
2008
  }
1994
2009
  const rgb = Lab_to_sRGB(l, a, b);
1995
- if (alpha != null && alpha != 1) {
2010
+ if (alpha != null && alpha < 1) {
1996
2011
  rgb.push(alpha);
1997
2012
  }
1998
2013
  return rgb;
@@ -2072,6 +2087,9 @@
2072
2087
  value[7] == value[8]) {
2073
2088
  value = `#${value[1]}${value[3]}${value[5]}${value[7] == 'f' ? '' : value[7]}`;
2074
2089
  }
2090
+ if (value.endsWith('ff')) {
2091
+ value = value.slice(0, -2);
2092
+ }
2075
2093
  }
2076
2094
  return named_color != null && named_color.length <= value.length ? named_color : value;
2077
2095
  }
@@ -2492,12 +2510,15 @@
2492
2510
  function hslToken(values) {
2493
2511
  values[0] = toPrecisionAngle(values[0] * 360);
2494
2512
  const chi = [
2495
- { typ: exports.EnumToken.NumberTokenType, val: values[0] },
2496
- { typ: exports.EnumToken.PercentageTokenType, val: values[1] * 100 },
2497
- { typ: exports.EnumToken.PercentageTokenType, val: values[2] * 100 },
2513
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
2514
+ { typ: exports.EnumToken.PercentageTokenType, val: toPrecisionValue(values[1]) * 100 },
2515
+ { typ: exports.EnumToken.PercentageTokenType, val: toPrecisionValue(values[2]) * 100 },
2498
2516
  ];
2499
2517
  if (values.length == 4 && values[3] != 1) {
2500
- chi.push({ typ: exports.EnumToken.LiteralTokenType, val: '/' }, { typ: exports.EnumToken.PercentageTokenType, val: values[3] * 100 });
2518
+ chi.push({ typ: exports.EnumToken.LiteralTokenType, val: '/' }, {
2519
+ typ: exports.EnumToken.PercentageTokenType,
2520
+ val: values[3] * 100
2521
+ });
2501
2522
  }
2502
2523
  return {
2503
2524
  typ: exports.EnumToken.ColorTokenType,
@@ -2563,12 +2584,20 @@
2563
2584
  return hsv2hsl(...hwb2hsv(...Object.values(hslvalues(token))));
2564
2585
  }
2565
2586
  function lab2hslvalues(token) {
2587
+ const values = lab2rgbvalues(token);
2588
+ if (values == null) {
2589
+ return null;
2590
+ }
2566
2591
  // @ts-ignore
2567
- return rgbvalues2hslvalues(...lab2rgbvalues(token));
2592
+ return rgbvalues2hslvalues(...values);
2568
2593
  }
2569
2594
  function lch2hslvalues(token) {
2595
+ const values = lch2rgbvalues(token);
2596
+ if (values == null) {
2597
+ return null;
2598
+ }
2570
2599
  // @ts-ignore
2571
- return rgbvalues2hslvalues(...lch2rgbvalues(token));
2600
+ return rgbvalues2hslvalues(...values);
2572
2601
  }
2573
2602
  function oklab2hslvalues(token) {
2574
2603
  const t = oklab2srgbvalues(token);
@@ -2674,8 +2703,8 @@
2674
2703
  values[0] = toPrecisionAngle(values[0] * 360);
2675
2704
  const chi = [
2676
2705
  { typ: exports.EnumToken.NumberTokenType, val: values[0] },
2677
- { typ: exports.EnumToken.PercentageTokenType, val: values[1] * 100 },
2678
- { typ: exports.EnumToken.PercentageTokenType, val: values[2] * 100 },
2706
+ { typ: exports.EnumToken.PercentageTokenType, val: toPrecisionValue(values[1]) * 100 },
2707
+ { typ: exports.EnumToken.PercentageTokenType, val: toPrecisionValue(values[2]) * 100 },
2679
2708
  ];
2680
2709
  if (values.length == 4) {
2681
2710
  chi.push({ typ: exports.EnumToken.LiteralTokenType, val: '/' }, {
@@ -3069,11 +3098,10 @@
3069
3098
  // @ts-ignore
3070
3099
  const calculate = () => [colorSpace].concat(values1.map((v1, i) => {
3071
3100
  return {
3072
- // @ts-ignore
3073
- typ: exports.EnumToken.NumberTokenType, val: String((mul1 * v1 * p1 + mul2 * values2[i] * p2) / mul)
3101
+ typ: exports.EnumToken.NumberTokenType, val: (mul1 * v1 * p1 + mul2 * values2[i] * p2) / mul
3074
3102
  };
3075
3103
  }).concat(mul == 1 ? [] : [{
3076
- typ: exports.EnumToken.NumberTokenType, val: String(mul)
3104
+ typ: exports.EnumToken.NumberTokenType, val: mul
3077
3105
  }]));
3078
3106
  switch (colorSpace.val) {
3079
3107
  case 'srgb':
@@ -3816,7 +3844,7 @@
3816
3844
  let keys = {};
3817
3845
  let values = {};
3818
3846
  // colorFuncColorSpace x,y,z or r,g,b
3819
- const names = relativeKeys.startsWith('xyz') ? 'xyz' : relativeKeys.slice(-3);
3847
+ const names = relativeKeys.startsWith('xyz') ? 'xyz' : ['srgb', 'srgb-linear', 'display-p3', 'a98-rgb', 'prophoto-rgb', 'rec2020', 'rgb'].includes(relativeKeys.toLowerCase()) ? 'rgb' : relativeKeys.slice(-3);
3820
3848
  const converted = convertColor(original, exports.ColorType[relativeKeys.toUpperCase().replaceAll('-', '_')]);
3821
3849
  if (converted == null) {
3822
3850
  return null;
@@ -3830,13 +3858,13 @@
3830
3858
  // @ts-ignore
3831
3859
  alpha: alpha == null ? {
3832
3860
  typ: exports.EnumToken.NumberTokenType,
3833
- val: '1'
3861
+ val: 1
3834
3862
  } : (alpha.typ == exports.EnumToken.IdenTokenType && alpha.val == 'none') ? {
3835
3863
  typ: exports.EnumToken.NumberTokenType,
3836
- val: '0'
3864
+ val: 0
3837
3865
  } : (alpha.typ == exports.EnumToken.PercentageTokenType ? {
3838
3866
  typ: exports.EnumToken.NumberTokenType,
3839
- val: String(getNumber(alpha))
3867
+ val: getNumber(alpha)
3840
3868
  } : alpha)
3841
3869
  };
3842
3870
  keys = {
@@ -3846,19 +3874,15 @@
3846
3874
  // @ts-ignore
3847
3875
  alpha: getValue(aExp == null ? {
3848
3876
  typ: exports.EnumToken.NumberTokenType,
3849
- val: '1'
3877
+ val: 1
3850
3878
  } : (aExp.typ == exports.EnumToken.IdenTokenType && aExp.val == 'none') ? {
3851
3879
  typ: exports.EnumToken.NumberTokenType,
3852
- val: '0'
3880
+ val: 0
3853
3881
  } : aExp)
3854
3882
  };
3855
3883
  return computeComponentValue(keys, converted, values);
3856
3884
  }
3857
3885
  function getValue(t, converted, component) {
3858
- // if (t == null) {
3859
- //
3860
- // return t;
3861
- // }
3862
3886
  if (t.typ == exports.EnumToken.PercentageTokenType) {
3863
3887
  let value = getNumber(t);
3864
3888
  let colorSpace = exports.ColorType[converted.kin].toLowerCase().replaceAll('-', '_');
@@ -3888,55 +3912,13 @@
3888
3912
  }
3889
3913
  }
3890
3914
  for (const [key, exp] of Object.entries(expr)) {
3891
- /*
3892
- if (exp == null) {
3893
-
3894
- if (key in values) {
3895
-
3896
- if (typeof values[<RelativeColorTypes>key] == 'number') {
3897
-
3898
- expr[<RelativeColorTypes>key] = {
3899
- typ: EnumToken.NumberTokenType,
3900
- val: reduceNumber(<number>values[<RelativeColorTypes>key])
3901
- };
3902
- } else {
3903
-
3904
- expr[<RelativeColorTypes>key] = <Token>values[<RelativeColorTypes>key];
3905
- }
3906
- }
3907
-
3908
- } else
3909
- */
3910
3915
  if ([exports.EnumToken.NumberTokenType, exports.EnumToken.PercentageTokenType, exports.EnumToken.AngleTokenType, exports.EnumToken.LengthTokenType].includes(exp.typ)) ;
3911
3916
  else if (exp.typ == exports.EnumToken.IdenTokenType && exp.val in values) {
3912
- // if (typeof values[<RelativeColorTypes>exp.val] == 'number') {
3913
- //
3914
- // expr[<RelativeColorTypes>key] = {
3915
- // typ: EnumToken.NumberTokenType,
3916
- // val: reduceNumber(<number>values[<RelativeColorTypes>exp.val])
3917
- // };
3918
- // } else {
3919
3917
  expr[key] = values[exp.val];
3920
- // }
3921
3918
  }
3922
3919
  else if (exp.typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(exp.val)) {
3923
3920
  for (let { value, parent } of walkValues(exp.chi, exp)) {
3924
- // if (parent == null) {
3925
- //
3926
- // parent = exp;
3927
- // }
3928
- /*
3929
- if (value.typ == EnumToken.PercentageTokenType) {
3930
-
3931
- replaceValue(parent as BinaryExpressionToken | FunctionToken | ParensToken, value, getValue(value, converted, <RelativeColorTypes>key));
3932
- } else
3933
- */
3934
3921
  if (value.typ == exports.EnumToken.IdenTokenType) {
3935
- // @ts-ignore
3936
- // if (!(value.val in values || typeof Math[(value as IdentToken).val.toUpperCase()] == 'number')) {
3937
- //
3938
- // return null;
3939
- // }
3940
3922
  // @ts-ignore
3941
3923
  replaceValue(parent, value, values[value.val] ?? {
3942
3924
  typ: exports.EnumToken.NumberTokenType,
@@ -3950,10 +3932,6 @@
3950
3932
  if (result.length == 1 && result[0].typ != exports.EnumToken.BinaryExpressionTokenType) {
3951
3933
  expr[key] = result[0];
3952
3934
  }
3953
- // else {
3954
- //
3955
- // return null;
3956
- // }
3957
3935
  }
3958
3936
  }
3959
3937
  return expr;
@@ -3964,13 +3942,16 @@
3964
3942
  if (pr.typ == exports.EnumToken.BinaryExpressionTokenType) {
3965
3943
  if (pr.l == val) {
3966
3944
  pr.l = newValue;
3945
+ return;
3967
3946
  }
3968
3947
  else {
3969
3948
  pr.r = newValue;
3949
+ return;
3970
3950
  }
3971
3951
  }
3972
3952
  else {
3973
3953
  pr.chi.splice(pr.chi.indexOf(val), 1, newValue);
3954
+ return;
3974
3955
  }
3975
3956
  }
3976
3957
  }
@@ -4058,11 +4039,14 @@
4058
4039
  chi: values.reduce((acc, curr, index) => index < 4 ? [...acc, {
4059
4040
  typ: exports.EnumToken.PercentageTokenType,
4060
4041
  // @ts-ignore
4061
- val: curr * 100
4042
+ val: toPrecisionValue(curr) * 100
4062
4043
  }] : [...acc, {
4063
4044
  typ: exports.EnumToken.LiteralTokenType,
4064
4045
  val: '/'
4065
- }, { typ: exports.EnumToken.PercentageTokenType, val: curr * 100 }], []),
4046
+ }, {
4047
+ typ: exports.EnumToken.PercentageTokenType,
4048
+ val: toPrecisionValue(curr) * 100
4049
+ }], []),
4066
4050
  kin: exports.ColorType.DEVICE_CMYK
4067
4051
  };
4068
4052
  }
@@ -4121,144 +4105,401 @@
4121
4105
  return multiplyMatrices(M, [x, y, z]).concat(a == null || a == 1 ? [] : [a]);
4122
4106
  }
4123
4107
 
4124
- /**
4125
- * Converts a color to another color space
4126
- * @param token
4127
- * @param to
4128
- *
4129
- * <code>
4130
- *
4131
- * const token = {typ: EnumToken.ColorTokenType, kin: ColorType.HEX, val: '#F00'}
4132
- * const result = convertColor(token, ColorType.LCH);
4133
- *
4134
- * </code>
4135
- */
4136
- function convertColor(token, to) {
4137
- if (token.kin == exports.ColorType.SYS ||
4138
- token.kin == exports.ColorType.DPSYS ||
4139
- (isIdentColor(token) &&
4140
- 'currentcolor' == token.val.toLowerCase())) {
4141
- return token;
4108
+ const epsilon = 1e-5;
4109
+ function identity() {
4110
+ return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
4111
+ }
4112
+ function pLength(point) {
4113
+ return Math.sqrt(point[0] * point[0] + point[1] * point[1] + point[2] * point[2]);
4114
+ }
4115
+ function normalize(point) {
4116
+ const [x, y, z] = point;
4117
+ const norm = Math.sqrt(point[0] * point[0] + point[1] * point[1] + point[2] * point[2]);
4118
+ return norm === 0 ? [0, 0, 0] : [x / norm, y / norm, z / norm];
4119
+ }
4120
+ function dot(point1, point2) {
4121
+ if (point1.length === 4 && point2.length === 4) {
4122
+ return point1[0] * point2[0] + point1[1] * point2[1] + point1[2] * point2[2] + point1[3] * point2[3];
4142
4123
  }
4143
- if (token.kin == exports.ColorType.COLOR_MIX && to != exports.ColorType.COLOR_MIX) {
4144
- const children = token.chi.reduce((acc, t) => {
4145
- if (t.typ == exports.EnumToken.ColorTokenType) {
4146
- acc.push([t]);
4147
- }
4148
- else {
4149
- if (![exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommentTokenType, exports.EnumToken.CommaTokenType].includes(t.typ)) {
4150
- acc[acc.length - 1].push(t);
4151
- }
4124
+ return point1[0] * point2[0] + point1[1] * point2[1] + point1[2] * point2[2];
4125
+ }
4126
+ function multiply(matrixA, matrixB) {
4127
+ let result = new Array(16).fill(0);
4128
+ for (let i = 0; i < 4; i++) {
4129
+ for (let j = 0; j < 4; j++) {
4130
+ for (let k = 0; k < 4; k++) {
4131
+ // Utiliser l'indexation linéaire pour accéder aux éléments
4132
+ // Pour une matrice 4x4, l'index est (row * 4 + col)
4133
+ result[j * 4 + i] += matrixA[k * 4 + i] * matrixB[j * 4 + k];
4152
4134
  }
4153
- return acc;
4154
- }, [[]]);
4155
- token = colorMix(children[0][1], children[0][2], children[1][0], children[1][1], children[2][0], children[2][1]);
4156
- if (token == null) {
4157
- return null;
4158
4135
  }
4159
4136
  }
4160
- if (token.cal == 'rel' && ['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch', 'color'].includes(token.val.toLowerCase())) {
4161
- const chi = getComponents(token);
4162
- const offset = token.val == 'color' ? 2 : 1;
4163
- if (chi != null) {
4164
- // @ts-ignore
4165
- const color = chi[1];
4166
- const components = parseRelativeColor(token.val.toLowerCase() == 'color' ? chi[offset].val : token.val, color, chi[offset + 1], chi[offset + 2], chi[offset + 3], chi[offset + 4]);
4167
- if (components != null) {
4168
- token = {
4169
- ...token,
4170
- chi: [...(token.val == 'color' ? [chi[offset]] : []), ...Object.values(components)]
4171
- };
4172
- delete token.cal;
4137
+ return result;
4138
+ }
4139
+ function inverse(matrix) {
4140
+ // Create augmented matrix [matrix | identity]
4141
+ let augmented = [
4142
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
4143
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1
4144
+ ];
4145
+ // Gaussian elimination with partial pivoting
4146
+ for (let col = 0; col < 4; col++) {
4147
+ // Find pivot row with maximum absolute value
4148
+ let maxRow = col;
4149
+ let maxVal = Math.abs(augmented[col * 4 + col]);
4150
+ for (let row = col + 1; row < 4; row++) {
4151
+ let val = Math.abs(augmented[row * 4 + col]);
4152
+ if (val > maxVal) {
4153
+ maxVal = val;
4154
+ maxRow = row;
4173
4155
  }
4174
4156
  }
4175
- }
4176
- if (token.kin == to) {
4177
- if (token.kin == exports.ColorType.HEX || token.kin == exports.ColorType.LIT) {
4178
- token.val = reduceHexValue(token.val);
4179
- token.kin = token.val[0] == '#' ? exports.ColorType.HEX : exports.ColorType.LIT;
4180
- }
4181
- return token;
4182
- }
4183
- if (token.kin == exports.ColorType.COLOR) {
4184
- const colorSpace = token.chi.find(t => ![exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommentTokenType].includes(t.typ));
4185
- if (colorSpace.val == exports.ColorType[to].toLowerCase().replaceAll('_', '-')) {
4186
- return token;
4157
+ // Check for singularity
4158
+ if (maxVal < 1e-5) {
4159
+ return null;
4187
4160
  }
4188
- }
4189
- if (to == exports.ColorType.HSL) {
4190
- switch (token.kin) {
4191
- case exports.ColorType.RGB:
4192
- case exports.ColorType.RGBA:
4193
- return rgb2HslToken(token);
4194
- case exports.ColorType.HEX:
4195
- case exports.ColorType.LIT:
4196
- return hex2HslToken(token);
4197
- case exports.ColorType.HWB:
4198
- return hwb2HslToken(token);
4199
- case exports.ColorType.DEVICE_CMYK:
4200
- return cmyk2HslToken(token);
4201
- case exports.ColorType.OKLAB:
4202
- return oklab2HslToken(token);
4203
- case exports.ColorType.OKLCH:
4204
- return oklch2HslToken(token);
4205
- case exports.ColorType.LAB:
4206
- return lab2HslToken(token);
4207
- case exports.ColorType.LCH:
4208
- return lch2HslToken(token);
4209
- case exports.ColorType.COLOR:
4210
- return color2HslToken(token);
4161
+ // Swap rows if necessary
4162
+ if (maxRow !== col) {
4163
+ [augmented[col], augmented[maxRow]] = [augmented[maxRow], augmented[col]];
4211
4164
  }
4212
- }
4213
- else if (to == exports.ColorType.HWB) {
4214
- switch (token.kin) {
4215
- case exports.ColorType.RGB:
4216
- case exports.ColorType.RGBA:
4217
- return rgb2hwbToken(token);
4218
- case exports.ColorType.HEX:
4219
- case exports.ColorType.LIT:
4220
- return rgb2hwbToken(token);
4221
- case exports.ColorType.HSL:
4222
- case exports.ColorType.HSLA:
4223
- return hsl2hwbToken(token);
4224
- case exports.ColorType.OKLAB:
4225
- return oklab2hwbToken(token);
4226
- case exports.ColorType.OKLCH:
4227
- return oklch2hwbToken(token);
4228
- case exports.ColorType.LAB:
4229
- return lab2hwbToken(token);
4230
- case exports.ColorType.LCH:
4231
- return lch2hwbToken(token);
4232
- case exports.ColorType.DEVICE_CMYK:
4233
- return cmyk2hwbToken(token);
4234
- case exports.ColorType.COLOR:
4235
- return color2hwbToken(token);
4165
+ // Scale pivot row to make pivot element 1
4166
+ let pivot = augmented[col * 4 + col];
4167
+ for (let j = 0; j < 8; j++) {
4168
+ augmented[col * 4 + j] /= pivot;
4236
4169
  }
4237
- }
4238
- else if (to == exports.ColorType.DEVICE_CMYK) {
4239
- switch (token.kin) {
4240
- case exports.ColorType.RGB:
4241
- case exports.ColorType.RGBA:
4242
- return rgb2cmykToken(token);
4243
- case exports.ColorType.HEX:
4244
- case exports.ColorType.LIT:
4245
- return rgb2cmykToken(token);
4246
- case exports.ColorType.HSL:
4247
- case exports.ColorType.HSLA:
4248
- return hsl2cmykToken(token);
4249
- case exports.ColorType.HWB:
4250
- return hwb2cmykToken(token);
4251
- case exports.ColorType.OKLAB:
4252
- return oklab2cmyk(token);
4253
- case exports.ColorType.OKLCH:
4254
- return oklch2cmykToken(token);
4255
- case exports.ColorType.LAB:
4256
- return lab2cmykToken(token);
4257
- //
4258
- case exports.ColorType.LCH:
4259
- return lch2cmykToken(token);
4260
- case exports.ColorType.COLOR:
4261
- return color2cmykToken(token);
4170
+ // Eliminate column in other rows
4171
+ for (let row = 0; row < 4; row++) {
4172
+ if (row !== col) {
4173
+ let factor = augmented[row * 4 + col];
4174
+ for (let j = 0; j < 8; j++) {
4175
+ augmented[row * 4 + j] -= factor * augmented[col * 4 + j];
4176
+ }
4177
+ }
4178
+ }
4179
+ }
4180
+ // Extract the inverse from the right side of the augmented matrix
4181
+ return augmented.slice(0, 16);
4182
+ }
4183
+ // function transpose(matrix: Matrix): Matrix {
4184
+ // // Crée une nouvelle matrice vide 4x4
4185
+ // // @ts-ignore
4186
+ // let transposed: Matrix = [[], [], [], []] as Matrix;
4187
+ //
4188
+ // // Parcourt chaque ligne et colonne pour transposer
4189
+ // for (let i = 0; i < 4; i++) {
4190
+ //
4191
+ // for (let j = 0; j < 4; j++) {
4192
+ //
4193
+ // transposed[j][i] = matrix[i][j];
4194
+ // }
4195
+ // }
4196
+ //
4197
+ // return transposed;
4198
+ // }
4199
+ function round(number) {
4200
+ return Math.abs(number) < epsilon ? 0 : +number.toPrecision(6);
4201
+ }
4202
+ // translate3d(25.9808px, 0, 15px ) rotateY(60deg) skewX(49.9999deg) scale(1, 1.2)
4203
+ // translate → rotate → skew → scale
4204
+ function decompose(original) {
4205
+ const matrix = original.slice();
4206
+ // Normalize last row
4207
+ if (matrix[15] === 0) {
4208
+ return null;
4209
+ }
4210
+ for (let i = 0; i < 16; i++)
4211
+ matrix[i] /= matrix[15];
4212
+ // Perspective extraction
4213
+ const perspective = [0, 0, 0, 1];
4214
+ if (matrix[3] !== 0 || matrix[7] !== 0 || matrix[11] !== 0) {
4215
+ const rightHandSide = [matrix[3], matrix[7], matrix[11], matrix[15]];
4216
+ const perspectiveMatrix = matrix.slice();
4217
+ perspectiveMatrix[3] = 0;
4218
+ perspectiveMatrix[7] = 0;
4219
+ perspectiveMatrix[11] = 0;
4220
+ perspectiveMatrix[15] = 1;
4221
+ // @ts-ignore
4222
+ const inverted = inverse(original.slice());
4223
+ if (!inverted) {
4224
+ return null;
4225
+ }
4226
+ const transposedInverse = transposeMatrix4(inverted);
4227
+ perspective[0] = dot(rightHandSide, transposedInverse.slice(0, 4));
4228
+ perspective[1] = dot(rightHandSide, transposedInverse.slice(4, 8));
4229
+ perspective[2] = dot(rightHandSide, transposedInverse.slice(8, 12));
4230
+ perspective[3] = dot(rightHandSide, transposedInverse.slice(12, 16));
4231
+ // Clear perspective from matrix
4232
+ matrix[3] = 0;
4233
+ matrix[7] = 0;
4234
+ matrix[11] = 0;
4235
+ matrix[15] = 1;
4236
+ }
4237
+ // Translation
4238
+ const translate = [matrix[12], matrix[13], matrix[14]];
4239
+ matrix[12] = matrix[13] = matrix[14] = 0;
4240
+ // Build the 3x3 matrix
4241
+ const row0 = [matrix[0], matrix[1], matrix[2]];
4242
+ const row1 = [matrix[4], matrix[5], matrix[6]];
4243
+ const row2 = [matrix[8], matrix[9], matrix[10]];
4244
+ // Compute scale
4245
+ const scaleX = pLength(row0);
4246
+ const row0Norm = normalize(row0);
4247
+ const skewXY = dot(row0Norm, row1);
4248
+ const row1Proj = [
4249
+ row1[0] - skewXY * row0Norm[0],
4250
+ row1[1] - skewXY * row0Norm[1],
4251
+ row1[2] - skewXY * row0Norm[2]
4252
+ ];
4253
+ const scaleY = pLength(row1Proj);
4254
+ const row1Norm = normalize(row1Proj);
4255
+ const skewXZ = dot(row0Norm, row2);
4256
+ const skewYZ = dot(row1Norm, row2);
4257
+ const row2Proj = [
4258
+ row2[0] - skewXZ * row0Norm[0] - skewYZ * row1Norm[0],
4259
+ row2[1] - skewXZ * row0Norm[1] - skewYZ * row1Norm[1],
4260
+ row2[2] - skewXZ * row0Norm[2] - skewYZ * row1Norm[2]
4261
+ ];
4262
+ const scaleZ = pLength(row2Proj);
4263
+ const row2Norm = normalize(row2Proj);
4264
+ // Build rotation matrix from orthonormalized vectors
4265
+ const r00 = row0Norm[0], r01 = row1Norm[0], r02 = row2Norm[0];
4266
+ const r10 = row0Norm[1], r11 = row1Norm[1], r12 = row2Norm[1];
4267
+ const r20 = row0Norm[2], r21 = row1Norm[2], r22 = row2Norm[2];
4268
+ // Convert to quaternion
4269
+ const trace = r00 + r11 + r22;
4270
+ let qw, qx, qy, qz;
4271
+ if (trace > 0) {
4272
+ const s = 0.5 / Math.sqrt(trace + 1.0);
4273
+ qw = 0.25 / s;
4274
+ qx = (r21 - r12) * s;
4275
+ qy = (r02 - r20) * s;
4276
+ qz = (r10 - r01) * s;
4277
+ }
4278
+ else if (r00 > r11 && r00 > r22) {
4279
+ const s = 2.0 * Math.sqrt(1.0 + r00 - r11 - r22);
4280
+ qw = (r21 - r12) / s;
4281
+ qx = 0.25 * s;
4282
+ qy = (r01 + r10) / s;
4283
+ qz = (r02 + r20) / s;
4284
+ }
4285
+ else if (r11 > r22) {
4286
+ const s = 2.0 * Math.sqrt(1.0 + r11 - r00 - r22);
4287
+ qw = (r02 - r20) / s;
4288
+ qx = (r01 + r10) / s;
4289
+ qy = 0.25 * s;
4290
+ qz = (r12 + r21) / s;
4291
+ }
4292
+ else {
4293
+ const s = 2.0 * Math.sqrt(1.0 + r22 - r00 - r11);
4294
+ qw = (r10 - r01) / s;
4295
+ qx = (r02 + r20) / s;
4296
+ qy = (r12 + r21) / s;
4297
+ qz = 0.25 * s;
4298
+ }
4299
+ [qx, qy, qz] = toZero([qx, qy, qz]);
4300
+ // const q = gcd(qx, gcd(qy, qz));
4301
+ let q = [Math.abs(qx), Math.abs(qy), Math.abs(qz)].reduce((acc, curr) => {
4302
+ if (acc == 0 || (curr > 0 && curr < acc)) {
4303
+ acc = curr;
4304
+ }
4305
+ return acc;
4306
+ }, 0);
4307
+ if (q > 0) {
4308
+ qx /= q;
4309
+ qy /= q;
4310
+ qz /= q;
4311
+ }
4312
+ const rotate = [qx, qy, qz, Object.is(qw, 0) ? 0 : 2 * Math.acos(qw) * 180 / Math.PI];
4313
+ const scale = [scaleX, scaleY, scaleZ];
4314
+ const skew = [skewXY, skewXZ, skewYZ];
4315
+ return {
4316
+ translate,
4317
+ scale,
4318
+ rotate,
4319
+ skew,
4320
+ perspective
4321
+ };
4322
+ }
4323
+ function transposeMatrix4(m) {
4324
+ return [
4325
+ m[0], m[4], m[8], m[12],
4326
+ m[1], m[5], m[9], m[13],
4327
+ m[2], m[6], m[10], m[14],
4328
+ m[3], m[7], m[11], m[15],
4329
+ ];
4330
+ }
4331
+ function toZero(v) {
4332
+ for (let i = 0; i < v.length; i++) {
4333
+ if (Math.abs(v[i]) <= epsilon) {
4334
+ v[i] = 0;
4335
+ }
4336
+ else {
4337
+ v[i] = +v[i].toPrecision(6);
4338
+ }
4339
+ }
4340
+ return v;
4341
+ }
4342
+ // https://drafts.csswg.org/css-transforms-1/#2d-matrix
4343
+ function is2DMatrix(matrix) {
4344
+ // m13,m14, m23, m24, m31, m32, m34, m43 are all 0
4345
+ return matrix[0 * 4 + 2] === 0 &&
4346
+ matrix[0 * 4 + 3] === 0 &&
4347
+ matrix[1 * 4 + 2] === 0 &&
4348
+ matrix[1 * 4 + 3] === 0 &&
4349
+ matrix[2 * 4 + 0] === 0 &&
4350
+ matrix[2 * 4 + 1] === 0 &&
4351
+ matrix[2 * 4 + 3] === 0 &&
4352
+ matrix[3 * 4 + 2] === 0 &&
4353
+ matrix[2 * 4 + 2] === 1 &&
4354
+ matrix[3 * 4 + 3] === 1;
4355
+ }
4356
+
4357
+ /**
4358
+ * Converts a color to another color space
4359
+ * @param token
4360
+ * @param to
4361
+ *
4362
+ * @private
4363
+ *
4364
+ * <code>
4365
+ *
4366
+ * const token = {typ: EnumToken.ColorTokenType, kin: ColorType.HEX, val: '#F00'}
4367
+ * const result = convertColor(token, ColorType.LCH);
4368
+ *
4369
+ * </code>
4370
+ */
4371
+ function convertColor(token, to) {
4372
+ if (token.kin == exports.ColorType.SYS ||
4373
+ token.kin == exports.ColorType.DPSYS ||
4374
+ (isIdentColor(token) &&
4375
+ 'currentcolor' == token.val.toLowerCase())) {
4376
+ return token;
4377
+ }
4378
+ if (token.kin == exports.ColorType.COLOR_MIX && to != exports.ColorType.COLOR_MIX) {
4379
+ const children = token.chi.reduce((acc, t) => {
4380
+ if (t.typ == exports.EnumToken.ColorTokenType) {
4381
+ acc.push([t]);
4382
+ }
4383
+ else {
4384
+ if (![exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommentTokenType, exports.EnumToken.CommaTokenType].includes(t.typ)) {
4385
+ acc[acc.length - 1].push(t);
4386
+ }
4387
+ }
4388
+ return acc;
4389
+ }, [[]]);
4390
+ token = colorMix(children[0][1], children[0][2], children[1][0], children[1][1], children[2][0], children[2][1]);
4391
+ if (token == null) {
4392
+ return null;
4393
+ }
4394
+ }
4395
+ if (token.cal == 'rel' && ['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch', 'color'].includes(token.val.toLowerCase())) {
4396
+ const chi = getComponents(token);
4397
+ const offset = token.val == 'color' ? 2 : 1;
4398
+ if (chi != null) {
4399
+ // @ts-ignore
4400
+ const color = chi[1];
4401
+ const components = parseRelativeColor(token.val.toLowerCase() == 'color' ? chi[offset].val : token.val, color, chi[offset + 1], chi[offset + 2], chi[offset + 3], chi[offset + 4]);
4402
+ if (components != null) {
4403
+ token = {
4404
+ ...token,
4405
+ chi: [...(token.val == 'color' ? [chi[offset]] : []), ...Object.values(components)],
4406
+ kin: exports.ColorType[token.val.toUpperCase().replaceAll('-', '_')]
4407
+ };
4408
+ delete token.cal;
4409
+ }
4410
+ }
4411
+ }
4412
+ if (token.kin == to) {
4413
+ if (token.kin == exports.ColorType.HEX || token.kin == exports.ColorType.LIT) {
4414
+ token.val = reduceHexValue(token.val);
4415
+ token.kin = token.val[0] == '#' ? exports.ColorType.HEX : exports.ColorType.LIT;
4416
+ }
4417
+ return token;
4418
+ }
4419
+ if (token.kin == exports.ColorType.COLOR) {
4420
+ const colorSpace = token.chi.find(t => ![exports.EnumToken.WhitespaceTokenType, exports.EnumToken.CommentTokenType].includes(t.typ));
4421
+ if (colorSpace.val == exports.ColorType[to].toLowerCase().replaceAll('_', '-')) {
4422
+ for (const chi of token.chi) {
4423
+ if (chi.typ == exports.EnumToken.NumberTokenType && typeof chi.val == 'number') {
4424
+ chi.val = toPrecisionValue(getNumber(chi));
4425
+ }
4426
+ }
4427
+ return token;
4428
+ }
4429
+ }
4430
+ if (to == exports.ColorType.HSL) {
4431
+ switch (token.kin) {
4432
+ case exports.ColorType.RGB:
4433
+ case exports.ColorType.RGBA:
4434
+ return rgb2HslToken(token);
4435
+ case exports.ColorType.HEX:
4436
+ case exports.ColorType.LIT:
4437
+ return hex2HslToken(token);
4438
+ case exports.ColorType.HWB:
4439
+ return hwb2HslToken(token);
4440
+ case exports.ColorType.DEVICE_CMYK:
4441
+ return cmyk2HslToken(token);
4442
+ case exports.ColorType.OKLAB:
4443
+ return oklab2HslToken(token);
4444
+ case exports.ColorType.OKLCH:
4445
+ return oklch2HslToken(token);
4446
+ case exports.ColorType.LAB:
4447
+ return lab2HslToken(token);
4448
+ case exports.ColorType.LCH:
4449
+ return lch2HslToken(token);
4450
+ case exports.ColorType.COLOR:
4451
+ return color2HslToken(token);
4452
+ }
4453
+ }
4454
+ else if (to == exports.ColorType.HWB) {
4455
+ switch (token.kin) {
4456
+ case exports.ColorType.RGB:
4457
+ case exports.ColorType.RGBA:
4458
+ return rgb2hwbToken(token);
4459
+ case exports.ColorType.HEX:
4460
+ case exports.ColorType.LIT:
4461
+ return rgb2hwbToken(token);
4462
+ case exports.ColorType.HSL:
4463
+ case exports.ColorType.HSLA:
4464
+ return hsl2hwbToken(token);
4465
+ case exports.ColorType.OKLAB:
4466
+ return oklab2hwbToken(token);
4467
+ case exports.ColorType.OKLCH:
4468
+ return oklch2hwbToken(token);
4469
+ case exports.ColorType.LAB:
4470
+ return lab2hwbToken(token);
4471
+ case exports.ColorType.LCH:
4472
+ return lch2hwbToken(token);
4473
+ case exports.ColorType.DEVICE_CMYK:
4474
+ return cmyk2hwbToken(token);
4475
+ case exports.ColorType.COLOR:
4476
+ return color2hwbToken(token);
4477
+ }
4478
+ }
4479
+ else if (to == exports.ColorType.DEVICE_CMYK) {
4480
+ switch (token.kin) {
4481
+ case exports.ColorType.RGB:
4482
+ case exports.ColorType.RGBA:
4483
+ return rgb2cmykToken(token);
4484
+ case exports.ColorType.HEX:
4485
+ case exports.ColorType.LIT:
4486
+ return rgb2cmykToken(token);
4487
+ case exports.ColorType.HSL:
4488
+ case exports.ColorType.HSLA:
4489
+ return hsl2cmykToken(token);
4490
+ case exports.ColorType.HWB:
4491
+ return hwb2cmykToken(token);
4492
+ case exports.ColorType.OKLAB:
4493
+ return oklab2cmyk(token);
4494
+ case exports.ColorType.OKLCH:
4495
+ return oklch2cmykToken(token);
4496
+ case exports.ColorType.LAB:
4497
+ return lab2cmykToken(token);
4498
+ //
4499
+ case exports.ColorType.LCH:
4500
+ return lch2cmykToken(token);
4501
+ case exports.ColorType.COLOR:
4502
+ return color2cmykToken(token);
4262
4503
  }
4263
4504
  }
4264
4505
  else if (to == exports.ColorType.HEX || to == exports.ColorType.LIT) {
@@ -4606,9 +4847,9 @@
4606
4847
  function values2colortoken(values, to) {
4607
4848
  values = srgb2srgbcolorspace(values, to);
4608
4849
  const chi = [
4609
- { typ: exports.EnumToken.NumberTokenType, val: values[0] },
4610
- { typ: exports.EnumToken.NumberTokenType, val: values[1] },
4611
- { typ: exports.EnumToken.NumberTokenType, val: values[2] },
4850
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
4851
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[1]) },
4852
+ { typ: exports.EnumToken.NumberTokenType, val: toPrecisionValue(values[2]) },
4612
4853
  ];
4613
4854
  if (values.length == 4) {
4614
4855
  chi.push({ typ: exports.EnumToken.LiteralTokenType, val: "/" }, {
@@ -4633,8 +4874,17 @@
4633
4874
  if (token.typ == exports.EnumToken.IdenTokenType && token.val == 'none') {
4634
4875
  return 0;
4635
4876
  }
4877
+ let val;
4878
+ // @ts-ignore
4879
+ if (typeof token.val != 'number' && token.val?.typ == exports.EnumToken.FractionTokenType) {
4880
+ // @ts-ignore
4881
+ val = token.val.l.val / token.val.r.val;
4882
+ }
4883
+ else {
4884
+ val = token.val;
4885
+ }
4636
4886
  // @ts-ignore
4637
- return token.typ == exports.EnumToken.PercentageTokenType ? token.val / 100 : token.val;
4887
+ return token.typ == exports.EnumToken.PercentageTokenType ? val / 100 : val;
4638
4888
  }
4639
4889
  /**
4640
4890
  * convert angle to turn
@@ -4665,6 +4915,10 @@
4665
4915
  // @ts-ignore
4666
4916
  return token.val / 360;
4667
4917
  }
4918
+ function toPrecisionValue(value) {
4919
+ value = +value.toFixed(colorPrecision);
4920
+ return Math.abs(value) < epsilon ? 0 : value;
4921
+ }
4668
4922
  function toPrecisionAngle(angle) {
4669
4923
  angle = +angle.toPrecision(colorPrecision);
4670
4924
  if (Math.abs(angle) >= 360) {
@@ -7477,7 +7731,7 @@
7477
7731
  function updateSourceMap(node, options, cache, sourcemap, position, str) {
7478
7732
  if ([
7479
7733
  exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType,
7480
- exports.EnumToken.KeyFrameRuleNodeType, exports.EnumToken.KeyframeAtRuleNodeType
7734
+ exports.EnumToken.KeyFramesRuleNodeType, exports.EnumToken.KeyframesAtRuleNodeType
7481
7735
  ].includes(node.typ)) {
7482
7736
  let src = node.loc?.src ?? '';
7483
7737
  let output = options.output ?? '';
@@ -7551,9 +7805,9 @@
7551
7805
  }, '');
7552
7806
  case exports.EnumToken.AtRuleNodeType:
7553
7807
  case exports.EnumToken.RuleNodeType:
7554
- case exports.EnumToken.KeyFrameRuleNodeType:
7555
- case exports.EnumToken.KeyframeAtRuleNodeType:
7556
- if ([exports.EnumToken.AtRuleNodeType, exports.EnumToken.KeyframeAtRuleNodeType].includes(data.typ) && !('chi' in data)) {
7808
+ case exports.EnumToken.KeyFramesRuleNodeType:
7809
+ case exports.EnumToken.KeyframesAtRuleNodeType:
7810
+ if ([exports.EnumToken.AtRuleNodeType, exports.EnumToken.KeyframesAtRuleNodeType].includes(data.typ) && !('chi' in data)) {
7557
7811
  return `${indent}@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val};`;
7558
7812
  }
7559
7813
  // @ts-ignore
@@ -7594,7 +7848,7 @@
7594
7848
  if (children.endsWith(';')) {
7595
7849
  children = children.slice(0, -1);
7596
7850
  }
7597
- if ([exports.EnumToken.AtRuleNodeType, exports.EnumToken.KeyframeAtRuleNodeType].includes(data.typ)) {
7851
+ if ([exports.EnumToken.AtRuleNodeType, exports.EnumToken.KeyframesAtRuleNodeType].includes(data.typ)) {
7598
7852
  return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
7599
7853
  }
7600
7854
  return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
@@ -8563,7 +8817,7 @@
8563
8817
  const reader = input.getReader();
8564
8818
  while (true) {
8565
8819
  const { done, value } = await reader.read();
8566
- parseInfo.stream += decoder.decode(value, { stream: true });
8820
+ parseInfo.stream += ArrayBuffer.isView(value) ? decoder.decode(value, { stream: true }) : value;
8567
8821
  yield* tokenize$1(parseInfo, done);
8568
8822
  if (done) {
8569
8823
  break;
@@ -10192,6 +10446,9 @@
10192
10446
  "text-anchor": {
10193
10447
  syntax: "start | middle | end"
10194
10448
  },
10449
+ "text-autospace": {
10450
+ syntax: "normal | <autospace> | auto"
10451
+ },
10195
10452
  "text-box": {
10196
10453
  syntax: "normal | <'text-box-trim'> || <'text-box-edge'>"
10197
10454
  },
@@ -12759,19 +13016,8 @@
12759
13016
  }
12760
13017
  }
12761
13018
  },
12762
- charset: {
12763
- syntax: "<string>"
12764
- },
12765
- container: {
12766
- syntax: "[ <container-name> ]? <container-condition>"
12767
- },
12768
- nest: {
13019
+ "@nest": {
12769
13020
  syntax: "<complex-selector-list>"
12770
- },
12771
- scope: {
12772
- syntax: "[ ( <scope-start> ) ]? [ to ( <scope-end> ) ]?"
12773
- },
12774
- "position-try": {
12775
13021
  }
12776
13022
  };
12777
13023
  var config$3 = {
@@ -17069,6 +17315,37 @@
17069
17315
  function reject(reason) {
17070
17316
  throw new Error(reason ?? 'Parsing aborted');
17071
17317
  }
17318
+ function normalizeVisitorKeyName(keyName) {
17319
+ return keyName.replace(/-([a-z])/g, (all, one) => one.toUpperCase());
17320
+ }
17321
+ function replaceToken(parent, value, replacement) {
17322
+ // @ts-ignore
17323
+ if ('parent' in value && value.parent != replacement.parent) {
17324
+ Object.defineProperty(replacement, 'parent', {
17325
+ ...definedPropertySettings,
17326
+ value: value.parent
17327
+ });
17328
+ }
17329
+ if (parent.typ == exports.EnumToken.BinaryExpressionTokenType) {
17330
+ if (parent.l == value) {
17331
+ parent.l = replacement;
17332
+ }
17333
+ else {
17334
+ parent.r = replacement;
17335
+ }
17336
+ }
17337
+ else {
17338
+ // @ts-ignore
17339
+ const target = 'val' in parent && Array.isArray(parent.val) ? parent.val : parent.chi;
17340
+ // @ts-ignore
17341
+ const index = target.indexOf(value);
17342
+ if (index == -1) {
17343
+ return;
17344
+ }
17345
+ // @ts-ignore
17346
+ target.splice(index, 1, ...(Array.isArray(replacement) ? replacement : [replacement]));
17347
+ }
17348
+ }
17072
17349
  /**
17073
17350
  * parse css string
17074
17351
  * @param iter
@@ -17151,7 +17428,7 @@
17151
17428
  const rawTokens = [];
17152
17429
  const imports = [];
17153
17430
  // @ts-ignore ignore error
17154
- const isAsync = typeof iter[Symbol.asyncIterator] === 'function';
17431
+ let isAsync = typeof iter[Symbol.asyncIterator] === 'function';
17155
17432
  while (item = isAsync ? (await iter.next()).value : iter.next().value) {
17156
17433
  stats.bytesIn = item.bytesIn;
17157
17434
  rawTokens.push(item);
@@ -17270,21 +17547,18 @@
17270
17547
  const token = node.tokens[0];
17271
17548
  const url = token.typ == exports.EnumToken.StringTokenType ? token.val.slice(1, -1) : token.val;
17272
17549
  try {
17273
- const root = await options.getStream(url, options.src).then(async (stream) => {
17274
- return doParse(tokenizeStream(stream), Object.assign({}, options, {
17275
- minify: false,
17276
- setParent: false,
17277
- src: options.resolve(url, options.src).absolute
17278
- })); // )
17279
- });
17280
- // const root: ParseResult = await options.load!(url, <string>options.src).then((src: string) => {
17281
- //
17282
- // return doParse(src, Object.assign({}, options, {
17283
- // minify: false,
17284
- // setParent: false,
17285
- // src: options.resolve!(url, options.src as string).absolute
17286
- // }))
17287
- // });
17550
+ const result = options.load(url, options.src);
17551
+ const stream = result instanceof Promise || Object.getPrototypeOf(result).constructor.name == 'AsyncFunction' ? await result : result;
17552
+ const root = await doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize$1({
17553
+ stream,
17554
+ buffer: '',
17555
+ position: { ind: 0, lin: 1, col: 1 },
17556
+ currentPosition: { ind: -1, lin: 1, col: 0 }
17557
+ }), Object.assign({}, options, {
17558
+ minify: false,
17559
+ setParent: false,
17560
+ src: options.resolve(url, options.src).absolute
17561
+ }));
17288
17562
  stats.importedBytesIn += root.stats.bytesIn;
17289
17563
  stats.imports.push(root.stats);
17290
17564
  node.parent.chi.splice(node.parent.chi.indexOf(node), 1, ...root.ast.chi);
@@ -17312,39 +17586,230 @@
17312
17586
  if (options.expandNestingRules) {
17313
17587
  ast = expand(ast);
17314
17588
  }
17589
+ const valuesHandlers = new Map;
17590
+ const preValuesHandlers = new Map;
17591
+ const postValuesHandlers = new Map;
17592
+ const preVisitorsHandlersMap = new Map;
17593
+ const visitorsHandlersMap = new Map;
17594
+ const postVisitorsHandlersMap = new Map;
17595
+ const allValuesHandlers = [];
17315
17596
  if (options.visitor != null) {
17316
- for (const result of walk(ast)) {
17317
- if (result.node.typ == exports.EnumToken.DeclarationNodeType &&
17318
- (typeof options.visitor.Declaration == 'function' || options.visitor.Declaration?.[result.node.nam] != null)) {
17319
- const callable = typeof options.visitor.Declaration == 'function' ? options.visitor.Declaration : options.visitor.Declaration[result.node.nam];
17320
- const isAsync = Object.getPrototypeOf(callable).constructor.name == 'AsyncFunction';
17321
- const results = isAsync ? await callable(result.node) : callable(result.node);
17322
- if (results == null || (Array.isArray(results) && results.length == 0)) {
17323
- continue;
17597
+ for (const [key, value] of Object.entries(options.visitor)) {
17598
+ if (key in exports.EnumToken) {
17599
+ if (typeof value == 'function') {
17600
+ valuesHandlers.set(exports.EnumToken[key], value);
17601
+ }
17602
+ else if (typeof value == 'object' && 'type' in value && 'handler' in value && value.type in exports.WalkerValueEvent) {
17603
+ if (exports.WalkerValueEvent[value.type] == exports.WalkerValueEvent.Enter) {
17604
+ preValuesHandlers.set(exports.EnumToken[key], value.handler);
17605
+ }
17606
+ else if (exports.WalkerValueEvent[value.type] == exports.WalkerValueEvent.Leave) {
17607
+ postValuesHandlers.set(exports.EnumToken[key], value.handler);
17608
+ }
17609
+ }
17610
+ else {
17611
+ console.warn(`doParse: visitor.${key} is not a valid key name`);
17324
17612
  }
17325
- // @ts-ignore
17326
- result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
17327
17613
  }
17328
- else if (options.visitor.Rule != null && result.node.typ == exports.EnumToken.RuleNodeType) {
17329
- const isAsync = Object.getPrototypeOf(options.visitor.Rule).constructor.name == 'AsyncFunction';
17330
- const results = isAsync ? await options.visitor.Rule(result.node) : options.visitor.Rule(result.node);
17331
- if (results == null || (Array.isArray(results) && results.length == 0)) {
17332
- continue;
17614
+ else if (['Declaration', 'Rule', 'AtRule', 'KeyframesRule', 'KeyframesAtRule'].includes(key)) {
17615
+ if (typeof value == 'function') {
17616
+ visitorsHandlersMap.set(key, value);
17617
+ }
17618
+ else if (typeof value == 'object') {
17619
+ if ('type' in value && 'handler' in value && value.type in exports.WalkerValueEvent) {
17620
+ if (exports.WalkerValueEvent[value.type] == exports.WalkerValueEvent.Enter) {
17621
+ preVisitorsHandlersMap.set(key, value.handler);
17622
+ }
17623
+ else if (exports.WalkerValueEvent[value.type] == exports.WalkerValueEvent.Leave) {
17624
+ postVisitorsHandlersMap.set(key, value.handler);
17625
+ }
17626
+ }
17627
+ else {
17628
+ visitorsHandlersMap.set(key, value);
17629
+ }
17630
+ }
17631
+ else {
17632
+ console.warn(`doParse: visitor.${key} is not a valid key name`);
17633
+ }
17634
+ }
17635
+ else {
17636
+ console.warn(`doParse: visitor.${key} is not a valid key name`);
17637
+ }
17638
+ }
17639
+ if (preValuesHandlers.size > 0) {
17640
+ allValuesHandlers.push(preValuesHandlers);
17641
+ }
17642
+ if (valuesHandlers.size > 0) {
17643
+ allValuesHandlers.push(valuesHandlers);
17644
+ }
17645
+ if (postValuesHandlers.size > 0) {
17646
+ allValuesHandlers.push(postValuesHandlers);
17647
+ }
17648
+ }
17649
+ for (const result of walk(ast)) {
17650
+ // if (result.parent != null && !isNodeAllowedInContext(result.node, result.parent as AstNode)) {
17651
+ //
17652
+ // errors.push({
17653
+ // action: 'drop',
17654
+ // message: `${EnumToken[result.parent.typ]}: child ${EnumToken[result.node.typ]}${result.node.typ == EnumToken.DeclarationNodeType ? ` '${(result.node as AstDeclaration).nam}'` : result.node.typ == EnumToken.AtRuleNodeType || result.node.typ == EnumToken.KeyframesAtRuleNodeType ? ` '@${(result.node as AstAtRule).nam}'` : ''} not allowed in context${result.parent.typ == EnumToken.AtRuleNodeType ? ` '@${(result.parent as AstAtRule).nam}'` : result.parent.typ == EnumToken.StyleSheetNodeType ? ` 'stylesheet'` : ''}`,
17655
+ // // @ts-ignore
17656
+ // location: result.node.loc ?? map.get(result.node ) ?? null
17657
+ // });
17658
+ //
17659
+ // // @ts-ignore
17660
+ // removeNode(result.node, result.parent as AstNode);
17661
+ // continue;
17662
+ // }
17663
+ if (allValuesHandlers.length > 0 || preVisitorsHandlersMap.size > 0 || visitorsHandlersMap.size > 0 || postVisitorsHandlersMap.size > 0) {
17664
+ if ((result.node.typ == exports.EnumToken.DeclarationNodeType &&
17665
+ (preVisitorsHandlersMap.has('Declaration') || visitorsHandlersMap.has('Declaration') || postVisitorsHandlersMap.has('Declaration'))) ||
17666
+ (result.node.typ == exports.EnumToken.AtRuleNodeType && (preVisitorsHandlersMap.has('AtRule') || visitorsHandlersMap.has('AtRule') || postVisitorsHandlersMap.has('AtRule'))) ||
17667
+ (result.node.typ == exports.EnumToken.KeyframesAtRuleNodeType && (preVisitorsHandlersMap.has('KeyframesAtRule') || visitorsHandlersMap.has('KeyframesAtRule') || postVisitorsHandlersMap.has('KeyframesAtRule')))) {
17668
+ const handlers = [];
17669
+ const key = result.node.typ == exports.EnumToken.DeclarationNodeType ? 'Declaration' : result.node.typ == exports.EnumToken.AtRuleNodeType ? 'AtRule' : 'KeyframesAtRule';
17670
+ if (preVisitorsHandlersMap.has(key)) {
17671
+ // @ts-ignore
17672
+ handlers.push(preVisitorsHandlersMap.get(key));
17673
+ }
17674
+ if (visitorsHandlersMap.has(key)) {
17675
+ // @ts-ignore
17676
+ handlers.push(visitorsHandlersMap.get(key));
17677
+ }
17678
+ if (postVisitorsHandlersMap.has(key)) {
17679
+ // @ts-ignore
17680
+ handlers.push(postVisitorsHandlersMap.get(key));
17681
+ }
17682
+ let callable;
17683
+ let node = result.node;
17684
+ for (const handler of handlers) {
17685
+ callable = typeof handler == 'function' ? handler : handler[normalizeVisitorKeyName(node.typ == exports.EnumToken.DeclarationNodeType || node.typ == exports.EnumToken.AtRuleNodeType ? node.nam : node.val)];
17686
+ if (callable == null) {
17687
+ continue;
17688
+ }
17689
+ let replacement = callable(node, result.parent);
17690
+ if (replacement == null) {
17691
+ continue;
17692
+ }
17693
+ isAsync = replacement instanceof Promise || Object.getPrototypeOf(replacement).constructor.name == 'AsyncFunction';
17694
+ if (replacement) {
17695
+ replacement = await replacement;
17696
+ }
17697
+ if (replacement == null || replacement == node) {
17698
+ continue;
17699
+ }
17700
+ // @ts-ignore
17701
+ node = replacement;
17702
+ //
17703
+ if (Array.isArray(node)) {
17704
+ break;
17705
+ }
17706
+ }
17707
+ if (node != result.node) {
17708
+ // @ts-ignore
17709
+ replaceToken(result.parent, result.node, node);
17710
+ }
17711
+ }
17712
+ else if ((result.node.typ == exports.EnumToken.RuleNodeType && (preVisitorsHandlersMap.has('Rule') || visitorsHandlersMap.has('Rule') || postVisitorsHandlersMap.has('Rule'))) ||
17713
+ (result.node.typ == exports.EnumToken.KeyFramesRuleNodeType && (preVisitorsHandlersMap.has('KeyframesRule') || visitorsHandlersMap.has('KeyframesRule') || postVisitorsHandlersMap.has('KeyframesRule')))) {
17714
+ const handlers = [];
17715
+ const key = result.node.typ == exports.EnumToken.RuleNodeType ? 'Rule' : 'KeyframesRule';
17716
+ if (preVisitorsHandlersMap.has(key)) {
17717
+ // @ts-ignore
17718
+ handlers.push(preVisitorsHandlersMap.get(key));
17719
+ }
17720
+ if (visitorsHandlersMap.has(key)) {
17721
+ // @ts-ignore
17722
+ handlers.push(visitorsHandlersMap.get(key));
17723
+ }
17724
+ if (postVisitorsHandlersMap.has(key)) {
17725
+ // @ts-ignore
17726
+ handlers.push(postVisitorsHandlersMap.get(key));
17727
+ }
17728
+ let node = result.node;
17729
+ for (const callable of handlers) {
17730
+ // @ts-ignore
17731
+ let replacement = callable(node, result.parent);
17732
+ if (replacement == null) {
17733
+ continue;
17734
+ }
17735
+ isAsync = replacement instanceof Promise || Object.getPrototypeOf(replacement).constructor.name == 'AsyncFunction';
17736
+ if (replacement) {
17737
+ replacement = await replacement;
17738
+ }
17739
+ if (replacement == null || replacement == node) {
17740
+ continue;
17741
+ }
17742
+ // @ts-ignore
17743
+ node = replacement;
17744
+ //
17745
+ if (Array.isArray(node)) {
17746
+ break;
17747
+ }
17333
17748
  }
17334
17749
  // @ts-ignore
17335
- result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
17336
- }
17337
- else if (options.visitor.AtRule != null &&
17338
- result.node.typ == exports.EnumToken.AtRuleNodeType &&
17339
- (typeof options.visitor.AtRule == 'function' || options.visitor.AtRule?.[result.node.nam] != null)) {
17340
- const callable = typeof options.visitor.AtRule == 'function' ? options.visitor.AtRule : options.visitor.AtRule[result.node.nam];
17341
- const isAsync = Object.getPrototypeOf(callable).constructor.name == 'AsyncFunction';
17342
- const results = isAsync ? await callable(result.node) : callable(result.node);
17343
- if (results == null || (Array.isArray(results) && results.length == 0)) {
17750
+ if (node != result.node) {
17751
+ // @ts-ignore
17752
+ replaceToken(result.parent, result.node, node);
17753
+ }
17754
+ }
17755
+ else if (allValuesHandlers.length > 0) {
17756
+ let callable;
17757
+ let node = null;
17758
+ node = result.node;
17759
+ for (const valueHandler of allValuesHandlers) {
17760
+ if (valueHandler.has(node.typ)) {
17761
+ callable = valueHandler.get(node.typ);
17762
+ let replacement = callable(node, result.parent);
17763
+ if (replacement == null) {
17764
+ continue;
17765
+ }
17766
+ isAsync = replacement instanceof Promise || Object.getPrototypeOf(replacement).constructor.name == 'AsyncFunction';
17767
+ if (isAsync) {
17768
+ replacement = await replacement;
17769
+ }
17770
+ if (replacement != null && replacement != node) {
17771
+ node = replacement;
17772
+ }
17773
+ }
17774
+ }
17775
+ if (node != result.node) {
17776
+ // @ts-ignore
17777
+ replaceToken(result.parent, value, node);
17778
+ }
17779
+ const tokens = 'tokens' in result.node ? result.node.tokens : [];
17780
+ if ('val' in result.node && Array.isArray(result.node.val)) {
17781
+ tokens.push(...result.node.val);
17782
+ }
17783
+ if (tokens.length == 0) {
17344
17784
  continue;
17345
17785
  }
17346
- // @ts-ignore
17347
- result.parent.chi.splice(result.parent.chi.indexOf(result.node), 1, ...(Array.isArray(results) ? results : [results]));
17786
+ for (const { value, parent, root } of walkValues(tokens, result.node)) {
17787
+ node = value;
17788
+ for (const valueHandler of allValuesHandlers) {
17789
+ if (valueHandler.has(node.typ)) {
17790
+ callable = valueHandler.get(node.typ);
17791
+ let result = callable(node, parent, root);
17792
+ if (result == null) {
17793
+ continue;
17794
+ }
17795
+ isAsync = result instanceof Promise || Object.getPrototypeOf(result).constructor.name == 'AsyncFunction';
17796
+ if (isAsync) {
17797
+ result = await result;
17798
+ }
17799
+ if (result != null && result != node) {
17800
+ node = result;
17801
+ }
17802
+ //
17803
+ if (Array.isArray(node)) {
17804
+ break;
17805
+ }
17806
+ }
17807
+ }
17808
+ if (node != value) {
17809
+ // @ts-ignore
17810
+ replaceToken(parent, value, node);
17811
+ }
17812
+ }
17348
17813
  }
17349
17814
  }
17350
17815
  }
@@ -17404,7 +17869,6 @@
17404
17869
  continue;
17405
17870
  }
17406
17871
  loc = location;
17407
- // @ts-ignore
17408
17872
  context.chi.push(tokens[i]);
17409
17873
  if (options.sourcemap) {
17410
17874
  tokens[i].loc = loc;
@@ -17438,9 +17902,7 @@
17438
17902
  rawTokens.shift();
17439
17903
  if (atRule.val == 'import') {
17440
17904
  // only @charset and @layer are accepted before @import
17441
- // @ts-ignore
17442
17905
  if (context.chi.length > 0) {
17443
- // @ts-ignore
17444
17906
  let i = context.chi.length;
17445
17907
  while (i--) {
17446
17908
  // @ts-ignore
@@ -17449,11 +17911,8 @@
17449
17911
  continue;
17450
17912
  }
17451
17913
  if (type != exports.EnumToken.AtRuleNodeType) {
17452
- // @ts-ignore
17453
17914
  if (!(type == exports.EnumToken.InvalidAtRuleTokenType &&
17454
- // @ts-ignore
17455
17915
  ['charset', 'layer', 'import'].includes(context.chi[i].nam))) {
17456
- // @ts-ignore
17457
17916
  errors.push({
17458
17917
  action: 'drop',
17459
17918
  message: 'invalid @import',
@@ -17464,7 +17923,6 @@
17464
17923
  return null;
17465
17924
  }
17466
17925
  }
17467
- // @ts-ignore
17468
17926
  const name = context.chi[i].nam;
17469
17927
  if (name != 'charset' && name != 'import' && name != 'layer') {
17470
17928
  errors.push({ action: 'drop', message: 'invalid @import', location });
@@ -17562,7 +18020,7 @@
17562
18020
  const nam = renderToken(atRule, { removeComments: true });
17563
18021
  // @ts-ignore
17564
18022
  const node = {
17565
- typ: /^(-[a-z]+-)?keyframes$/.test(nam) ? exports.EnumToken.KeyframeAtRuleNodeType : exports.EnumToken.AtRuleNodeType,
18023
+ typ: /^(-[a-z]+-)?keyframes$/.test(nam) ? exports.EnumToken.KeyframesAtRuleNodeType : exports.EnumToken.AtRuleNodeType,
17566
18024
  nam,
17567
18025
  val: raw.join('')
17568
18026
  };
@@ -17596,7 +18054,7 @@
17596
18054
  error: '',
17597
18055
  node,
17598
18056
  syntax: '@' + node.nam
17599
- } : isValid ? (node.typ == exports.EnumToken.KeyframeAtRuleNodeType ? validateAtRuleKeyframes(node) : validateAtRule(node, options, context)) : {
18057
+ } : isValid ? (node.typ == exports.EnumToken.KeyframesAtRuleNodeType ? validateAtRuleKeyframes(node) : validateAtRule(node, options, context)) : {
17600
18058
  valid: SyntaxValidationResult.Drop,
17601
18059
  node,
17602
18060
  syntax: '@' + node.nam,
@@ -17632,7 +18090,7 @@
17632
18090
  const location = map.get(tokens[0]);
17633
18091
  const uniq = new Map;
17634
18092
  parseTokens(tokens, { minify: true });
17635
- const ruleType = context.typ == exports.EnumToken.KeyframeAtRuleNodeType ? exports.EnumToken.KeyFrameRuleNodeType : exports.EnumToken.RuleNodeType;
18093
+ const ruleType = context.typ == exports.EnumToken.KeyframesAtRuleNodeType ? exports.EnumToken.KeyFramesRuleNodeType : exports.EnumToken.RuleNodeType;
17636
18094
  if (ruleType == exports.EnumToken.RuleNodeType) {
17637
18095
  parseSelector(tokens);
17638
18096
  }
@@ -17642,6 +18100,34 @@
17642
18100
  if (curr.typ == exports.EnumToken.CommentTokenType) {
17643
18101
  return acc;
17644
18102
  }
18103
+ if (options.minify) {
18104
+ if (curr.typ == exports.EnumToken.PseudoClassFuncTokenType && curr.val == ':nth-child') {
18105
+ let i = 0;
18106
+ for (; i < curr.chi.length; i++) {
18107
+ if (curr.chi[i].typ == exports.EnumToken.IdenTokenType && curr.chi[i].val == 'even') {
18108
+ Object.assign(curr.chi[i], {
18109
+ typ: exports.EnumToken.Dimension,
18110
+ val: 2,
18111
+ unit: 'n'
18112
+ });
18113
+ }
18114
+ else if (curr.chi[i].typ == exports.EnumToken.Dimension &&
18115
+ curr.chi[i].val == 2 &&
18116
+ curr.chi[i].unit == 'n' &&
18117
+ curr.chi[i + 1]?.typ == exports.EnumToken.WhitespaceTokenType &&
18118
+ curr.chi[i + 2]?.typ == exports.EnumToken.LiteralTokenType &&
18119
+ curr.chi[i + 2].val == '+' &&
18120
+ curr.chi[i + 3]?.typ == exports.EnumToken.WhitespaceTokenType &&
18121
+ curr.chi[i + 4]?.typ == exports.EnumToken.NumberTokenType &&
18122
+ curr.chi[i + 4].val == 1) {
18123
+ curr.chi.splice(i, 5, Object.assign(curr.chi[i], {
18124
+ typ: exports.EnumToken.IdenTokenType,
18125
+ val: 'odd'
18126
+ }));
18127
+ }
18128
+ }
18129
+ }
18130
+ }
17645
18131
  if (curr.typ == exports.EnumToken.WhitespaceTokenType) {
17646
18132
  if (trimWhiteSpace.includes(array[index - 1]?.typ) ||
17647
18133
  trimWhiteSpace.includes(array[index + 1]?.typ) ||
@@ -17650,7 +18136,7 @@
17650
18136
  return acc;
17651
18137
  }
17652
18138
  }
17653
- if (ruleType == exports.EnumToken.KeyFrameRuleNodeType) {
18139
+ if (ruleType == exports.EnumToken.KeyFramesRuleNodeType && options.minify) {
17654
18140
  if (curr.typ == exports.EnumToken.IdenTokenType && curr.val == 'from') {
17655
18141
  Object.assign(curr, { typ: exports.EnumToken.PercentageTokenType, val: '0' });
17656
18142
  }
@@ -17699,7 +18185,7 @@
17699
18185
  const valid = options.validation == exports.ValidationLevel.None ? {
17700
18186
  valid: SyntaxValidationResult.Valid,
17701
18187
  error: null
17702
- } : ruleType == exports.EnumToken.KeyFrameRuleNodeType ? validateKeyframeSelector(tokens) : validateSelector(tokens, options, context);
18188
+ } : ruleType == exports.EnumToken.KeyFramesRuleNodeType ? validateKeyframeSelector(tokens) : validateSelector(tokens, options, context);
17703
18189
  if (valid.valid != SyntaxValidationResult.Valid) {
17704
18190
  // @ts-ignore
17705
18191
  node.typ = exports.EnumToken.InvalidRuleTokenType;
@@ -18075,7 +18561,7 @@
18075
18561
  position: { ind: 0, lin: 1, col: 1 },
18076
18562
  currentPosition: { ind: -1, lin: 1, col: 0 }
18077
18563
  }), { setParent: false, minify: false, validation: false }).then(result => {
18078
- return result.ast.chi[0].chi.filter(t => t.typ == exports.EnumToken.DeclarationNodeType);
18564
+ return result.ast.chi[0].chi.filter(t => t.typ == exports.EnumToken.DeclarationNodeType || t.typ == exports.EnumToken.CommentNodeType);
18079
18565
  });
18080
18566
  }
18081
18567
  /**
@@ -18728,63 +19214,130 @@
18728
19214
  return true;
18729
19215
  }
18730
19216
 
19217
+ /**
19218
+ * options for the walk function
19219
+ */
18731
19220
  exports.WalkerOptionEnum = void 0;
18732
19221
  (function (WalkerOptionEnum) {
18733
19222
  /**
18734
19223
  * ignore the current node and its children
18735
19224
  */
18736
- WalkerOptionEnum[WalkerOptionEnum["Ignore"] = 0] = "Ignore";
19225
+ WalkerOptionEnum[WalkerOptionEnum["Ignore"] = 1] = "Ignore";
18737
19226
  /**
18738
19227
  * stop walking the tree
18739
19228
  */
18740
- WalkerOptionEnum[WalkerOptionEnum["Stop"] = 1] = "Stop";
19229
+ WalkerOptionEnum[WalkerOptionEnum["Stop"] = 2] = "Stop";
18741
19230
  /**
18742
19231
  * ignore node and process children
18743
19232
  */
18744
- WalkerOptionEnum[WalkerOptionEnum["Children"] = 2] = "Children";
19233
+ WalkerOptionEnum[WalkerOptionEnum["Children"] = 4] = "Children";
18745
19234
  /**
18746
19235
  * ignore children
18747
19236
  */
18748
- WalkerOptionEnum[WalkerOptionEnum["IgnoreChildren"] = 3] = "IgnoreChildren";
19237
+ WalkerOptionEnum[WalkerOptionEnum["IgnoreChildren"] = 8] = "IgnoreChildren";
18749
19238
  })(exports.WalkerOptionEnum || (exports.WalkerOptionEnum = {}));
19239
+ /**
19240
+ * event types for the walkValues function
19241
+ */
18750
19242
  exports.WalkerValueEvent = void 0;
18751
19243
  (function (WalkerValueEvent) {
18752
19244
  /**
18753
19245
  * enter node
18754
19246
  */
18755
- WalkerValueEvent[WalkerValueEvent["Enter"] = 0] = "Enter";
19247
+ WalkerValueEvent[WalkerValueEvent["Enter"] = 1] = "Enter";
18756
19248
  /**
18757
19249
  * leave node
18758
19250
  */
18759
- WalkerValueEvent[WalkerValueEvent["Leave"] = 1] = "Leave";
19251
+ WalkerValueEvent[WalkerValueEvent["Leave"] = 2] = "Leave";
18760
19252
  })(exports.WalkerValueEvent || (exports.WalkerValueEvent = {}));
18761
19253
  /**
18762
19254
  * walk ast nodes
18763
- * @param node
18764
- * @param filter
19255
+ * @param node initial node
19256
+ * @param filter control the walk process
19257
+ * @param reverse walk in reverse order
19258
+ *
19259
+ * ```ts
19260
+ *
19261
+ * import {walk} from '@tbela99/css-parser';
19262
+ *
19263
+ * const css = `
19264
+ * body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }
19265
+ *
19266
+ * html,
19267
+ * body {
19268
+ * line-height: 1.474;
19269
+ * }
19270
+ *
19271
+ * .ruler {
19272
+ *
19273
+ * height: 10px;
19274
+ * }
19275
+ * `;
19276
+ *
19277
+ * for (const {node, parent, root} of walk(ast)) {
19278
+ *
19279
+ * // do something with node
19280
+ * }
19281
+ * ```
19282
+ *
19283
+ * Using a filter to control the walk process:
19284
+ *
19285
+ * ```ts
19286
+ *
19287
+ * import {walk} from '@tbela99/css-parser';
19288
+ *
19289
+ * const css = `
19290
+ * body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }
19291
+ *
19292
+ * html,
19293
+ * body {
19294
+ * line-height: 1.474;
19295
+ * }
19296
+ *
19297
+ * .ruler {
19298
+ *
19299
+ * height: 10px;
19300
+ * }
19301
+ * `;
19302
+ *
19303
+ * for (const {node, parent, root} of walk(ast, (node) => {
19304
+ *
19305
+ * if (node.typ == EnumToken.AstRule && node.sel.includes('html')) {
19306
+ *
19307
+ * // skip the children of the current node
19308
+ * return WalkerOptionEnum.IgnoreChildren;
19309
+ * }
19310
+ * })) {
19311
+ *
19312
+ * // do something with node
19313
+ * }
19314
+ * ```
18765
19315
  */
18766
- function* walk(node, filter) {
19316
+ function* walk(node, filter, reverse) {
18767
19317
  const parents = [node];
18768
19318
  const root = node;
18769
19319
  const map = new Map;
19320
+ let isNumeric = false;
18770
19321
  while ((node = parents.shift())) {
18771
19322
  let option = null;
18772
19323
  if (filter != null) {
18773
19324
  option = filter(node);
18774
- if (option === exports.WalkerOptionEnum.Ignore) {
18775
- continue;
18776
- }
18777
- if (option === exports.WalkerOptionEnum.Stop) {
18778
- break;
19325
+ isNumeric = typeof option == 'number';
19326
+ if (isNumeric) {
19327
+ if ((option & exports.WalkerOptionEnum.Ignore)) {
19328
+ continue;
19329
+ }
19330
+ if ((option & exports.WalkerOptionEnum.Stop)) {
19331
+ break;
19332
+ }
18779
19333
  }
18780
19334
  }
18781
- // @ts-ignore
18782
- if (option !== 'children') {
19335
+ if (!isNumeric || (option & exports.WalkerOptionEnum.Children) === 0) {
18783
19336
  // @ts-ignore
18784
19337
  yield { node, parent: map.get(node), root };
18785
19338
  }
18786
- if (option !== exports.WalkerOptionEnum.IgnoreChildren && 'chi' in node) {
18787
- parents.unshift(...node.chi);
19339
+ if ('chi' in node && (!isNumeric || ((option & exports.WalkerOptionEnum.IgnoreChildren) === 0))) {
19340
+ parents.unshift(...node.chi[reverse ? 'reverse' : 'slice']());
18788
19341
  for (const child of node.chi.slice()) {
18789
19342
  map.set(child, node);
18790
19343
  }
@@ -18797,13 +19350,38 @@
18797
19350
  * @param root
18798
19351
  * @param filter
18799
19352
  * @param reverse
19353
+ *
19354
+ * Example:
19355
+ *
19356
+ * ```ts
19357
+ *
19358
+ * import {EnumToken, walk} from '@tbela99/css-parser';
19359
+ *
19360
+ * const css = `
19361
+ * body { color: color(from var(--base-color) display-p3 r calc(g + 0.24) calc(b + 0.15)); }
19362
+ *
19363
+ * html,
19364
+ * body {
19365
+ * line-height: 1.474;
19366
+ * }
19367
+ *
19368
+ * .ruler {
19369
+ *
19370
+ * height: 10px;
19371
+ * }
19372
+ * `;
19373
+ *
19374
+ * for (const {value} of walkValues(result.ast.chi[0].chi[0].val, null, null,true)) {
19375
+ *
19376
+ * console.error([EnumToken[value.typ], value.val]);
19377
+ * }
19378
+ *
18800
19379
  */
18801
19380
  function* walkValues(values, root = null, filter, reverse) {
18802
19381
  // const set = new Set<Token>();
18803
19382
  const stack = values.slice();
18804
19383
  const map = new Map;
18805
19384
  let previous = null;
18806
- // let parent: FunctionToken | ParensToken | BinaryExpressionToken | null = null;
18807
19385
  if (filter != null && typeof filter == 'function') {
18808
19386
  filter = {
18809
19387
  event: exports.WalkerValueEvent.Enter,
@@ -18815,21 +19393,23 @@
18815
19393
  event: exports.WalkerValueEvent.Enter
18816
19394
  };
18817
19395
  }
19396
+ let isNumeric = false;
18818
19397
  const eventType = filter.event ?? exports.WalkerValueEvent.Enter;
18819
19398
  while (stack.length > 0) {
18820
19399
  let value = reverse ? stack.pop() : stack.shift();
18821
19400
  let option = null;
18822
- if (filter.fn != null && eventType == exports.WalkerValueEvent.Enter) {
19401
+ if (filter.fn != null && (eventType & exports.WalkerValueEvent.Enter)) {
18823
19402
  const isValid = filter.type == null || value.typ == filter.type ||
18824
19403
  (Array.isArray(filter.type) && filter.type.includes(value.typ)) ||
18825
19404
  (typeof filter.type == 'function' && filter.type(value));
18826
19405
  if (isValid) {
18827
- option = filter.fn(value, map.get(value) ?? root);
18828
- if (option === exports.WalkerOptionEnum.Ignore) {
18829
- continue;
19406
+ option = filter.fn(value, map.get(value) ?? root, exports.WalkerValueEvent.Enter);
19407
+ isNumeric = typeof option == 'number';
19408
+ if (isNumeric && (option & exports.WalkerOptionEnum.Stop)) {
19409
+ return;
18830
19410
  }
18831
- if (option === exports.WalkerOptionEnum.Stop) {
18832
- break;
19411
+ if (isNumeric && (option & exports.WalkerOptionEnum.Ignore)) {
19412
+ continue;
18833
19413
  }
18834
19414
  // @ts-ignore
18835
19415
  if (option != null && typeof option == 'object' && 'typ' in option) {
@@ -18837,38 +19417,33 @@
18837
19417
  }
18838
19418
  }
18839
19419
  }
18840
- if (eventType == exports.WalkerValueEvent.Enter && option !== exports.WalkerOptionEnum.Children) {
18841
- yield {
18842
- value,
18843
- parent: map.get(value) ?? root,
18844
- previousValue: previous,
18845
- nextValue: stack[0] ?? null,
18846
- // @ts-ignore
18847
- root: root ?? null
18848
- };
18849
- }
18850
- if (option !== exports.WalkerOptionEnum.IgnoreChildren && 'chi' in value) {
19420
+ // if ((eventType & WalkerValueEvent.Enter) && (!isNumeric || ((option as number) & WalkerOptionEnum.Children) === 0)) {
19421
+ yield {
19422
+ value,
19423
+ parent: map.get(value) ?? root,
19424
+ previousValue: previous,
19425
+ nextValue: stack[0] ?? null,
19426
+ // @ts-ignore
19427
+ root: root ?? null
19428
+ };
19429
+ // }
19430
+ if ('chi' in value && (!isNumeric || (option & exports.WalkerOptionEnum.IgnoreChildren) === 0)) {
18851
19431
  const sliced = value.chi.slice();
18852
19432
  for (const child of sliced) {
18853
19433
  map.set(child, value);
18854
19434
  }
18855
- if (reverse) {
18856
- stack.push(...sliced);
18857
- }
18858
- else {
18859
- stack.unshift(...sliced);
18860
- }
19435
+ stack[reverse ? 'push' : 'unshift'](...sliced);
18861
19436
  }
18862
19437
  else {
18863
19438
  const values = [];
18864
19439
  if ('l' in value && value.l != null) {
18865
19440
  // @ts-ignore
18866
- values.push(value.l);
19441
+ values[reverse ? 'push' : 'unshift'](value.l);
18867
19442
  // @ts-ignore
18868
19443
  map.set(value.l, value);
18869
19444
  }
18870
19445
  if ('op' in value && typeof value.op == 'object') {
18871
- values.push(value.op);
19446
+ values[reverse ? 'push' : 'unshift'](value.op);
18872
19447
  // @ts-ignore
18873
19448
  map.set(value.op, value);
18874
19449
  }
@@ -18876,48 +19451,66 @@
18876
19451
  if (Array.isArray(value.r)) {
18877
19452
  for (const r of value.r) {
18878
19453
  // @ts-ignore
18879
- values.push(r);
19454
+ values[reverse ? 'push' : 'unshift'](r);
18880
19455
  // @ts-ignore
18881
19456
  map.set(r, value);
18882
19457
  }
18883
19458
  }
18884
19459
  else {
18885
19460
  // @ts-ignore
18886
- values.push(value.r);
19461
+ values[reverse ? 'push' : 'unshift'](value.r);
18887
19462
  // @ts-ignore
18888
19463
  map.set(value.r, value);
18889
19464
  }
18890
19465
  }
18891
19466
  if (values.length > 0) {
18892
- stack.unshift(...values);
19467
+ stack[reverse ? 'push' : 'unshift'](...values);
18893
19468
  }
18894
19469
  }
18895
- if (eventType == exports.WalkerValueEvent.Leave && filter.fn != null) {
19470
+ if ((eventType & exports.WalkerValueEvent.Leave) && filter.fn != null) {
18896
19471
  const isValid = filter.type == null || value.typ == filter.type ||
18897
19472
  (Array.isArray(filter.type) && filter.type.includes(value.typ)) ||
18898
19473
  (typeof filter.type == 'function' && filter.type(value));
18899
19474
  if (isValid) {
18900
- option = filter.fn(value, map.get(value));
19475
+ option = filter.fn(value, map.get(value), exports.WalkerValueEvent.Leave);
18901
19476
  // @ts-ignore
18902
19477
  if (option != null && 'typ' in option) {
18903
19478
  map.set(option, map.get(value) ?? root);
18904
19479
  }
18905
19480
  }
18906
19481
  }
18907
- if (eventType == exports.WalkerValueEvent.Leave && option !== exports.WalkerOptionEnum.Children) {
18908
- yield {
18909
- value,
18910
- parent: map.get(value) ?? root,
18911
- previousValue: previous,
18912
- nextValue: stack[0] ?? null,
18913
- // @ts-ignore
18914
- root: root ?? null
18915
- };
18916
- }
19482
+ // if ((eventType & WalkerValueEvent.Leave) && (!isNumeric && ((option as number) & WalkerOptionEnum.Children) === 0)) {
19483
+ //
19484
+ // yield {
19485
+ // value,
19486
+ // parent: <FunctionToken | ParensToken>map.get(value) ?? root,
19487
+ // previousValue: previous,
19488
+ // nextValue: <Token>stack[0] ?? null,
19489
+ // // @ts-ignore
19490
+ // root: root ?? null
19491
+ // };
19492
+ // }
18917
19493
  previous = value;
18918
19494
  }
18919
19495
  }
18920
19496
 
19497
+ /**
19498
+ * feature walk mode
19499
+ *
19500
+ * @internal
19501
+ */
19502
+ exports.FeatureWalkMode = void 0;
19503
+ (function (FeatureWalkMode) {
19504
+ /**
19505
+ * pre process
19506
+ */
19507
+ FeatureWalkMode[FeatureWalkMode["Pre"] = 1] = "Pre";
19508
+ /**
19509
+ * post process
19510
+ */
19511
+ FeatureWalkMode[FeatureWalkMode["Post"] = 2] = "Post";
19512
+ })(exports.FeatureWalkMode || (exports.FeatureWalkMode = {}));
19513
+
18921
19514
  const config$1 = getSyntaxConfig();
18922
19515
  function replacePseudo(tokens) {
18923
19516
  return tokens.map((raw) => raw.map(r => {
@@ -18963,11 +19556,8 @@
18963
19556
  get ordering() {
18964
19557
  return 2;
18965
19558
  }
18966
- get preProcess() {
18967
- return true;
18968
- }
18969
- get postProcess() {
18970
- return false;
19559
+ get processMode() {
19560
+ return exports.FeatureWalkMode.Pre;
18971
19561
  }
18972
19562
  static register(options) {
18973
19563
  if (options.removePrefix) {
@@ -19032,7 +19622,7 @@
19032
19622
  }
19033
19623
  }
19034
19624
  }
19035
- else if (node.typ == exports.EnumToken.AtRuleNodeType || node.typ == exports.EnumToken.KeyframeAtRuleNodeType) {
19625
+ else if (node.typ == exports.EnumToken.AtRuleNodeType || node.typ == exports.EnumToken.KeyframesAtRuleNodeType) {
19036
19626
  if (node.nam.startsWith('-')) {
19037
19627
  const match = node.nam.match(/^-([^-]+)-(.+)$/);
19038
19628
  if (match != null && '@' + match[2] in config$1.atRules) {
@@ -19040,14 +19630,6 @@
19040
19630
  }
19041
19631
  }
19042
19632
  if (node.typ == exports.EnumToken.AtRuleNodeType && node.val !== '') {
19043
- // if ((node as AstAtRule).tokens == null) {
19044
- //
19045
- // Object.defineProperty(node, 'tokens', {
19046
- // // @ts-ignore
19047
- // ...definedPropertySettings,
19048
- // value: parseAtRulePrelude(parseString((node as AstAtRule).val), node as AstAtRule),
19049
- // })
19050
- // }
19051
19633
  if (replaceAstNodes(node.tokens)) {
19052
19634
  node.val = node.tokens.reduce((acc, curr) => acc + renderToken(curr), '');
19053
19635
  }
@@ -19103,11 +19685,8 @@
19103
19685
  get ordering() {
19104
19686
  return 0;
19105
19687
  }
19106
- get preProcess() {
19107
- return true;
19108
- }
19109
- get postProcess() {
19110
- return false;
19688
+ get processMode() {
19689
+ return exports.FeatureWalkMode.Pre;
19111
19690
  }
19112
19691
  static register(options) {
19113
19692
  if (options.inlineCssVariables) {
@@ -19117,7 +19696,7 @@
19117
19696
  }
19118
19697
  run(ast, options = {}, parent, context) {
19119
19698
  if (!('chi' in ast)) {
19120
- return;
19699
+ return null;
19121
19700
  }
19122
19701
  if (!('variableScope' in context)) {
19123
19702
  context.variableScope = new Map;
@@ -19160,6 +19739,7 @@
19160
19739
  replace(node, variableScope);
19161
19740
  }
19162
19741
  }
19742
+ return null;
19163
19743
  }
19164
19744
  cleanup(ast, options = {}, context) {
19165
19745
  const variableScope = context.variableScope;
@@ -19999,7 +20579,7 @@
19999
20579
  }
20000
20580
  add(...declarations) {
20001
20581
  for (const declaration of declarations) {
20002
- if (declaration.typ != exports.EnumToken.DeclarationNodeType || !this.options.removeDuplicateDeclarations) {
20582
+ if (declaration.typ != exports.EnumToken.DeclarationNodeType || (Array.isArray(this.options.removeDuplicateDeclarations) ? this.options.removeDuplicateDeclarations.includes(declaration.nam) : !this.options.removeDuplicateDeclarations)) {
20003
20583
  this.declarations.set(Number(Math.random().toString().slice(2)).toString(36), declaration);
20004
20584
  continue;
20005
20585
  }
@@ -20036,455 +20616,201 @@
20036
20616
  this.declarations.set(shorthand, new PropertyMap(config.map[shorthand]));
20037
20617
  }
20038
20618
  // @ts-ignore
20039
- this.declarations.get(shorthand).add(declaration);
20040
- // return this;
20041
- }
20042
- // @ts-ignore
20043
- else if (shortHandType == 'set') {
20044
- // @ts-ignore
20045
- // const shorthand: string = <string>config.properties[propertyName].shorthand;
20046
- if (!this.declarations.has(shorthand)) {
20047
- // @ts-ignore
20048
- this.declarations.set(shorthand, new PropertySet(config.properties[shorthand]));
20049
- }
20050
- // @ts-ignore
20051
- this.declarations.get(shorthand).add(declaration);
20052
- // return this;
20053
- }
20054
- else {
20055
- this.declarations.set(propertyName, declaration);
20056
- }
20057
- }
20058
- return this;
20059
- }
20060
- [Symbol.iterator]() {
20061
- let iterator = this.declarations.values();
20062
- const iterators = [];
20063
- return {
20064
- next() {
20065
- let value = iterator.next();
20066
- while ((value.done && iterators.length > 0) ||
20067
- value.value instanceof PropertySet ||
20068
- value.value instanceof PropertyMap) {
20069
- if (value.value instanceof PropertySet || value.value instanceof PropertyMap) {
20070
- iterators.unshift(iterator);
20071
- // @ts-ignore
20072
- iterator = value.value[Symbol.iterator]();
20073
- value = iterator.next();
20074
- }
20075
- if (value.done && iterators.length > 0) {
20076
- iterator = iterators.shift();
20077
- value = iterator.next();
20078
- }
20079
- }
20080
- return value;
20081
- }
20082
- };
20083
- }
20084
- }
20085
-
20086
- class ComputeShorthandFeature {
20087
- get ordering() {
20088
- return 3;
20089
- }
20090
- get preProcess() {
20091
- return false;
20092
- }
20093
- get postProcess() {
20094
- return true;
20095
- }
20096
- static register(options) {
20097
- if (options.computeShorthand) {
20098
- // @ts-ignore
20099
- options.features.push(new ComputeShorthandFeature(options));
20100
- }
20101
- }
20102
- run(ast, options = {}, parent, context) {
20103
- if (!('chi' in ast)) {
20104
- return ast;
20105
- }
20106
- // @ts-ignore
20107
- const j = ast.chi.length;
20108
- let k = 0;
20109
- let l;
20110
- let properties = new PropertyList(options);
20111
- const rules = [];
20112
- // @ts-ignore
20113
- for (; k < j; k++) {
20114
- l = k;
20115
- // capture comments with the next token
20116
- while (l + 1 < j) {
20117
- // @ts-ignore
20118
- const node = ast.chi[l];
20119
- if (node.typ == exports.EnumToken.CommentNodeType) {
20120
- l++;
20121
- continue;
20122
- }
20123
- break;
20124
- }
20125
- // @ts-ignore
20126
- const node = ast.chi[l];
20127
- if (node.typ == exports.EnumToken.DeclarationNodeType) {
20128
- properties.add(...ast.chi.slice(k, l + 1));
20129
- }
20130
- else {
20131
- rules.push(...ast.chi.slice(k, l + 1));
20132
- }
20133
- k = l;
20134
- }
20135
- // @ts-ignore
20136
- ast.chi = [...properties, ...rules];
20137
- return ast;
20138
- }
20139
- }
20140
-
20141
- class ComputeCalcExpressionFeature {
20142
- get ordering() {
20143
- return 1;
20144
- }
20145
- get preProcess() {
20146
- return false;
20147
- }
20148
- get postProcess() {
20149
- return true;
20150
- }
20151
- static register(options) {
20152
- if (options.computeCalcExpression) {
20153
- // @ts-ignore
20154
- options.features.push(new ComputeCalcExpressionFeature());
20155
- }
20156
- }
20157
- run(ast) {
20158
- if (!('chi' in ast)) {
20159
- return;
20160
- }
20161
- for (const node of ast.chi) {
20162
- if (node.typ != exports.EnumToken.DeclarationNodeType) {
20163
- continue;
20164
- }
20165
- const set = new Set;
20166
- for (const { value, parent } of walkValues(node.val, node, {
20167
- event: exports.WalkerValueEvent.Enter,
20168
- // @ts-ignore
20169
- fn(node, parent) {
20170
- if (parent != null &&
20171
- // @ts-ignore
20172
- parent.typ == exports.EnumToken.DeclarationNodeType &&
20173
- // @ts-ignore
20174
- parent.val.length == 1 &&
20175
- node.typ == exports.EnumToken.FunctionTokenType &&
20176
- mathFuncs.includes(node.val) &&
20177
- node.chi.length == 1 &&
20178
- node.chi[0].typ == exports.EnumToken.IdenTokenType) {
20179
- return exports.WalkerOptionEnum.Ignore;
20180
- }
20181
- if ((node.typ == exports.EnumToken.FunctionTokenType && node.val == 'var') || (!mathFuncs.includes(parent.val) && [exports.EnumToken.ColorTokenType, exports.EnumToken.DeclarationNodeType, exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType, exports.EnumToken.StyleSheetNodeType].includes(parent?.typ))) {
20182
- return null;
20183
- }
20184
- // @ts-ignore
20185
- const slice = (node.typ == exports.EnumToken.FunctionTokenType ? node.chi : (node.typ == exports.EnumToken.DeclarationNodeType ? node.val : node.chi))?.slice();
20186
- if (slice != null && node.typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(node.val)) {
20187
- // @ts-ignore
20188
- const key = 'chi' in node ? 'chi' : 'val';
20189
- const str1 = renderToken({ ...node, [key]: slice });
20190
- const str2 = renderToken(node); // values.reduce((acc: string, curr: Token): string => acc + renderToken(curr), '');
20191
- if (str1.length <= str2.length) {
20192
- // @ts-ignore
20193
- node[key] = slice;
20194
- }
20195
- return exports.WalkerOptionEnum.Ignore;
20196
- }
20197
- return null;
20198
- }
20199
- })) {
20200
- if (value != null && value.typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(value.val)) {
20201
- if (!set.has(value)) {
20202
- set.add(value);
20203
- if (parent != null) {
20204
- // @ts-ignore
20205
- const cp = value.typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(value.val) && value.val != 'calc' ? [value] : (value.typ == exports.EnumToken.DeclarationNodeType ? value.val : value.chi);
20206
- const values = evaluate(cp);
20207
- // @ts-ignore
20208
- const children = parent.typ == exports.EnumToken.DeclarationNodeType ? parent.val : parent.chi;
20209
- if (values.length == 1 && values[0].typ != exports.EnumToken.BinaryExpressionTokenType) {
20210
- for (let i = 0; i < children.length; i++) {
20211
- if (children[i] == value) {
20212
- children.splice(i, 1, !(parent.typ == exports.EnumToken.FunctionTokenType && parent.val == 'calc') && (typeof values[0].val != 'number' && !(values[0].typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(values[0].val))) ? {
20213
- typ: exports.EnumToken.FunctionTokenType,
20214
- val: 'calc',
20215
- chi: values
20216
- } : values[0]);
20217
- break;
20218
- }
20219
- }
20220
- }
20221
- else {
20222
- for (let i = 0; i < children.length; i++) {
20223
- if (children[i] == value) {
20224
- children.splice(i, 1, {
20225
- typ: exports.EnumToken.FunctionTokenType,
20226
- val: 'calc',
20227
- chi: values
20228
- });
20229
- break;
20230
- }
20231
- }
20232
- }
20233
- }
20234
- }
20235
- }
20236
- }
20237
- }
20238
- }
20239
- }
20240
-
20241
- const epsilon = 1e-5;
20242
- function identity() {
20243
- return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
20244
- }
20245
- function pLength(point) {
20246
- return Math.sqrt(point[0] * point[0] + point[1] * point[1] + point[2] * point[2]);
20247
- }
20248
- function normalize(point) {
20249
- const [x, y, z] = point;
20250
- const norm = Math.sqrt(point[0] * point[0] + point[1] * point[1] + point[2] * point[2]);
20251
- return norm === 0 ? [0, 0, 0] : [x / norm, y / norm, z / norm];
20252
- }
20253
- function dot(point1, point2) {
20254
- if (point1.length === 4 && point2.length === 4) {
20255
- return point1[0] * point2[0] + point1[1] * point2[1] + point1[2] * point2[2] + point1[3] * point2[3];
20256
- }
20257
- return point1[0] * point2[0] + point1[1] * point2[1] + point1[2] * point2[2];
20258
- }
20259
- function multiply(matrixA, matrixB) {
20260
- let result = new Array(16).fill(0);
20261
- for (let i = 0; i < 4; i++) {
20262
- for (let j = 0; j < 4; j++) {
20263
- for (let k = 0; k < 4; k++) {
20264
- // Utiliser l'indexation linéaire pour accéder aux éléments
20265
- // Pour une matrice 4x4, l'index est (row * 4 + col)
20266
- result[j * 4 + i] += matrixA[k * 4 + i] * matrixB[j * 4 + k];
20267
- }
20268
- }
20269
- }
20270
- return result;
20271
- }
20272
- function inverse(matrix) {
20273
- // Create augmented matrix [matrix | identity]
20274
- let augmented = [
20275
- 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
20276
- 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1
20277
- ];
20278
- // Gaussian elimination with partial pivoting
20279
- for (let col = 0; col < 4; col++) {
20280
- // Find pivot row with maximum absolute value
20281
- let maxRow = col;
20282
- let maxVal = Math.abs(augmented[col * 4 + col]);
20283
- for (let row = col + 1; row < 4; row++) {
20284
- let val = Math.abs(augmented[row * 4 + col]);
20285
- if (val > maxVal) {
20286
- maxVal = val;
20287
- maxRow = row;
20619
+ this.declarations.get(shorthand).add(declaration);
20620
+ // return this;
20288
20621
  }
20289
- }
20290
- // Check for singularity
20291
- if (maxVal < 1e-5) {
20292
- return null;
20293
- }
20294
- // Swap rows if necessary
20295
- if (maxRow !== col) {
20296
- [augmented[col], augmented[maxRow]] = [augmented[maxRow], augmented[col]];
20297
- }
20298
- // Scale pivot row to make pivot element 1
20299
- let pivot = augmented[col * 4 + col];
20300
- for (let j = 0; j < 8; j++) {
20301
- augmented[col * 4 + j] /= pivot;
20302
- }
20303
- // Eliminate column in other rows
20304
- for (let row = 0; row < 4; row++) {
20305
- if (row !== col) {
20306
- let factor = augmented[row * 4 + col];
20307
- for (let j = 0; j < 8; j++) {
20308
- augmented[row * 4 + j] -= factor * augmented[col * 4 + j];
20622
+ // @ts-ignore
20623
+ else if (shortHandType == 'set') {
20624
+ // @ts-ignore
20625
+ // const shorthand: string = <string>config.properties[propertyName].shorthand;
20626
+ if (!this.declarations.has(shorthand)) {
20627
+ // @ts-ignore
20628
+ this.declarations.set(shorthand, new PropertySet(config.properties[shorthand]));
20309
20629
  }
20630
+ // @ts-ignore
20631
+ this.declarations.get(shorthand).add(declaration);
20632
+ // return this;
20633
+ }
20634
+ else {
20635
+ this.declarations.set(propertyName, declaration);
20310
20636
  }
20311
20637
  }
20638
+ return this;
20312
20639
  }
20313
- // Extract the inverse from the right side of the augmented matrix
20314
- return augmented.slice(0, 16);
20315
- }
20316
- // function transpose(matrix: Matrix): Matrix {
20317
- // // Crée une nouvelle matrice vide 4x4
20318
- // // @ts-ignore
20319
- // let transposed: Matrix = [[], [], [], []] as Matrix;
20320
- //
20321
- // // Parcourt chaque ligne et colonne pour transposer
20322
- // for (let i = 0; i < 4; i++) {
20323
- //
20324
- // for (let j = 0; j < 4; j++) {
20325
- //
20326
- // transposed[j][i] = matrix[i][j];
20327
- // }
20328
- // }
20329
- //
20330
- // return transposed;
20331
- // }
20332
- function round(number) {
20333
- return Math.abs(number) < epsilon ? 0 : +number.toPrecision(6);
20334
- }
20335
- // translate3d(25.9808px, 0, 15px ) rotateY(60deg) skewX(49.9999deg) scale(1, 1.2)
20336
- // translate → rotate → skew → scale
20337
- function decompose(original) {
20338
- const matrix = original.slice();
20339
- // Normalize last row
20340
- if (matrix[15] === 0) {
20341
- return null;
20342
- }
20343
- for (let i = 0; i < 16; i++)
20344
- matrix[i] /= matrix[15];
20345
- // Perspective extraction
20346
- const perspective = [0, 0, 0, 1];
20347
- if (matrix[3] !== 0 || matrix[7] !== 0 || matrix[11] !== 0) {
20348
- const rightHandSide = [matrix[3], matrix[7], matrix[11], matrix[15]];
20349
- const perspectiveMatrix = matrix.slice();
20350
- perspectiveMatrix[3] = 0;
20351
- perspectiveMatrix[7] = 0;
20352
- perspectiveMatrix[11] = 0;
20353
- perspectiveMatrix[15] = 1;
20354
- // @ts-ignore
20355
- const inverted = inverse(original.slice());
20356
- if (!inverted) {
20357
- return null;
20358
- }
20359
- const transposedInverse = transposeMatrix4(inverted);
20360
- perspective[0] = dot(rightHandSide, transposedInverse.slice(0, 4));
20361
- perspective[1] = dot(rightHandSide, transposedInverse.slice(4, 8));
20362
- perspective[2] = dot(rightHandSide, transposedInverse.slice(8, 12));
20363
- perspective[3] = dot(rightHandSide, transposedInverse.slice(12, 16));
20364
- // Clear perspective from matrix
20365
- matrix[3] = 0;
20366
- matrix[7] = 0;
20367
- matrix[11] = 0;
20368
- matrix[15] = 1;
20369
- }
20370
- // Translation
20371
- const translate = [matrix[12], matrix[13], matrix[14]];
20372
- matrix[12] = matrix[13] = matrix[14] = 0;
20373
- // Build the 3x3 matrix
20374
- const row0 = [matrix[0], matrix[1], matrix[2]];
20375
- const row1 = [matrix[4], matrix[5], matrix[6]];
20376
- const row2 = [matrix[8], matrix[9], matrix[10]];
20377
- // Compute scale
20378
- const scaleX = pLength(row0);
20379
- const row0Norm = normalize(row0);
20380
- const skewXY = dot(row0Norm, row1);
20381
- const row1Proj = [
20382
- row1[0] - skewXY * row0Norm[0],
20383
- row1[1] - skewXY * row0Norm[1],
20384
- row1[2] - skewXY * row0Norm[2]
20385
- ];
20386
- const scaleY = pLength(row1Proj);
20387
- const row1Norm = normalize(row1Proj);
20388
- const skewXZ = dot(row0Norm, row2);
20389
- const skewYZ = dot(row1Norm, row2);
20390
- const row2Proj = [
20391
- row2[0] - skewXZ * row0Norm[0] - skewYZ * row1Norm[0],
20392
- row2[1] - skewXZ * row0Norm[1] - skewYZ * row1Norm[1],
20393
- row2[2] - skewXZ * row0Norm[2] - skewYZ * row1Norm[2]
20394
- ];
20395
- const scaleZ = pLength(row2Proj);
20396
- const row2Norm = normalize(row2Proj);
20397
- // Build rotation matrix from orthonormalized vectors
20398
- const r00 = row0Norm[0], r01 = row1Norm[0], r02 = row2Norm[0];
20399
- const r10 = row0Norm[1], r11 = row1Norm[1], r12 = row2Norm[1];
20400
- const r20 = row0Norm[2], r21 = row1Norm[2], r22 = row2Norm[2];
20401
- // Convert to quaternion
20402
- const trace = r00 + r11 + r22;
20403
- let qw, qx, qy, qz;
20404
- if (trace > 0) {
20405
- const s = 0.5 / Math.sqrt(trace + 1.0);
20406
- qw = 0.25 / s;
20407
- qx = (r21 - r12) * s;
20408
- qy = (r02 - r20) * s;
20409
- qz = (r10 - r01) * s;
20640
+ [Symbol.iterator]() {
20641
+ let iterator = this.declarations.values();
20642
+ const iterators = [];
20643
+ return {
20644
+ next() {
20645
+ let value = iterator.next();
20646
+ while ((value.done && iterators.length > 0) ||
20647
+ value.value instanceof PropertySet ||
20648
+ value.value instanceof PropertyMap) {
20649
+ if (value.value instanceof PropertySet || value.value instanceof PropertyMap) {
20650
+ iterators.unshift(iterator);
20651
+ // @ts-ignore
20652
+ iterator = value.value[Symbol.iterator]();
20653
+ value = iterator.next();
20654
+ }
20655
+ if (value.done && iterators.length > 0) {
20656
+ iterator = iterators.shift();
20657
+ value = iterator.next();
20658
+ }
20659
+ }
20660
+ return value;
20661
+ }
20662
+ };
20410
20663
  }
20411
- else if (r00 > r11 && r00 > r22) {
20412
- const s = 2.0 * Math.sqrt(1.0 + r00 - r11 - r22);
20413
- qw = (r21 - r12) / s;
20414
- qx = 0.25 * s;
20415
- qy = (r01 + r10) / s;
20416
- qz = (r02 + r20) / s;
20664
+ }
20665
+
20666
+ class ComputeShorthandFeature {
20667
+ get ordering() {
20668
+ return 3;
20417
20669
  }
20418
- else if (r11 > r22) {
20419
- const s = 2.0 * Math.sqrt(1.0 + r11 - r00 - r22);
20420
- qw = (r02 - r20) / s;
20421
- qx = (r01 + r10) / s;
20422
- qy = 0.25 * s;
20423
- qz = (r12 + r21) / s;
20670
+ get processMode() {
20671
+ return exports.FeatureWalkMode.Post;
20424
20672
  }
20425
- else {
20426
- const s = 2.0 * Math.sqrt(1.0 + r22 - r00 - r11);
20427
- qw = (r10 - r01) / s;
20428
- qx = (r02 + r20) / s;
20429
- qy = (r12 + r21) / s;
20430
- qz = 0.25 * s;
20673
+ static register(options) {
20674
+ if (options.computeShorthand) {
20675
+ // @ts-ignore
20676
+ options.features.push(new ComputeShorthandFeature(options));
20677
+ }
20431
20678
  }
20432
- [qx, qy, qz] = toZero([qx, qy, qz]);
20433
- // const q = gcd(qx, gcd(qy, qz));
20434
- let q = [Math.abs(qx), Math.abs(qy), Math.abs(qz)].reduce((acc, curr) => {
20435
- if (acc == 0 || (curr > 0 && curr < acc)) {
20436
- acc = curr;
20679
+ run(ast, options = {}, parent, context) {
20680
+ if (!('chi' in ast)) {
20681
+ return null;
20437
20682
  }
20438
- return acc;
20439
- }, 0);
20440
- if (q > 0) {
20441
- qx /= q;
20442
- qy /= q;
20443
- qz /= q;
20683
+ // @ts-ignore
20684
+ const j = ast.chi.length;
20685
+ let k = 0;
20686
+ let l;
20687
+ let properties = new PropertyList(options);
20688
+ const rules = [];
20689
+ // @ts-ignore
20690
+ for (; k < j; k++) {
20691
+ l = k;
20692
+ // capture comments with the next token
20693
+ while (l + 1 < j) {
20694
+ // @ts-ignore
20695
+ const node = ast.chi[l];
20696
+ if (node.typ == exports.EnumToken.CommentNodeType) {
20697
+ l++;
20698
+ continue;
20699
+ }
20700
+ break;
20701
+ }
20702
+ // @ts-ignore
20703
+ const node = ast.chi[l];
20704
+ if (node.typ == exports.EnumToken.DeclarationNodeType) {
20705
+ properties.add(...ast.chi.slice(k, l + 1));
20706
+ }
20707
+ else {
20708
+ rules.push(...ast.chi.slice(k, l + 1));
20709
+ }
20710
+ k = l;
20711
+ }
20712
+ // @ts-ignore
20713
+ ast.chi = [...properties, ...rules];
20714
+ return ast;
20444
20715
  }
20445
- const rotate = [qx, qy, qz, Object.is(qw, 0) ? 0 : 2 * Math.acos(qw) * 180 / Math.PI];
20446
- const scale = [scaleX, scaleY, scaleZ];
20447
- const skew = [skewXY, skewXZ, skewYZ];
20448
- return {
20449
- translate,
20450
- scale,
20451
- rotate,
20452
- skew,
20453
- perspective
20454
- };
20455
20716
  }
20456
- function transposeMatrix4(m) {
20457
- return [
20458
- m[0], m[4], m[8], m[12],
20459
- m[1], m[5], m[9], m[13],
20460
- m[2], m[6], m[10], m[14],
20461
- m[3], m[7], m[11], m[15],
20462
- ];
20463
- }
20464
- function toZero(v) {
20465
- for (let i = 0; i < v.length; i++) {
20466
- if (Math.abs(v[i]) <= epsilon) {
20467
- v[i] = 0;
20717
+
20718
+ class ComputeCalcExpressionFeature {
20719
+ get ordering() {
20720
+ return 1;
20721
+ }
20722
+ get processMode() {
20723
+ return exports.FeatureWalkMode.Post;
20724
+ }
20725
+ static register(options) {
20726
+ if (options.computeCalcExpression) {
20727
+ // @ts-ignore
20728
+ options.features.push(new ComputeCalcExpressionFeature());
20468
20729
  }
20469
- else {
20470
- v[i] = +v[i].toPrecision(6);
20730
+ }
20731
+ run(ast) {
20732
+ if (!('chi' in ast)) {
20733
+ return null;
20734
+ }
20735
+ for (const node of ast.chi) {
20736
+ if (node.typ != exports.EnumToken.DeclarationNodeType) {
20737
+ continue;
20738
+ }
20739
+ const set = new Set;
20740
+ for (const { value, parent } of walkValues(node.val, node, {
20741
+ event: exports.WalkerValueEvent.Enter,
20742
+ // @ts-ignore
20743
+ fn(node, parent) {
20744
+ if (parent != null &&
20745
+ // @ts-ignore
20746
+ parent.typ == exports.EnumToken.DeclarationNodeType &&
20747
+ // @ts-ignore
20748
+ parent.val.length == 1 &&
20749
+ node.typ == exports.EnumToken.FunctionTokenType &&
20750
+ mathFuncs.includes(node.val) &&
20751
+ node.chi.length == 1 &&
20752
+ node.chi[0].typ == exports.EnumToken.IdenTokenType) {
20753
+ return exports.WalkerOptionEnum.Ignore;
20754
+ }
20755
+ if ((node.typ == exports.EnumToken.FunctionTokenType && node.val == 'var') || (!mathFuncs.includes(parent.val) && [exports.EnumToken.ColorTokenType, exports.EnumToken.DeclarationNodeType, exports.EnumToken.RuleNodeType, exports.EnumToken.AtRuleNodeType, exports.EnumToken.StyleSheetNodeType].includes(parent?.typ))) {
20756
+ return null;
20757
+ }
20758
+ // @ts-ignore
20759
+ const slice = (node.typ == exports.EnumToken.FunctionTokenType ? node.chi : (node.typ == exports.EnumToken.DeclarationNodeType ? node.val : node.chi))?.slice();
20760
+ if (slice != null && node.typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(node.val)) {
20761
+ // @ts-ignore
20762
+ const key = 'chi' in node ? 'chi' : 'val';
20763
+ const str1 = renderToken({ ...node, [key]: slice });
20764
+ const str2 = renderToken(node); // values.reduce((acc: string, curr: Token): string => acc + renderToken(curr), '');
20765
+ if (str1.length <= str2.length) {
20766
+ // @ts-ignore
20767
+ node[key] = slice;
20768
+ }
20769
+ return exports.WalkerOptionEnum.Ignore;
20770
+ }
20771
+ return null;
20772
+ }
20773
+ })) {
20774
+ if (value != null && value.typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(value.val)) {
20775
+ if (!set.has(value)) {
20776
+ set.add(value);
20777
+ if (parent != null) {
20778
+ // @ts-ignore
20779
+ const cp = value.typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(value.val) && value.val != 'calc' ? [value] : (value.typ == exports.EnumToken.DeclarationNodeType ? value.val : value.chi);
20780
+ const values = evaluate(cp);
20781
+ // @ts-ignore
20782
+ const children = parent.typ == exports.EnumToken.DeclarationNodeType ? parent.val : parent.chi;
20783
+ if (values.length == 1 && values[0].typ != exports.EnumToken.BinaryExpressionTokenType) {
20784
+ for (let i = 0; i < children.length; i++) {
20785
+ if (children[i] == value) {
20786
+ children.splice(i, 1, !(parent.typ == exports.EnumToken.FunctionTokenType && parent.val == 'calc') && (typeof values[0].val != 'number' && !(values[0].typ == exports.EnumToken.FunctionTokenType && mathFuncs.includes(values[0].val))) ? {
20787
+ typ: exports.EnumToken.FunctionTokenType,
20788
+ val: 'calc',
20789
+ chi: values
20790
+ } : values[0]);
20791
+ break;
20792
+ }
20793
+ }
20794
+ }
20795
+ else {
20796
+ for (let i = 0; i < children.length; i++) {
20797
+ if (children[i] == value) {
20798
+ children.splice(i, 1, {
20799
+ typ: exports.EnumToken.FunctionTokenType,
20800
+ val: 'calc',
20801
+ chi: values
20802
+ });
20803
+ break;
20804
+ }
20805
+ }
20806
+ }
20807
+ }
20808
+ }
20809
+ }
20810
+ }
20471
20811
  }
20812
+ return null;
20472
20813
  }
20473
- return v;
20474
- }
20475
- // https://drafts.csswg.org/css-transforms-1/#2d-matrix
20476
- function is2DMatrix(matrix) {
20477
- // m13,m14, m23, m24, m31, m32, m34, m43 are all 0
20478
- return matrix[0 * 4 + 2] === 0 &&
20479
- matrix[0 * 4 + 3] === 0 &&
20480
- matrix[1 * 4 + 2] === 0 &&
20481
- matrix[1 * 4 + 3] === 0 &&
20482
- matrix[2 * 4 + 0] === 0 &&
20483
- matrix[2 * 4 + 1] === 0 &&
20484
- matrix[2 * 4 + 3] === 0 &&
20485
- matrix[3 * 4 + 2] === 0 &&
20486
- matrix[2 * 4 + 2] === 1 &&
20487
- matrix[3 * 4 + 3] === 1;
20488
20814
  }
20489
20815
 
20490
20816
  function translateX(x, from) {
@@ -21272,11 +21598,8 @@
21272
21598
  get ordering() {
21273
21599
  return 4;
21274
21600
  }
21275
- get preProcess() {
21276
- return false;
21277
- }
21278
- get postProcess() {
21279
- return true;
21601
+ get processMode() {
21602
+ return exports.FeatureWalkMode.Post;
21280
21603
  }
21281
21604
  static register(options) {
21282
21605
  // @ts-ignore
@@ -21287,7 +21610,7 @@
21287
21610
  }
21288
21611
  run(ast) {
21289
21612
  if (!('chi' in ast)) {
21290
- return;
21613
+ return null;
21291
21614
  }
21292
21615
  let i = 0;
21293
21616
  let node;
@@ -21334,6 +21657,7 @@
21334
21657
  return acc;
21335
21658
  }, [matrix]);
21336
21659
  }
21660
+ return null;
21337
21661
  }
21338
21662
  }
21339
21663
 
@@ -21346,21 +21670,6 @@
21346
21670
  TransformCssFeature: TransformCssFeature
21347
21671
  });
21348
21672
 
21349
- /**
21350
- * feature walk mode
21351
- */
21352
- exports.FeatureWalkMode = void 0;
21353
- (function (FeatureWalkMode) {
21354
- /**
21355
- * pre process
21356
- */
21357
- FeatureWalkMode[FeatureWalkMode["Pre"] = 0] = "Pre";
21358
- /**
21359
- * post process
21360
- */
21361
- FeatureWalkMode[FeatureWalkMode["Post"] = 1] = "Post";
21362
- })(exports.FeatureWalkMode || (exports.FeatureWalkMode = {}));
21363
-
21364
21673
  const combinators = ['+', '>', '~', '||', '|'];
21365
21674
  const definedPropertySettings = { configurable: true, enumerable: false, writable: true };
21366
21675
  const notEndingWith = ['(', '['].concat(combinators);
@@ -21380,6 +21689,7 @@
21380
21689
  let preprocess = false;
21381
21690
  let postprocess = false;
21382
21691
  let parents;
21692
+ let replacement;
21383
21693
  if (!('features' in options)) {
21384
21694
  // @ts-ignore
21385
21695
  options = {
@@ -21389,82 +21699,92 @@
21389
21699
  removePrefix: false,
21390
21700
  features: [], ...options
21391
21701
  };
21392
- // @ts-ignore
21393
21702
  for (const feature of features) {
21394
21703
  feature.register(options);
21395
21704
  }
21396
21705
  options.features.sort((a, b) => a.ordering - b.ordering);
21397
21706
  }
21398
21707
  for (const feature of options.features) {
21399
- if (feature.preProcess) {
21708
+ if (feature.processMode & exports.FeatureWalkMode.Pre) {
21400
21709
  preprocess = true;
21401
21710
  }
21402
- if (feature.postProcess) {
21711
+ if (feature.processMode & exports.FeatureWalkMode.Post) {
21403
21712
  postprocess = true;
21404
21713
  }
21405
21714
  }
21406
21715
  if (preprocess) {
21407
- parents = [ast];
21716
+ parents = new Set([ast]);
21408
21717
  for (const parent of parents) {
21409
21718
  if (parent.typ == exports.EnumToken.CommentTokenType ||
21410
21719
  parent.typ == exports.EnumToken.CDOCOMMTokenType) {
21411
- Object.defineProperty(parent, 'parent', {
21412
- ...definedPropertySettings,
21413
- value: parent
21414
- });
21415
21720
  continue;
21416
21721
  }
21722
+ replacement = parent;
21417
21723
  for (const feature of options.features) {
21418
- if (!feature.preProcess) {
21724
+ if ((feature.processMode & exports.FeatureWalkMode.Pre) === 0) {
21419
21725
  continue;
21420
21726
  }
21421
- feature.run(parent, options, parent.parent ?? ast, context, exports.FeatureWalkMode.Pre);
21727
+ const result = feature.run(replacement, options, parent.parent ?? ast, context, exports.FeatureWalkMode.Pre);
21728
+ if (result != null) {
21729
+ replacement = result;
21730
+ }
21422
21731
  }
21423
- if (('chi' in parent)) {
21732
+ if (replacement != parent && parent.parent != null) {
21424
21733
  // @ts-ignore
21425
- for (const node of parent.chi) {
21426
- parents.push(Object.defineProperty(node, 'parent', {
21734
+ replaceToken(parent.parent, parent, replacement);
21735
+ }
21736
+ if (('chi' in replacement)) {
21737
+ // @ts-ignore
21738
+ for (const node of replacement.chi) {
21739
+ parents.add(Object.defineProperty(node, 'parent', {
21427
21740
  ...definedPropertySettings,
21428
- value: parent
21741
+ value: replacement
21429
21742
  }));
21430
21743
  }
21431
21744
  }
21432
21745
  }
21433
21746
  for (const feature of options.features) {
21434
- if (feature.preProcess && 'cleanup' in feature) {
21747
+ if ((feature.processMode & exports.FeatureWalkMode.Pre) && 'cleanup' in feature) {
21435
21748
  // @ts-ignore
21436
21749
  feature.cleanup(ast, options, context, exports.FeatureWalkMode.Pre);
21437
21750
  }
21438
21751
  }
21439
21752
  }
21440
21753
  doMinify(ast, options, recursive, errors, nestingContent, context);
21441
- parents = [ast];
21754
+ parents = new Set([ast]);
21442
21755
  for (const parent of parents) {
21443
21756
  if (parent.typ == exports.EnumToken.CommentTokenType ||
21444
21757
  parent.typ == exports.EnumToken.CDOCOMMTokenType) {
21445
21758
  continue;
21446
21759
  }
21760
+ replacement = parent;
21447
21761
  if (postprocess) {
21448
21762
  for (const feature of options.features) {
21449
- if (!feature.postProcess) {
21763
+ if ((feature.processMode & exports.FeatureWalkMode.Post) === 0) {
21450
21764
  continue;
21451
21765
  }
21452
- feature.run(parent, options, parent.parent ?? ast, context, exports.FeatureWalkMode.Post);
21766
+ const result = feature.run(replacement, options, parent.parent ?? ast, context, exports.FeatureWalkMode.Post);
21767
+ if (result != null) {
21768
+ replacement = result;
21769
+ }
21453
21770
  }
21454
21771
  }
21455
- if (('chi' in parent)) {
21772
+ if (replacement != null && replacement != parent && parent.parent != null) {
21456
21773
  // @ts-ignore
21457
- for (const node of parent.chi) {
21458
- parents.push(Object.defineProperty(node, 'parent', {
21774
+ replaceToken(parent.parent, parent, replacement);
21775
+ }
21776
+ if (('chi' in replacement)) {
21777
+ for (const node of replacement.chi) {
21778
+ parents.add(Object.defineProperty(node, 'parent', {
21459
21779
  ...definedPropertySettings,
21460
- value: parent
21780
+ value: replacement
21461
21781
  }));
21462
21782
  }
21463
21783
  }
21464
21784
  }
21465
21785
  if (postprocess) {
21466
21786
  for (const feature of options.features) {
21467
- if (feature.postProcess && 'cleanup' in feature) {
21787
+ if (feature.processMode & exports.FeatureWalkMode.Post && 'cleanup' in feature) {
21468
21788
  // @ts-ignore
21469
21789
  feature.cleanup(ast, options, context, exports.FeatureWalkMode.Post);
21470
21790
  }
@@ -21476,12 +21796,10 @@
21476
21796
  * reduce selectors
21477
21797
  * @param acc
21478
21798
  * @param curr
21479
- * @param index
21480
- * @param array
21481
21799
  *
21482
21800
  * @private
21483
21801
  */
21484
- function reduce(acc, curr, index, array) {
21802
+ function reduce(acc, curr) {
21485
21803
  // trim :is()
21486
21804
  // if (array.length == 1 && array[0][0] == ':is(' && array[0].at(-1) == ')') {
21487
21805
  //
@@ -21522,21 +21840,18 @@
21522
21840
  }
21523
21841
  let i = 0;
21524
21842
  let previous = null;
21525
- let node;
21843
+ let node = null;
21526
21844
  let nodeIndex = -1;
21527
- // @ts-ignore
21528
21845
  for (; i < ast.chi.length; i++) {
21529
- // @ts-ignore
21530
21846
  if (ast.chi[i].typ == exports.EnumToken.CommentNodeType) {
21531
21847
  continue;
21532
21848
  }
21533
- // @ts-ignore
21534
21849
  node = ast.chi[i];
21535
21850
  if (node.typ == exports.EnumToken.AtRuleNodeType && node.nam == 'font-face') {
21536
21851
  continue;
21537
21852
  }
21538
- if (node.typ == exports.EnumToken.KeyframeAtRuleNodeType) {
21539
- if (previous?.typ == exports.EnumToken.KeyframeAtRuleNodeType &&
21853
+ if (node.typ == exports.EnumToken.KeyframesAtRuleNodeType) {
21854
+ if (previous?.typ == exports.EnumToken.KeyframesAtRuleNodeType &&
21540
21855
  node.nam == previous.nam &&
21541
21856
  node.val == previous.val) {
21542
21857
  ast.chi?.splice(nodeIndex--, 1);
@@ -21544,15 +21859,11 @@
21544
21859
  i = nodeIndex;
21545
21860
  continue;
21546
21861
  }
21547
- if (node.chi.length > 0) {
21548
- doMinify(node, options, true, errors, nestingContent, context);
21549
- }
21550
21862
  }
21551
- else if (node.typ == exports.EnumToken.KeyFrameRuleNodeType) {
21552
- if (previous?.typ == exports.EnumToken.KeyFrameRuleNodeType &&
21863
+ else if (node.typ == exports.EnumToken.KeyFramesRuleNodeType) {
21864
+ if (previous?.typ == exports.EnumToken.KeyFramesRuleNodeType &&
21553
21865
  node.sel == previous.sel) {
21554
21866
  previous.chi.push(...node.chi);
21555
- // @ts-ignore
21556
21867
  ast.chi.splice(i--, 1);
21557
21868
  continue;
21558
21869
  }
@@ -21574,25 +21885,25 @@
21574
21885
  }
21575
21886
  }
21576
21887
  else if (node.typ == exports.EnumToken.AtRuleNodeType) {
21577
- // @ts-ignore
21578
21888
  if (node.nam == 'media' && ['all', '', null].includes(node.val)) {
21579
- // @ts-ignore
21580
21889
  ast.chi?.splice(i, 1, ...node.chi);
21581
21890
  i--;
21582
21891
  continue;
21583
21892
  }
21584
- // @ts-ignore
21585
21893
  if (previous?.typ == exports.EnumToken.AtRuleNodeType &&
21586
21894
  previous.nam == node.nam &&
21587
21895
  previous.val == node.val) {
21588
21896
  if ('chi' in node) {
21589
21897
  // @ts-ignore
21590
21898
  previous.chi.push(...node.chi);
21899
+ if (!hasDeclaration(previous)) {
21900
+ context.nodes.delete(previous);
21901
+ doMinify(previous, options, recursive, errors, nestingContent, context);
21902
+ }
21591
21903
  }
21592
21904
  ast?.chi?.splice(i--, 1);
21593
21905
  continue;
21594
21906
  }
21595
- // @ts-ignore
21596
21907
  if (!hasDeclaration(node)) {
21597
21908
  doMinify(node, options, recursive, errors, nestingContent, context);
21598
21909
  }
@@ -21603,47 +21914,33 @@
21603
21914
  // @ts-ignore
21604
21915
  else if (node.typ == exports.EnumToken.RuleNodeType) {
21605
21916
  reduceRuleSelector(node);
21606
- let wrapper;
21917
+ let wrapper = null;
21607
21918
  let match;
21608
- // @ts-ignore
21609
21919
  if (options.nestingRules) {
21610
- // @ts-ignore
21611
21920
  if (previous?.typ == exports.EnumToken.RuleNodeType) {
21612
- // @ts-ignore
21613
21921
  reduceRuleSelector(previous);
21614
21922
  // @ts-ignore
21615
21923
  match = matchSelectors(previous.raw, node.raw, ast.typ);
21616
- // @ts-ignore
21617
21924
  if (match != null) {
21618
- // @ts-ignore
21619
21925
  wrapper = wrapNodes(previous, node, match, ast, reducer, i, nodeIndex);
21620
21926
  nodeIndex = i - 1;
21621
- // @ts-ignore
21622
21927
  previous = ast.chi[nodeIndex];
21623
21928
  }
21624
21929
  }
21625
- // @ts-ignore
21626
21930
  if (wrapper != null) {
21627
- // @ts-ignore
21628
21931
  while (i < ast.chi.length) {
21629
- // @ts-ignore
21630
21932
  const nextNode = ast.chi[i];
21631
- // @ts-ignore
21632
21933
  if (nextNode.typ != exports.EnumToken.RuleNodeType) {
21633
21934
  break;
21634
21935
  }
21635
21936
  reduceRuleSelector(nextNode);
21636
- // @ts-ignore
21637
- match = matchSelectors(wrapper.raw, nextNode.raw, ast.typ);
21638
- // @ts-ignore
21937
+ match = matchSelectors(wrapper.raw, nextNode.raw);
21639
21938
  if (match == null) {
21640
21939
  break;
21641
21940
  }
21642
- // @ts-ignore
21643
21941
  wrapper = wrapNodes(wrapper, nextNode, match, ast, reducer, i, nodeIndex);
21644
21942
  }
21645
21943
  nodeIndex = --i;
21646
- // @ts-ignore
21647
21944
  previous = ast.chi[nodeIndex];
21648
21945
  doMinify(wrapper, options, recursive, errors, nestingContent, context);
21649
21946
  continue;
@@ -21690,7 +21987,6 @@
21690
21987
  curr.unshift('&');
21691
21988
  wrap = false;
21692
21989
  }
21693
- // @ts-ignore
21694
21990
  acc.push(curr);
21695
21991
  return acc;
21696
21992
  }, []);
@@ -21716,82 +22012,65 @@
21716
22012
  }
21717
22013
  }
21718
22014
  if (rule == null) {
21719
- rule = selector.map(s => {
22015
+ rule = selector.map((s) => {
21720
22016
  if (s[0] == '&') {
21721
22017
  s.splice(0, 1, ...node.optimized.optimized);
21722
22018
  }
21723
22019
  return s.join('');
21724
22020
  }).join(',');
21725
22021
  }
21726
- // @ts-ignore
21727
22022
  let sel = wrap ? node.optimized.optimized.join('') + `:is(${rule})` : rule;
21728
22023
  if (sel.length < node.sel.length) {
21729
22024
  node.sel = sel;
21730
22025
  }
21731
22026
  }
22027
+ doMinify(node, options, recursive, errors, nestingContent, context);
21732
22028
  }
21733
- // @ts-ignore
21734
22029
  if (previous != null) {
21735
- // @ts-ignore
21736
22030
  if ('chi' in previous && ('chi' in node)) {
21737
- // @ts-ignore
21738
22031
  if (previous.typ == node.typ) {
21739
22032
  let shouldMerge = true;
21740
- // @ts-ignore
21741
22033
  let k = previous.chi.length;
21742
22034
  while (k-- > 0) {
21743
- // @ts-ignore
21744
22035
  if (previous.chi[k].typ == exports.EnumToken.CommentNodeType) {
21745
22036
  continue;
21746
22037
  }
21747
- // @ts-ignore
21748
22038
  shouldMerge = previous.chi[k].typ == exports.EnumToken.DeclarationNodeType;
21749
22039
  break;
21750
22040
  }
21751
22041
  if (shouldMerge) {
21752
- // @ts-ignore
21753
- if (((node.typ == exports.EnumToken.RuleNodeType || node.typ == exports.EnumToken.KeyFrameRuleNodeType) && node.sel == previous.sel) ||
21754
- // @ts-ignore
22042
+ if (((node.typ == exports.EnumToken.RuleNodeType || node.typ == exports.EnumToken.KeyFramesRuleNodeType) && node.sel == previous.sel) ||
21755
22043
  (node.typ == exports.EnumToken.AtRuleNodeType) && node.val != 'font-face' && node.val == previous.val) {
21756
22044
  // @ts-ignore
21757
22045
  node.chi.unshift(...previous.chi);
21758
- // @ts-ignore
22046
+ doMinify(node, options, recursive, errors, nestingContent, context);
21759
22047
  ast.chi.splice(nodeIndex, 1);
21760
- i--;
21761
- previous = node;
22048
+ previous = ast.chi[--i];
21762
22049
  nodeIndex = i;
21763
22050
  continue;
21764
22051
  }
21765
- else if (node.typ == previous?.typ && [exports.EnumToken.KeyFrameRuleNodeType, exports.EnumToken.RuleNodeType].includes(node.typ)) {
22052
+ else if (node.typ == previous?.typ && [exports.EnumToken.KeyFramesRuleNodeType, exports.EnumToken.RuleNodeType].includes(node.typ)) {
21766
22053
  const intersect = diff(previous, node, reducer, options);
21767
22054
  if (intersect != null) {
21768
22055
  if (intersect.node1.chi.length == 0) {
21769
- // @ts-ignore
21770
22056
  ast.chi.splice(i--, 1);
21771
22057
  }
21772
22058
  else {
21773
- // @ts-ignore
21774
22059
  ast.chi.splice(i--, 1, intersect.node1);
21775
22060
  }
21776
22061
  if (intersect.node2.chi.length == 0) {
21777
- // @ts-ignore
21778
22062
  ast.chi.splice(nodeIndex, 1, intersect.result);
21779
22063
  i--;
21780
- // @ts-ignore
21781
22064
  if (nodeIndex == i) {
21782
22065
  nodeIndex = i;
21783
22066
  }
21784
22067
  }
21785
22068
  else {
21786
- // @ts-ignore
21787
22069
  ast.chi.splice(nodeIndex, 1, intersect.result, intersect.node2);
21788
- // @ts-ignore
21789
22070
  i = (nodeIndex ?? 0) + 1;
21790
22071
  }
21791
22072
  reduceRuleSelector(intersect.result);
21792
- // @ts-ignore
21793
22073
  if (node != ast.chi[i]) {
21794
- // @ts-ignore
21795
22074
  node = ast.chi[i];
21796
22075
  }
21797
22076
  previous = intersect.result;
@@ -21800,9 +22079,7 @@
21800
22079
  }
21801
22080
  }
21802
22081
  }
21803
- // @ts-ignore
21804
22082
  if (recursive && previous != node) {
21805
- // @ts-ignore
21806
22083
  if (!hasDeclaration(previous)) {
21807
22084
  doMinify(previous, options, recursive, errors, nestingContent, context);
21808
22085
  }
@@ -21810,9 +22087,7 @@
21810
22087
  }
21811
22088
  }
21812
22089
  if (!nestingContent &&
21813
- // @ts-ignore
21814
22090
  previous != null &&
21815
- // previous.optimized != null &&
21816
22091
  previous.typ == exports.EnumToken.RuleNodeType &&
21817
22092
  previous.sel.includes('&')) {
21818
22093
  fixSelector(previous);
@@ -21820,20 +22095,15 @@
21820
22095
  previous = node;
21821
22096
  nodeIndex = i;
21822
22097
  }
21823
- // @ts-ignore
21824
22098
  if (recursive && node != null && ('chi' in node)) {
21825
- // @ts-ignore
21826
- if (node.typ == exports.EnumToken.KeyframeAtRuleNodeType || !node.chi.some(n => n.typ == exports.EnumToken.DeclarationNodeType)) {
21827
- // @ts-ignore
22099
+ if (node.typ == exports.EnumToken.KeyframesAtRuleNodeType || !node.chi.some(n => n.typ == exports.EnumToken.DeclarationNodeType)) {
21828
22100
  if (!(node.typ == exports.EnumToken.AtRuleNodeType && node.nam != 'font-face')) {
21829
22101
  doMinify(node, options, recursive, errors, nestingContent, context);
21830
22102
  }
21831
22103
  }
21832
22104
  }
21833
22105
  if (!nestingContent &&
21834
- // @ts-ignore
21835
22106
  node != null &&
21836
- // previous.optimized != null &&
21837
22107
  node.typ == exports.EnumToken.RuleNodeType &&
21838
22108
  node.sel.includes('&')) {
21839
22109
  fixSelector(node);
@@ -21984,7 +22254,6 @@
21984
22254
  }
21985
22255
  if (chr == ',') {
21986
22256
  if (str !== '') {
21987
- // @ts-ignore
21988
22257
  result.at(-1).push(str);
21989
22258
  str = '';
21990
22259
  }
@@ -21993,7 +22262,6 @@
21993
22262
  }
21994
22263
  if (chr == '.') {
21995
22264
  if (str !== '') {
21996
- // @ts-ignore
21997
22265
  result.at(-1).push(str);
21998
22266
  str = '';
21999
22267
  }
@@ -22002,20 +22270,17 @@
22002
22270
  }
22003
22271
  if (combinators.includes(chr)) {
22004
22272
  if (str !== '') {
22005
- // @ts-ignore
22006
22273
  result.at(-1).push(str);
22007
22274
  str = '';
22008
22275
  }
22009
22276
  if (chr == '|' && buffer.charAt(i + 1) == '|') {
22010
22277
  chr += buffer.charAt(++i);
22011
22278
  }
22012
- // @ts-ignore
22013
22279
  result.at(-1).push(chr);
22014
22280
  continue;
22015
22281
  }
22016
22282
  if (chr == ':') {
22017
22283
  if (str !== '') {
22018
- // @ts-ignore
22019
22284
  result.at(-1).push(str);
22020
22285
  str = '';
22021
22286
  }
@@ -22057,7 +22322,6 @@
22057
22322
  }
22058
22323
  }
22059
22324
  if (str !== '') {
22060
- // @ts-ignore
22061
22325
  result.at(-1).push(str);
22062
22326
  }
22063
22327
  return result;
@@ -22122,7 +22386,7 @@
22122
22386
  *
22123
22387
  * @private
22124
22388
  */
22125
- function matchSelectors(selector1, selector2 /*, parentType: EnumToken, errors: ErrorDescription[] */) {
22389
+ function matchSelectors(selector1, selector2) {
22126
22390
  let match = [[]];
22127
22391
  const j = Math.min(selector1.reduce((acc, curr) => Math.min(acc, curr.length), selector1.length > 0 ? selector1[0].length : 0), selector2.reduce((acc, curr) => Math.min(acc, curr.length), selector2.length > 0 ? selector2[0].length : 0));
22128
22392
  let i = 0;
@@ -22197,7 +22461,6 @@
22197
22461
  * @private
22198
22462
  */
22199
22463
  function fixSelector(node) {
22200
- // @ts-ignore
22201
22464
  if (node.sel.includes('&')) {
22202
22465
  const attributes = parseString(node.sel);
22203
22466
  for (const attr of walkValues(attributes)) {
@@ -22232,40 +22495,27 @@
22232
22495
  let nSel = match.selector2.reduce(reducer, []).join(',');
22233
22496
  // @ts-ignore
22234
22497
  const wrapper = { ...previous, chi: [], sel: match.match.reduce(reducer, []).join(',') };
22235
- // @ts-ignore
22236
22498
  Object.defineProperty(wrapper, 'raw', {
22237
22499
  ...definedPropertySettings,
22238
- // @ts-ignore
22239
22500
  value: match.match.map(t => t.slice())
22240
22501
  });
22241
22502
  if (pSel == '&' || pSel === '') {
22242
- // @ts-ignore
22243
22503
  wrapper.chi.push(...previous.chi);
22244
- // @ts-ignore
22245
22504
  if ((nSel == '&' || nSel === '')) {
22246
- // @ts-ignore
22247
22505
  wrapper.chi.push(...node.chi);
22248
22506
  }
22249
22507
  else {
22250
- // @ts-ignore
22251
22508
  wrapper.chi.push(node);
22252
22509
  }
22253
22510
  }
22254
22511
  else {
22255
- // @ts-ignore
22256
22512
  wrapper.chi.push(previous, node);
22257
22513
  }
22258
- // @ts-ignore
22259
22514
  ast.chi.splice(i, 1, wrapper);
22260
- // @ts-ignore
22261
22515
  ast.chi.splice(nodeIndex, 1);
22262
- // @ts-ignore
22263
22516
  previous.sel = pSel;
22264
- // @ts-ignore
22265
22517
  previous.raw = match.selector1;
22266
- // @ts-ignore
22267
22518
  node.sel = nSel;
22268
- // @ts-ignore
22269
22519
  node.raw = match.selector2;
22270
22520
  reduceRuleSelector(wrapper);
22271
22521
  return wrapper;
@@ -22674,12 +22924,14 @@
22674
22924
  /**
22675
22925
  * return the directory name of a path
22676
22926
  * @param path
22677
- * @internal
22927
+ *
22928
+ * @private
22678
22929
  */
22679
22930
  function dirname(path) {
22680
- if (path == '/' || path === '') {
22681
- return path;
22682
- }
22931
+ // if (path == '/' || path === '') {
22932
+ //
22933
+ // return path;
22934
+ // }
22683
22935
  let i = 0;
22684
22936
  let parts = [''];
22685
22937
  for (; i < path.length; i++) {
@@ -22776,17 +23028,13 @@
22776
23028
  }
22777
23029
 
22778
23030
  /**
22779
- * web module entry point
22780
- * @module web
22781
- */
22782
- /**
22783
- * load file or url as stream
23031
+ * default file or url loader
22784
23032
  * @param url
22785
23033
  * @param currentFile
22786
23034
  *
22787
23035
  * @private
22788
23036
  */
22789
- async function getStream(url, currentFile = '.') {
23037
+ async function load(url, currentFile = '.') {
22790
23038
  let t;
22791
23039
  if (matchUrl.test(url)) {
22792
23040
  t = new URL(url);
@@ -22808,13 +23056,35 @@
22808
23056
  });
22809
23057
  }
22810
23058
  /**
22811
- * render ast node
23059
+ * render the ast tree
22812
23060
  * @param data
22813
23061
  * @param options
23062
+ *
23063
+ * Example:
23064
+ *
23065
+ * ```ts
23066
+ *
23067
+ * import {render, ColorType} from '@tbela99/css-parser';
23068
+ *
23069
+ * const css = 'body { color: color(from hsl(0 100% 50%) xyz x y z); }';
23070
+ * const parseResult = await parse(css);
23071
+ *
23072
+ * let renderResult = render(parseResult.ast);
23073
+ * console.log(result.code);
23074
+ *
23075
+ * // body{color:red}
23076
+ *
23077
+ *
23078
+ * renderResult = render(parseResult.ast, {beautify: true, convertColor: ColorType.SRGB});
23079
+ * console.log(renderResult.code);
23080
+ *
23081
+ * // body {
23082
+ * // color: color(srgb 1 0 0)
23083
+ * // }
23084
+ * ```
22814
23085
  */
22815
23086
  function render(data, options = {}) {
22816
23087
  return doRender(data, Object.assign(options, {
22817
- getStream,
22818
23088
  resolve,
22819
23089
  dirname,
22820
23090
  cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
@@ -22824,26 +23094,66 @@
22824
23094
  * parse css file
22825
23095
  * @param file url or path
22826
23096
  * @param options
23097
+ *
23098
+ * @throws Error file not found
23099
+ *
23100
+ * Example:
23101
+ *
23102
+ * ```ts
23103
+ *
23104
+ * import {parseFile} from '@tbela99/css-parser/web';
23105
+ *
23106
+ * // remote file
23107
+ * let result = await parseFile('https://docs.deno.com/styles.css');
23108
+ * console.log(result.ast);
23109
+ *
23110
+ * // local file
23111
+ * result = await parseFile('./css/styles.css');
23112
+ * console.log(result.ast);
23113
+ * ```
22827
23114
  */
22828
23115
  async function parseFile(file, options = {}) {
22829
- return getStream(file).then(stream => parse(stream, { src: file, ...options }));
23116
+ return load(file).then(stream => parse(stream, { src: file, ...options }));
22830
23117
  }
22831
23118
  /**
22832
23119
  * parse css
22833
23120
  * @param stream
22834
- * @param opt
23121
+ * @param options
23122
+ *
23123
+ * Example:
23124
+ *
23125
+ * ```ts
23126
+ *
23127
+ * import {parse} from '@tbela99/css-parser/web';
23128
+ *
23129
+ * // css string
23130
+ * const result = await parse(css);
23131
+ * console.log(result.ast);
23132
+ * ```
23133
+ *
23134
+ * Example using fetch and readable stream
23135
+ *
23136
+ * ```ts
23137
+ *
23138
+ * import {parse} from '@tbela99/css-parser/web';
23139
+ *
23140
+ * const response = await fetch('https://docs.deno.com/styles.css');
23141
+ * const result = await parse(response.body, {beautify: true});
23142
+ *
23143
+ * console.log(result.ast);
23144
+ * ```
22835
23145
  */
22836
- async function parse(stream, opt = {}) {
23146
+ async function parse(stream, options = {}) {
22837
23147
  return doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize$1({
22838
23148
  stream,
22839
23149
  buffer: '',
22840
23150
  position: { ind: 0, lin: 1, col: 1 },
22841
23151
  currentPosition: { ind: -1, lin: 1, col: 0 }
22842
- }), Object.assign(opt, {
22843
- getStream,
23152
+ }), Object.assign(options, {
23153
+ load,
22844
23154
  resolve,
22845
23155
  dirname,
22846
- cwd: opt.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
23156
+ cwd: options.cwd ?? self.location.pathname.endsWith('/') ? self.location.pathname : dirname(self.location.pathname)
22847
23157
  }));
22848
23158
  }
22849
23159
  /**
@@ -22867,7 +23177,7 @@
22867
23177
  * ```
22868
23178
  */
22869
23179
  async function transformFile(file, options = {}) {
22870
- return getStream(file).then(stream => transform(stream, { src: file, ...options }));
23180
+ return load(file).then(stream => transform(stream, { src: file, ...options }));
22871
23181
  }
22872
23182
  /**
22873
23183
  * transform css
@@ -22895,7 +23205,8 @@
22895
23205
  options = { minify: true, removeEmpty: true, removeCharset: true, ...options };
22896
23206
  const startTime = performance.now();
22897
23207
  return parse(css, options).then((parseResult) => {
22898
- const rendered = render(parseResult.ast, options);
23208
+ // ast already expanded by parse
23209
+ const rendered = render(parseResult.ast, { ...options, expandNestingRules: false });
22899
23210
  return {
22900
23211
  ...parseResult,
22901
23212
  ...rendered,
@@ -22914,8 +23225,8 @@
22914
23225
  exports.convertColor = convertColor;
22915
23226
  exports.dirname = dirname;
22916
23227
  exports.expand = expand;
22917
- exports.getStream = getStream;
22918
23228
  exports.isOkLabClose = isOkLabClose;
23229
+ exports.load = load;
22919
23230
  exports.minify = minify;
22920
23231
  exports.okLabDistance = okLabDistance;
22921
23232
  exports.parse = parse;