@@ -13,7 +13,7 @@ $ npm install @tbela99/css-parser
1313## Features
1414
1515- 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 ) , see [ benchmark ] ( https://tbela99.github.io/css-parser/benchmark/index.html )
16+ - efficient minification, see [ benchmark] ( https://tbela99.github.io/css-parser/benchmark/index.html )
1717- automatically generate nested css rules
1818- generate sourcemap
1919- compute css shorthands. see the list below
@@ -64,6 +64,8 @@ Include ParseOptions and RenderOptions
6464- inlineCssVariables: boolean, optional. replace css variables with their current value.
6565- computeCalcExpression: boolean, optional. evaluate calc() expression
6666- 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.
6769
6870#### RenderOptions
6971
@@ -100,7 +102,7 @@ const {ast, errors, stats} = await parse(css);
100102### Usage
101103
102104``` javascript
103- doRender (ast, RenderOptions = {});
105+ render (ast, RenderOptions = {});
104106```
105107
106108### Example
@@ -416,6 +418,203 @@ result
416418
417419- [x] flatten @import
418420
421+ ## Node Transformation
422+
423+ Ast can be transformed using node visitors
424+
425+ ### Exemple 1: Declaration
426+
427+ ``` typescript
428+
429+ import {AstDeclaration , ParserOptions } from " ../src/@types" ;
430+
431+ const options: ParserOptions = {
432+
433+ visitor: {
434+
435+ Declaration : (node : AstDeclaration ) => {
436+
437+ if (node .nam == ' -webkit-transform' ) {
438+
439+ node .nam = ' transform'
440+ }
441+ }
442+ }
443+ }
444+
445+ const css = `
446+
447+ .foo {
448+ -webkit-transform: scale(calc(100 * 2/ 15));
449+ }
450+ ` ;
451+
452+ console .debug (await transform (css , options ));
453+
454+ // .foo{transform:scale(calc(40/3))}
455+ ```
456+
457+ ### Exemple 2: Declaration
458+
459+ ``` typescript
460+
461+ import {AstDeclaration , LengthToken , ParserOptions } from " ../src/@types" ;
462+ import {EnumToken , NodeType } from " ../src/lib" ;
463+ import {transform } from " ../src/node" ;
464+
465+ const options: ParserOptions = {
466+
467+ visitor: {
468+
469+ Declaration: {
470+
471+ // called only for height declaration
472+ height : (node : AstDeclaration ): AstDeclaration [] => {
473+
474+
475+ return [
476+ node ,
477+ {
478+
479+ typ: NodeType .DeclarationNodeType ,
480+ nam: ' width' ,
481+ val: [
482+ <LengthToken >{
483+ typ: EnumToken .Length ,
484+ val: ' 3' ,
485+ unit: ' px'
486+ }
487+ ]
488+ }
489+ ];
490+ }
491+ }
492+ }
493+ };
494+
495+ const css = `
496+
497+ .foo {
498+ height: calc(100px * 2/ 15);
499+ }
500+ ` ;
501+
502+ console .debug (await transform (css , options ));
503+
504+ // .foo{height:calc(40px/3);width:3px}
505+
506+ ```
507+
508+ ### Exemple 3: At-Rule
509+
510+ ``` typescript
511+
512+ import {AstAtRule , ParserOptions } from " ../src/@types" ;
513+ import {transform } from " ../src/node" ;
514+
515+
516+ const options: ParserOptions = {
517+
518+ visitor: {
519+
520+ AtRule : (node : AstAtRule ): AstAtRule => {
521+
522+ if (node .nam == ' media' ) {
523+
524+ return {... node , val: ' all' }
525+ }
526+ }
527+ }
528+ };
529+
530+ const css = `
531+
532+ @media screen {
533+
534+ .foo {
535+
536+ height: calc(100px * 2/ 15);
537+ }
538+ }
539+ ` ;
540+
541+ console .debug (await transform (css , options ));
542+
543+ // .foo{height:calc(40px/3)}
544+
545+ ```
546+
547+ ### Exemple 4: At-Rule
548+
549+ ``` typescript
550+
551+ import {AstAtRule , ParserOptions } from " ../src/@types" ;
552+ import {transform } from " ../src/node" ;
553+
554+ const options: ParserOptions = {
555+
556+ visitor: {
557+
558+ AtRule: {
559+
560+ media : (node : AstAtRule ): AstAtRule => {
561+
562+ return {... node , val: ' all' }
563+ }
564+ }
565+ }
566+ };
567+
568+ const css = `
569+
570+ @media screen {
571+
572+ .foo {
573+
574+ height: calc(100px * 2/ 15);
575+ }
576+ }
577+ ` ;
578+
579+ console .debug (await transform (css , options ));
580+
581+ // .foo{height:calc(40px/3)}
582+
583+ ```
584+
585+ ### Exemple 5: Rule
586+
587+ ``` typescript
588+
589+ import {AstAtRule , ParserOptions } from " ../src/@types" ;
590+ import {transform } from " ../src/node" ;
591+
592+ const options: ParserOptions = {
593+
594+ visitor: {
595+
596+
597+ Rule (node : AstRule ): AstRule {
598+
599+ return {... node , sel: ' .foo,.bar,.fubar' };
600+ }
601+ }
602+ };
603+
604+ const css = `
605+
606+ .foo {
607+
608+ height: calc(100px * 2/ 15);
609+ }
610+ ` ;
611+
612+ console .debug (await transform (css , options ));
613+
614+ // .foo,.bar,.fubar{height:calc(40px/3)}
615+
616+ ```
617+
419618---
420619
421620Thanks to [ Jetbrains] ( https://jetbrains.com ) for sponsoring this project with a free license
0 commit comments