@tbela99/css-parser 0.2.0 → 0.4.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 (57) hide show
  1. package/{LICENSE → LICENSE.md} +1 -1
  2. package/README.md +250 -77
  3. package/dist/config.json.js +245 -1
  4. package/dist/index-umd-web.js +4241 -1583
  5. package/dist/index.cjs +4242 -1584
  6. package/dist/index.d.ts +71 -23
  7. package/dist/lib/ast/expand.js +1 -1
  8. package/dist/lib/ast/features/calc.js +31 -192
  9. package/dist/lib/ast/features/index.js +3 -3
  10. package/dist/lib/ast/features/inlinecssvariables.js +6 -6
  11. package/dist/lib/ast/features/shorthand.js +5 -6
  12. package/dist/lib/ast/math/expression.js +220 -0
  13. package/dist/lib/ast/{features/utils → math}/math.js +4 -4
  14. package/dist/lib/ast/minify.js +0 -1
  15. package/dist/lib/ast/types.js +31 -13
  16. package/dist/lib/ast/utils/minifyfeature.js +4 -3
  17. package/dist/lib/ast/walk.js +24 -4
  18. package/dist/lib/fs/resolve.js +4 -3
  19. package/dist/lib/parser/declaration/list.js +6 -2
  20. package/dist/lib/parser/declaration/map.js +158 -24
  21. package/dist/lib/parser/declaration/set.js +42 -22
  22. package/dist/lib/parser/parse.js +345 -349
  23. package/dist/lib/parser/tokenize.js +220 -223
  24. package/dist/lib/parser/utils/declaration.js +67 -0
  25. package/dist/lib/parser/utils/syntax.js +172 -6
  26. package/dist/lib/parser/utils/type.js +2 -2
  27. package/dist/lib/renderer/color/a98rgb.js +64 -0
  28. package/dist/lib/renderer/color/color.js +521 -0
  29. package/dist/lib/renderer/color/colormix.js +337 -0
  30. package/dist/lib/renderer/color/hex.js +92 -0
  31. package/dist/lib/renderer/color/hsl.js +118 -0
  32. package/dist/lib/renderer/color/hsv.js +20 -0
  33. package/dist/lib/renderer/color/hwb.js +101 -0
  34. package/dist/lib/renderer/color/lab.js +136 -0
  35. package/dist/lib/renderer/color/lch.js +79 -0
  36. package/dist/lib/renderer/color/oklab.js +121 -0
  37. package/dist/lib/renderer/color/oklch.js +65 -0
  38. package/dist/lib/renderer/color/p3.js +57 -0
  39. package/dist/lib/renderer/color/prophotorgb.js +56 -0
  40. package/dist/lib/renderer/color/rec2020.js +70 -0
  41. package/dist/lib/renderer/color/relativecolor.js +152 -0
  42. package/dist/lib/renderer/color/rgb.js +44 -0
  43. package/dist/lib/renderer/color/srgb.js +261 -0
  44. package/dist/lib/renderer/color/utils/components.js +20 -0
  45. package/dist/lib/renderer/color/utils/constants.js +191 -0
  46. package/dist/lib/renderer/color/utils/matrix.js +35 -0
  47. package/dist/lib/renderer/color/xyz.js +64 -0
  48. package/dist/lib/renderer/color/xyzd50.js +33 -0
  49. package/dist/lib/renderer/render.js +128 -30
  50. package/dist/node/index.js +1 -1
  51. package/dist/node/load.js +1 -1
  52. package/dist/web/index.js +1 -1
  53. package/package.json +19 -18
  54. package/quickjs.sh +1 -0
  55. package/dist/lib/iterable/weakmap.js +0 -53
  56. package/dist/lib/renderer/utils/color.js +0 -499
  57. /package/dist/lib/iterable/{set.js → weakset.js} +0 -0
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2023 Thierry Bela
3
+ Copyright (c) 2024 Thierry Bela
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,4 +1,4 @@
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)
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)
2
2
 
