@tbela99/css-parser 0.7.1 → 0.9.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 (90) hide show
  1. package/.editorconfig +484 -0
  2. package/README.md +140 -84
  3. package/dist/index-umd-web.js +8461 -51655
  4. package/dist/index.cjs +8437 -51636
  5. package/dist/index.d.ts +220 -68
  6. package/dist/lib/ast/expand.js +46 -9
  7. package/dist/lib/ast/features/calc.js +76 -12
  8. package/dist/lib/ast/features/inlinecssvariables.js +6 -1
  9. package/dist/lib/ast/features/prefix.js +17 -9
  10. package/dist/lib/ast/features/shorthand.js +1 -0
  11. package/dist/lib/ast/math/expression.js +299 -11
  12. package/dist/lib/ast/math/math.js +7 -1
  13. package/dist/lib/ast/minify.js +30 -16
  14. package/dist/lib/ast/types.js +59 -49
  15. package/dist/lib/ast/walk.js +92 -18
  16. package/dist/lib/parser/declaration/list.js +1 -0
  17. package/dist/lib/parser/declaration/map.js +60 -52
  18. package/dist/lib/parser/declaration/set.js +1 -12
  19. package/dist/lib/parser/parse.js +371 -119
  20. package/dist/lib/parser/tokenize.js +31 -6
  21. package/dist/lib/parser/utils/declaration.js +2 -2
  22. package/dist/lib/parser/utils/type.js +6 -6
  23. package/dist/lib/renderer/color/a98rgb.js +1 -0
  24. package/dist/lib/renderer/color/color.js +1 -0
  25. package/dist/lib/renderer/color/colormix.js +1 -0
  26. package/dist/lib/renderer/color/hex.js +2 -1
  27. package/dist/lib/renderer/color/hsl.js +2 -1
  28. package/dist/lib/renderer/color/hwb.js +3 -2
  29. package/dist/lib/renderer/color/lab.js +2 -1
  30. package/dist/lib/renderer/color/lch.js +2 -1
  31. package/dist/lib/renderer/color/oklab.js +3 -2
  32. package/dist/lib/renderer/color/oklch.js +2 -1
  33. package/dist/lib/renderer/color/p3.js +2 -1
  34. package/dist/lib/renderer/color/prophotoRgb.js +56 -0
  35. package/dist/lib/renderer/color/prophotorgb.js +1 -1
  36. package/dist/lib/renderer/color/rec2020.js +1 -0
  37. package/dist/lib/renderer/color/relativecolor.js +52 -28
  38. package/dist/lib/renderer/color/rgb.js +2 -1
  39. package/dist/lib/renderer/color/srgb.js +3 -2
  40. package/dist/lib/renderer/color/utils/components.js +1 -0
  41. package/dist/lib/renderer/color/utils/constants.js +2 -1
  42. package/dist/lib/renderer/color/xyz.js +2 -1
  43. package/dist/lib/renderer/color/xyzd50.js +1 -0
  44. package/dist/lib/renderer/render.js +62 -12
  45. package/dist/lib/syntax/syntax.js +362 -4
  46. package/dist/lib/validation/at-rules/container.js +353 -0
  47. package/dist/lib/validation/at-rules/counter-style.js +78 -0
  48. package/dist/lib/validation/at-rules/custom-media.js +52 -0
  49. package/dist/lib/validation/at-rules/document.js +114 -0
  50. package/dist/lib/validation/at-rules/else.js +5 -0
  51. package/dist/lib/validation/at-rules/font-feature-values.js +52 -0
  52. package/dist/lib/validation/at-rules/import.js +199 -0
  53. package/dist/lib/validation/at-rules/keyframes.js +70 -0
  54. package/dist/lib/validation/at-rules/layer.js +30 -0
  55. package/dist/lib/validation/at-rules/media.js +254 -0
  56. package/dist/lib/validation/at-rules/namespace.js +85 -0
  57. package/dist/lib/validation/at-rules/page-margin-box.js +56 -0
  58. package/dist/lib/validation/at-rules/page.js +88 -0
  59. package/dist/lib/validation/at-rules/supports.js +262 -0
  60. package/dist/lib/validation/at-rules/when.js +178 -0
  61. package/dist/lib/validation/atrule.js +187 -0
  62. package/dist/lib/validation/config.js +35 -2
  63. package/dist/lib/validation/config.json.js +1683 -50905
  64. package/dist/lib/validation/declaration.js +102 -0
  65. package/dist/lib/validation/parser/parse.js +1137 -7
  66. package/dist/lib/validation/parser/types.js +28 -12
  67. package/dist/lib/validation/selector.js +26 -444
  68. package/dist/lib/validation/syntax.js +1475 -0
  69. package/dist/lib/validation/syntaxes/complex-selector-list.js +45 -0
  70. package/dist/lib/validation/syntaxes/complex-selector.js +53 -0
  71. package/dist/lib/validation/syntaxes/compound-selector.js +226 -0
  72. package/dist/lib/validation/syntaxes/family-name.js +91 -0
  73. package/dist/lib/validation/syntaxes/image.js +29 -0
  74. package/dist/lib/validation/syntaxes/keyframe-block-list.js +27 -0
  75. package/dist/lib/validation/syntaxes/keyframe-selector.js +137 -0
  76. package/dist/lib/validation/syntaxes/layer-name.js +67 -0
  77. package/dist/lib/validation/syntaxes/relative-selector-list.js +57 -0
  78. package/dist/lib/validation/syntaxes/relative-selector.js +36 -0
  79. package/dist/lib/validation/syntaxes/selector-list.js +5 -0
  80. package/dist/lib/validation/syntaxes/selector.js +5 -0
  81. package/dist/lib/validation/syntaxes/url.js +75 -0
  82. package/dist/lib/validation/utils/list.js +24 -0
  83. package/dist/lib/validation/utils/whitespace.js +22 -0
  84. package/dist/node/index.js +5 -5
  85. package/dist/web/index.js +5 -1
  86. package/dist/web/load.js +1 -0
  87. package/package.json +16 -14
  88. package/dist/lib/ast/utils/minifyfeature.js +0 -9
  89. package/dist/lib/iterable/weakset.js +0 -58
  90. package/dist/lib/parser/utils/syntax.js +0 -450
