@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
package/README.md CHANGED
@@ -1,4 +1,6 @@
1
- [![npm](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Ftbela99%2Fcss-parser%2Fmaster%2Fpackage.json&query=version&logo=npm&label=npm&link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2F%40tbela99%2Fcss-parser)](https://www.npmjs.com/package/@tbela99/css-parser) [![cov](https://tbela99.github.io/css-parser/badges/coverage.svg)](https://github.com/tbela99/css-parser/actions) [![NPM Downloads](https://img.shields.io/npm/dm/%40tbela99%2Fcss-parser)](https://www.npmjs.com/package/@tbela99/css-parser)
1
+ [![playground](https://img.shields.io/badge/playground-try%20it%20now-%230a7398
2
+ )](https://tbela99.github.io/css-parser/playground/)[![npm](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fraw.githubusercontent.com%2Ftbela99%2Fcss-parser%2Fmaster%2Fpackage.json&query=version&logo=npm&label=npm&link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2F%40tbela99%2Fcss-parser)](https://www.npmjs.com/package/@tbela99/css-parser) [![npm](https://img.shields.io/jsr/v/%40tbela99/css-parser?link=https%3A%2F%2Fjsr.io%2F%40tbela99%2Fcss-parser
3
+ )](https://jsr.io/@tbela99/css-parser) [![cov](https://tbela99.github.io/css-parser/badges/coverage.svg)](https://github.com/tbela99/css-parser/actions) [![NPM Downloads](https://img.shields.io/npm/dm/%40tbela99%2Fcss-parser)](https://www.npmjs.com/package/@tbela99/css-parser)
2
4
 
3
5
  # css-parser
4
6
 
@@ -6,26 +8,37 @@ CSS parser and minifier for node and the browser
6
8
 
7
9
  ## Installation
8
10
 
11
+ From npm
12
+
9
13
  ```shell
10
14
  $ npm install @tbela99/css-parser
11
15
  ```
12
16
 
17
+ from jsr
18
+
19
+ ```shell
20
+ $ deno add @tbela99/css-parser
21
+ ```
22
+
13
23
  ## Features
14
24
 
15
25
  - no dependency
26
+ - partial css validation based upon mdn-data: at-rules and selectors validation
16
27
  - fault-tolerant parser, will try to fix invalid tokens according to the CSS syntax module 3 recommendations.
17
- - fast and efficient minification without unsafe transforms, see [benchmark](https://tbela99.github.io/css-parser/benchmark/index.html)
28
+ - fast and efficient minification without unsafe transforms,
29
+ see [benchmark](https://tbela99.github.io/css-parser/benchmark/index.html)
18
30
  - minify colors.
19
- - support css color level 4 & 5: color(), lab(), lch(), oklab(), oklch(), color-mix(), light-dark(), system colors and relative color
31
+ - support css color level 4 & 5: color(), lab(), lch(), oklab(), oklch(), color-mix(), light-dark(), system colors and
32
+ relative color
20
33
  - generate nested css rules
21
34
  - convert nested css rules to legacy syntax
22
35
  - generate sourcemap
23
36
  - compute css shorthands. see supported properties list below
24
- - evaluate calc()
37
+ - evaluate math functions: calc(), clamp(), min(), max(), round(), mod(), rem(), sin(), cos(), tan(), asin(), acos(),
38
+ atan(), atan2(), pow(), sqrt(), hypot(), log(), exp(), abs(), sign()
25
39
  - inline css variables
26
40
  - remove duplicate properties
27
41
  - flatten @import rules
28
- - partial css validation: only css selector is validated
29
42
 
30
43
  ## Playground
31
44
 
@@ -45,6 +58,7 @@ import {transform} from '@tbela99/css-parser';
45
58
 
46
59
  // ...
47
60
  ```
61
+
48
62
  ### Deno exports
49
63
 
50
64
  import as a module
@@ -55,6 +69,7 @@ import {transform} from 'npm:@tbela99/css-parser';
55
69
 
56
70
  // ...
57
71
  ```
72
+
58
73
  import as a CommonJS module
59
74
 
60
75
  ```javascript
@@ -137,18 +152,22 @@ Include ParseOptions and RenderOptions
137
152
  #### ParseOptions
138
153
 
139
154
  > Minify Options
155
+
140
156
  - minify: boolean, optional. default to _true_. optimize ast.
141
157
  - nestingRules: boolean, optional. automatically generated nested rules.
142
- - expandNestingRules: boolean, optional. convert nesting rules into separate rules. will automatically set nestingRules to false.
158
+ - expandNestingRules: boolean, optional. convert nesting rules into separate rules. will automatically set nestingRules
159
+ to false.
143
160
  - removeDuplicateDeclarations: boolean, optional. remove duplicate declarations.
144
161
  - computeShorthand: boolean, optional. compute shorthand properties.
145
162
  - computeCalcExpression: boolean, optional. evaluate calc() expression
146
- - inlineCssVariables: boolean, optional. replace some css variables with their actual value. they must be declared once in the :root {} or html {} rule.
163
+ - inlineCssVariables: boolean, optional. replace some css variables with their actual value. they must be declared once
164
+ in the :root {} or html {} rule.
147
165
  - removeEmpty: boolean, optional. remove empty rule lists from the ast.
148
166
 
149
167
  > Minify Options
150
168
 
151
- - validation: boolean, optional. enable strict css validation using (mdn data)[https://github.com/mdn/data]. only the selector is validated at this time.
169
+ - validation: boolean, optional. enable strict css validation using (mdn data)[https://github.com/mdn/data]. only the
170
+ selector is validated at this time.
152
171
 
153
172
  > Sourcemap Options
154
173
 
@@ -170,6 +189,7 @@ Include ParseOptions and RenderOptions
170
189
 
171
190
  - minify: boolean, optional. default to _true_. minify css output.
172
191
  - withParents: boolean, optional. render this node and its parents.
192
+ - removeEmpty: boolean, optional. remove empty rule lists from the ast.
173
193
  - expandNestingRules: boolean, optional. expand nesting rules.
174
194
  - preserveLicense: boolean, force preserving comments starting with '/\*!' when minify is enabled.
175
195
  - removeComments: boolean, remove comments in generated css.
@@ -183,7 +203,8 @@ Include ParseOptions and RenderOptions
183
203
 
184
204
  - indent: string, optional. css indention string. uses space character by default.
185
205
  - newLine: string, optional. new line character.
186
- - output: string, optional. file where to store css. url() are resolved according to the specified value. no file is created though.
206
+ - output: string, optional. file where to store css. url() are resolved according to the specified value. no file is
207
+ created though.
187
208
  - cwd: string, optional. destination directory used to resolve url().
188
209
 
189
210
  ## Parsing
@@ -248,15 +269,15 @@ CSS
248
269
  ```css
249
270
 
250
271
  .clear {
251
- width: 0;
252
- height: 0;
253
- color: transparent;
272
+ width: 0;
273
+ height: 0;
274
+ color: transparent;
254
275
  }
255
276
 
256
277
  .clearfix:before {
257
278
 
258
- height: 0;
259
- width: 0;
279
+ height: 0;
280
+ width: 0;
260
281
  }
261
282
  ```
262
283
 
@@ -271,7 +292,14 @@ const result = await transform(css);
271
292
  Result
272
293
 
273
294
  ```css
274
- .clear,.clearfix:before{height:0;width:0}.clear{color:#0000}
295
+ .clear, .clearfix:before {
296
+ height: 0;
297
+ width: 0
298
+ }
299
+
300
+ .clear {
301
+ color: #0000
302
+ }
275
303
  ```
276
304
 
277
305
  ### Automatic CSS Nesting
@@ -298,26 +326,30 @@ table.colortable th {
298
326
  }
299
327
  `;
300
328
 
301
- const result = await parse(css, {nestingRules:true}).then(result => render(result.ast, {minify:false}).code);
329
+ const result = await parse(css, {nestingRules: true}).then(result => render(result.ast, {minify: false}).code);
302
330
  ```
303
331
 
304
332
  Result
333
+
305
334
  ```css
306
335
  table.colortable {
307
- & td {
308
- text-align: center;
309
- &.c {
310
- text-transform: uppercase
311
- }
312
- &:first-child,&:first-child+td {
313
- border: 1px solid #000
314
- }
315
- }
316
- & th {
317
- text-align: center;
318
- background: #000;
319
- color: #fff
320
- }
336
+ & td {
337
+ text-align: center;
338
+
339
+ &.c {
340
+ text-transform: uppercase
341
+ }
342
+
343
+ &:first-child, &:first-child + td {
344
+ border: 1px solid #000
345
+ }
346
+ }
347
+
348
+ & th {
349
+ text-align: center;
350
+ background: #000;
351
+ color: #fff
352
+ }
321
353
  }
322
354
  ```
323
355
 
@@ -328,62 +360,69 @@ CSS
328
360
  ```css
329
361
 
330
362
  #404 {
331
- --animate-duration: 1s;
363
+ --animate-duration: 1s;
332
364
  }
333
365
 
334
366
  .s, #404 {
335
- --animate-duration: 1s;
367
+ --animate-duration: 1s;
336
368
  }
337
369
 
338
370
  .s [type="text" {
339
- --animate-duration: 1s;
371
+ --animate-duration: 1s;
340
372
  }
341
373
 
342
- .s [type="text"]] {
343
- --animate-duration: 1s;
374
+ .s [type="text"]]
375
+ {
376
+ --animate-duration: 1s;
344
377
  }
345
378
 
346
379
  .s [type="text"] {
347
- --animate-duration: 1s;
380
+ --animate-duration: 1s;
348
381
  }
349
382
 
350
383
  .s [type="text" i] {
351
- --animate-duration: 1s;
384
+ --animate-duration: 1s;
352
385
  }
353
386
 
354
- .s [type="text" s] {
355
- --animate-duration: 1s;
387
+ .s [type="text" s]
388
+ {
389
+ --animate-duration: 1s
390
+ ;
356
391
  }
357
392
 
358
- .s [type="text" b] {
359
- --animate-duration: 1s;
393
+ .s [type="text" b]
394
+ {
395
+ --animate-duration: 1s;
360
396
  }
361
397
 
362
- .s [type="text" b], {
363
- --animate-duration: 1s;
398
+ .s [type="text" b],{
399
+ --animate-duration: 1s
400
+ ;
364
401
  }
365
402
 
366
- .s [type="text" b]+ {
367
- --animate-duration: 1s;
403
+ .s [type="text" b]
404
+ + {
405
+ --animate-duration: 1s;
368
406
  }
369
407
 
370
- .s [type="text" b]+ b {
371
- --animate-duration: 1s;
408
+ .s [type="text" b]
409
+ + b {
410
+ --animate-duration: 1s;
372
411
  }
373
412
 
374
- .s [type="text" i]+ b {
375
- --animate-duration: 1s;
413
+ .s [type="text" i] + b {
414
+ --animate-duration: 1s;
376
415
  }
377
416
 
378
417
 
379
- .s [type="text"())] {
380
- --animate-duration: 1s;
418
+ .s [type="text"())]{
419
+ --animate-duration: 1s;
381
420
  }
382
- .s() {
383
- --animate-duration: 1s;
421
+ .s(){
422
+ --animate-duration: 1s;
384
423
  }
385
424
  .s:focus {
386
- --animate-duration: 1s;
425
+ --animate-duration: 1s;
387
426
  }
388
427
  ```
389
428
 
@@ -391,6 +430,7 @@ with validation enabled
391
430
 
392
431
  ```javascript
393
432
  import {parse, render} from '@tbela99/css-parser';
433
+
394
434
  const options = {minify: true, validate: true};
395
435
  const {code} = await parse(css, options).then(result => render(result.ast, {minify: false}));
396
436
  //
@@ -399,7 +439,7 @@ console.debug(code);
399
439
 
400
440
  ```css
401
441
  .s:is([type=text],[type=text i],[type=text s],[type=text i]+b,:focus) {
402
- --animate-duration: 1s
442
+ --animate-duration: 1s
403
443
  }
404
444
  ```
405
445
 
@@ -407,6 +447,7 @@ with validation disabled
407
447
 
408
448
  ```javascript
409
449
  import {parse, render} from '@tbela99/css-parser';
450
+
410
451
  const options = {minify: true, validate: false};
411
452
  const {code} = await parse(css, options).then(result => render(result.ast, {minify: false}));
412
453
  //
@@ -425,22 +466,26 @@ CSS
425
466
 
426
467
  ```css
427
468
  table.colortable {
428
- & td {
429
- text-align: center;
430
- &.c {
431
- text-transform: uppercase
432
- }
433
- &:first-child,&:first-child+td {
434
- border: 1px solid #000
435
- }
436
- }
437
- & th {
438
- text-align: center;
439
- background: #000;
440
- color: #fff
441
- }
469
+ & td {
470
+ text-align: center;
471
+
472
+ &.c {
473
+ text-transform: uppercase
474
+ }
475
+
476
+ &:first-child, &:first-child + td {
477
+ border: 1px solid #000
478
+ }
479
+ }
480
+
481
+ & th {
482
+ text-align: center;
483
+ background: #000;
484
+ color: #fff
485
+ }
442
486
  }
443
487
  ```
488
+
444
489
  Javascript
445
490
 
446
491
  ```javascript
@@ -457,18 +502,21 @@ Result
457
502
  ```css
458
503
 
459
504
  table.colortable td {
460
- text-align:center;
505
+ text-align: center;
461
506
  }
507
+
462
508
  table.colortable td.c {
463
- text-transform:uppercase;
509
+ text-transform: uppercase;
464
510
  }
465
- table.colortable td:first-child, table.colortable td:first-child+td {
466
- border:1px solid black;
511
+
512
+ table.colortable td:first-child, table.colortable td:first-child + td {
513
+ border: 1px solid black;
467
514
  }
515
+
468
516
  table.colortable th {
469
- text-align:center;
470
- background:black;
471
- color:white;
517
+ text-align: center;
518
+ background: black;
519
+ color: white;
472
520
  }
473
521
  ```
474
522
 
@@ -479,7 +527,10 @@ table.colortable th {
479
527
  import {parse, render} from '@tbela99/css-parser';
480
528
 
481
529
  const css = `
530
+ a {
482
531
 
532
+ width: calc(100px * log(625, 5));
533
+ }
483
534
  .foo-bar {
484
535
  width: calc(100px * 2);
485
536
  height: calc(((75.37% - 63.5px) - 900px) + (2 * 100px));
@@ -490,13 +541,18 @@ const css = `
490
541
  const prettyPrint = await parse(css).then(result => render(result.ast, {minify: false}).code);
491
542
 
492
543
  ```
544
+
493
545
  result
494
546
 
495
547
  ```css
548
+ a {
549
+ width: 400px;
550
+ }
551
+
496
552
  .foo-bar {
497
553
  width: 200px;
498
554
  height: calc(75.37% - 763.5px);
499
- max-width: calc(3.5rem + var(--bs-border-width)*2)
555
+ max-width: calc(3.5rem + var(--bs-border-width) * 2)
500
556
  }
501
557
  ```
502
558
 
@@ -521,6 +577,7 @@ const css = `
521
577
  const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
522
578
 
523
579
  ```
580
+
524
581
  result
525
582
 
526
583
  ```css
@@ -551,6 +608,7 @@ const css = `
551
608
  const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
552
609
 
553
610
  ```
611
+
554
612
  result
555
613
 
556
614
  ```css
@@ -559,6 +617,7 @@ result
559
617
  }
560
618
 
561
619
  ```
620
+
562
621
  ### CSS variable inlining and relative color
563
622
 
564
623
  ```javascript
@@ -576,6 +635,7 @@ html { --bluegreen: oklab(54.3% -22.5% -5%); }
576
635
  const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
577
636
 
578
637
  ```
638
+
579
639
  result
580
640
 
581
641
  ```css
@@ -591,7 +651,7 @@ result
591
651
  import {walk} from '@tbela99/css-parser';
592
652
 
593
653
  for (const {node, parent, root} of walk(ast)) {
594
-
654
+
595
655
  // do something
596
656
  }
597
657
  ```
@@ -600,7 +660,7 @@ for (const {node, parent, root} of walk(ast)) {
600
660
 
601
661
  ### Comment
602
662
 
603
- - typ: number
663
+ - typ: number
604
664
  - val: string, the comment
605
665
 
606
666
  ### Declaration
@@ -818,7 +878,7 @@ const options: ParserOptions = {
818
878
  visitor: {
819
879
 
820
880
  AtRule: (node: AstAtRule): AstAtRule => {
821
-
881
+
822
882
  if (node.nam == 'media') {
823
883
 
824
884
  return {...node, val: 'all'}
@@ -898,7 +958,7 @@ const options: ParserOptions = {
898
958
  visitor: {
899
959
 
900
960
 
901
- Rule (node: AstRule): AstRule {
961
+ Rule(node: AstRule): AstRule {
902
962
 
903
963
  return {...node, sel: '.foo,.bar,.fubar'};
904
964
  }
@@ -918,6 +978,7 @@ console.debug(await transform(css, options));
918
978
  // .foo,.bar,.fubar{height:calc(40px/3)}
919
979
 
920
980
  ```
981
+
921
982
  ### Exemple 6: Rule
922
983
 
923
984
  Adding declarations to any rule