@tbela99/css-parser 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/README.md +136 -82
  2. package/dist/index-umd-web.js +6956 -51524
  3. package/dist/index.cjs +6955 -51528
  4. package/dist/index.d.ts +180 -65
  5. package/dist/lib/ast/expand.js +34 -9
  6. package/dist/lib/ast/features/calc.js +76 -12
  7. package/dist/lib/ast/features/inlinecssvariables.js +6 -1
  8. package/dist/lib/ast/features/prefix.js +17 -9
  9. package/dist/lib/ast/features/shorthand.js +1 -0
  10. package/dist/lib/ast/math/expression.js +299 -11
  11. package/dist/lib/ast/math/math.js +7 -1
  12. package/dist/lib/ast/minify.js +1 -1
  13. package/dist/lib/ast/types.js +58 -49
  14. package/dist/lib/ast/walk.js +80 -18
  15. package/dist/lib/parser/declaration/list.js +1 -0
  16. package/dist/lib/parser/declaration/map.js +1 -0
  17. package/dist/lib/parser/declaration/set.js +1 -0
  18. package/dist/lib/parser/parse.js +285 -72
  19. package/dist/lib/parser/tokenize.js +16 -3
  20. package/dist/lib/parser/utils/declaration.js +2 -2
  21. package/dist/lib/parser/utils/type.js +6 -6
  22. package/dist/lib/renderer/color/a98rgb.js +1 -0
  23. package/dist/lib/renderer/color/color.js +1 -0
  24. package/dist/lib/renderer/color/colormix.js +1 -0
  25. package/dist/lib/renderer/color/hex.js +1 -0
  26. package/dist/lib/renderer/color/hsl.js +1 -0
  27. package/dist/lib/renderer/color/hwb.js +1 -0
  28. package/dist/lib/renderer/color/lab.js +1 -0
  29. package/dist/lib/renderer/color/lch.js +1 -0
  30. package/dist/lib/renderer/color/oklab.js +1 -0
  31. package/dist/lib/renderer/color/oklch.js +1 -0
  32. package/dist/lib/renderer/color/p3.js +1 -0
  33. package/dist/lib/renderer/color/prophotoRgb.js +56 -0
  34. package/dist/lib/renderer/color/rec2020.js +1 -0
  35. package/dist/lib/renderer/color/relativecolor.js +52 -28
  36. package/dist/lib/renderer/color/rgb.js +1 -0
  37. package/dist/lib/renderer/color/srgb.js +1 -0
  38. package/dist/lib/renderer/color/utils/components.js +1 -0
  39. package/dist/lib/renderer/color/utils/constants.js +1 -0
  40. package/dist/lib/renderer/color/xyz.js +1 -0
  41. package/dist/lib/renderer/color/xyzd50.js +1 -0
  42. package/dist/lib/renderer/render.js +28 -6
  43. package/dist/lib/syntax/syntax.js +27 -4
  44. package/dist/lib/validation/at-rules/counter-style.js +78 -0
  45. package/dist/lib/validation/at-rules/document.js +114 -0
  46. package/dist/lib/validation/at-rules/font-feature-values.js +49 -0
  47. package/dist/lib/validation/at-rules/import.js +196 -0
  48. package/dist/lib/validation/at-rules/keyframes.js +70 -0
  49. package/dist/lib/validation/at-rules/layer.js +27 -0
  50. package/dist/lib/validation/at-rules/media.js +166 -0
  51. package/dist/lib/validation/at-rules/namespace.js +85 -0
  52. package/dist/lib/validation/at-rules/page-margin-box.js +56 -0
  53. package/dist/lib/validation/at-rules/page.js +88 -0
  54. package/dist/lib/validation/at-rules/supports.js +262 -0
  55. package/dist/lib/validation/atrule.js +172 -0
  56. package/dist/lib/validation/config.js +30 -2
  57. package/dist/lib/validation/config.json.js +1560 -50902
  58. package/dist/lib/validation/declaration.js +72 -0
  59. package/dist/lib/validation/parser/parse.js +1059 -7
  60. package/dist/lib/validation/parser/types.js +27 -12
  61. package/dist/lib/validation/selector.js +23 -444
  62. package/dist/lib/validation/syntax.js +1429 -0
  63. package/dist/lib/validation/syntaxes/complex-selector-list.js +41 -0
  64. package/dist/lib/validation/syntaxes/complex-selector.js +283 -0
  65. package/dist/lib/validation/syntaxes/family-name.js +91 -0
  66. package/dist/lib/validation/syntaxes/keyframe-block-list.js +27 -0
  67. package/dist/lib/validation/syntaxes/keyframe-selector.js +137 -0
  68. package/dist/lib/validation/syntaxes/layer-name.js +67 -0
  69. package/dist/lib/validation/syntaxes/relative-selector-list.js +27 -0
  70. package/dist/lib/validation/syntaxes/relative-selector.js +36 -0
  71. package/dist/lib/validation/syntaxes/selector-list.js +5 -0
  72. package/dist/lib/validation/syntaxes/selector.js +5 -0
  73. package/dist/lib/validation/syntaxes/url.js +75 -0
  74. package/dist/lib/validation/utils/list.js +24 -0
  75. package/dist/lib/validation/utils/whitespace.js +22 -0
  76. package/dist/node/index.js +4 -4
  77. package/dist/web/index.js +4 -0
  78. package/dist/web/load.js +1 -0
  79. package/package.json +15 -13
  80. package/dist/lib/ast/utils/minifyfeature.js +0 -9
  81. package/dist/lib/iterable/weakset.js +0 -58
  82. package/dist/lib/parser/utils/syntax.js +0 -450
