@tbela99/css-parser 0.9.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +22 -12
  3. package/dist/index-umd-web.js +2678 -2838
  4. package/dist/index.cjs +2468 -2628
  5. package/dist/index.d.ts +71 -26
  6. package/dist/lib/ast/expand.js +15 -2
  7. package/dist/lib/ast/features/calc.js +7 -10
  8. package/dist/lib/ast/features/index.js +1 -0
  9. package/dist/lib/ast/features/inlinecssvariables.js +0 -5
  10. package/dist/lib/ast/features/prefix.js +2 -7
  11. package/dist/lib/ast/features/shorthand.js +6 -9
  12. package/dist/lib/ast/features/transform.js +60 -0
  13. package/dist/lib/ast/math/expression.js +14 -10
  14. package/dist/lib/ast/math/math.js +14 -2
  15. package/dist/lib/ast/minify.js +47 -6
  16. package/dist/lib/ast/transform/compute.js +336 -0
  17. package/dist/lib/ast/transform/convert.js +33 -0
  18. package/dist/lib/ast/transform/matrix.js +111 -0
  19. package/dist/lib/ast/transform/minify.js +296 -0
  20. package/dist/lib/ast/transform/perspective.js +10 -0
  21. package/dist/lib/ast/transform/rotate.js +40 -0
  22. package/dist/lib/ast/transform/scale.js +32 -0
  23. package/dist/lib/ast/transform/skew.js +23 -0
  24. package/dist/lib/ast/transform/translate.js +32 -0
  25. package/dist/lib/ast/transform/utils.js +198 -0
  26. package/dist/lib/ast/types.js +2 -0
  27. package/dist/lib/ast/walk.js +23 -17
  28. package/dist/lib/parser/parse.js +174 -127
  29. package/dist/lib/parser/utils/declaration.js +1 -1
  30. package/dist/lib/renderer/color/{colormix.js → color-mix.js} +6 -0
  31. package/dist/lib/renderer/color/color.js +96 -20
  32. package/dist/lib/renderer/color/hex.js +17 -7
  33. package/dist/lib/renderer/color/hsl.js +7 -2
  34. package/dist/lib/renderer/color/lab.js +10 -1
  35. package/dist/lib/renderer/color/lch.js +8 -0
  36. package/dist/lib/renderer/color/oklab.js +8 -0
  37. package/dist/lib/renderer/color/oklch.js +8 -0
  38. package/dist/lib/renderer/color/prophotorgb.js +2 -2
  39. package/dist/lib/renderer/color/relativecolor.js +10 -21
  40. package/dist/lib/renderer/color/rgb.js +10 -7
  41. package/dist/lib/renderer/color/srgb.js +30 -6
  42. package/dist/lib/renderer/color/utils/components.js +13 -2
  43. package/dist/lib/renderer/color/xyz.js +2 -18
  44. package/dist/lib/renderer/color/xyzd50.js +20 -2
  45. package/dist/lib/renderer/render.js +70 -32
  46. package/dist/lib/renderer/sourcemap/sourcemap.js +1 -1
  47. package/dist/lib/syntax/syntax.js +75 -56
  48. package/dist/lib/validation/at-rules/container.js +6 -6
  49. package/dist/lib/validation/at-rules/document.js +40 -60
  50. package/dist/lib/validation/at-rules/import.js +61 -59
  51. package/dist/lib/validation/at-rules/keyframes.js +1 -1
  52. package/dist/lib/validation/at-rules/media.js +1 -1
  53. package/dist/lib/validation/at-rules/supports.js +40 -9
  54. package/dist/lib/validation/atrule.js +0 -4
  55. package/dist/lib/validation/config.json.js +83 -35
  56. package/dist/lib/validation/parser/parse.js +1 -95
  57. package/dist/lib/validation/parser/types.js +1 -2
  58. package/dist/lib/validation/selector.js +5 -2
  59. package/dist/lib/validation/syntaxes/compound-selector.js +2 -2
  60. package/dist/lib/validation/syntaxes/keyframe-block-list.js +2 -2
  61. package/dist/lib/validation/syntaxes/keyframe-selector.js +11 -90
  62. package/dist/lib/validation/syntaxes/layer-name.js +5 -16
  63. package/dist/lib/validation/syntaxes/relative-selector.js +15 -14
  64. package/dist/lib/validation/utils/list.js +18 -1
  65. package/dist/node/load.js +1 -1
  66. package/package.json +13 -12
  67. package/dist/lib/renderer/color/prophotoRgb.js +0 -56
  68. package/dist/lib/validation/declaration.js +0 -102
  69. package/dist/lib/validation/syntax.js +0 -1475
  70. package/dist/lib/validation/syntaxes/image.js +0 -29
