@tbela99/css-parser 0.7.0 → 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 +142 -81
  2. package/dist/index-umd-web.js +7027 -51519
  3. package/dist/index.cjs +7022 -51515
  4. package/dist/index.d.ts +189 -60
  5. package/dist/lib/ast/expand.js +87 -2
  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 +23 -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 +13 -0
  77. package/dist/web/index.js +13 -0
  78. package/dist/web/load.js +1 -0
  79. package/package.json +17 -15
  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,450 +0,0 @@
1
- import { colorsFunc } from '../../renderer/render.js';
2
- import { EnumToken } from '../../ast/types.js';
3
- import '../../ast/minify.js';
4
- import '../parse.js';
5
- import './config.js';
6
- import { COLORS_NAMES } from '../../renderer/color/utils/constants.js';
7
-
8
- // https://www.w3.org/TR/CSS21/syndata.html#syntax
9
- // https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/#typedef-ident-token
10
- // '\\'
11
- const REVERSE_SOLIDUS = 0x5c;
12
- const dimensionUnits = new Set([
13
- 'q', 'cap', 'ch', 'cm', 'cqb', 'cqh', 'cqi', 'cqmax', 'cqmin', 'cqw', 'dvb',
14
- 'dvh', 'dvi', 'dvmax', 'dvmin', 'dvw', 'em', 'ex', 'ic', 'in', 'lh', 'lvb',
15
- 'lvh', 'lvi', 'lvmax', 'lvw', 'mm', 'pc', 'pt', 'px', 'rem', 'rlh', 'svb',
16
- 'svh', 'svi', 'svmin', 'svw', 'vb', 'vh', 'vi', 'vmax', 'vmin', 'vw'
17
- ]);
18
- function isLength(dimension) {
19
- return 'unit' in dimension && dimensionUnits.has(dimension.unit.toLowerCase());
20
- }
21
- function isResolution(dimension) {
22
- return 'unit' in dimension && ['dpi', 'dpcm', 'dppx', 'x'].includes(dimension.unit.toLowerCase());
23
- }
24
- function isAngle(dimension) {
25
- return 'unit' in dimension && ['rad', 'turn', 'deg', 'grad'].includes(dimension.unit.toLowerCase());
26
- }
27
- function isTime(dimension) {
28
- return 'unit' in dimension && ['ms', 's'].includes(dimension.unit.toLowerCase());
29
- }
30
- function isFrequency(dimension) {
31
- return 'unit' in dimension && ['hz', 'khz'].includes(dimension.unit.toLowerCase());
32
- }
33
- function isColorspace(token) {
34
- if (token.typ != EnumToken.IdenTokenType) {
35
- return false;
36
- }
37
- 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());
38
- }
39
- function isRectangularOrthogonalColorspace(token) {
40
- if (token.typ != EnumToken.IdenTokenType) {
41
- return false;
42
- }
43
- return ['srgb', 'srgb-linear', 'display-p3', 'a98-rgb', 'prophoto-rgb', 'rec2020', 'lab', 'oklab', 'xyz', 'xyz-d50', 'xyz-d65'].includes(token.val.toLowerCase());
44
- }
45
- function isPolarColorspace(token) {
46
- if (token.typ != EnumToken.IdenTokenType) {
47
- return false;
48
- }
49
- return ['hsl', 'hwb', 'lch', 'oklch'].includes(token.val);
50
- }
51
- function isHueInterpolationMethod(token) {
52
- if (token.typ != EnumToken.IdenTokenType) {
53
- return false;
54
- }
55
- return ['shorter', 'longer', 'increasing', 'decreasing'].includes(token.val);
56
- }
57
- function isColor(token) {
58
- if (token.typ == EnumToken.ColorTokenType) {
59
- return true;
60
- }
61
- if (token.typ == EnumToken.IdenTokenType) {
62
- // named color
63
- return token.val.toLowerCase() in COLORS_NAMES;
64
- }
65
- let isLegacySyntax = false;
66
- if (token.typ == EnumToken.FunctionTokenType && token.chi.length > 0 && colorsFunc.includes(token.val)) {
67
- if (token.val == 'light-dark') {
68
- const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
69
- if (children.length != 2) {
70
- return false;
71
- }
72
- if (isColor(children[0]) && isColor(children[1])) {
73
- return true;
74
- }
75
- }
76
- if (token.val == 'color') {
77
- const children = token.chi.filter((t) => [EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.LiteralTokenType, EnumToken.ColorTokenType, EnumToken.FunctionTokenType, EnumToken.PercentageTokenType].includes(t.typ));
78
- const isRelative = children[0].typ == EnumToken.IdenTokenType && children[0].val == 'from';
79
- if (children.length < 4 || children.length > 8) {
80
- return false;
81
- }
82
- if (!isRelative && !isColorspace(children[0])) {
83
- return false;
84
- }
85
- for (let i = 1; i < children.length - 2; i++) {
86
- if (children[i].typ == EnumToken.IdenTokenType) {
87
- if (children[i].val != 'none' &&
88
- !(isRelative && ['alpha', 'r', 'g', 'b', 'x', 'y', 'z'].includes(children[i].val) || isColorspace(children[i]))) {
89
- return false;
90
- }
91
- }
92
- if (children[i].typ == EnumToken.FunctionTokenType && !['calc'].includes(children[i].val)) {
93
- return false;
94
- }
95
- }
96
- if (children.length == 4 || (isRelative && children.length == 6)) {
97
- return true;
98
- }
99
- if (children.length == 8 || children.length == 6) {
100
- const sep = children.at(-2);
101
- const alpha = children.at(-1);
102
- // @ts-ignore
103
- if ((children.length > 6 || !isRelative) && sep.typ != EnumToken.LiteralTokenType || sep.val != '/') {
104
- return false;
105
- }
106
- if (alpha.typ == EnumToken.IdenTokenType && alpha.val != 'none') {
107
- return false;
108
- }
109
- else {
110
- // @ts-ignore
111
- if (alpha.typ == EnumToken.PercentageTokenType) {
112
- if (+alpha.val < 0 || +alpha.val > 100) {
113
- return false;
114
- }
115
- }
116
- else if (alpha.typ == EnumToken.NumberTokenType) {
117
- if (+alpha.val < 0 || +alpha.val > 1) {
118
- return false;
119
- }
120
- }
121
- }
122
- }
123
- return true;
124
- }
125
- else if (token.val == 'color-mix') {
126
- const children = token.chi.reduce((acc, t) => {
127
- if (t.typ == EnumToken.CommaTokenType) {
128
- acc.push([]);
129
- }
130
- else {
131
- if (![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)) {
132
- acc[acc.length - 1].push(t);
133
- }
134
- }
135
- return acc;
136
- }, [[]]);
137
- if (children.length == 3) {
138
- if (children[0].length > 3 ||
139
- children[0][0].typ != EnumToken.IdenTokenType ||
140
- children[0][0].val != 'in' ||
141
- !isColorspace(children[0][1]) ||
142
- (children[0].length == 3 && !isHueInterpolationMethod(children[0][2])) ||
143
- children[1].length > 2 ||
144
- children[1][0].typ != EnumToken.ColorTokenType ||
145
- children[2].length > 2 ||
146
- children[2][0].typ != EnumToken.ColorTokenType) {
147
- return false;
148
- }
149
- if (children[1].length == 2) {
150
- if (!(children[1][1].typ == EnumToken.PercentageTokenType || (children[1][1].typ == EnumToken.NumberTokenType && children[1][1].val == '0'))) {
151
- return false;
152
- }
153
- }
154
- if (children[2].length == 2) {
155
- if (!(children[2][1].typ == EnumToken.PercentageTokenType || (children[2][1].typ == EnumToken.NumberTokenType && children[2][1].val == '0'))) {
156
- return false;
157
- }
158
- }
159
- return true;
160
- }
161
- return false;
162
- }
163
- else {
164
- const keywords = ['from', 'none'];
165
- if (['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch'].includes(token.val)) {
166
- keywords.push('alpha', ...token.val.slice(-3).split(''));
167
- }
168
- // @ts-ignore
169
- for (const v of token.chi) {
170
- if (v.typ == EnumToken.CommaTokenType) {
171
- isLegacySyntax = true;
172
- }
173
- if (v.typ == EnumToken.IdenTokenType) {
174
- if (!(keywords.includes(v.val) || v.val.toLowerCase() in COLORS_NAMES)) {
175
- return false;
176
- }
177
- if (keywords.includes(v.val)) {
178
- if (isLegacySyntax) {
179
- return false;
180
- }
181
- if (v.val == 'from' && ['rgba', 'hsla'].includes(token.val)) {
182
- return false;
183
- }
184
- }
185
- continue;
186
- }
187
- if (v.typ == EnumToken.FunctionTokenType && (v.val == 'calc' || v.val == 'var' || colorsFunc.includes(v.val))) {
188
- continue;
189
- }
190
- if (![EnumToken.ColorTokenType, EnumToken.IdenTokenType, EnumToken.NumberTokenType, EnumToken.AngleTokenType, EnumToken.PercentageTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.LiteralTokenType].includes(v.typ)) {
191
- return false;
192
- }
193
- }
194
- }
195
- return true;
196
- }
197
- return false;
198
- }
199
- function isLetter(codepoint) {
200
- // lowercase
201
- return (codepoint >= 0x61 && codepoint <= 0x7a) ||
202
- // uppercase
203
- (codepoint >= 0x41 && codepoint <= 0x5a);
204
- }
205
- function isNonAscii(codepoint) {
206
- return codepoint >= 0x80;
207
- }
208
- function isIdentStart(codepoint) {
209
- // _
210
- return codepoint == 0x5f || isLetter(codepoint) || isNonAscii(codepoint);
211
- }
212
- function isDigit(codepoint) {
213
- return codepoint >= 0x30 && codepoint <= 0x39;
214
- }
215
- function isIdentCodepoint(codepoint) {
216
- // -
217
- return codepoint == 0x2d || isDigit(codepoint) || isIdentStart(codepoint);
218
- }
219
- function isIdent(name) {
220
- const j = name.length - 1;
221
- let i = 0;
222
- let codepoint = name.charCodeAt(0);
223
- // -
224
- if (codepoint == 0x2d) {
225
- const nextCodepoint = name.charCodeAt(1);
226
- if (Number.isNaN(nextCodepoint)) {
227
- return false;
228
- }
229
- // -
230
- if (nextCodepoint == 0x2d) {
231
- return true;
232
- }
233
- if (nextCodepoint == REVERSE_SOLIDUS) {
234
- return name.length > 2 && !isNewLine(name.charCodeAt(2));
235
- }
236
- return true;
237
- }
238
- if (!isIdentStart(codepoint)) {
239
- return false;
240
- }
241
- while (i < j) {
242
- i += codepoint < 0x80 ? 1 : String.fromCodePoint(codepoint).length;
243
- codepoint = name.charCodeAt(i);
244
- if (!isIdentCodepoint(codepoint)) {
245
- return false;
246
- }
247
- }
248
- return true;
249
- }
250
- function isNonPrintable(codepoint) {
251
- // null -> backspace
252
- return (codepoint >= 0 && codepoint <= 0x8) ||
253
- // tab
254
- codepoint == 0xb ||
255
- // delete
256
- codepoint == 0x7f ||
257
- (codepoint >= 0xe && codepoint <= 0x1f);
258
- }
259
- function isPseudo(name) {
260
- return name.charAt(0) == ':' &&
261
- ((name.endsWith('(') && isIdent(name.charAt(1) == ':' ? name.slice(2, -1) : name.slice(1, -1))) ||
262
- isIdent(name.charAt(1) == ':' ? name.slice(2) : name.slice(1)));
263
- }
264
- function isHash(name) {
265
- return name.charAt(0) == '#' && isIdent(name.charAt(1));
266
- }
267
- function isNumber(name) {
268
- if (name.length == 0) {
269
- return false;
270
- }
271
- let codepoint = name.charCodeAt(0);
272
- let i = 0;
273
- const j = name.length;
274
- if (j == 1 && !isDigit(codepoint)) {
275
- return false;
276
- }
277
- // '+' '-'
278
- if ([0x2b, 0x2d].includes(codepoint)) {
279
- i++;
280
- }
281
- // consume digits
282
- while (i < j) {
283
- codepoint = name.charCodeAt(i);
284
- if (isDigit(codepoint)) {
285
- i++;
286
- continue;
287
- }
288
- // '.' 'E' 'e'
289
- if (codepoint == 0x2e || codepoint == 0x45 || codepoint == 0x65) {
290
- break;
291
- }
292
- return false;
293
- }
294
- // '.'
295
- if (codepoint == 0x2e) {
296
- if (!isDigit(name.charCodeAt(++i))) {
297
- return false;
298
- }
299
- }
300
- while (i < j) {
301
- codepoint = name.charCodeAt(i);
302
- if (isDigit(codepoint)) {
303
- i++;
304
- continue;
305
- }
306
- // 'E' 'e'
307
- if (codepoint == 0x45 || codepoint == 0x65) {
308
- i++;
309
- break;
310
- }
311
- return false;
312
- }
313
- // 'E' 'e'
314
- if (codepoint == 0x45 || codepoint == 0x65) {
315
- if (i == j) {
316
- return false;
317
- }
318
- codepoint = name.charCodeAt(i + 1);
319
- // '+' '-'
320
- if ([0x2b, 0x2d].includes(codepoint)) {
321
- i++;
322
- }
323
- codepoint = name.charCodeAt(i + 1);
324
- if (!isDigit(codepoint)) {
325
- return false;
326
- }
327
- }
328
- while (++i < j) {
329
- codepoint = name.charCodeAt(i);
330
- if (!isDigit(codepoint)) {
331
- return false;
332
- }
333
- }
334
- return true;
335
- }
336
- function isDimension(name) {
337
- let index = name.length;
338
- while (index--) {
339
- if (isLetter(name.charCodeAt(index))) {
340
- continue;
341
- }
342
- index++;
343
- break;
344
- }
345
- const number = name.slice(0, index);
346
- return number.length > 0 && isIdentStart(name.charCodeAt(index)) && isNumber(number);
347
- }
348
- function isPercentage(name) {
349
- return name.endsWith('%') && isNumber(name.slice(0, -1));
350
- }
351
- function isFlex(name) {
352
- return name.endsWith('fr') && isNumber(name.slice(0, -2));
353
- }
354
- function parseDimension(name) {
355
- let index = name.length;
356
- while (index--) {
357
- if (isLetter(name.charCodeAt(index))) {
358
- continue;
359
- }
360
- index++;
361
- break;
362
- }
363
- const dimension = {
364
- typ: EnumToken.DimensionTokenType,
365
- val: name.slice(0, index),
366
- unit: name.slice(index)
367
- };
368
- if (isAngle(dimension)) {
369
- // @ts-ignore
370
- dimension.typ = EnumToken.AngleTokenType;
371
- }
372
- else if (isLength(dimension)) {
373
- // @ts-ignore
374
- dimension.typ = EnumToken.LengthTokenType;
375
- }
376
- else if (isTime(dimension)) {
377
- // @ts-ignore
378
- dimension.typ = EnumToken.TimeTokenType;
379
- }
380
- else if (isResolution(dimension)) {
381
- // @ts-ignore
382
- dimension.typ = EnumToken.ResolutionTokenType;
383
- if (dimension.unit == 'dppx') {
384
- dimension.unit = 'x';
385
- }
386
- }
387
- else if (isFrequency(dimension)) {
388
- // @ts-ignore
389
- dimension.typ = EnumToken.FrequencyTokenType;
390
- }
391
- return dimension;
392
- }
393
- function isHexColor(name) {
394
- if (name.charAt(0) != '#' || ![4, 5, 7, 9].includes(name.length)) {
395
- return false;
396
- }
397
- for (let chr of name.slice(1)) {
398
- let codepoint = chr.charCodeAt(0);
399
- if (!isDigit(codepoint) &&
400
- // A-F
401
- !(codepoint >= 0x41 && codepoint <= 0x46) &&
402
- // a-f
403
- !(codepoint >= 0x61 && codepoint <= 0x66)) {
404
- return false;
405
- }
406
- }
407
- return true;
408
- }
409
- /*
410
- export function isHexDigit(name: string): boolean {
411
-
412
- if (name.length || name.length > 6) {
413
-
414
- return false;
415
- }
416
-
417
- for (let chr of name) {
418
-
419
- let codepoint = <number>chr.charCodeAt(0);
420
-
421
- if (!isDigit(codepoint) &&
422
- // A F
423
- !(codepoint >= 0x41 && codepoint <= 0x46) &&
424
- // a f
425
- !(codepoint >= 0x61 && codepoint <= 0x66)) {
426
-
427
- return false;
428
- }
429
- }
430
-
431
- return true;
432
- }
433
- */
434
- function isFunction(name) {
435
- return name.endsWith('(') && isIdent(name.slice(0, -1));
436
- }
437
- function isAtKeyword(name) {
438
- return name.charCodeAt(0) == 0x40 && isIdent(name.slice(1));
439
- }
440
- function isNewLine(codepoint) {
441
- // \n \r \f
442
- return codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
443
- }
444
- function isWhiteSpace(codepoint) {
445
- return codepoint == 0x9 || codepoint == 0x20 ||
446
- // isNewLine
447
- codepoint == 0xa || codepoint == 0xc || codepoint == 0xd;
448
- }
449
-
450
- 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 };