@@ -1,12 +1,12 @@
1
1
  import { EnumToken } from '../../ast/types.js';
2
2
  import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
3
4
  import '../parse.js';
5
+ import { mathFuncs } from '../../syntax/syntax.js';
6
+ import './config.js';
4
7
  import '../../renderer/color/utils/constants.js';
5
8
  import '../../renderer/sourcemap/lib/encode.js';
6
- import './config.js';
7
9
 
8
- // https://www.w3.org/TR/css-values-4/#math-function
9
- const funcList = ['clamp', 'calc'];
10
10
  function matchType(val, properties) {
11
11
  if (val.typ == EnumToken.IdenTokenType && properties.keywords.includes(val.val) ||
12
12
  // @ts-ignore
@@ -22,8 +22,8 @@ function matchType(val, properties) {
22
22
  });
23
23
  }
24
24
  if (val.typ == EnumToken.FunctionTokenType) {
25
- if (funcList.includes(val.val)) {
26
- return val.chi.every(((t) => [EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.StartParensTokenType, EnumToken.EndParensTokenType].includes(t.typ) || matchType(t, properties)));
25
+ if (mathFuncs.includes(val.val)) {
26
+ return val.chi.every(((t) => [EnumToken.Add, EnumToken.Mul, EnumToken.Div, EnumToken.Sub, EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.DimensionTokenType, EnumToken.NumberTokenType, EnumToken.LengthTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.ResolutionTokenType, EnumToken.TimeTokenType, EnumToken.BinaryExpressionTokenType].includes(t.typ) || matchType(t, properties)));
27
27
  }
28
28
  // match type defined like function 'symbols()', 'url()', 'attr()' etc.
29
29
  // return properties.types.includes((<FunctionToken>val).val + '()')
@@ -31,4 +31,4 @@ function matchType(val, properties) {
31
31
  return false;
32
32
  }
33
33
 
34
- export { funcList, matchType };
34
+ export { matchType };
@@ -3,6 +3,7 @@ import { multiplyMatrices } from './utils/matrix.js';
3
3
  import './utils/constants.js';
4
4
  import '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
+ import '../../ast/walk.js';
6
7
  import '../../parser/parse.js';
7
8
  import { srgb2xyz } from './xyz.js';
8
9
  import '../sourcemap/lib/encode.js';
@@ -1,5 +1,6 @@
1
1
  import { EnumToken } from '../../ast/types.js';
2
2
  import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
3
4
  import '../../parser/parse.js';
4
5
  import { srgb2rgb, lch2rgb, lab2rgb, oklch2rgb, oklab2rgb, hwb2rgb, hsl2rgb, hex2rgb } from './rgb.js';
5
6
  import { srgb2hsl, lch2hsl, lab2hsl, oklch2hsl, oklab2hsl, hwb2hsl, hex2hsl, rgb2hsl } from './hsl.js';
@@ -1,5 +1,6 @@
1
1
  import { EnumToken } from '../../ast/types.js';
2
2
  import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
3
4
  import '../../parser/parse.js';
4
5
  import { isRectangularOrthogonalColorspace, isPolarColorspace } from '../../syntax/syntax.js';
5
6
  import '../../parser/utils/config.js';
@@ -1,5 +1,6 @@
1
1
  import { EnumToken } from '../../ast/types.js';
2
2
  import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
3
4
  import '../../parser/parse.js';
4
5
  import { getNumber, minmax } from './color.js';
5
6
  import { hsl2rgb, hwb2rgb, cmyk2rgb, oklab2rgb, oklch2rgb, lab2rgb, lch2rgb } from './rgb.js';
@@ -5,6 +5,7 @@ import './utils/constants.js';
5
5
  import { getComponents } from './utils/components.js';
6
6
  import { EnumToken } from '../../ast/types.js';
7
7
  import '../../ast/minify.js';
8
+ import '../../ast/walk.js';
8
9
  import '../../parser/parse.js';
9
10
  import { hslvalues } from './srgb.js';
10
11
  import '../sourcemap/lib/encode.js';
@@ -4,6 +4,7 @@ import { getComponents } from './utils/components.js';
4
4
  import { getNumber, getAngle } from './color.js';
5
5
  import { EnumToken } from '../../ast/types.js';
6
6
  import '../../ast/minify.js';
7
+ import '../../ast/walk.js';
7
8
  import '../../parser/parse.js';
8
9
  import { lab2srgb, lch2srgb, oklab2srgb, oklch2srgb } from './srgb.js';
9
10
  import '../sourcemap/lib/encode.js';
@@ -7,6 +7,7 @@ import { OKLab_to_XYZ, getOKLABComponents } from './oklab.js';
7
7
  import { getNumber } from './color.js';
8
8
  import { EnumToken } from '../../ast/types.js';
9
9
  import '../../ast/minify.js';
10
+ import '../../ast/walk.js';
10
11
  import '../../parser/parse.js';
11
12
  import '../sourcemap/lib/encode.js';
12
13
  import '../../parser/utils/config.js';
@@ -3,6 +3,7 @@ import { getComponents } from './utils/components.js';
3
3
  import { getNumber, getAngle } from './color.js';
4
4
  import { EnumToken } from '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
+ import '../../ast/walk.js';
6
7
  import '../../parser/parse.js';
7
8
  import { srgb2lab, xyz2lab, hex2lab, rgb2lab, hsl2lab, hwb2lab, getLABComponents, oklab2lab, oklch2lab } from './lab.js';
8
9
  import '../sourcemap/lib/encode.js';
@@ -5,6 +5,7 @@ import { srgb2lsrgbvalues, hex2srgb, rgb2srgb, hsl2srgb, hwb2srgb, lab2srgb, lch
5
5
  import { getNumber } from './color.js';
6
6
  import { EnumToken } from '../../ast/types.js';
7
7
  import '../../ast/minify.js';
8
+ import '../../ast/walk.js';
8
9
  import '../../parser/parse.js';
9
10
  import { lch2labvalues } from './lab.js';
10
11
  import { getOKLCHComponents } from './oklch.js';
@@ -3,6 +3,7 @@ import { getComponents } from './utils/components.js';
3
3
  import { getNumber, getAngle } from './color.js';
4
4
  import { EnumToken } from '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
+ import '../../ast/walk.js';
6
7
  import '../../parser/parse.js';
7
8
  import { lab2lchvalues } from './lch.js';
8
9
  import { srgb2oklab, hex2oklab, rgb2oklab, hsl2oklab, hwb2oklab, lab2oklab, lch2oklab, getOKLABComponents } from './oklab.js';
@@ -3,6 +3,7 @@ import { multiplyMatrices } from './utils/matrix.js';
3
3
  import './utils/constants.js';
4
4
  import '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
+ import '../../ast/walk.js';
6
7
  import '../../parser/parse.js';
7
8
  import { srgb2xyz } from './xyz.js';
8
9
  import '../sourcemap/lib/encode.js';
@@ -0,0 +1,56 @@
1
+ import { xyzd502srgb, srgb2xyz } from './xyz.js';
2
+ import { XYZ_D65_to_D50 } from './xyzd50.js';
3
+
4
+ function prophotorgb2srgbvalues(r, g, b, a = null) {
5
+ // @ts-ignore
6
+ return xyzd502srgb(...prophotorgb2xyz50(r, g, b, a));
7
+ }
8
+ function srgb2prophotorgbvalues(r, g, b, a) {
9
+ // @ts-ignore
10
+ return xyz50_to_prophotorgb(...XYZ_D65_to_D50(...srgb2xyz(r, g, b, a)));
11
+ }
12
+ function prophotorgb2lin_ProPhoto(r, g, b, a = null) {
13
+ return [r, g, b].map(v => {
14
+ let abs = Math.abs(v);
15
+ if (abs >= 16 / 512) {
16
+ return Math.sign(v) * Math.pow(abs, 1.8);
17
+ }
18
+ return v / 16;
19
+ }).concat(a == null || a == 1 ? [] : [a]);
20
+ }
21
+ function prophotorgb2xyz50(r, g, b, a = null) {
22
+ [r, g, b, a] = prophotorgb2lin_ProPhoto(r, g, b, a);
23
+ const xyz = [
24
+ 0.7977666449006423 * r +
25
+ 0.1351812974005331 * g +
26
+ 0.0313477341283922 * b,
27
+ 0.2880748288194013 * r +
28
+ 0.7118352342418731 * g +
29
+ 0.0000899369387256 * b,
30
+ 0.8251046025104602 * b
31
+ ];
32
+ return xyz.concat(a == null || a == 1 ? [] : [a]);
33
+ }
34
+ function xyz50_to_prophotorgb(x, y, z, a) {
35
+ // @ts-ignore
36
+ return gam_prophotorgb(...[
37
+ x * 1.3457868816471585 -
38
+ y * 0.2555720873797946 -
39
+ 0.0511018649755453 * z,
40
+ x * -0.5446307051249019 +
41
+ y * 1.5082477428451466 +
42
+ 0.0205274474364214 * z,
43
+ 1.2119675456389452 * z
44
+ ].concat(a == null || a == 1 ? [] : [a]));
45
+ }
46
+ function gam_prophotorgb(r, g, b, a) {
47
+ return [r, g, b].map(v => {
48
+ let abs = Math.abs(v);
49
+ if (abs >= 1 / 512) {
50
+ return Math.sign(v) * Math.pow(abs, 1 / 1.8);
51
+ }
52
+ return 16 * v;
53
+ }).concat(a == null || a == 1 ? [] : [a]);
54
+ }
55
+
56
+ export { prophotorgb2srgbvalues, srgb2prophotorgbvalues };
@@ -3,6 +3,7 @@ import { multiplyMatrices } from './utils/matrix.js';
3
3
  import './utils/constants.js';
4
4
  import '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
+ import '../../ast/walk.js';
6
7
  import '../../parser/parse.js';
7
8
  import { srgb2xyz } from './xyz.js';
8
9
  import '../sourcemap/lib/encode.js';
@@ -3,10 +3,11 @@ import { EnumToken } from '../../ast/types.js';
3
3
  import '../../ast/minify.js';
4
4
  import { walkValues } from '../../ast/walk.js';
5
5
  import '../../parser/parse.js';
6
+ import { mathFuncs } from '../../syntax/syntax.js';
7
+ import '../../parser/utils/config.js';
6
8
  import { reduceNumber } from '../render.js';
9
+ import { evaluateFunc, evaluate } from '../../ast/math/expression.js';
7
10
  import { colorRange } from './utils/constants.js';
8
- import { evaluate } from '../../ast/math/expression.js';
9
- import '../../parser/utils/config.js';
10
11
 
11
12
  function parseRelativeColor(relativeKeys, original, rExp, gExp, bExp, aExp) {
12
13
  let r;
@@ -47,7 +48,7 @@ function parseRelativeColor(relativeKeys, original, rExp, gExp, bExp, aExp) {
47
48
  val: '1'
48
49
  } : aExp)
49
50
  };
50
- return computeComponentValue(keys, values);
51
+ return computeComponentValue(keys, converted, values);
51
52
  }
52
53
  function getValue(t, converted, component) {
53
54
  if (t == null) {
@@ -66,7 +67,7 @@ function getValue(t, converted, component) {
66
67
  }
67
68
  return t;
68
69
  }
69
- function computeComponentValue(expr, values) {
70
+ function computeComponentValue(expr, converted, values) {
70
71
  for (const object of [values, expr]) {
71
72
  if ('h' in object) {
72
73
  // normalize hue
@@ -107,34 +108,29 @@ function computeComponentValue(expr, values) {
107
108
  expr[key] = values[exp.val];
108
109
  }
109
110
  }
110
- else if (exp.typ == EnumToken.FunctionTokenType && exp.val == 'calc') {
111
- for (let { value, parent } of walkValues(exp.chi)) {
112
- if (value.typ == EnumToken.IdenTokenType) {
113
- if (!(value.val in values)) {
111
+ else if (exp.typ == EnumToken.FunctionTokenType && mathFuncs.includes(exp.val)) {
112
+ for (let { value, parent } of walkValues(exp.chi, exp)) {
113
+ if (parent == null) {
114
+ parent = exp;
115
+ }
116
+ if (value.typ == EnumToken.PercentageTokenType) {
117
+ replaceValue(parent, value, getValue(value, converted, key));
118
+ }
119
+ else if (value.typ == EnumToken.IdenTokenType) {
120
+ // @ts-ignore
121
+ if (!(value.val in values || typeof Math[value.val.toUpperCase()] == 'number')) {
114
122
  return null;
115
123
  }
116
- if (parent == null) {
117
- parent = exp;
118
- }
119
- if (parent.typ == EnumToken.BinaryExpressionTokenType) {
120
- if (parent.l == value) {
121
- parent.l = values[value.val];
122
- }
123
- else {
124
- parent.r = values[value.val];
125
- }
126
- }
127
- else {
128
- for (let i = 0; i < parent.chi.length; i++) {
129
- if (parent.chi[i] == value) {
130
- parent.chi.splice(i, 1, values[value.val]);
131
- break;
132
- }
133
- }
134
- }
124
+ // @ts-ignore
125
+ replaceValue(parent, value, values[value.val] ?? {
126
+ typ: EnumToken.NumberTokenType,
127
+ // @ts-ignore
128
+ val: '' + Math[value.val.toUpperCase()]
129
+ // @ts-ignore
130
+ });
135
131
  }
136
132
  }
137
- const result = evaluate(exp.chi);
133
+ const result = exp.typ == EnumToken.FunctionTokenType && mathFuncs.includes(exp.val) && exp.val != 'calc' ? evaluateFunc(exp) : evaluate(exp.chi);
138
134
  if (result.length == 1 && result[0].typ != EnumToken.BinaryExpressionTokenType) {
139
135
  expr[key] = result[0];
140
136
  }
@@ -145,5 +141,33 @@ function computeComponentValue(expr, values) {
145
141
  }
146
142
  return expr;
147
143
  }
144
+ function replaceValue(parent, value, newValue) {
145
+ if (parent.typ == EnumToken.BinaryExpressionTokenType) {
146
+ if (parent.l == value) {
147
+ parent.l = newValue;
148
+ }
149
+ else {
150
+ parent.r = newValue;
151
+ }
152
+ }
153
+ else {
154
+ for (let i = 0; i < parent.chi.length; i++) {
155
+ if (parent.chi[i] == value) {
156
+ parent.chi.splice(i, 1, newValue);
157
+ break;
158
+ }
159
+ if (parent.chi[i].typ == EnumToken.BinaryExpressionTokenType) {
160
+ if (parent.chi[i].l == value) {
161
+ parent.chi[i].l = newValue;
162
+ break;
163
+ }
164
+ else if (parent.chi[i].r == value) {
165
+ parent.chi[i].r = newValue;
166
+ break;
167
+ }
168
+ }
169
+ }
170
+ }
171
+ }
148
172
 
149
173
  export { parseRelativeColor };
@@ -2,6 +2,7 @@ import { minmax } from './color.js';
2
2
  import { COLORS_NAMES } from './utils/constants.js';
3
3
  import '../../ast/types.js';
4
4
  import '../../ast/minify.js';
5
+ import '../../ast/walk.js';
5
6
  import '../../parser/parse.js';
6
7
  import { expandHexValue } from './hex.js';
7
8
  import { hwb2srgb, hslvalues, hsl2srgbvalues, cmyk2srgb, oklab2srgb, oklch2srgb, lab2srgb, lch2srgb } from './srgb.js';
@@ -3,6 +3,7 @@ import { getComponents } from './utils/components.js';
3
3
  import { color2srgbvalues, getNumber, getAngle } from './color.js';
4
4
  import { EnumToken } from '../../ast/types.js';
5
5
  import '../../ast/minify.js';
6
+ import '../../ast/walk.js';
6
7
  import '../../parser/parse.js';
7
8
  import { expandHexValue } from './hex.js';
8
9
  import { lch2labvalues, getLABComponents, Lab_to_sRGB } from './lab.js';
@@ -1,5 +1,6 @@
1
1
  import { EnumToken } from '../../../ast/types.js';
2
2
  import '../../../ast/minify.js';
3
+ import '../../../ast/walk.js';
3
4
  import '../../../parser/parse.js';
4
5
  import { COLORS_NAMES } from './constants.js';
5
6
  import { expandHexValue } from '../hex.js';
@@ -1,5 +1,6 @@
1
1
  import { EnumToken } from '../../../ast/types.js';
2
2
  import '../../../ast/minify.js';
3
+ import '../../../ast/walk.js';
3
4
  import '../../../parser/parse.js';
4
5
  import '../../sourcemap/lib/encode.js';
5
6
  import '../../../parser/utils/config.js';
@@ -2,6 +2,7 @@ import { multiplyMatrices } from './utils/matrix.js';
2
2
  import './utils/constants.js';
3
3
  import '../../ast/types.js';
4
4
  import '../../ast/minify.js';
5
+ import '../../ast/walk.js';
5
6
  import '../../parser/parse.js';
6
7
  import { lsrgb2srgbvalues, srgb2lsrgbvalues } from './srgb.js';
7
8
  import '../sourcemap/lib/encode.js';
@@ -2,6 +2,7 @@ import { multiplyMatrices } from './utils/matrix.js';
2
2
  import './utils/constants.js';
3
3
  import '../../ast/types.js';
4
4
  import '../../ast/minify.js';
5
+ import '../../ast/walk.js';
5
6
  import '../../parser/parse.js';
6
7
  import { xyz2lab } from './lab.js';
7
8
  import { lab2lchvalues } from './lch.js';
@@ -4,11 +4,12 @@ import { getComponents } from './color/utils/components.js';
4
4
  import { reduceHexValue, srgb2hexvalues, rgb2hex, hsl2hex, hwb2hex, cmyk2hex, oklab2hex, oklch2hex, lab2hex, lch2hex } from './color/hex.js';
5
5
  import { EnumToken } from '../ast/types.js';
6
6
  import '../ast/minify.js';
7
+ import '../ast/walk.js';
7
8
  import { expand } from '../ast/expand.js';
8
9
  import { colorMix } from './color/colormix.js';
9
10
  import { parseRelativeColor } from './color/relativecolor.js';
10
11
  import { SourceMap } from './sourcemap/sourcemap.js';
11
- import { isColor, isNewLine } from '../syntax/syntax.js';
12
+ import { isColor, mathFuncs, isNewLine } from '../syntax/syntax.js';
12
13
 
13
14
  const colorsFunc = ['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'device-cmyk', 'color-mix', 'color', 'oklab', 'lab', 'oklch', 'lch', 'light-dark'];
14
15
  function reduceNumber(val) {
@@ -45,6 +46,7 @@ function doRender(data, options = {}) {
45
46
  ...(options.minify ?? true ? {
46
47
  indent: '',
47
48
  newLine: '',
49
+ removeEmpty: true,
48
50
  removeComments: true
49
51
  } : {
50
52
  indent: ' ',
@@ -193,6 +195,9 @@ function renderAstNode(data, options, sourcemap, position, errors, reducer, cach
193
195
  }
194
196
  return `${css}${options.newLine}${indentSub}${str}`;
195
197
  }, '');
198
+ if (options.removeEmpty && children === '') {
199
+ return '';
200
+ }
196
201
  if (children.endsWith(';')) {
197
202
  children = children.slice(0, -1);
198
203
  }
@@ -201,8 +206,10 @@ function renderAstNode(data, options, sourcemap, position, errors, reducer, cach
201
206
  }
202
207
  return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
203
208
  case EnumToken.InvalidRuleTokenType:
209
+ case EnumToken.InvalidAtRuleTokenType:
204
210
  return '';
205
211
  default:
212
+ // return renderToken(data as Token, options, cache, reducer, errors);
206
213
  throw new Error(`render: unexpected token ${JSON.stringify(data, null, 1)}`);
207
214
  }
208
215
  return '';
@@ -394,19 +401,18 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
394
401
  case EnumToken.TimelineFunctionTokenType:
395
402
  case EnumToken.GridTemplateFuncTokenType:
396
403
  if (token.typ == EnumToken.FunctionTokenType &&
397
- token.val == 'calc' &&
404
+ mathFuncs.includes(token.val) &&
398
405
  token.chi.length == 1 &&
399
- token.chi[0].typ != EnumToken.BinaryExpressionTokenType &&
400
- token.chi[0].typ != EnumToken.FractionTokenType &&
406
+ ![EnumToken.BinaryExpressionTokenType, EnumToken.FractionTokenType, EnumToken.IdenTokenType].includes(token.chi[0].typ) &&
407
+ // @ts-ignore
401
408
  token.chi[0].val?.typ != EnumToken.FractionTokenType) {
402
- // calc(200px) => 200px
403
409
  return token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache, reducer), '');
404
410
  }
405
411
  // @ts-ignore
406
412
  return ( /* options.minify && 'Pseudo-class-func' == token.typ && token.val.slice(0, 2) == '::' ? token.val.slice(1) :*/token.val ?? '') + '(' + token.chi.reduce(reducer, '') + ')';
407
413
  case EnumToken.MatchExpressionTokenType:
408
414
  return renderToken(token.l, options, cache, reducer, errors) +
409
- renderToken({ typ: token.op }, options, cache, reducer, errors) +
415
+ renderToken(token.op, options, cache, reducer, errors) +
410
416
  renderToken(token.r, options, cache, reducer, errors) +
411
417
  (token.attr ? ' ' + token.attr : '');
412
418
  case EnumToken.NameSpaceAttributeTokenType:
@@ -419,6 +425,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
419
425
  case EnumToken.StartParensTokenType:
420
426
  return '(';
421
427
  case EnumToken.DelimTokenType:
428
+ case EnumToken.EqualMatchTokenType:
422
429
  return '=';
423
430
  case EnumToken.IncludeMatchTokenType:
424
431
  return '~=';
@@ -587,6 +594,7 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
587
594
  case EnumToken.StringTokenType:
588
595
  case EnumToken.LiteralTokenType:
589
596
  case EnumToken.DashedIdenTokenType:
597
+ case EnumToken.PseudoPageTokenType:
590
598
  case EnumToken.ClassSelectorTokenType:
591
599
  return /* options.minify && 'Pseudo-class' == token.typ && '::' == token.val.slice(0, 2) ? token.val.slice(1) : */ token.val;
592
600
  case EnumToken.NestingSelectorTokenType:
@@ -595,6 +603,20 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
595
603
  return '[' + token.chi.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
596
604
  case EnumToken.InvalidClassSelectorTokenType:
597
605
  return token.val;
606
+ case EnumToken.DeclarationNodeType:
607
+ return token.nam + ':' + token.val.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
608
+ case EnumToken.MediaQueryConditionTokenType:
609
+ return renderToken(token.l, options, cache, reducer, errors) + renderToken(token.op, options, cache, reducer, errors) + token.r.reduce((acc, curr) => acc + renderToken(curr, options, cache), '');
610
+ case EnumToken.MediaFeatureTokenType:
611
+ return token.val;
612
+ case EnumToken.MediaFeatureNotTokenType:
613
+ return 'not ' + renderToken(token.val, options, cache, reducer, errors);
614
+ case EnumToken.MediaFeatureOnlyTokenType:
615
+ return 'only ' + renderToken(token.val, options, cache, reducer, errors);
616
+ case EnumToken.MediaFeatureAndTokenType:
617
+ return 'and';
618
+ case EnumToken.MediaFeatureOrTokenType:
619
+ return 'or';
598
620
  default:
599
621
  throw new Error(`render: unexpected token ${JSON.stringify(token, null, 1)}`);
600
622
  }
@@ -1,6 +1,7 @@
1
1
  import { colorsFunc } from '../renderer/render.js';
2
2
  import { EnumToken } from '../ast/types.js';
3
3
  import '../ast/minify.js';
4
+ import '../ast/walk.js';
4
5
  import '../parser/parse.js';
5
6
  import '../parser/utils/config.js';
6
7
  import { COLORS_NAMES } from '../renderer/color/utils/constants.js';
@@ -15,6 +16,15 @@ const dimensionUnits = new Set([
15
16
  'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
16
17
  'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
17
18
  ]);
19
+ const fontFormat = ['collection', 'embedded-opentype', 'opentype', 'svg', 'truetype', 'woff', 'woff2'];
20
+ const colorFontTech = ['color-colrv0', 'color-colrv1', 'color-svg', 'color-sbix', 'color-cbdt'];
21
+ const fontFeaturesTech = ['features-opentype', 'features-aat', 'features-graphite', 'incremental-patch', 'incremental-range', 'incremental-auto', 'variations', 'palettes'];
22
+ // https://drafts.csswg.org/mediaqueries/#media-types
23
+ const mediaTypes = ['all', 'print', 'screen',
24
+ /* deprecated */
25
+ 'aural', 'braille', 'embossed', 'handheld', 'projection', 'tty', 'tv', 'speech'];
26
+ // https://www.w3.org/TR/css-values-4/#math-function
27
+ const mathFuncs = ['calc', 'clamp', 'min', 'max', 'round', 'mod', 'rem', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2', 'pow', 'sqrt', 'hypot', 'log', 'exp', 'abs', 'sign'];
18
28
  function isLength(dimension) {
19
29
  return 'unit' in dimension && dimensionUnits.has(dimension.unit.toLowerCase());
20
30
  }
@@ -89,7 +99,7 @@ function isColor(token) {
89
99
  return false;
90
100
  }
91
101
  }
92
- if (children[i].typ == EnumToken.FunctionTokenType && !['calc'].includes(children[i].val)) {
102
+ if (children[i].typ == EnumToken.FunctionTokenType && !mathFuncs.includes(children[i].val)) {
93
103
  return false;
94
104
  }
95
105
  }
@@ -184,7 +194,7 @@ function isColor(token) {
184
194
  }
185
195
  continue;
186
196
  }
187
- if (v.typ == EnumToken.FunctionTokenType && (v.val == 'calc' || v.val == 'var' || colorsFunc.includes(v.val))) {
197
+ if (v.typ == EnumToken.FunctionTokenType && (mathFuncs.includes(v.val) || v.val == 'var' || colorsFunc.includes(v.val))) {
188
198
  continue;
189
199
  }
190
200
  if (![EnumToken.ColorTokenType, EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType].includes(v.typ)) {
@@ -207,7 +217,7 @@ function isNonAscii(codepoint) {
207
217
  }
208
218
  function isIdentStart(codepoint) {
209
219
  // _
210
- return codepoint == 0x5f || isLetter(codepoint) || isNonAscii(codepoint);
220
+ return codepoint == 0x5f || isLetter(codepoint) || isNonAscii(codepoint) || codepoint == REVERSE_SOLIDUS;
211
221
  }
212
222
  function isDigit(codepoint) {
213
223
  return codepoint >= 0x30 && codepoint <= 0x39;
@@ -238,6 +248,19 @@ function isIdent(name) {
238
248
  if (!isIdentStart(codepoint)) {
239
249
  return false;
240
250
  }
251
+ if (codepoint == REVERSE_SOLIDUS) {
252
+ codepoint = name.codePointAt(i + 1);
253
+ if (!isIdentCodepoint(codepoint)) {
254
+ return false;
255
+ }
256
+ i += String.fromCodePoint(codepoint).length;
257
+ if (i < j) {
258
+ codepoint = name.codePointAt(i);
259
+ if (!isIdentCodepoint(codepoint)) {
260
+ return false;
261
+ }
262
+ }
263
+ }
241
264
  while (i < j) {
242
265
  i += codepoint < 0x80 ? 1 : String.fromCodePoint(codepoint).length;
243
266
  codepoint = name.charCodeAt(i);
@@ -453,4 +476,4 @@ function isWhiteSpace(codepoint) {
453
476
  codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
454
477
  }
455
478
 
456
- export { isAngle, isAtKeyword, isColor, isColorspace, isDigit, isDimension, isFlex, isFrequency, isFunction, isHash, isHexColor, isHueInterpolationMethod, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPolarColorspace, isPseudo, isRectangularOrthogonalColorspace, isResolution, isTime, isWhiteSpace, parseDimension };
479
+ export { colorFontTech, fontFeaturesTech, fontFormat, isAngle, isAtKeyword, isColor, isColorspace, isDigit, isDimension, isFlex, isFrequency, isFunction, isHash, isHexColor, isHueInterpolationMethod, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPolarColorspace, isPseudo, isRectangularOrthogonalColorspace, isResolution, isTime, isWhiteSpace, mathFuncs, mediaTypes, parseDimension };
@@ -0,0 +1,78 @@
1
+ import { ValidationLevel, EnumToken } from '../../ast/types.js';
2
+ import '../../ast/minify.js';
3
+ import '../../ast/walk.js';
4
+ import '../../parser/parse.js';
5
+ import '../../renderer/color/utils/constants.js';
6
+ import '../../renderer/sourcemap/lib/encode.js';
7
+ import '../../parser/utils/config.js';
8
+
9
+ function validateAtRuleCounterStyle(atRule, options, root) {
10
+ // media-query-list
11
+ if (!Array.isArray(atRule.tokens) || atRule.tokens.length == 0) {
12
+ // @ts-ignore
13
+ return {
14
+ valid: ValidationLevel.Drop,
15
+ matches: [],
16
+ node: atRule,
17
+ syntax: '@counter-style',
18
+ error: 'expected media query list',
19
+ tokens: []
20
+ };
21
+ }
22
+ const tokens = atRule.tokens.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ));
23
+ if (tokens.length == 0) {
24
+ // @ts-ignore
25
+ return {
26
+ valid: ValidationLevel.Valid,
27
+ matches: [],
28
+ node: atRule,
29
+ syntax: '@counter-style',
30
+ error: 'expected counter style name',
31
+ tokens
32
+ };
33
+ }
34
+ if (tokens.length > 1) {
35
+ // @ts-ignore
36
+ return {
37
+ valid: ValidationLevel.Drop,
38
+ matches: [],
39
+ node: tokens[1] ?? atRule,
40
+ syntax: '@counter-style',
41
+ error: 'unexpected token',
42
+ tokens
43
+ };
44
+ }
45
+ if (![EnumToken.IdenTokenType, EnumToken.DashedIdenTokenType].includes(tokens[0].typ)) {
46
+ // @ts-ignore
47
+ return {
48
+ valid: ValidationLevel.Drop,
49
+ matches: [],
50
+ node: tokens[0],
51
+ syntax: '@counter-style',
52
+ error: 'expected counter style name',
53
+ tokens
54
+ };
55
+ }
56
+ if (!('chi' in atRule)) {
57
+ // @ts-ignore
58
+ return {
59
+ valid: ValidationLevel.Drop,
60
+ matches: [],
61
+ node: atRule,
62
+ syntax: '@counter-style',
63
+ error: 'expected counter style body',
64
+ tokens
65
+ };
66
+ }
67
+ // @ts-ignore
68
+ return {
69
+ valid: ValidationLevel.Valid,
70
+ matches: [],
71
+ node: atRule,
72
+ syntax: '@counter-style',
73
+ error: '',
74
+ tokens
75
+ };
76
+ }
77
+
78
+ export { validateAtRuleCounterStyle };