package/README.md CHANGED
@@ -1,4 +1,5 @@
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) [![npm](https://img.shields.io/jsr/v/%40tbela99/css-parser?link=https%3A%2F%2Fjsr.io%2F%40tbela99%2Fcss-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
2
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)
3
4
 
4
5
  # css-parser
@@ -8,31 +9,36 @@ CSS parser and minifier for node and the browser
8
9
  ## Installation
9
10
 
10
11
  From npm
12
+
11
13
  ```shell
12
14
  $ npm install @tbela99/css-parser
13
15
  ```
16
+
14
17
  from jsr
18
+
15
19
  ```shell
16
20
  $ deno add @tbela99/css-parser
17
21
  ```
18
22
 
19
-
20
23
  ## Features
21
24
 
22
25
  - no dependency
26
+ - partial css validation based upon mdn-data: at-rules and selectors validation
23
27
  - fault-tolerant parser, will try to fix invalid tokens according to the CSS syntax module 3 recommendations.
24
- - 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)
25
30
  - minify colors.
26
- - 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
27
33
  - generate nested css rules
28
34
  - convert nested css rules to legacy syntax
29
35
  - generate sourcemap
30
36
  - compute css shorthands. see supported properties list below
31
- - 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()
32
39
  - inline css variables
33
40
  - remove duplicate properties
34
41
  - flatten @import rules
35
- - partial css validation: only css selector is validated
36
42
 
37
43
  ## Playground
38
44
 
@@ -52,6 +58,7 @@ import {transform} from '@tbela99/css-parser';
52
58
 
53
59
  // ...
54
60
  ```
61
+
55
62
  ### Deno exports
56
63
 
57
64
  import as a module
@@ -62,6 +69,7 @@ import {transform} from 'npm:@tbela99/css-parser';
62
69
 
63
70
  // ...
64
71
  ```
72
+
65
73
  import as a CommonJS module
66
74
 
