@tbela99/css-parser 0.7.1 → 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 +136 -82
  2. package/dist/index-umd-web.js +6956 -51524
  3. package/dist/index.cjs +6955 -51528
  4. package/dist/index.d.ts +180 -65
  5. package/dist/lib/ast/expand.js +34 -9
  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 +16 -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 +4 -4
  77. package/dist/web/index.js +4 -0
  78. package/dist/web/load.js +1 -0
  79. package/package.json +15 -13
  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,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,22 @@ 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
167
  > Minify 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.
159
171
 
160
172
  > Sourcemap Options
161
173
 
@@ -177,6 +189,7 @@ Include ParseOptions and RenderOptions
177
189
 
178
190
  - minify: boolean, optional. default to _true_. minify css output.
179
191
  - withParents: boolean, optional. render this node and its parents.
192
+ - removeEmpty: boolean, optional. remove empty rule lists from the ast.
180
193
  - expandNestingRules: boolean, optional. expand nesting rules.
181
194
  - preserveLicense: boolean, force preserving comments starting with '/\*!' when minify is enabled.
182
195
  - removeComments: boolean, remove comments in generated css.
@@ -190,7 +203,8 @@ Include ParseOptions and RenderOptions
190
203
 
191
204
  - indent: string, optional. css indention string. uses space character by default.
192
205
  - 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.
206
+ - output: string, optional. file where to store css. url() are resolved according to the specified value. no file is
207
+ created though.
194
208
  - cwd: string, optional. destination directory used to resolve url().
195
209
 
196
210
  ## Parsing
@@ -255,15 +269,15 @@ CSS
255
269
  ```css
256
270
 
257
271
  .clear {
258
- width: 0;
259
- height: 0;
260
- color: transparent;
272
+ width: 0;
273
+ height: 0;
274
+ color: transparent;
261
275
  }
262
276
 
263
277
  .clearfix:before {
264
278
 
265
- height: 0;
266
- width: 0;
279
+ height: 0;
280
+ width: 0;
267
281
  }
268
282
  ```
269
283
 
@@ -278,7 +292,14 @@ const result = await transform(css);
278
292
  Result
279
293
 
280
294
  ```css
281
- .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
+ }
282
303
  ```
283
304
 
284
305
  ### Automatic CSS Nesting
@@ -305,26 +326,30 @@ table.colortable th {
305
326
  }
306
327
  `;
307
328
 
308
- 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);
309
330
  ```
310
331
 
311
332
  Result
333
+
312
334
  ```css
313
335
  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
- }
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
+ }
328
353
  }
329
354
  ```
330
355
 
@@ -335,62 +360,69 @@ CSS
335
360
  ```css
336
361
 
337
362
  #404 {
338
- --animate-duration: 1s;
363
+ --animate-duration: 1s;
339
364
  }
340
365
 
341
366
  .s, #404 {
342
- --animate-duration: 1s;
367
+ --animate-duration: 1s;
343
368
  }
344
369
 
345
370
  .s [type="text" {
346
- --animate-duration: 1s;
371
+ --animate-duration: 1s;
347
372
  }
348
373
 
349
- .s [type="text"]] {
350
- --animate-duration: 1s;
374
+ .s [type="text"]]
375
+ {
376
+ --animate-duration: 1s;
351
377
  }
352
378
 
353
379
  .s [type="text"] {
354
- --animate-duration: 1s;
380
+ --animate-duration: 1s;
355
381
  }
356
382
 
357
383
  .s [type="text" i] {
358
- --animate-duration: 1s;
384
+ --animate-duration: 1s;
359
385
  }
360
386
 
361
- .s [type="text" s] {
362
- --animate-duration: 1s;
387
+ .s [type="text" s]
388
+ {
389
+ --animate-duration: 1s
390
+ ;
363
391
  }
364
392
 
365
- .s [type="text" b] {
366
- --animate-duration: 1s;
393
+ .s [type="text" b]
394
+ {
395
+ --animate-duration: 1s;
367
396
  }
368
397
 
369
- .s [type="text" b], {
370
- --animate-duration: 1s;
398
+ .s [type="text" b],{
399
+ --animate-duration: 1s
400
+ ;
371
401
  }
372
402
 
373
- .s [type="text" b]+ {
374
- --animate-duration: 1s;
403
+ .s [type="text" b]
404
+ + {
405
+ --animate-duration: 1s;
375
406
  }
376
407
 
377
- .s [type="text" b]+ b {
378
- --animate-duration: 1s;
408
+ .s [type="text" b]
409
+ + b {
410
+ --animate-duration: 1s;
379
411
  }
380
412
 
381
- .s [type="text" i]+ b {
382
- --animate-duration: 1s;
413
+ .s [type="text" i] + b {
414
+ --animate-duration: 1s;
383
415
  }
384
416
 
385
417
 
386
- .s [type="text"())] {
387
- --animate-duration: 1s;
418
+ .s [type="text"())]{
419
+ --animate-duration: 1s;
388
420
  }
389
- .s() {
390
- --animate-duration: 1s;
421
+ .s(){
422
+ --animate-duration: 1s;
391
423
  }
392
424
  .s:focus {
393
- --animate-duration: 1s;
425
+ --animate-duration: 1s;
394
426
  }
395
427
  ```
396
428
 
@@ -398,6 +430,7 @@ with validation enabled
398
430
 
