@tbela99/css-parser 0.3.0 → 0.4.1

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 (60) hide show
  1. package/{LICENSE → LICENSE.md} +1 -1
  2. package/README.md +191 -80
  3. package/dist/config.json.js +20 -1
  4. package/dist/index-umd-web.js +3210 -1352
  5. package/dist/index.cjs +3211 -1353
  6. package/dist/index.d.ts +910 -0
  7. package/dist/lib/ast/expand.js +1 -1
  8. package/dist/lib/ast/features/calc.js +1 -2
  9. package/dist/lib/ast/features/inlinecssvariables.js +1 -1
  10. package/dist/lib/ast/features/shorthand.js +1 -1
  11. package/dist/lib/ast/math/expression.js +38 -3
  12. package/dist/lib/ast/math/math.js +2 -2
  13. package/dist/lib/ast/minify.js +0 -1
  14. package/dist/lib/ast/types.js +1 -0
  15. package/dist/lib/ast/utils/minifyfeature.js +4 -3
  16. package/dist/lib/parser/declaration/list.js +1 -1
  17. package/dist/lib/parser/declaration/map.js +129 -26
  18. package/dist/lib/parser/declaration/set.js +1 -1
  19. package/dist/lib/parser/parse.js +325 -303
  20. package/dist/lib/parser/tokenize.js +220 -223
  21. package/dist/lib/parser/utils/declaration.js +1 -1
  22. package/dist/lib/parser/utils/syntax.js +159 -23
  23. package/dist/lib/parser/utils/type.js +2 -2
  24. package/dist/lib/renderer/color/a98rgb.js +64 -0
  25. package/dist/lib/renderer/color/color.js +521 -0
  26. package/dist/lib/renderer/color/colormix.js +337 -0
  27. package/dist/lib/renderer/color/hex.js +92 -0
  28. package/dist/lib/renderer/color/hsl.js +118 -0
  29. package/dist/lib/renderer/color/hsv.js +20 -0
  30. package/dist/lib/renderer/color/hwb.js +101 -0
  31. package/dist/lib/renderer/color/lab.js +136 -0
  32. package/dist/lib/renderer/color/lch.js +79 -0
  33. package/dist/lib/renderer/color/oklab.js +121 -0
  34. package/dist/lib/renderer/color/oklch.js +65 -0
  35. package/dist/lib/renderer/color/p3.js +57 -0
  36. package/dist/lib/renderer/color/prophotorgb.js +56 -0
  37. package/dist/lib/renderer/color/rec2020.js +70 -0
  38. package/dist/lib/renderer/color/relativecolor.js +152 -0
  39. package/dist/lib/renderer/color/rgb.js +44 -0
  40. package/dist/lib/renderer/color/srgb.js +261 -0
  41. package/dist/lib/renderer/color/utils/components.js +20 -0
  42. package/dist/lib/renderer/color/utils/constants.js +191 -0
  43. package/dist/lib/renderer/color/utils/matrix.js +35 -0
  44. package/dist/lib/renderer/color/xyz.js +64 -0
  45. package/dist/lib/renderer/color/xyzd50.js +33 -0
  46. package/dist/lib/renderer/render.js +61 -32
  47. package/dist/node/index.js +1 -1
  48. package/dist/node/load.js +1 -1
  49. package/dist/web/index.js +1 -1
  50. package/package.json +15 -14
  51. package/dist/lib/ast/features/utils/math.js +0 -95
  52. package/dist/lib/iterable/set.js +0 -48
  53. package/dist/lib/iterable/weakmap.js +0 -53
  54. package/dist/lib/renderer/utils/calccolor.js +0 -238
  55. package/dist/lib/renderer/utils/color.js +0 -371
  56. package/dist/lib/renderer/utils/hex.js +0 -124
  57. package/dist/lib/renderer/utils/hsl.js +0 -49
  58. package/dist/lib/renderer/utils/hsv.js +0 -15
  59. package/dist/lib/renderer/utils/hwb.js +0 -50
  60. package/dist/lib/renderer/utils/rgb.js +0 -66