67
75
  ```javascript
@@ -144,18 +152,23 @@ Include ParseOptions and RenderOptions
144
152
  #### ParseOptions
145
153
 
146
154
  > Minify Options
155
+
147
156
  - minify: boolean, optional. default to _true_. optimize ast.
148
157
  - nestingRules: boolean, optional. automatically generated nested rules.
149
- - 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.
150
160
  - removeDuplicateDeclarations: boolean, optional. remove duplicate declarations.
151
161
  - computeShorthand: boolean, optional. compute shorthand properties.
152
162
  - computeCalcExpression: boolean, optional. evaluate calc() expression
153
- - 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.
154
165
  - removeEmpty: boolean, optional. remove empty rule lists from the ast.
155
166
 
156
- > Minify Options
167
+ > Validation Options
157
168
 
158
- - 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.
171
+ - lenient: boolean, optional. ignore unknown at-rules, pseudo-classes and declarations.
159
172
 
160
173
  > Sourcemap Options
161
174
 
@@ -175,8 +188,10 @@ Include ParseOptions and RenderOptions
175
188
 
176
189
  > Minify Options
177
190
 
178
- - minify: boolean, optional. default to _true_. minify css output.
191
+ - beautify: boolean, optional. default to _false_. beautify css output.
192
+ - minify: boolean, optional. default to _true_. minify css values.
179
193
  - withParents: boolean, optional. render this node and its parents.
194
+ - removeEmpty: boolean, optional. remove empty rule lists from the ast.
180
195
  - expandNestingRules: boolean, optional. expand nesting rules.
181
196
  - preserveLicense: boolean, force preserving comments starting with '/\*!' when minify is enabled.
182
197
  - removeComments: boolean, remove comments in generated css.
@@ -190,7 +205,8 @@ Include ParseOptions and RenderOptions
190
205
 
191
206
  - indent: string, optional. css indention string. uses space character by default.
192
207
  - newLine: string, optional. new line character.
193
- - output: string, optional. file where to store css. url() are resolved according to the specified value. no file is created though.
208
+ - output: string, optional. file where to store css. url() are resolved according to the specified value. no file is
209
+ created though.
194
210
  - cwd: string, optional. destination directory used to resolve url().
195
211
 
196
212
  ## Parsing
@@ -255,15 +271,15 @@ CSS
255
271
  ```css
256
272
 
257
273
  .clear {
258
- width: 0;
259
- height: 0;
260
- color: transparent;
274
+ width: 0;
275
+ height: 0;
276
+ color: transparent;
261
277
  }
262
278
 
263
279
  .clearfix:before {
264
280
 
265
- height: 0;
266
- width: 0;
281
+ height: 0;
282
+ width: 0;
267
283
  }
268
284
  ```
269
285
 
@@ -278,7 +294,14 @@ const result = await transform(css);
278
294
  Result
279
295
 
280
296
  ```css
281
- .clear,.clearfix:before{height:0;width:0}.clear{color:#0000}
297
+ .clear, .clearfix:before {
298
+ height: 0;
299
+ width: 0
300
+ }
301
+
302
+ .clear {
303
+ color: #0000
304
+ }
282
305
  ```
283
306
 
284
307
  ### Automatic CSS Nesting
@@ -305,26 +328,30 @@ table.colortable th {
305
328
  }
306
329
  `;
307
330
 
308
- const result = await parse(css, {nestingRules:true}).then(result => render(result.ast, {minify:false}).code);
331
+ const result = await parse(css, {nestingRules: true}).then(result => render(result.ast, {minify: false}).code);
309
332
  ```
310
333
 
311
334
  Result
335
+
312
336
  ```css
313
337
  table.colortable {
314
- & td {
315
- text-align: center;
316
- &.c {
317
- text-transform: uppercase
318
- }
319
- &:first-child,&:first-child+td {
320
- border: 1px solid #000
321
- }
322
- }
323
- & th {
324
- text-align: center;
325
- background: #000;
326
- color: #fff
327
- }
338
+ & td {
339
+ text-align: center;
340
+
341
+ &.c {
342
+ text-transform: uppercase
343
+ }
344
+
345
+ &:first-child, &:first-child + td {
346
+ border: 1px solid #000
347
+ }
348
+ }
349
+
350
+ & th {
351
+ text-align: center;
352
+ background: #000;
353
+ color: #fff
354
+ }
328
355
  }
329
356
  ```
330
357
 
@@ -335,62 +362,69 @@ CSS
335
362
  ```css
336
363
 
337
364
  #404 {
338
- --animate-duration: 1s;
365
+ --animate-duration: 1s;
339
366
  }
340
367
 