@@ -0,0 +1,336 @@
1
+ import { multiply, identity } from './utils.js';
2
+ import { EnumToken } from '../types.js';
3
+ import { length2Px } from './convert.js';
4
+ import { transformFunctions } from '../../syntax/syntax.js';
5
+ import '../minify.js';
6
+ import '../walk.js';
7
+ import '../../parser/parse.js';
8
+ import '../../parser/utils/config.js';
9
+ import { getNumber, getAngle } from '../../renderer/color/color.js';
10
+ import '../../renderer/color/utils/constants.js';
11
+ import '../../renderer/sourcemap/lib/encode.js';
12
+ import { stripCommaToken } from '../../validation/utils/list.js';
13
+ import { translateX, translateY, translateZ, translate, translate3d } from './translate.js';
14
+ import { rotate, rotate3D } from './rotate.js';
15
+ import { scale3d, scale, scaleX, scaleY, scaleZ } from './scale.js';
16
+ import { minify } from './minify.js';
17
+ import { skew, skewX, skewY } from './skew.js';
18
+ import { serialize, matrix } from './matrix.js';
19
+ import { perspective } from './perspective.js';
20
+
21
+ function compute(transformLists) {
22
+ transformLists = transformLists.slice();
23
+ stripCommaToken(transformLists);
24
+ if (transformLists.length == 0) {
25
+ return null;
26
+ }
27
+ let matrix = identity();
28
+ let mat;
29
+ const cumulative = [];
30
+ for (const transformList of splitTransformList(transformLists)) {
31
+ mat = computeMatrix(transformList, identity());
32
+ if (mat == null) {
33
+ return null;
34
+ }
35
+ matrix = multiply(matrix, mat);
36
+ cumulative.push(...(minify(mat) ?? transformList));
37
+ }
38
+ const serialized = serialize(matrix);
39
+ if (cumulative.length > 0) {
40
+ for (let i = 0; i < cumulative.length; i++) {
41
+ if (cumulative[i].typ == EnumToken.IdenTokenType && cumulative[i].val == 'none') {
42
+ cumulative.splice(i--, 1);
43
+ }
44
+ }
45
+ if (cumulative.length == 0) {
46
+ cumulative.push({
47
+ typ: EnumToken.IdenTokenType, val: 'none'
48
+ });
49
+ }
50
+ }
51
+ return {
52
+ matrix: serialize(matrix),
53
+ cumulative,
54
+ minified: minify(matrix) ?? [serialized]
55
+ };
56
+ }
57
+ function computeMatrix(transformList, matrixVar) {
58
+ let values = [];
59
+ let val;
60
+ let i = 0;
61
+ for (; i < transformList.length; i++) {
62
+ if (transformList[i].typ == EnumToken.WhitespaceTokenType) {
63
+ continue;
64
+ }
65
+ if (transformList[i].typ != EnumToken.FunctionTokenType || !transformFunctions.includes(transformList[i].val)) {
66
+ return null;
67
+ }
68
+ switch (transformList[i].val) {
69
+ case 'translate':
70
+ case 'translateX':
71
+ case 'translateY':
72
+ case 'translateZ':
73
+ case 'translate3d':
74
+ {
75
+ values.length = 0;
76
+ const children = stripCommaToken(transformList[i].chi.slice());
77
+ if (children == null || children.length == 0) {
78
+ return null;
79
+ }
80
+ const valCount = transformList[i].val == 'translate3d' || transformList[i].val == 'translate' ? 3 : 1;
81
+ if (children.length == 1 && children[0].typ == EnumToken.IdenTokenType && children[0].val == 'none') {
82
+ values.fill(0, 0, valCount);
83
+ }
84
+ else {
85
+ for (let j = 0; j < children.length; j++) {
86
+ if (children[j].typ == EnumToken.WhitespaceTokenType) {
87
+ continue;
88
+ }
89
+ val = length2Px(children[j]);
90
+ if (typeof val != 'number' || Number.isNaN(val)) {
91
+ return null;
92
+ }
93
+ values.push(val);
94
+ }
95
+ }
96
+ if (values.length == 0 || values.length > valCount) {
97
+ return null;
98
+ }
99
+ if (transformList[i].val == 'translateX') {
100
+ matrixVar = translateX(values[0], matrixVar);
101
+ }
102
+ else if (transformList[i].val == 'translateY') {
103
+ matrixVar = translateY(values[0], matrixVar);
104
+ }
105
+ else if (transformList[i].val == 'translateZ') {
106
+ matrixVar = translateZ(values[0], matrixVar);
107
+ }
108
+ else if (transformList[i].val == 'translate') {
109
+ matrixVar = translate(values, matrixVar);
110
+ }
111
+ else {
112
+ // @ts-ignore
113
+ matrixVar = translate3d(values, matrixVar);
114
+ }
115
+ }
116
+ break;
117
+ case 'rotate':
118
+ case 'rotateX':
119
+ case 'rotateY':
120
+ case 'rotateZ':
121
+ case 'rotate3d':
122
+ {
123
+ let x = 0;
124
+ let y = 0;
125
+ let z = 0;
126
+ let angle;
127
+ let values = [];
128
+ let valuesCount = transformList[i].val == 'rotate3d' ? 4 : 1;
129
+ for (const child of stripCommaToken(transformList[i].chi.slice())) {
130
+ if (child.typ == EnumToken.WhitespaceTokenType) {
131
+ continue;
132
+ }
133
+ values.push(child);
134
+ if (transformList[i].val == 'rotateX') {
135
+ x = 1;
136
+ }
137
+ else if (transformList[i].val == 'rotateY') {
138
+ y = 1;
139
+ }
140
+ else if (transformList[i].val == 'rotate' || transformList[i].val == 'rotateZ') {
141
+ z = 1;
142
+ }
143
+ }
144
+ if (values.length != valuesCount) {
145
+ return null;
146
+ }
147
+ if (transformList[i].val == 'rotate3d') {
148
+ x = getNumber(values[0]);
149
+ y = getNumber(values[1]);
150
+ z = getNumber(values[2]);
151
+ }
152
+ angle = getAngle(values.at(-1));
153
+ if ([x, y, z, angle].some(t => typeof t != 'number' || Number.isNaN(+t))) {
154
+ return null;
155
+ }
156
+ if (transformList[i].val == 'rotate' || transformList[i].val == 'rotateZ') {
157
+ matrixVar = rotate(angle * 2 * Math.PI, matrixVar);
158
+ }
159
+ else {
160
+ matrixVar = rotate3D(angle * 2 * Math.PI, x, y, z, matrixVar);
161
+ }
162
+ }
163
+ break;
164
+ case 'scale':
165
+ case 'scaleX':
166
+ case 'scaleY':
167
+ case 'scaleZ':
168
+ case 'scale3d':
169
+ {
170
+ values.length = 0;
171
+ let child;
172
+ const children = stripCommaToken(transformList[i].chi.slice());
173
+ for (let k = 0; k < children.length; k++) {
174
+ child = children[k];
175
+ if (child.typ == EnumToken.CommentTokenType || child.typ == EnumToken.WhitespaceTokenType) {
176
+ continue;
177
+ }
178
+ if (child.typ != EnumToken.NumberTokenType) {
179
+ return null;
180
+ }
181
+ values.push(getNumber(child));
182
+ }
183
+ if (values.length == 0) {
184
+ return null;
185
+ }
186
+ if (transformList[i].val == 'scale3d') {
187
+ if (values.length != 3) {
188
+ return null;
189
+ }
190
+ matrixVar = scale3d(...values, matrixVar);
191
+ break;
192
+ }
193
+ if (transformList[i].val == 'scale') {
194
+ if (values.length != 1 && values.length != 2) {
195
+ return null;
196
+ }
197
+ matrixVar = scale(values[0], values[1] ?? values[0], matrixVar);
198
+ break;
199
+ }
200
+ if (values.length != 1) {
201
+ return null;
202
+ }
203
+ else if (transformList[i].val == 'scaleX') {
204
+ matrixVar = scaleX(values[0], matrixVar);
205
+ }
206
+ else if (transformList[i].val == 'scaleY') {
207
+ matrixVar = scaleY(values[0], matrixVar);
208
+ }
209
+ else if (transformList[i].val == 'scaleZ') {
210
+ matrixVar = scaleZ(values[0], matrixVar);
211
+ }
212
+ }
213
+ break;
214
+ case 'skew':
215
+ case 'skewX':
216
+ case 'skewY':
217
+ {
218
+ values.length = 0;
219
+ let child;
220
+ let value;
221
+ for (let k = 0; k < transformList[i].chi.length; k++) {
222
+ child = transformList[i].chi[k];
223
+ if (child.typ == EnumToken.CommentTokenType || child.typ == EnumToken.WhitespaceTokenType) {
224
+ continue;
225
+ }
226
+ value = getAngle(child);
227
+ if (value == null) {
228
+ return null;
229
+ }
230
+ values.push(value * 2 * Math.PI);
231
+ }
232
+ if (values.length == 0 || (values.length > (transformList[i].val == 'skew' ? 2 : 1))) {
233
+ return null;
234
+ }
235
+ if (transformList[i].val == 'skew') {
236
+ matrixVar = skew(values, matrixVar);
237
+ }
238
+ else {
239
+ matrixVar = transformList[i].val == 'skewX' ? skewX(values[0], matrixVar) : skewY(values[0], matrixVar);
240
+ }
241
+ }
242
+ break;
243
+ case 'perspective':
244
+ {
245
+ const values = [];
246
+ let child;
247
+ let value;
248
+ for (let k = 0; k < transformList[i].chi.length; k++) {
249
+ child = transformList[i].chi[k];
250
+ if (child.typ == EnumToken.CommentTokenType || child.typ == EnumToken.WhitespaceTokenType) {
251
+ continue;
252
+ }
253
+ if (child.typ == EnumToken.IdenTokenType && child.val == 'none') {
254
+ values.push(child);
255
+ continue;
256
+ }
257
+ value = length2Px(child);
258
+ if (value == null) {
259
+ return null;
260
+ }
261
+ values.push(value);
262
+ }
263
+ if (values.length != 1) {
264
+ return null;
265
+ }
266
+ matrixVar = perspective(values[0], matrixVar);
267
+ }
268
+ break;
269
+ case 'matrix3d':
270
+ // return null;
271
+ case 'matrix':
272
+ {
273
+ const values = [];
274
+ let value;
275
+ for (const token of transformList[i].chi) {
276
+ if ([EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType, EnumToken.CommaTokenType].includes(token.typ)) {
277
+ continue;
278
+ }
279
+ value = getNumber(token);
280
+ if (value == null) {
281
+ return null;
282
+ }
283
+ values.push(value);
284
+ }
285
+ if (transformList[i].val == 'matrix') {
286
+ if (values.length != 6) {
287
+ return null;
288
+ }
289
+ }
290
+ else if (values.length != 16) {
291
+ return null;
292
+ }
293
+ matrixVar = multiply(matrixVar, matrix(values));
294
+ }
295
+ break;
296
+ default:
297
+ return null;
298
+ }
299
+ }
300
+ return matrixVar;
301
+ }
302
+ function splitTransformList(transformList) {
303
+ let pattern = null;
304
+ const tokens = [];
305
+ for (let i = 0; i < transformList.length; i++) {
306
+ if (transformList[i].typ == EnumToken.CommentTokenType || transformList[i].typ == EnumToken.WhitespaceTokenType) {
307
+ continue;
308
+ }
309
+ if (pattern == null || (transformList[i].typ == EnumToken.FunctionTokenType && !transformList[i].val.startsWith(pattern))) {
310
+ if (transformList[i].typ == EnumToken.FunctionTokenType) {
311
+ if (transformList[i].val.startsWith('scale')) {
312
+ pattern = 'scale';
313
+ }
314
+ else if (transformList[i].val.startsWith('rotate')) {
315
+ pattern = 'rotate';
316
+ }
317
+ else if (transformList[i].val.startsWith('translate')) {
318
+ pattern = 'translate';
319
+ }
320
+ else {
321
+ pattern = null;
322
+ }
323
+ tokens.push([transformList[i]]);
324
+ continue;
325
+ }
326
+ }
327
+ if (pattern != null && transformList[i].typ == EnumToken.FunctionTokenType && transformList[i].val.startsWith(pattern)) {
328
+ tokens[tokens.length - 1].push(transformList[i]);
329
+ continue;
330
+ }
331
+ tokens.push([transformList[i]]);
332
+ }
333
+ return tokens;
334
+ }
335
+
336
+ export { compute, computeMatrix };
@@ -0,0 +1,33 @@
1
+ import { EnumToken } from '../types.js';
2
+
3
+ // https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Values_and_units#absolute_length_units
4
+ function length2Px(value) {
5
+ if (value.typ == EnumToken.NumberTokenType) {
6
+ return +value.val;
7
+ }
8
+ switch (value.unit) {
9
+ case 'cm':
10
+ // @ts-ignore
11
+ return value.val * 37.8;
12
+ case 'mm':
13
+ // @ts-ignore
14
+ return value.val * 3.78;
15
+ case 'Q':
16
+ // @ts-ignore
17
+ return value.val * 37.8 / 40;
18
+ case 'in':
19
+ // @ts-ignore
20
+ return value.val / 96;
21
+ case 'pc':
22
+ // @ts-ignore
23
+ return value.val / 16;
24
+ case 'pt':
25
+ // @ts-ignore
26
+ return value.val * 4 / 3;
27
+ case 'px':
28
+ return +value.val;
29
+ }
30
+ return null;
31
+ }
32
+
33
+ export { length2Px };
@@ -0,0 +1,111 @@
1
+ import { toZero, is2DMatrix, identity } from './utils.js';
2
+ import { EnumToken } from '../types.js';
3
+ import { reduceNumber } from '../../renderer/render.js';
4
+ import { eq } from '../../parser/utils/eq.js';
5
+ import { getNumber } from '../../renderer/color/color.js';
6
+ import '../../renderer/color/utils/constants.js';
7
+ import '../minify.js';
8
+ import '../walk.js';
9
+ import '../../parser/parse.js';
10
+ import '../../parser/utils/config.js';
11
+
12
+ function parseMatrix(mat) {
13
+ if (mat.typ == EnumToken.IdenTokenType) {
14
+ return mat.val == 'none' ? identity() : null;
15
+ }
16
+ const children = mat.chi.filter((t) => t.typ == EnumToken.NumberTokenType || t.typ == EnumToken.IdenTokenType);
17
+ const values = [];
18
+ for (const child of children) {
19
+ if (child.typ != EnumToken.NumberTokenType) {
20
+ return null;
21
+ }
22
+ // @ts-ignore
23
+ values.push(getNumber(child));
24
+ }
25
+ // @ts-ignore
26
+ return matrix(values);
27
+ }
28
+ // use column-major order
29
+ function matrix(values) {
30
+ const matrix = identity();
31
+ if (values.length === 6) {
32
+ matrix[0][0] = values[0];
33
+ matrix[0][1] = values[1];
34
+ matrix[1][0] = values[2];
35
+ matrix[1][1] = values[3];
36
+ matrix[3][0] = values[4];
37
+ matrix[3][1] = values[5];
38
+ }
39
+ else if (values.length === 16) {
40
+ matrix[0][0] = values[0];
41
+ matrix[0][1] = values[1];
42
+ matrix[0][2] = values[2];
43
+ matrix[0][3] = values[3];
44
+ matrix[1][0] = values[4];
45
+ matrix[1][1] = values[5];
46
+ matrix[1][2] = values[6];
47
+ matrix[1][3] = values[7];
48
+ matrix[2][0] = values[8];
49
+ matrix[2][1] = values[9];
50
+ matrix[2][2] = values[10];
51
+ matrix[2][3] = values[11];
52
+ matrix[3][0] = values[12];
53
+ matrix[3][1] = values[13];
54
+ matrix[3][2] = values[14];
55
+ matrix[3][3] = values[15];
56
+ }
57
+ else {
58
+ return null;
59
+ }
60
+ return matrix;
61
+ }
62
+ function serialize(matrix) {
63
+ matrix = matrix.map(t => toZero(t.slice()));
64
+ // @ts-ignore
65
+ if (eq(matrix, identity())) {
66
+ return {
67
+ typ: EnumToken.IdenTokenType,
68
+ val: 'none'
69
+ };
70
+ }
71
+ if (is2DMatrix(matrix)) {
72
+ // https://drafts.csswg.org/css-transforms-2/#two-dimensional-subset
73
+ return {
74
+ typ: EnumToken.FunctionTokenType,
75
+ val: 'matrix',
76
+ chi: [
77
+ matrix[0][0],
78
+ matrix[0][1],
79
+ matrix[1][0],
80
+ matrix[1][1],
81
+ matrix[3][0],
82
+ matrix[3][1]
83
+ ].reduce((acc, t) => {
84
+ if (acc.length > 0) {
85
+ acc.push({ typ: EnumToken.CommaTokenType });
86
+ }
87
+ acc.push({
88
+ typ: EnumToken.NumberTokenType,
89
+ val: reduceNumber(t)
90
+ });
91
+ return acc;
92
+ }, [])
93
+ };
94
+ }
95
+ return {
96
+ typ: EnumToken.FunctionTokenType,
97
+ val: 'matrix3d',
98
+ chi: matrix.flat().reduce((acc, curr) => {
99
+ if (acc.length > 0) {
100
+ acc.push({ typ: EnumToken.CommaTokenType });
101
+ }
102
+ acc.push({
103
+ typ: EnumToken.NumberTokenType,
104
+ val: reduceNumber(curr)
105
+ });
106
+ return acc;
107
+ }, [])
108
+ };
109
+ }
110
+
111
+ export { matrix, parseMatrix, serialize };