3
3
  # css-parser
4
4
 
@@ -12,16 +12,98 @@ $ npm install @tbela99/css-parser
12
12
 
13
13
  ## Features
14
14
 
15
+ - no dependency
15
16
  - fault-tolerant parser, will try to fix invalid tokens according to the CSS syntax module 3 recommendations.
16
- - efficient minification, see [benchmark](https://tbela99.github.io/css-parser/benchmark/index.html)
17
- - automatically generate nested css rules
17
+ - efficient minification without unsafe transforms, see [benchmark](https://tbela99.github.io/css-parser/benchmark/index.html)
18
+ - minify colors.
19
+ - support css color level 4 & 5: color(), lab(), lch(), oklab(), oklch(), color-mix() and relative color
20
+ - generate nested css rules
21
+ - convert nested css rules to legacy syntax
18
22
  - generate sourcemap
19
- - compute css shorthands. see the list below
20
- - compute calc() expression
21
- - nested css expansion
23
+ - compute css shorthands. see supported properties list below
24
+ - evaluate calc()
25
+ - inline css variables
22
26
  - remove duplicate properties
23
27
  - flatten @import rules
24
- - works the same way in node and web browser
28
+
29
+ ## Exports
30
+
31
+ There are several ways to import the library into your application.
32
+
33
+ ### Node exports
34
+
35
+ import as a module
36
+
37
+ ```javascript
38
+
39
+ import {transform} from '@tbela99/css-parser';
40
+
41
+ // ...
42
+ ```
43
+ ### Deno exports
44
+
45
+ import as a module
46
+
47
+ ```javascript
48
+
49
+ import {transform} from 'npm:@tbela99/css-parser';
50
+
51
+ // ...
52
+ ```
53
+ import as a CommonJS module
54
+
55
+ ```javascript
56
+
57
+ const {transform} = require('@tbela99/css-parser/cjs');
58
+
59
+ // ...
60
+ ```
61
+
62
+ ### Web export
63
+
64
+ Programmatic import
65
+
66
+ ```javascript
67
+
68
+ import {transform} from '@tbela99/css-parser/web';
69
+
70
+ // ...
71
+ ```
72
+
73
+ Javascript module from cdn
74
+
75
+ ```javascript
76
+
77
+ <script type="module">
78
+
79
+ import {transform} from 'https://esm.sh/@tbela99/css-parser@0.4.0/web';
80
+
81
+
82
+ const css = `
83
+ .s {
84
+
85
+ background: color-mix(in hsl, color(display-p3 0 1 0) 80%, yellow);
86
+ }
87
+ `;
88
+
89
+ console.debug(await transform(css).then(r => r.code));
90
+
91
+ </script>
92
+ ```
93
+
94
+ Javascript module
95
+
96
+ ```javascript
97
+
98
+ <script src="dist/web/index.js" type="module"></script>
99
+ ```
100
+
101
+ Single Javascript file
102
+
103
+ ```javascript
104
+
105
+ <script src="dist/index-umd-web.js"></script>
106
+ ```
25
107
 
26
108
  ## Transform
27
109
 
@@ -49,35 +131,49 @@ Include ParseOptions and RenderOptions
49
131
 
50
132
  #### ParseOptions
51
133
 
134
+ > Minify Options
52
135
  - minify: boolean, optional. default to _true_. optimize ast.
53
- - src: string, optional. original css file location to be used with sourcemap.
54
- - sourcemap: boolean, optional. preserve node location data.
55
136
  - nestingRules: boolean, optional. automatically generated nested rules.
56
137
  - expandNestingRules: boolean, optional. convert nesting rules into separate rules. will automatically set nestingRules to false.
57
- - removeCharset: boolean, optional. remove @charset.
58
- - removeEmpty: boolean, optional. remove empty rule lists from the ast.
59
- - resolveUrls: boolean, optional. resolve css 'url()' according to the parameters 'src' and 'cwd'
60
- - resolveImport: boolean, optional. replace @import rule by the content of its referenced stylesheet.
61
- - cwd: string, optional. the current working directory. when specified url() are resolved using this value
62
138
  - removeDuplicateDeclarations: boolean, optional. remove duplicate declarations.
63
139
  - computeShorthand: boolean, optional. compute shorthand properties.
64
140
  - inlineCssVariables: boolean, optional. replace css variables with their current value.
65
141
  - computeCalcExpression: boolean, optional. evaluate calc() expression
66
- - inlineCssVariables: boolean, optional. replace some css variables with their actual value. they must be declared once in the :root {} rule.
142
+ - inlineCssVariables: boolean, optional. replace some css variables with their actual value. they must be declared once in the :root {} or html {} rule.
143
+ - removeEmpty: boolean, optional. remove empty rule lists from the ast.
144
+
145
+ > Sourcemap Options
146
+
147
+ - src: string, optional. original css file location to be used with sourcemap.
148
+ - sourcemap: boolean, optional. preserve node location data.
149
+
150
+ > Misc Options
151
+
152
+ - resolveUrls: boolean, optional. resolve css 'url()' according to the parameters 'src' and 'cwd'
153
+ - resolveImport: boolean, optional. replace @import rule by the content of its referenced stylesheet.
154
+ - removeCharset: boolean, optional. remove @charset.
155
+ - cwd: string, optional. the current working directory. when specified url() are resolved using this value
67
156
  - visitor: VisitorNodeMap, optional. node visitor used to transform the ast.
68
157
  - signal: AbortSignal, optional. abort parsing.
69
158
 
70
159
  #### RenderOptions
71
160
 
161
+ > Minify Options
162
+
72
163
  - minify: boolean, optional. default to _true_. minify css output.
73
164
  - expandNestingRules: boolean, optional. expand nesting rules.
74
- - sourcemap: boolean, optional. generate sourcemap
75
165
  - preserveLicense: boolean, force preserving comments starting with '/\*!' when minify is enabled.
76
- - sourcemap: boolean, optional. generate sourcemap.
77
- - indent: string, optional. css indention string. uses space character by default.
78
- - newLine: string, optional. new line character.
79
166
  - removeComments: boolean, remove comments in generated css.
80
167
  - colorConvert: boolean, convert colors to hex.
168
+
169
+ > Sourcemap Options
170
+
171
+ - sourcemap: boolean, optional. generate sourcemap
172
+
173
+ > Misc Options
174
+
175
+ - indent: string, optional. css indention string. uses space character by default.
176
+ - newLine: string, optional. new line character.
81
177
  - output: string, optional. file where to store css. url() are resolved according to the specified value. no file is created though.
82
178
  - cwd: string, optional. value used as current working directory. when output is not provided, urls are resolved according to this value.
83
179
 
@@ -105,9 +201,12 @@ const {ast, errors, stats} = await parse(css);
105
201
  render(ast, RenderOptions = {});
106
202
  ```
107
203
 
108
- ### Example
204
+ ### Examples
205
+
206
+ Rendering ast
109
207
 
110
208
  ```javascript
209
+
111
210
  import {render} from '@tbela99/css-parser';
112
211
 
113
212
  // minified
@@ -116,67 +215,39 @@ const {code, stats} = render(ast, {minify: true});
116
215
  console.log(code);
117
216
  ```
118
217
 
119
- ## Node Walker
120
-
121
- ```javascript
122
- import {walk} from '@tbela99/css-parser';
218
+ ### Merge similar rules
123
219
 
124
- for (const {node, parent, root} of walk(ast)) {
125
-
126
- // do somehting
127
- }
128
- ```
129
-
130
- ## Exports
131
-
132
- There are several ways to import the library into your application.
133
-
134
- ### Node exports
135
-
136
- import as a module
137
-
138
- ```javascript
139
-
140
- import {transform} from '@tbela99/css-parser';
220
+ CSS
141
221
 
142
- // ...
143
- ```
144
- import as a CommonJS module
222
+ ```css
145
223
 
146
- ```javascript
224
+ .clear {
225
+ width: 0;
226
+ height: 0;
227
+ color: transparent;
228
+ }
147
229
 
148
- const {transform} = require('@tbela99/css-parser/cjs');
230
+ .clearfix:before {
149
231
 
150
- // ...
232
+ height: 0;
233
+ width: 0;
234
+ }
151
235
  ```
152
236
 
153
- ### Web export
154
-
155
- Programmatic import
156
-
157
237
  ```javascript
158
238
 
159
- import {transform} from '@tbela99/css-parser/web';
160
-
161
- // ...
162
- ```
163
-
164
- Javascript module
239
+ import {transform} from '@tbela99/css-parser';
165
240
 
166
- ```javascript
241
+ const result = await transform(css);
167
242
 
168
- <script src="dist/web/index.js" type="module"></script>
169
243
  ```
170
244
 
171
- Single JavaScript file
172
-
173
- ```javascript
245
+ Result
174
246
 
175
- <script src="dist/index-umd-web.js"></script>
247
+ ```css
248
+ .clear,.clearfix:before{height:0;width:0}.clear{color:#0000}
176
249
  ```
177
250
 
178
- ## Example 1
179
-
180
251
  ### Automatic CSS Nesting
181
252
 
182
253
  CSS
@@ -224,8 +295,6 @@ table.colortable {
224
295
  }
225
296
  ```
226
297
 
227
- ## Example 2
228
-
229
298
  ### Nested CSS Expansion
230
299
 
231
300
  CSS
@@ -248,14 +317,12 @@ table.colortable {
248
317
  }
249
318
  }
250
319
  ```
251
-
252
320
  Javascript
321
+
253
322
  ```javascript
254
323
  import {parse, render} from '@tbela99/css-parser';
255
324
 
256
-
257
325
  const options = {minify: true};
258
-
259
326
  const {code} = await parse(css, options).then(result => render(result.ast, {minify: false, expandNestingRules: true}));
260
327
  //
261
328
  console.debug(code);
@@ -281,8 +348,6 @@ table.colortable th {
281
348
  }
282
349
  ```
283
350
 
284
- ### Example 3
285
-
286
351
  ### Calc() resolution
287
352
 
288
353
  ```javascript
@@ -311,8 +376,6 @@ result
311
376
  }
312
377
  ```
313
378
 
314
- ### Example 4
315
-
316
379
  ### CSS variable inlining
317
380
 
318
381
  ```javascript
@@ -344,6 +407,46 @@ result
344
407
 
345
408
  ```
346
409
 
410
+ ### CSS variable inlining and relative color
411
+
412
+ ```javascript
413
+
414
+ import {parse, render} from '@tbela99/css-parser';
415
+
416
+ const css = `
417
+
418
+ :root {
419
+ --color: green;
420
+ }
421
+ ._19_u :focus {
422
+ color: hsl(from var(--color) calc(h * 2) s l);
423
+
424
+ }
425
+ `
426
+
427
+ const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
428
+
429
+ ```
430
+ result
431
+
432
+ ```css
433
+ ._19_u :focus {
434
+ color: navy
435
+ }
436
+
437
+ ```
438
+
439
+ ## Node Walker
440
+
441
+ ```javascript
442
+ import {walk} from '@tbela99/css-parser';
443
+
444
+ for (const {node, parent, root} of walk(ast)) {
445
+
446
+ // do something
447
+ }
448
+ ```
449
+
347
450
  ## AST
348
451
 
349
452
  ### Comment
@@ -396,24 +499,53 @@ result
396
499
  - [x] decode and replace utf-8 escape sequence
397
500
 
398
501
  ## Computed shorthands properties
502
+
503
+ - ~all~
399
504
  - [x] animation
400
505
  - [x] background
401
506
  - [x] border
507
+ - [ ] border-block-end
508
+ - [ ] border-block-start
402
509
  - [x] border-bottom
403
510
  - [x] border-color
511
+ - [ ] border-image
512
+ - [ ] border-inline-end
513
+ - [ ] border-inline-start
404
514
  - [x] border-left
405
515
  - [x] border-radius
406
516
  - [x] border-right
407
517
  - [x] border-style
408
518
  - [x] border-top
409
519
  - [x] border-width
520
+ - [x] column-rule
521
+ - [x] columns
522
+ - [x] container
523
+ - [ ] contain-intrinsic-size
524
+ - [x] flex
525
+ - [x] flex-flow
410
526
  - [x] font
527
+ - [ ] font-synthesis
528
+ - [ ] font-variant
529
+ - [x] gap
530
+ - [ ] grid
531
+ - [ ] grid-area
532
+ - [ ] grid-column
533
+ - [ ] grid-row
534
+ - [ ] grid-template
411
535
  - [x] inset
412
536
  - [x] list-style
413
537
  - [x] margin
538
+ - [ ] mask
539
+ - [ ] offset
414
540
  - [x] outline
415
541
  - [x] overflow
416
542
  - [x] padding
543
+ - [ ] place-content
544
+ - [ ] place-items
545
+ - [ ] place-self
546
+ - [ ] scroll-margin
547
+ - [ ] scroll-padding
548
+ - [ ] scroll-timeline
417
549
  - [x] text-decoration
418
550
  - [x] text-emphasis
419
551
  - [x] transition
@@ -463,7 +595,7 @@ console.debug(await transform(css, options));
463
595
  ```typescript
464
596
 
465
597
  import {AstDeclaration, LengthToken, ParserOptions} from "../src/@types";
466
- import {EnumToken, NodeType} from "../src/lib";
598
+ import {EnumToken, EnumToken} from "../src/lib";
467
599
  import {transform} from "../src/node";
468
600
 
469
601
  const options: ParserOptions = {
@@ -480,7 +612,7 @@ const options: ParserOptions = {
480
612
  node,
481
613
  {
482
614
 
483
- typ: NodeType.DeclarationNodeType,
615
+ typ: EnumToken.DeclarationNodeType,
484
616
  nam: 'width',
485
617
  val: [
486
618
  <LengthToken>{
@@ -501,11 +633,14 @@ const css = `
501
633
  .foo {
502
634
  height: calc(100px * 2/ 15);
503
635
  }
636
+ .selector {
637
+ color: lch(from peru calc(l * 0.8) calc(c * 0.7) calc(h + 180))
638
+ }
504
639
  `;
505
640
 
506
641
  console.debug(await transform(css, options));
507
642
 
508
- // .foo{height:calc(40px/3);width:3px}
643
+ // .foo{height:calc(40px/3);width:3px}.selector{color:#0880b0}
509
644
 
510
645
  ```
511
646
 
@@ -617,6 +752,44 @@ console.debug(await transform(css, options));
617
752
 
618
753
  // .foo,.bar,.fubar{height:calc(40px/3)}
619
754
 
755
+ ```
756
+ ### Exemple 6: Rule
757
+
758
+ Adding declarations
759
+
760
+ ```typescript
761
+ import {transform} from "../src/node";
762
+ import {AstRule, ParserOptions} from "../src/@types";
763
+ import {parseDeclarations} from "../src/lib";
764
+
765
+ const options: ParserOptions = {
766
+
767
+ removeEmpty: false,
768
+ visitor: {
769
+
770
+ Rule: async (node: AstRule): Promise<AstRule | null> => {
771
+
772
+ if (node.sel == '.foo') {
773
+
774
+ node.chi.push(...await parseDeclarations('width: 3px'));
775
+ return node;
776
+ }
777
+
778
+ return null;
779
+ }
780
+ }
781
+ };
782
+
783
+ const css = `
784
+
785
+ .foo {
786
+ }
787
+ `;
788
+
789
+ console.debug(await transform(css, options));
790
+
791
+ // .foo{width:3px}
792
+
620
793
  ```
621
794
 
622
795
  ---