341
368
  .s, #404 {
342
- --animate-duration: 1s;
369
+ --animate-duration: 1s;
343
370
  }
344
371
 
345
372
  .s [type="text" {
346
- --animate-duration: 1s;
373
+ --animate-duration: 1s;
347
374
  }
348
375
 
349
- .s [type="text"]] {
350
- --animate-duration: 1s;
376
+ .s [type="text"]]
377
+ {
378
+ --animate-duration: 1s;
351
379
  }
352
380
 
353
381
  .s [type="text"] {
354
- --animate-duration: 1s;
382
+ --animate-duration: 1s;
355
383
  }
356
384
 
357
385
  .s [type="text" i] {
358
- --animate-duration: 1s;
386
+ --animate-duration: 1s;
359
387
  }
360
388
 
361
- .s [type="text" s] {
362
- --animate-duration: 1s;
389
+ .s [type="text" s]
390
+ {
391
+ --animate-duration: 1s
392
+ ;
363
393
  }
364
394
 
365
- .s [type="text" b] {
366
- --animate-duration: 1s;
395
+ .s [type="text" b]
396
+ {
397
+ --animate-duration: 1s;
367
398
  }
368
399
 
369
- .s [type="text" b], {
370
- --animate-duration: 1s;
400
+ .s [type="text" b],{
401
+ --animate-duration: 1s
402
+ ;
371
403
  }
372
404
 
373
- .s [type="text" b]+ {
374
- --animate-duration: 1s;
405
+ .s [type="text" b]
406
+ + {
407
+ --animate-duration: 1s;
375
408
  }
376
409
 
377
- .s [type="text" b]+ b {
378
- --animate-duration: 1s;
410
+ .s [type="text" b]
411
+ + b {
412
+ --animate-duration: 1s;
379
413
  }
380
414
 
381
- .s [type="text" i]+ b {
382
- --animate-duration: 1s;
415
+ .s [type="text" i] + b {
416
+ --animate-duration: 1s;
383
417
  }
384
418
 
385
419
 
386
- .s [type="text"())] {
387
- --animate-duration: 1s;
420
+ .s [type="text"())]{
421
+ --animate-duration: 1s;
388
422
  }
389
- .s() {
390
- --animate-duration: 1s;
423
+ .s(){
424
+ --animate-duration: 1s;
391
425
  }
392
426
  .s:focus {
393
- --animate-duration: 1s;
427
+ --animate-duration: 1s;
394
428
  }
395
429
  ```
396
430
 
@@ -398,6 +432,7 @@ with validation enabled
398
432
 
399
433
  ```javascript
400
434
  import {parse, render} from '@tbela99/css-parser';
435
+
401
436
  const options = {minify: true, validate: true};
402
437
  const {code} = await parse(css, options).then(result => render(result.ast, {minify: false}));
403
438
  //
@@ -406,7 +441,7 @@ console.debug(code);
406
441
 
407
442
  ```css
408
443
  .s:is([type=text],[type=text i],[type=text s],[type=text i]+b,:focus) {
409
- --animate-duration: 1s
444
+ --animate-duration: 1s
410
445
  }
411
446
  ```
412
447
 
@@ -414,6 +449,7 @@ with validation disabled
414
449
 
415
450
  ```javascript
416
451
  import {parse, render} from '@tbela99/css-parser';
452
+
417
453
  const options = {minify: true, validate: false};
418
454
  const {code} = await parse(css, options).then(result => render(result.ast, {minify: false}));
419
455
  //
@@ -432,22 +468,26 @@ CSS
432
468
 
433
469
  ```css
434
470
  table.colortable {
435
- & td {
436
- text-align: center;
437
- &.c {
438
- text-transform: uppercase
439
- }
440
- &:first-child,&:first-child+td {
441
- border: 1px solid #000
442
- }
443
- }
444
- & th {
445
- text-align: center;
446
- background: #000;
447
- color: #fff
448
- }
471
+ & td {
472
+ text-align: center;
473
+
474
+ &.c {
475
+ text-transform: uppercase
476
+ }
477
+
478
+ &:first-child, &:first-child + td {
479
+ border: 1px solid #000
480
+ }
481
+ }
482
+
483
+ & th {
484
+ text-align: center;
485
+ background: #000;
486
+ color: #fff
487
+ }
449
488
  }
450
489
  ```
490
+
451
491
  Javascript
452
492
 
453
493
  ```javascript
@@ -464,18 +504,21 @@ Result
464
504
  ```css
465
505
 
466
506
  table.colortable td {
467
- text-align:center;
507
+ text-align: center;
468
508
  }
509
+
469
510
  table.colortable td.c {
470
- text-transform:uppercase;
511
+ text-transform: uppercase;
471
512
  }
472
- table.colortable td:first-child, table.colortable td:first-child+td {
473
- border:1px solid black;
513
+
514
+ table.colortable td:first-child, table.colortable td:first-child + td {
515
+ border: 1px solid black;
474
516
  }
517
+
475
518
  table.colortable th {
476
- text-align:center;
477
- background:black;
478
- color:white;
519
+ text-align: center;
520
+ background: black;
521
+ color: white;
479
522
  }
480
523
  ```
481
524
 
@@ -486,7 +529,10 @@ table.colortable th {
486
529
  import {parse, render} from '@tbela99/css-parser';
487
530
 
488
531
  const css = `
532
+ a {
489
533
 
534
+ width: calc(100px * log(625, 5));
535
+ }
490
536
  .foo-bar {
491
537
  width: calc(100px * 2);
492
538
  height: calc(((75.37% - 63.5px) - 900px) + (2 * 100px));
@@ -497,13 +543,18 @@ const css = `
497
543
  const prettyPrint = await parse(css).then(result => render(result.ast, {minify: false}).code);
498
544
 
499
545
  ```
546
+
500
547
  result
501
548
 
502
549
  ```css
550
+ a {
551
+ width: 400px;
552
+ }
553
+
503
554
  .foo-bar {
504
555
  width: 200px;
505
556
  height: calc(75.37% - 763.5px);
506
- max-width: calc(3.5rem + var(--bs-border-width)*2)
557
+ max-width: calc(3.5rem + var(--bs-border-width) * 2)
507
558
  }
508
559
  ```
509
560
 
@@ -528,6 +579,7 @@ const css = `
528
579
  const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
529
580
 
530
581
  ```
582
+
531
583
  result
532
584
 
533
585
  ```css
@@ -558,6 +610,7 @@ const css = `
558
610
  const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
559
611
 
560
612
  ```
613
+
561
614
  result
562
615
 
563
616
  ```css
@@ -566,6 +619,7 @@ result
566
619
  }
567
620
 
568
621
  ```
622
+
569
623
  ### CSS variable inlining and relative color
570
624
 
571
625
  ```javascript
@@ -583,6 +637,7 @@ html { --bluegreen: oklab(54.3% -22.5% -5%); }
583
637
  const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
584
638
 
585
639
  ```
640
+
586
641
  result
587
642
 
588
643
  ```css
@@ -598,7 +653,7 @@ result
598
653
  import {walk} from '@tbela99/css-parser';
599
654
 
600
655
  for (const {node, parent, root} of walk(ast)) {
601
-
656
+
602
657
  // do something
603
658
  }
604
659
  ```
@@ -607,7 +662,7 @@ for (const {node, parent, root} of walk(ast)) {
607
662
 
608
663
  ### Comment
609
664
 
610
- - typ: number
665
+ - typ: number
611
666
  - val: string, the comment
612
667
 
613
668
  ### Declaration
@@ -825,7 +880,7 @@ const options: ParserOptions = {
825
880
  visitor: {
826
881
 
827
882
  AtRule: (node: AstAtRule): AstAtRule => {
828
-
883
+
829
884
  if (node.nam == 'media') {
830
885
 
831
886
  return {...node, val: 'all'}
@@ -905,7 +960,7 @@ const options: ParserOptions = {
905
960
  visitor: {
906
961
 
907
962
 
908
- Rule (node: AstRule): AstRule {
963
+ Rule(node: AstRule): AstRule {
909
964
 
910
965
  return {...node, sel: '.foo,.bar,.fubar'};
911
966
  }
@@ -925,6 +980,7 @@ console.debug(await transform(css, options));
925
980
  // .foo,.bar,.fubar{height:calc(40px/3)}
926
981
 
927
982
  ```
983
+
928
984
  ### Exemple 6: Rule
929
985
 
930
986
  Adding declarations to any rule