@tbela99/css-parser 0.0.1 → 0.2.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.
- package/README.md +318 -34
- package/dist/config.json.js +386 -4
- package/dist/index-umd-web.js +3260 -1563
- package/dist/index.cjs +3259 -1564
- package/dist/index.d.ts +687 -536
- package/dist/lib/ast/expand.js +14 -14
- package/dist/lib/ast/features/calc.js +225 -0
- package/dist/lib/ast/features/index.js +3 -0
- package/dist/lib/ast/features/inlinecssvariables.js +130 -0
- package/dist/lib/ast/features/shorthand.js +46 -0
- package/dist/lib/ast/features/utils/math.js +95 -0
- package/dist/lib/ast/minify.js +401 -372
- package/dist/lib/ast/types.js +101 -0
- package/dist/lib/ast/utils/minifyfeature.js +8 -0
- package/dist/lib/ast/walk.js +37 -9
- package/dist/lib/iterable/set.js +48 -0
- package/dist/lib/iterable/weakmap.js +53 -0
- package/dist/lib/parser/declaration/list.js +18 -4
- package/dist/lib/parser/declaration/map.js +102 -33
- package/dist/lib/parser/declaration/set.js +18 -12
- package/dist/lib/parser/parse.js +661 -421
- package/dist/lib/parser/tokenize.js +82 -46
- package/dist/lib/parser/utils/syntax.js +13 -10
- package/dist/lib/parser/utils/type.js +23 -6
- package/dist/lib/renderer/render.js +253 -84
- package/dist/lib/renderer/sourcemap/lib/encode.js +37 -0
- package/dist/lib/renderer/sourcemap/sourcemap.js +58 -0
- package/dist/lib/renderer/utils/color.js +25 -20
- package/dist/node/index.js +30 -15
- package/dist/web/index.js +36 -19
- package/package.json +9 -6
- package/dist/lib/transform.js +0 -24
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# css-parser
|
|
4
4
|
|
|
5
|
-
CSS parser for node and the browser
|
|
5
|
+
CSS parser and minifier for node and the browser
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -12,11 +12,15 @@ $ npm install @tbela99/css-parser
|
|
|
12
12
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
15
|
-
- fault
|
|
15
|
+
- fault-tolerant parser, will try to fix invalid tokens according to the CSS syntax module 3 recommendations.
|
|
16
16
|
- efficient minification, see [benchmark](https://tbela99.github.io/css-parser/benchmark/index.html)
|
|
17
17
|
- automatically generate nested css rules
|
|
18
|
+
- generate sourcemap
|
|
18
19
|
- compute css shorthands. see the list below
|
|
19
|
-
-
|
|
20
|
+
- compute calc() expression
|
|
21
|
+
- nested css expansion
|
|
22
|
+
- remove duplicate properties
|
|
23
|
+
- flatten @import rules
|
|
20
24
|
- works the same way in node and web browser
|
|
21
25
|
|
|
22
26
|
## Transform
|
|
@@ -25,9 +29,9 @@ Parse and render css in a single pass.
|
|
|
25
29
|
|
|
26
30
|
### Usage
|
|
27
31
|
|
|
28
|
-
```
|
|
32
|
+
```typescript
|
|
29
33
|
|
|
30
|
-
transform(css, transformOptions = {})
|
|
34
|
+
transform(css, transformOptions: TransformOptions = {}): TransformResult
|
|
31
35
|
```
|
|
32
36
|
|
|
33
37
|
### Example
|
|
@@ -36,7 +40,7 @@ transform(css, transformOptions = {})
|
|
|
36
40
|
|
|
37
41
|
import {transform} from '@tbela99/css-parser';
|
|
38
42
|
|
|
39
|
-
const {ast, code, errors, stats} = await transform(css, {minify: true, resolveImport: true, cwd: 'files/css'});
|
|
43
|
+
const {ast, code, map, errors, stats} = await transform(css, {minify: true, resolveImport: true, cwd: 'files/css'});
|
|
40
44
|
```
|
|
41
45
|
|
|
42
46
|
### TransformOptions
|
|
@@ -45,23 +49,37 @@ Include ParseOptions and RenderOptions
|
|
|
45
49
|
|
|
46
50
|
#### ParseOptions
|
|
47
51
|
|
|
48
|
-
- src: string, optional. css file location to be used with sourcemap.
|
|
49
52
|
- 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.
|
|
50
55
|
- nestingRules: boolean, optional. automatically generated nested rules.
|
|
51
|
-
-
|
|
52
|
-
-
|
|
56
|
+
- 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.
|
|
53
61
|
- cwd: string, optional. the current working directory. when specified url() are resolved using this value
|
|
54
|
-
-
|
|
55
|
-
-
|
|
62
|
+
- removeDuplicateDeclarations: boolean, optional. remove duplicate declarations.
|
|
63
|
+
- computeShorthand: boolean, optional. compute shorthand properties.
|
|
64
|
+
- inlineCssVariables: boolean, optional. replace css variables with their current value.
|
|
65
|
+
- 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.
|
|
67
|
+
- visitor: VisitorNodeMap, optional. node visitor used to transform the ast.
|
|
68
|
+
- signal: AbortSignal, optional. abort parsing.
|
|
56
69
|
|
|
57
70
|
#### RenderOptions
|
|
71
|
+
|
|
58
72
|
- minify: boolean, optional. default to _true_. minify css output.
|
|
73
|
+
- expandNestingRules: boolean, optional. expand nesting rules.
|
|
74
|
+
- sourcemap: boolean, optional. generate sourcemap
|
|
75
|
+
- preserveLicense: boolean, force preserving comments starting with '/\*!' when minify is enabled.
|
|
76
|
+
- sourcemap: boolean, optional. generate sourcemap.
|
|
59
77
|
- indent: string, optional. css indention string. uses space character by default.
|
|
60
|
-
- newLine: string, new line character.
|
|
78
|
+
- newLine: string, optional. new line character.
|
|
61
79
|
- removeComments: boolean, remove comments in generated css.
|
|
62
|
-
- preserveLicense: boolean, force preserving comments starting with '/\*!' when minify is enabled.
|
|
63
80
|
- colorConvert: boolean, convert colors to hex.
|
|
64
|
-
|
|
81
|
+
- output: string, optional. file where to store css. url() are resolved according to the specified value. no file is created though.
|
|
82
|
+
- cwd: string, optional. value used as current working directory. when output is not provided, urls are resolved according to this value.
|
|
65
83
|
|
|
66
84
|
## Parsing
|
|
67
85
|
|
|
@@ -163,34 +181,27 @@ Single JavaScript file
|
|
|
163
181
|
|
|
164
182
|
CSS
|
|
165
183
|
|
|
166
|
-
```
|
|
184
|
+
```javascript
|
|
185
|
+
const {parse, render} = require("@tbela99/css-parser/cjs");
|
|
167
186
|
|
|
187
|
+
const css = `
|
|
168
188
|
table.colortable td {
|
|
169
|
-
|
|
189
|
+
text-align:center;
|
|
170
190
|
}
|
|
171
191
|
table.colortable td.c {
|
|
172
|
-
|
|
192
|
+
text-transform:uppercase;
|
|
173
193
|
}
|
|
174
194
|
table.colortable td:first-child, table.colortable td:first-child+td {
|
|
175
|
-
|
|
195
|
+
border:1px solid black;
|
|
176
196
|
}
|
|
177
197
|
table.colortable th {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
198
|
+
text-align:center;
|
|
199
|
+
background:black;
|
|
200
|
+
color:white;
|
|
181
201
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
Javascript
|
|
185
|
-
```javascript
|
|
186
|
-
import {parse, render} from '@tbela99/css-parser';
|
|
202
|
+
`;
|
|
187
203
|
|
|
188
|
-
|
|
189
|
-
const options = {minify: true, nestingRules: true};
|
|
190
|
-
|
|
191
|
-
const {code} = await parse(css, options).then(result => render(result.ast, {minify: false}));
|
|
192
|
-
//
|
|
193
|
-
console.debug(code);
|
|
204
|
+
const result = await parse(css, {nestingRules:true}).then(result => render(result.ast, {minify:false}).code);
|
|
194
205
|
```
|
|
195
206
|
|
|
196
207
|
Result
|
|
@@ -270,6 +281,69 @@ table.colortable th {
|
|
|
270
281
|
}
|
|
271
282
|
```
|
|
272
283
|
|
|
284
|
+
### Example 3
|
|
285
|
+
|
|
286
|
+
### Calc() resolution
|
|
287
|
+
|
|
288
|
+
```javascript
|
|
289
|
+
|
|
290
|
+
import {parse, render} from '@tbela99/css-parser';
|
|
291
|
+
|
|
292
|
+
const css = `
|
|
293
|
+
|
|
294
|
+
.foo-bar {
|
|
295
|
+
width: calc(100px * 2);
|
|
296
|
+
height: calc(((75.37% - 63.5px) - 900px) + (2 * 100px));
|
|
297
|
+
max-width: calc(3.5rem + calc(var(--bs-border-width) * 2));
|
|
298
|
+
}
|
|
299
|
+
`;
|
|
300
|
+
|
|
301
|
+
const prettyPrint = await parse(css).then(result => render(result.ast, {minify: false}).code);
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
result
|
|
305
|
+
|
|
306
|
+
```css
|
|
307
|
+
.foo-bar {
|
|
308
|
+
width: 200px;
|
|
309
|
+
height: calc(75.37% - 763.5px);
|
|
310
|
+
max-width: calc(3.5rem + var(--bs-border-width)*2)
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Example 4
|
|
315
|
+
|
|
316
|
+
### CSS variable inlining
|
|
317
|
+
|
|
318
|
+
```javascript
|
|
319
|
+
|
|
320
|
+
import {parse, render} from '@tbela99/css-parser';
|
|
321
|
+
|
|
322
|
+
const css = `
|
|
323
|
+
|
|
324
|
+
:root {
|
|
325
|
+
|
|
326
|
+
--preferred-width: 20px;
|
|
327
|
+
}
|
|
328
|
+
.foo-bar {
|
|
329
|
+
|
|
330
|
+
width: calc(calc(var(--preferred-width) + 1px) / 3 + 5px);
|
|
331
|
+
height: calc(100% / 4);}
|
|
332
|
+
`
|
|
333
|
+
|
|
334
|
+
const prettyPrint = await parse(css, {inlineCssVariables: true}).then(result => render(result.ast, {minify: false}).code);
|
|
335
|
+
|
|
336
|
+
```
|
|
337
|
+
result
|
|
338
|
+
|
|
339
|
+
```css
|
|
340
|
+
.foo-bar {
|
|
341
|
+
width: 12px;
|
|
342
|
+
height: 25%
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
```
|
|
346
|
+
|
|
273
347
|
## AST
|
|
274
348
|
|
|
275
349
|
### Comment
|
|
@@ -300,8 +374,14 @@ table.colortable th {
|
|
|
300
374
|
- typ: string 'Stylesheet'
|
|
301
375
|
- chi: array of children
|
|
302
376
|
|
|
377
|
+
## Sourcemap
|
|
378
|
+
|
|
379
|
+
- [x] sourcemap generation
|
|
380
|
+
|
|
303
381
|
## Minification
|
|
304
382
|
|
|
383
|
+
- [x] reduce calc()
|
|
384
|
+
- [x] inline css variables
|
|
305
385
|
- [x] merge identical rules
|
|
306
386
|
- [x] merge adjacent rules
|
|
307
387
|
- [x] minify colors
|
|
@@ -311,12 +391,12 @@ table.colortable th {
|
|
|
311
391
|
- [x] conditionally unwrap :is()
|
|
312
392
|
- [x] automatic css nesting
|
|
313
393
|
- [x] automatically wrap selectors using :is()
|
|
314
|
-
- [x] multi-level shorthand properties (border - [border-width, border-color, border-style, etc.]) https://developer.mozilla.org/en-US/docs/Web/CSS/Shorthand_properties
|
|
315
394
|
- [x] avoid reparsing (declarations, selectors, at-rule)
|
|
316
395
|
- [x] node and browser versions
|
|
317
396
|
- [x] decode and replace utf-8 escape sequence
|
|
318
397
|
|
|
319
|
-
## Computed shorthands
|
|
398
|
+
## Computed shorthands properties
|
|
399
|
+
- [x] animation
|
|
320
400
|
- [x] background
|
|
321
401
|
- [x] border
|
|
322
402
|
- [x] border-bottom
|
|
@@ -329,12 +409,216 @@ table.colortable th {
|
|
|
329
409
|
- [x] border-width
|
|
330
410
|
- [x] font
|
|
331
411
|
- [x] inset
|
|
412
|
+
- [x] list-style
|
|
332
413
|
- [x] margin
|
|
333
414
|
- [x] outline
|
|
334
415
|
- [x] overflow
|
|
335
416
|
- [x] padding
|
|
336
417
|
- [x] text-decoration
|
|
418
|
+
- [x] text-emphasis
|
|
419
|
+
- [x] transition
|
|
337
420
|
|
|
338
421
|
## Performance
|
|
339
422
|
|
|
340
423
|
- [x] flatten @import
|
|
424
|
+
|
|
425
|
+
## Node Transformation
|
|
426
|
+
|
|
427
|
+
Ast can be transformed using node visitors
|
|
428
|
+
|
|
429
|
+
### Exemple 1: Declaration
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
|
|
433
|
+
import {AstDeclaration, ParserOptions} from "../src/@types";
|
|
434
|
+
|
|
435
|
+
const options: ParserOptions = {
|
|
436
|
+
|
|
437
|
+
visitor: {
|
|
438
|
+
|
|
439
|
+
Declaration: (node: AstDeclaration) => {
|
|
440
|
+
|
|
441
|
+
if (node.nam == '-webkit-transform') {
|
|
442
|
+
|
|
443
|
+
node.nam = 'transform'
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const css = `
|
|
450
|
+
|
|
451
|
+
.foo {
|
|
452
|
+
-webkit-transform: scale(calc(100 * 2/ 15));
|
|
453
|
+
}
|
|
454
|
+
`;
|
|
455
|
+
|
|
456
|
+
console.debug(await transform(css, options));
|
|
457
|
+
|
|
458
|
+
// .foo{transform:scale(calc(40/3))}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Exemple 2: Declaration
|
|
462
|
+
|
|
463
|
+
```typescript
|
|
464
|
+
|
|
465
|
+
import {AstDeclaration, LengthToken, ParserOptions} from "../src/@types";
|
|
466
|
+
import {EnumToken, NodeType} from "../src/lib";
|
|
467
|
+
import {transform} from "../src/node";
|
|
468
|
+
|
|
469
|
+
const options: ParserOptions = {
|
|
470
|
+
|
|
471
|
+
visitor: {
|
|
472
|
+
|
|
473
|
+
Declaration: {
|
|
474
|
+
|
|
475
|
+
// called only for height declaration
|
|
476
|
+
height: (node: AstDeclaration): AstDeclaration[] => {
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
return [
|
|
480
|
+
node,
|
|
481
|
+
{
|
|
482
|
+
|
|
483
|
+
typ: NodeType.DeclarationNodeType,
|
|
484
|
+
nam: 'width',
|
|
485
|
+
val: [
|
|
486
|
+
<LengthToken>{
|
|
487
|
+
typ: EnumToken.Length,
|
|
488
|
+
val: '3',
|
|
489
|
+
unit: 'px'
|
|
490
|
+
}
|
|
491
|
+
]
|
|
492
|
+
}
|
|
493
|
+
];
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
const css = `
|
|
500
|
+
|
|
501
|
+
.foo {
|
|
502
|
+
height: calc(100px * 2/ 15);
|
|
503
|
+
}
|
|
504
|
+
`;
|
|
505
|
+
|
|
506
|
+
console.debug(await transform(css, options));
|
|
507
|
+
|
|
508
|
+
// .foo{height:calc(40px/3);width:3px}
|
|
509
|
+
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
### Exemple 3: At-Rule
|
|
513
|
+
|
|
514
|
+
```typescript
|
|
515
|
+
|
|
516
|
+
import {AstAtRule, ParserOptions} from "../src/@types";
|
|
517
|
+
import {transform} from "../src/node";
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
const options: ParserOptions = {
|
|
521
|
+
|
|
522
|
+
visitor: {
|
|
523
|
+
|
|
524
|
+
AtRule: (node: AstAtRule): AstAtRule => {
|
|
525
|
+
|
|
526
|
+
if (node.nam == 'media') {
|
|
527
|
+
|
|
528
|
+
return {...node, val: 'all'}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
|
|
534
|
+
const css = `
|
|
535
|
+
|
|
536
|
+
@media screen {
|
|
537
|
+
|
|
538
|
+
.foo {
|
|
539
|
+
|
|
540
|
+
height: calc(100px * 2/ 15);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
`;
|
|
544
|
+
|
|
545
|
+
console.debug(await transform(css, options));
|
|
546
|
+
|
|
547
|
+
// .foo{height:calc(40px/3)}
|
|
548
|
+
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### Exemple 4: At-Rule
|
|
552
|
+
|
|
553
|
+
```typescript
|
|
554
|
+
|
|
555
|
+
import {AstAtRule, ParserOptions} from "../src/@types";
|
|
556
|
+
import {transform} from "../src/node";
|
|
557
|
+
|
|
558
|
+
const options: ParserOptions = {
|
|
559
|
+
|
|
560
|
+
visitor: {
|
|
561
|
+
|
|
562
|
+
AtRule: {
|
|
563
|
+
|
|
564
|
+
media: (node: AstAtRule): AstAtRule => {
|
|
565
|
+
|
|
566
|
+
return {...node, val: 'all'}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
const css = `
|
|
573
|
+
|
|
574
|
+
@media screen {
|
|
575
|
+
|
|
576
|
+
.foo {
|
|
577
|
+
|
|
578
|
+
height: calc(100px * 2/ 15);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
`;
|
|
582
|
+
|
|
583
|
+
console.debug(await transform(css, options));
|
|
584
|
+
|
|
585
|
+
// .foo{height:calc(40px/3)}
|
|
586
|
+
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
### Exemple 5: Rule
|
|
590
|
+
|
|
591
|
+
```typescript
|
|
592
|
+
|
|
593
|
+
import {AstAtRule, ParserOptions} from "../src/@types";
|
|
594
|
+
import {transform} from "../src/node";
|
|
595
|
+
|
|
596
|
+
const options: ParserOptions = {
|
|
597
|
+
|
|
598
|
+
visitor: {
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
Rule (node: AstRule): AstRule {
|
|
602
|
+
|
|
603
|
+
return {...node, sel: '.foo,.bar,.fubar'};
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
};
|
|
607
|
+
|
|
608
|
+
const css = `
|
|
609
|
+
|
|
610
|
+
.foo {
|
|
611
|
+
|
|
612
|
+
height: calc(100px * 2/ 15);
|
|
613
|
+
}
|
|
614
|
+
`;
|
|
615
|
+
|
|
616
|
+
console.debug(await transform(css, options));
|
|
617
|
+
|
|
618
|
+
// .foo,.bar,.fubar{height:calc(40px/3)}
|
|
619
|
+
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
624
|
+
Thanks to [Jetbrains](https://jetbrains.com) for sponsoring this project with a free license
|