399
431
  ```javascript
400
432
  import {parse, render} from '@tbela99/css-parser';
433
+
401
434
  const options = {minify: true, validate: true};
402
435
  const {code} = await parse(css, options).then(result => render(result.ast, {minify: false}));
403
436
  //
@@ -406,7 +439,7 @@ console.debug(code);
406
439
 
407
440
  ```css
408
441
  .s:is([type=text],[type=text i],[type=text s],[type=text i]+b,:focus) {
409
- --animate-duration: 1s
442
+ --animate-duration: 1s
410
443
  }
411
444
  ```
412
445
 
@@ -414,6 +447,7 @@ with validation disabled
414
447
 
415
448
  ```javascript
416
449
  import {parse, render} from '@tbela99/css-parser';
450
+
417
451
  const options = {minify: true, validate: false};
418
452
  const {code} = await parse(css, options).then(result => render(result.ast, {minify: false}));
419
453
  //
@@ -432,22 +466,26 @@ CSS
432
466
 
433
467
  ```css
434
468
  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
- }
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
+ }
449
486
  }
450
487
  ```
488
+
451
489
  Javascript
452
490
 
453
491
  ```javascript
@@ -464,18 +502,21 @@ Result
464
502
  ```css
465
503
 
466
504
  table.colortable td {
467
- text-align:center;
505
+ text-align: center;
468
506
  }
507
+
469
508
  table.colortable td.c {
470
- text-transform:uppercase;
509
+ text-transform: uppercase;
471
510
  }
472
- table.colortable td:first-child, table.colortable td:first-child+td {
473
- border:1px solid black;
511
+
512
+ table.colortable td:first-child, table.colortable td:first-child + td {
513
+ border: 1px solid black;
474
514
  }
515
+
475
516
  table.colortable th {
476
- text-align:center;
477
- background:black;
478
- color:white;
517
+ text-align: center;
518
+ background: black;
519
+ color: white;
479
520
  }
480
521
  ```
481
522
 
@@ -486,7 +527,10 @@ table.colortable th {
486
527
  import {parse, render} from '@tbela99/css-parser';
487
528
 
488
529
  const css = `
530
+ a {
489
531
 
532
+ width: calc(100px * log(625, 5));
533
+ }
490
534
  .foo-bar {
491
535
  width: calc(100px * 2);
492
536
  height: calc(((75.37% - 63.5px) - 900px) + (2 * 100px));
@@ -497,13 +541,18 @@ const css = `
497
541
  const prettyPrint = await parse(css).then(result => render(result.ast, {minify: false}).code);
498
542
 
499
543
  ```
544
+
500
545
  result
501
546
 
502
547
  ```css
548
+ a {
549
+ width: 400px;
550
+ }
551
+
503
552
  .foo-bar {
504
553
  width: 200px;
505
554
  height: calc(75.37% - 763.5px);
506
- max-width: calc(3.5rem + var(--bs-border-width)*2)
555
+ max-width: calc(3.5rem + var(--bs-border-width) * 2)
507
556
  }
508
557
  ```
509
558
 
@@ -528,6 +577,7 @@ const css = `
528
577
  const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
529
578
 
530
579
  ```
580
+
531
581
  result
532
582
 
533
583
  ```css
@@ -558,6 +608,7 @@ const css = `
558
608
  const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
559
609
 
560
610
  ```
611
+
561
612
  result
562
613
 
563
614
  ```css
@@ -566,6 +617,7 @@ result
566
617
  }
567
618
 
568
619
  ```
620
+
569
621
  ### CSS variable inlining and relative color
570
622
 
571
623
  ```javascript
@@ -583,6 +635,7 @@ html { --bluegreen: oklab(54.3% -22.5% -5%); }
583
635
  const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
584
636
 
585
637
  ```
638
+
586
639
  result
587
640
 
588
641
  ```css
@@ -598,7 +651,7 @@ result
598
651
  import {walk} from '@tbela99/css-parser';
599
652
 
600
653
  for (const {node, parent, root} of walk(ast)) {
601
-
654
+
602
655
  // do something
603
656
  }
604
657
  ```
@@ -607,7 +660,7 @@ for (const {node, parent, root} of walk(ast)) {
607
660
 
608
661
  ### Comment
609
662
 
610
- - typ: number
663
+ - typ: number
611
664
  - val: string, the comment
612
665
 
613
666
  ### Declaration
@@ -825,7 +878,7 @@ const options: ParserOptions = {
825
878
  visitor: {
826
879
 
827
880
  AtRule: (node: AstAtRule): AstAtRule => {
828
-
881
+
829
882
  if (node.nam == 'media') {
830
883
 
831
884
  return {...node, val: 'all'}
@@ -905,7 +958,7 @@ const options: ParserOptions = {
905
958
  visitor: {
906
959
 
907
960
 
908
- Rule (node: AstRule): AstRule {
961
+ Rule(node: AstRule): AstRule {
909
962
 
910
963
  return {...node, sel: '.foo,.bar,.fubar'};
911
964
  }
@@ -925,6 +978,7 @@ console.debug(await transform(css, options));
925
978
  // .foo,.bar,.fubar{height:calc(40px/3)}
926
979
 
927
980
  ```
981
+
928
982
  ### Exemple 6: Rule
929
983
 
930
984
  Adding declarations to any rule