@@ -3,7 +3,7 @@ import '../../ast/minify.js';
3
3
  import { walkValues } from '../../ast/walk.js';
4
4
  import '../parse.js';
5
5
  import { isWhiteSpace } from './syntax.js';
6
- import '../../renderer/utils/color.js';
6
+ import '../../renderer/color/utils/constants.js';
7
7
  import '../../renderer/sourcemap/lib/encode.js';
8
8
 
9
9
  function parseDeclaration(node, errors, src, position) {
@@ -1,8 +1,8 @@
1
1
  import { colorsFunc } from '../../renderer/render.js';
2
- import { COLORS_NAMES } from '../../renderer/utils/color.js';
3
2
  import { EnumToken } from '../../ast/types.js';
4
3
  import '../../ast/minify.js';
5
4
  import '../parse.js';
5
+ import { COLORS_NAMES } from '../../renderer/color/utils/constants.js';
6
6
 
7
7
  // https://www.w3.org/TR/CSS21/syndata.html#syntax
8
8
  // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
@@ -29,6 +29,30 @@ function isTime(dimension) {
29
29
  function isFrequency(dimension) {
30
30
  return 'unit' in dimension && ['hz', 'khz'].includes(dimension.unit.toLowerCase());
31
31
  }
32
+ function isColorspace(token) {
33
+ if (token.typ != EnumToken.IdenTokenType) {
34
+ return false;
35
+ }
36
+ return ['srgb', 'srgb-linear', 'lab', 'oklab', 'lch', 'oklch', 'xyz', 'xyz-d50', 'xyz-d65', 'display-p3', 'a98-rgb', 'prophoto-rgb', 'rec2020', 'rgb', 'hsl', 'hwb'].includes(token.val.toLowerCase());
37
+ }
38
+ function isRectangularOrthogonalColorspace(token) {
39
+ if (token.typ != EnumToken.IdenTokenType) {
40
+ return false;
41
+ }
42
+ return ['srgb', 'srgb-linear', 'display-p3', 'a98-rgb', 'prophoto-rgb', 'rec2020', 'lab', 'oklab', 'xyz', 'xyz-d50', 'xyz-d65'].includes(token.val.toLowerCase());
43
+ }
44
+ function isPolarColorspace(token) {
45
+ if (token.typ != EnumToken.IdenTokenType) {
46
+ return false;
47
+ }
48
+ return ['hsl', 'hwb', 'lch', 'oklch'].includes(token.val);
49
+ }
50
+ function isHueInterpolationMethod(token) {
51
+ if (token.typ != EnumToken.IdenTokenType) {
52
+ return false;
53
+ }
54
+ return ['shorter', 'longer', 'increasing', 'decreasing'].includes(token.val);
55
+ }
32
56
  function isColor(token) {
33
57
  if (token.typ == EnumToken.ColorTokenType) {
34
58
  return true;
@@ -39,36 +63,119 @@ function isColor(token) {
39
63
  }
40
64
  let isLegacySyntax = false;
41
65
  if (token.typ == EnumToken.FunctionTokenType && token.chi.length > 0 && colorsFunc.includes(token.val)) {
42
- const keywords = ['from', 'none'];
43
- if (['rgb', 'hsl', 'hwb'].includes(token.val)) {
44
- keywords.push('a', ...token.val.split(''));
45
- }
46
- // console.debug(JSON.stringify({token}, null, 1));
47
- // @ts-ignore
48
- for (const v of token.chi) {
49
- // console.debug(JSON.stringify({v}, null, 1));
50
- if (v.typ == EnumToken.CommaTokenType) {
51
- isLegacySyntax = true;
66
+ if (token.val == 'color') {
67
+ const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
68
+ const isRelative = children[0].typ == EnumToken.IdenTokenType && children[0].val == 'from';
69
+ if (children.length < 4 || children.length > 8) {
70
+ return false;
71
+ }
72
+ if (!isRelative && !isColorspace(children[0])) {
73
+ return false;
52
74
  }
53
- if (v.typ == EnumToken.IdenTokenType) {
54
- if (!(keywords.includes(v.val) || v.val.toLowerCase() in COLORS_NAMES)) {
75
+ for (let i = 1; i < children.length - 2; i++) {
76
+ if (children[i].typ == EnumToken.IdenTokenType) {
77
+ if (children[i].val != 'none' &&
78
+ !(isRelative && ['alpha', 'r', 'g', 'b'].includes(children[i].val) || isColorspace(children[i]))) {
79
+ return false;
80
+ }
81
+ }
82
+ if (children[i].typ == EnumToken.FunctionTokenType && !['calc'].includes(children[i].val)) {
83
+ return false;
84
+ }
85
+ }
86
+ if (children.length == 8 || children.length == 6) {
87
+ const sep = children.at(-2);
88
+ const alpha = children.at(-1);
89
+ if (sep.typ != EnumToken.LiteralTokenType || sep.val != '/') {
90
+ return false;
91
+ }
92
+ if (alpha.typ == EnumToken.IdenTokenType && alpha.val != 'none') {
55
93
  return false;
56
94
  }
57
- if (keywords.includes(v.val)) {
58
- if (isLegacySyntax) {
95
+ else {
96
+ // @ts-ignore
97
+ if (alpha.typ == EnumToken.PercentageTokenType) {
98
+ if (+alpha.val < 0 || +alpha.val > 100) {
99
+ return false;
100
+ }
101
+ }
102
+ else if (alpha.typ == EnumToken.NumberTokenType) {
103
+ if (+alpha.val < 0 || +alpha.val > 1) {
104
+ return false;
105
+ }
106
+ }
107
+ }
108
+ }
109
+ return true;
110
+ }
111
+ else if (token.val == 'color-mix') {
112
+ const children = token.chi.reduce((acc, t) => {
113
+ if (t.typ == EnumToken.CommaTokenType) {
114
+ acc.push([]);
115
+ }
116
+ else {
117
+ if (![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)) {
118
+ acc[acc.length - 1].push(t);
119
+ }
120
+ }
121
+ return acc;
122
+ }, [[]]);
123
+ if (children.length == 3) {
124
+ if (children[0].length > 3 ||
125
+ children[0][0].typ != EnumToken.IdenTokenType ||
126
+ children[0][0].val != 'in' ||
127
+ !isColorspace(children[0][1]) ||
128
+ (children[0].length == 3 && !isHueInterpolationMethod(children[0][2])) ||
129
+ children[1].length > 2 ||
130
+ children[1][0].typ != EnumToken.ColorTokenType ||
131
+ children[2].length > 2 ||
132
+ children[2][0].typ != EnumToken.ColorTokenType) {
133
+ return false;
134
+ }
135
+ if (children[1].length == 2) {
136
+ if (!(children[1][1].typ == EnumToken.PercentageTokenType || (children[1][1].typ == EnumToken.NumberTokenType && children[1][1].val == '0'))) {
59
137
  return false;
60
138
  }
61
- if (v.val == 'from' && ['rgba', 'hsla'].includes(token.val)) {
139
+ }
140
+ if (children[2].length == 2) {
141
+ if (!(children[2][1].typ == EnumToken.PercentageTokenType || (children[2][1].typ == EnumToken.NumberTokenType && children[2][1].val == '0'))) {
62
142
  return false;
63
143
  }
64
144
  }
65
- continue;
145
+ return true;
66
146
  }
67
- if (v.typ == EnumToken.FunctionTokenType && (v.val == 'calc' || colorsFunc.includes(v.val))) {
68
- continue;
147
+ return false;
148
+ }
149
+ else {
150
+ const keywords = ['from', 'none'];
151
+ if (['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch'].includes(token.val)) {
152
+ keywords.push('alpha', ...token.val.slice(-3).split(''));
69
153
  }
70
- if (![EnumToken.ColorTokenType, EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType].includes(v.typ)) {
71
- return false;
154
+ // @ts-ignore
155
+ for (const v of token.chi) {
156
+ if (v.typ == EnumToken.CommaTokenType) {
157
+ isLegacySyntax = true;
158
+ }
159
+ if (v.typ == EnumToken.IdenTokenType) {
160
+ if (!(keywords.includes(v.val) || v.val.toLowerCase() in COLORS_NAMES)) {
161
+ return false;
162
+ }
163
+ if (keywords.includes(v.val)) {
164
+ if (isLegacySyntax) {
165
+ return false;
166
+ }
167
+ if (v.val == 'from' && ['rgba', 'hsla'].includes(token.val)) {
168
+ return false;
169
+ }
170
+ }
171
+ continue;
172
+ }
173
+ if (v.typ == EnumToken.FunctionTokenType && (v.val == 'calc' || v.val == 'var' || colorsFunc.includes(v.val))) {
174
+ continue;
175
+ }
176
+ if (![EnumToken.ColorTokenType, EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType].includes(v.typ)) {
177
+ return false;
178
+ }
72
179
  }
73
180
  }
74
181
  return true;
@@ -239,7 +346,11 @@ function parseDimension(name) {
239
346
  index++;
240
347
  break;
241
348
  }
242
- const dimension = { typ: EnumToken.DimensionTokenType, val: name.slice(0, index), unit: name.slice(index) };
349
+ const dimension = {
350
+ typ: EnumToken.DimensionTokenType,
351
+ val: name.slice(0, index),
352
+ unit: name.slice(index)
353
+ };
243
354
  if (isAngle(dimension)) {
244
355
  // @ts-ignore
245
356
  dimension.typ = EnumToken.AngleTokenType;
@@ -281,6 +392,31 @@ function isHexColor(name) {
281
392
  }
282
393
  return true;
283
394
  }
395
+ /*
396
+ export function isHexDigit(name: string): boolean {
397
+
398
+ if (name.length || name.length > 6) {
399
+
400
+ return false;
401
+ }
402
+
403
+ for (let chr of name) {
404
+
405
+ let codepoint = <number>chr.charCodeAt(0);
406
+
407
+ if (!isDigit(codepoint) &&
408
+ // A F
409
+ !(codepoint >= 0x41 && codepoint <= 0x46) &&
410
+ // a f
411
+ !(codepoint >= 0x61 && codepoint <= 0x66)) {
412
+
413
+ return false;
414
+ }
415
+ }
416
+
417
+ return true;
418
+ }
419
+ */
284
420
  function isFunction(name) {
285
421
  return name.endsWith('(') && isIdent(name.slice(0, -1));
286
422
  }
@@ -297,4 +433,4 @@ function isWhiteSpace(codepoint) {
297
433
  codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
298
434
  }
299
435
 
300
- export { isAngle, isAtKeyword, isColor, isDigit, isDimension, isFlex, isFrequency, isFunction, isHash, isHexColor, isIdent, isIdentCodepoint, isIdentStart, isLength, isNewLine, isNonPrintable, isNumber, isPercentage, isPseudo, isResolution, isTime, isWhiteSpace, parseDimension };
436
+ 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 };
@@ -1,7 +1,7 @@
1
1
  import { EnumToken } from '../../ast/types.js';
2
2
  import '../../ast/minify.js';
3
3
  import '../parse.js';
4
- import '../../renderer/utils/color.js';
4
+ import '../../renderer/color/utils/constants.js';
5
5
  import '../../renderer/sourcemap/lib/encode.js';
6
6
 
7
7
  // https://www.w3.org/TR/css-values-4/#math-function
@@ -22,7 +22,7 @@ function matchType(val, properties) {
22
22
  }
23
23
  if (val.typ == EnumToken.FunctionTokenType) {
24
24
  if (funcList.includes(val.val)) {
25
- return val.chi.every((t => [EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.StartParensTokenType, EnumToken.EndParensTokenType].includes(t.typ) || matchType(t, properties)));
25
+ return val.chi.every(((t) => [EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.StartParensTokenType, EnumToken.EndParensTokenType].includes(t.typ) || matchType(t, properties)));
26
26
  }
27
27
  // match type defined like function 'symbols()', 'url()', 'attr()' etc.
28
28
  // return properties.types.includes((<FunctionToken>val).val + '()')
@@ -0,0 +1,64 @@
1
+ import { xyz2srgb } from './srgb.js';
2
+ import { multiplyMatrices } from './utils/matrix.js';
3
+ import './utils/constants.js';
4
+ import '../../ast/types.js';
5
+ import '../../ast/minify.js';
6
+ import '../../parser/parse.js';
7
+ import { srgb2xyz } from './xyz.js';
8
+ import '../sourcemap/lib/encode.js';
9
+
10
+ function a98rgb2srgbvalues(r, g, b, a = null) {
11
+ // @ts-ignore
12
+ return xyz2srgb(...la98rgb2xyz(...a98rgb2la98(r, g, b, a)));
13
+ }
14
+ function srgb2a98values(r, g, b, a = null) {
15
+ // @ts-ignore
16
+ return la98rgb2a98rgb(xyz2la98rgb(...srgb2xyz(r, g, b, a)));
17
+ }
18
+ // a98-rgb functions
19
+ function a98rgb2la98(r, g, b, a = null) {
20
+ // convert an array of a98-rgb values in the range 0.0 - 1.0
21
+ // to linear light (un-companded) form.
22
+ // negative values are also now accepted
23
+ return [r, g, b].map(function (val) {
24
+ let sign = val < 0 ? -1 : 1;
25
+ let abs = Math.abs(val);
26
+ return sign * Math.pow(abs, 563 / 256);
27
+ }).concat(a == null || a == 1 ? [] : [a]);
28
+ }
29
+ function la98rgb2a98rgb(r, g, b, a = null) {
30
+ // convert an array of linear-light a98-rgb in the range 0.0-1.0
31
+ // to gamma corrected form
32
+ // negative values are also now accepted
33
+ return [r, b, g].map(function (val) {
34
+ let sign = val < 0 ? -1 : 1;
35
+ let abs = Math.abs(val);
36
+ return sign * Math.pow(abs, 256 / 563);
37
+ }).concat(a == null || a == 1 ? [] : [a]);
38
+ }
39
+ function la98rgb2xyz(r, g, b, a = null) {
40
+ // convert an array of linear-light a98-rgb values to CIE XYZ
41
+ // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
42
+ // has greater numerical precision than section 4.3.5.3 of
43
+ // https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
44
+ // but the values below were calculated from first principles
45
+ // from the chromaticity coordinates of R G B W
46
+ // see matrixmaker.html
47
+ var M = [
48
+ [573536 / 994567, 263643 / 1420810, 187206 / 994567],
49
+ [591459 / 1989134, 6239551 / 9945670, 374412 / 4972835],
50
+ [53769 / 1989134, 351524 / 4972835, 4929758 / 4972835],
51
+ ];
52
+ return multiplyMatrices(M, [r, g, b]).concat(a == null || a == 1 ? [] : [a]);
53
+ }
54
+ function xyz2la98rgb(x, y, z, a = null) {
55
+ // convert XYZ to linear-light a98-rgb
56
+ var M = [
57
+ [1829569 / 896150, -506331 / 896150, -308931 / 896150],
58
+ [-851781 / 878810, 1648619 / 878810, 36519 / 878810],
59
+ [16779 / 1248040, -147721 / 1248040, 1266979 / 1248040],
60
+ ];
61
+ return multiplyMatrices(M, [x, y, z]).concat(a == null || a == 1 ? [] : [a]);
62
+ }
63
+
64
+ export { a98rgb2srgbvalues, srgb2a98values };