@tbela99/css-parser 0.7.0 → 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 +142 -81
  2. package/dist/index-umd-web.js +7027 -51519
  3. package/dist/index.cjs +7022 -51515
  4. package/dist/index.d.ts +189 -60
  5. package/dist/lib/ast/expand.js +87 -2
  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 +23 -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 +13 -0
  77. package/dist/web/index.js +13 -0
  78. package/dist/web/load.js +1 -0
  79. package/package.json +17 -15
  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/dist/index.d.ts CHANGED
@@ -38,57 +38,66 @@ declare enum EnumToken {
38
38
  WhitespaceTokenType = 36,
39
39
  IncludeMatchTokenType = 37,
40
40
  DashMatchTokenType = 38,
41
- LtTokenType = 39,
42
- LteTokenType = 40,
43
- GtTokenType = 41,
44
- GteTokenType = 42,
45
- PseudoClassTokenType = 43,
46
- PseudoClassFuncTokenType = 44,
47
- DelimTokenType = 45,
48
- UrlTokenTokenType = 46,
49
- EOFTokenType = 47,
50
- ImportantTokenType = 48,
51
- ColorTokenType = 49,
52
- AttrTokenType = 50,
53
- BadCommentTokenType = 51,
54
- BadCdoTokenType = 52,
55
- BadUrlTokenType = 53,
56
- BadStringTokenType = 54,
57
- BinaryExpressionTokenType = 55,
58
- UnaryExpressionTokenType = 56,
59
- FlexTokenType = 57,
60
- ListToken = 58,
61
- Add = 59,
62
- Mul = 60,
63
- Div = 61,
64
- Sub = 62,
65
- ColumnCombinatorTokenType = 63,
66
- ContainMatchTokenType = 64,
67
- StartMatchTokenType = 65,
68
- EndMatchTokenType = 66,
69
- MatchExpressionTokenType = 67,
70
- NameSpaceAttributeTokenType = 68,
71
- FractionTokenType = 69,
72
- IdenListTokenType = 70,
73
- GridTemplateFuncTokenType = 71,
74
- KeyFrameRuleNodeType = 72,
75
- ClassSelectorTokenType = 73,
76
- UniversalSelectorTokenType = 74,
77
- ChildCombinatorTokenType = 75,
78
- DescendantCombinatorTokenType = 76,// whitespace
79
- NextSiblingCombinatorTokenType = 77,
80
- SubsequentSiblingCombinatorTokenType = 78,
81
- NestingSelectorTokenType = 79,
82
- InvalidRuleTokenType = 80,
83
- InvalidClassSelectorTokenType = 81,
84
- InvalidAttrTokenType = 82,
41
+ EqualMatchTokenType = 39,
42
+ LtTokenType = 40,
43
+ LteTokenType = 41,
44
+ GtTokenType = 42,
45
+ GteTokenType = 43,
46
+ PseudoClassTokenType = 44,
47
+ PseudoClassFuncTokenType = 45,
48
+ DelimTokenType = 46,
49
+ UrlTokenTokenType = 47,
50
+ EOFTokenType = 48,
51
+ ImportantTokenType = 49,
52
+ ColorTokenType = 50,
53
+ AttrTokenType = 51,
54
+ BadCommentTokenType = 52,
55
+ BadCdoTokenType = 53,
56
+ BadUrlTokenType = 54,
57
+ BadStringTokenType = 55,
58
+ BinaryExpressionTokenType = 56,
59
+ UnaryExpressionTokenType = 57,
60
+ FlexTokenType = 58,
61
+ ListToken = 59,
62
+ Add = 60,
63
+ Mul = 61,
64
+ Div = 62,
65
+ Sub = 63,
66
+ ColumnCombinatorTokenType = 64,
67
+ ContainMatchTokenType = 65,
68
+ StartMatchTokenType = 66,
69
+ EndMatchTokenType = 67,
70
+ MatchExpressionTokenType = 68,
71
+ NameSpaceAttributeTokenType = 69,
72
+ FractionTokenType = 70,
73
+ IdenListTokenType = 71,
74
+ GridTemplateFuncTokenType = 72,
75
+ KeyFrameRuleNodeType = 73,
76
+ ClassSelectorTokenType = 74,
77
+ UniversalSelectorTokenType = 75,
78
+ ChildCombinatorTokenType = 76,// >
79
+ DescendantCombinatorTokenType = 77,// whitespace
80
+ NextSiblingCombinatorTokenType = 78,// +
81
+ SubsequentSiblingCombinatorTokenType = 79,// ~
82
+ NestingSelectorTokenType = 80,// &
83
+ InvalidRuleTokenType = 81,
84
+ InvalidClassSelectorTokenType = 82,
85
+ InvalidAttrTokenType = 83,
86
+ InvalidAtRuleTokenType = 84,
87
+ MediaQueryConditionTokenType = 85,
88
+ MediaFeatureTokenType = 86,
89
+ MediaFeatureOnlyTokenType = 87,
90
+ MediaFeatureNotTokenType = 88,
91
+ MediaFeatureAndTokenType = 89,
92
+ MediaFeatureOrTokenType = 90,
93
+ PseudoPageTokenType = 91,
85
94
  Time = 25,
86
95
  Iden = 7,
87
- EOF = 47,
96
+ EOF = 48,
88
97
  Hash = 28,
89
- Flex = 57,
98
+ Flex = 58,
90
99
  Angle = 24,
91
- Color = 49,
100
+ Color = 50,
92
101
  Comma = 9,
93
102
  String = 20,
94
103
  Length = 23,
@@ -101,9 +110,9 @@ declare enum EnumToken {
101
110
  Frequency = 26,
102
111
  Resolution = 27,
103
112
  Whitespace = 36,
104
- IdenList = 70,
113
+ IdenList = 71,
105
114
  DashedIden = 8,
106
- GridTemplateFunc = 71,
115
+ GridTemplateFunc = 72,
107
116
  ImageFunc = 19,
108
117
  CommentNodeType = 0,
109
118
  CDOCOMMNodeType = 1,
@@ -115,8 +124,16 @@ declare function minify(ast: AstNode, options?: ParserOptions | MinifyOptions, r
115
124
  [key: string]: any;
116
125
  }): AstNode;
117
126
 
127
+ declare enum WalkerValueEvent {
128
+ Enter = 0,
129
+ Leave = 1
130
+ }
118
131
  declare function walk(node: AstNode, filter?: WalkerFilter): Generator<WalkResult>;
119
- declare function walkValues(values: Token[], root?: AstNode | null, filter?: WalkerValueFilter): Generator<WalkAttributesResult>;
132
+ declare function walkValues(values: Token[], root?: AstNode | Token | null, filter?: WalkerValueFilter | {
133
+ event: WalkerValueEvent;
134
+ fn?: WalkerValueFilter;
135
+ type?: EnumToken | EnumToken[] | ((token: Token) => boolean);
136
+ }, reverse?: boolean): Generator<WalkAttributesResult>;
120
137
 
121
138
  declare function expand(ast: AstNode): AstNode;
122
139
 
@@ -201,6 +218,7 @@ export declare interface AtRuleToken extends BaseToken {
201
218
 
202
219
  typ: EnumToken.AtRuleTokenType,
203
220
  val: string;
221
+ pre: string;
204
222
  }
205
223
 
206
224
  export declare interface PercentageToken extends BaseToken {
@@ -401,6 +419,12 @@ export declare interface DashMatchToken extends BaseToken {
401
419
  // val: '|=';
402
420
  }
403
421
 
422
+ export declare interface EqualMatchToken extends BaseToken {
423
+
424
+ typ: EnumToken.EqualMatchTokenType;
425
+ // val: '|=';
426
+ }
427
+
404
428
  export declare interface StartMatchToken extends BaseToken {
405
429
 
406
430
  typ: EnumToken.StartMatchTokenType;
@@ -450,6 +474,12 @@ export declare interface PseudoClassToken extends BaseToken {
450
474
  val: string;
451
475
  }
452
476
 
477
+ export declare interface PseudoPageToken extends BaseToken {
478
+
479
+ typ: EnumToken.PseudoPageTokenType;
480
+ val: string;
481
+ }
482
+
453
483
  export declare interface PseudoClassFunctionToken extends BaseToken {
454
484
 
455
485
  typ: EnumToken.PseudoClassFuncTokenType;
@@ -531,6 +561,48 @@ export declare interface ChildCombinatorToken extends BaseToken {
531
561
  typ: EnumToken.ChildCombinatorTokenType
532
562
  }
533
563
 
564
+ export declare interface MediaFeatureToken extends BaseToken {
565
+
566
+ typ: EnumToken.MediaFeatureTokenType,
567
+ val: string;
568
+ }
569
+
570
+ export declare interface MediaFeatureOnlyToken extends BaseToken {
571
+
572
+ typ: EnumToken.MediaFeatureOnlyTokenType,
573
+ val: Token;
574
+ }
575
+
576
+ export declare interface MediaFeatureNotToken extends BaseToken {
577
+
578
+ typ: EnumToken.MediaFeatureNotTokenType,
579
+ val: Token;
580
+ }
581
+
582
+ export declare interface MediaFeatureNotToken extends BaseToken {
583
+
584
+ typ: EnumToken.MediaFeatureNotTokenType,
585
+ val: Token;
586
+ }
587
+
588
+ export declare interface MediaFeatureAndToken extends BaseToken {
589
+
590
+ typ: EnumToken.MediaFeatureAndTokenType;
591
+ }
592
+
593
+ export declare interface MediaFeatureOrToken extends BaseToken {
594
+
595
+ typ: EnumToken.MediaFeatureOrTokenType;
596
+ }
597
+
598
+ export declare interface MediaQueryConditionToken extends BaseToken {
599
+
600
+ typ: EnumToken.MediaQueryConditionTokenType,
601
+ l: Token,
602
+ op: ColonToken | GreaterThanToken | LessThanToken | GreaterThanOrEqualToken | LessThanOrEqualToken,
603
+ r: Token[]
604
+ }
605
+
534
606
  export declare interface DescendantCombinatorToken extends BaseToken {
535
607
 
536
608
  typ: EnumToken.DescendantCombinatorTokenType
@@ -591,7 +663,7 @@ export declare interface BinaryExpressionToken extends BaseToken {
591
663
  export declare interface MatchExpressionToken extends BaseToken {
592
664
 
593
665
  typ: EnumToken.MatchExpressionTokenType
594
- op: EnumToken.DashMatchTokenType | EnumToken.StartMatchTokenType | EnumToken.ContainMatchTokenType | EnumToken.EndMatchTokenType | EnumToken.IncludeMatchTokenType;
666
+ op: EqualMatchToken | DashMatchToken | StartMatchToken | ContainMatchToken | EndMatchToken | IncludeMatchToken;
595
667
  l: Token;
596
668
  r: Token;
597
669
  attr?: 'i' | 's';
@@ -642,6 +714,14 @@ export declare type Token =
642
714
  | ColumnCombinatorToken
643
715
  | NestingSelectorToken
644
716
  |
717
+ MediaQueryConditionToken
718
+ | MediaFeatureToken
719
+ | MediaFeatureNotToken
720
+ | MediaFeatureOnlyToken
721
+ | MediaFeatureAndToken
722
+ | MediaFeatureOrToken
723
+ | AstDeclaration
724
+ |
645
725
  NumberToken
646
726
  | AtRuleToken
647
727
  | PercentageToken
@@ -686,6 +766,7 @@ export declare type Token =
686
766
  | NameSpaceAttributeToken
687
767
  |
688
768
  DashMatchToken
769
+ | EqualMatchToken
689
770
  | LessThanToken
690
771
  | LessThanOrEqualToken
691
772
  | GreaterThanToken
@@ -693,6 +774,7 @@ export declare type Token =
693
774
  |
694
775
  ListToken
695
776
  | PseudoClassToken
777
+ | PseudoPageToken
696
778
  | PseudoClassFunctionToken
697
779
  | DelimToken
698
780
  | BinaryExpressionToken
@@ -729,6 +811,8 @@ export declare interface BaseToken {
729
811
 
730
812
  typ: EnumToken;
731
813
  loc?: Location;
814
+ tokens?: Token[];
815
+ parent?: AstRuleList;
732
816
  }
733
817
 
734
818
  export declare interface AstComment extends BaseToken {
@@ -754,6 +838,31 @@ export declare interface AstRule extends BaseToken {
754
838
  raw?: RawSelectorTokens;
755
839
  }
756
840
 
841
+ export declare interface AstInvalidRule extends BaseToken {
842
+
843
+ typ: EnumToken.InvalidRuleTokenType;
844
+ sel: string;
845
+ chi: Array<AstDeclaration | AstComment | AstRuleList>;
846
+ }
847
+
848
+ export declare interface AstInvalidAtRule extends BaseToken {
849
+
850
+ typ: EnumToken.InvalidAtRuleTokenType;
851
+ val: string;
852
+ chi?: Array<AstNode>;
853
+ }
854
+
855
+
856
+
857
+ export declare interface AstKeyFrameRule extends BaseToken {
858
+
859
+ typ: EnumToken.KeyFrameRuleNodeType;
860
+ sel: string;
861
+ chi: Array<AstDeclaration | AstComment>;
862
+ optimized?: OptimizedSelector;
863
+ raw?: RawSelectorTokens;
864
+ }
865
+
757
866
  export declare type RawSelectorTokens = string[][];
758
867
 
759
868
  export declare interface OptimizedSelector {
@@ -765,7 +874,7 @@ export declare interface OptimizedSelector {
765
874
 
766
875
  export declare interface AstAtRule extends BaseToken {
767
876
 
768
- typ: AtRuleNodeType,
877
+ typ: EnumToken.AtRuleNodeType,
769
878
  nam: string;
770
879
  val: string;
771
880
  chi?: Array<AstDeclaration | AstComment> | Array<AstRule | AstComment>
@@ -773,12 +882,12 @@ export declare interface AstAtRule extends BaseToken {
773
882
 
774
883
  export declare interface AstRuleList extends BaseToken {
775
884
 
776
- typ: StyleSheetNodeType | RuleNodeType | AtRuleNodeType,
777
- chi: Array<BaseToken | AstComment>
885
+ typ: EnumToken.StyleSheetNodeType | EnumToken.RuleNodeType | EnumToken.AtRuleNodeType,
886
+ chi: Array<BaseToken | AstComment>;
778
887
  }
779
888
 
780
889
  export declare interface AstRuleStyleSheet extends AstRuleList {
781
- typ: StyleSheetNodeType,
890
+ typ: EnumToken.StyleSheetNodeType,
782
891
  chi: Array<AstRuleList | AstComment>
783
892
  }
784
893
 
@@ -788,7 +897,10 @@ export declare type AstNode =
788
897
  | AstComment
789
898
  | AstAtRule
790
899
  | AstRule
791
- | AstDeclaration;
900
+ | AstDeclaration
901
+ | AstKeyFrameRule
902
+ | AstInvalidRule
903
+ | AstInvalidAtRule;
792
904
 
793
905
  /**
794
906
  * Declaration visitor handler
@@ -826,7 +938,13 @@ declare class SourceMap {
826
938
  toJSON(): SourceMapObject;
827
939
  }
828
940
 
829
- export declare type WalkerOption = 'ignore' | 'stop' | 'children' | 'ignore-children' | null;
941
+ export declare interface PropertyListOptions {
942
+
943
+ removeDuplicateDeclarations?: boolean;
944
+ computeShorthand?: boolean;
945
+ }
946
+
947
+ export declare type WalkerOption = 'ignore' | 'stop' | 'children' | 'ignore-children' | Token | null;
830
948
  /**
831
949
  * returned value:
832
950
  * - 'ignore': ignore this node and its children
@@ -843,20 +961,21 @@ export declare type WalkerFilter = (node: AstNode) => WalkerOption;
843
961
  * - 'children': walk the children and ignore the node itself
844
962
  * - 'ignore-children': walk the node and ignore children
845
963
  */
846
- export declare type WalkerValueFilter = (node: Token) => WalkerOption;
964
+ export declare type WalkerValueFilter = (node: AstNode | Token, parent: FunctionToken | ParensToken | BinaryExpressionToken, event?: WalkerValueEvent) => WalkerOption | null;
847
965
 
848
966
  export declare interface WalkResult {
849
967
  node: AstNode;
850
968
  parent?: AstRuleList;
851
- root?: AstRuleList;
969
+ root?: AstNode;
852
970
  }
853
971
 
854
972
  export declare interface WalkAttributesResult {
855
973
  value: Token;
856
974
  previousValue: Token | null;
857
- nextValue: AstNode | null;
975
+ nextValue: Token | null;
858
976
  root?: AstNode;
859
977
  parent: FunctionToken | ParensToken | BinaryExpressionToken | null;
978
+ list: Token[] | null;
860
979
  }
861
980
 
862
981
  export declare interface ErrorDescription {
@@ -941,6 +1060,7 @@ export declare interface ResolvedPath {
941
1060
  export declare interface RenderOptions {
942
1061
 
943
1062
  minify?: boolean;
1063
+ removeEmpty?: boolean;
944
1064
  expandNestingRules?: boolean;
945
1065
  preserveLicense?: boolean;
946
1066
  sourcemap?: boolean;
@@ -1013,8 +1133,17 @@ declare function resolve(url: string, currentDirectory: string, cwd?: string): {
1013
1133
 
1014
1134
  declare function load(url: string, currentFile: string): Promise<string>;
1015
1135
 
1136
+ /**
1137
+ * render ast node
1138
+ */
1016
1139
  declare function render(data: AstNode, options?: RenderOptions): RenderResult;
1140
+ /**
1141
+ * parse css
1142
+ */
1017
1143
  declare function parse(iterator: string, opt?: ParserOptions): Promise<ParseResult>;
1144
+ /**
1145
+ * parse and render css
1146
+ */
1018
1147
  declare function transform(css: string, options?: TransformOptions): Promise<TransformResult>;
1019
1148
 
1020
1149
  export { EnumToken, dirname, expand, load, minify, parse, parseString, parseTokens, render, renderToken, resolve, transform, walk, walkValues };
@@ -34,6 +34,7 @@ function expand(ast) {
34
34
  let hasRule = false;
35
35
  let j = node.chi.length;
36
36
  while (j--) {
37
+ // @ts-ignore
37
38
  if (node.chi[j].typ == EnumToken.RuleNodeType || node.chi[j].typ == EnumToken.AtRuleNodeType) {
38
39
  hasRule = true;
39
40
  break;
@@ -49,7 +50,7 @@ function expand(ast) {
49
50
  }
50
51
  return result;
51
52
  }
52
- function expandRule(node) {
53
+ function expandRule(node, parent) {
53
54
  const ast = { ...node, chi: node.chi.slice() };
54
55
  const result = [];
55
56
  if (ast.typ == EnumToken.RuleNodeType) {
@@ -72,7 +73,77 @@ function expandRule(node) {
72
73
  }
73
74
  }
74
75
  else {
75
- rule.sel = replaceCompound(rule.sel, ast.sel);
76
+ let childSelectorCompound = [];
77
+ let withCompound = [];
78
+ let withoutCompound = [];
79
+ const rules = splitRule(ast.sel);
80
+ const parentSelector = !node.sel.includes('&');
81
+ for (const sel of (rule.raw ?? splitRule(rule.sel))) {
82
+ const s = sel.join('');
83
+ if (s.includes('&') || parentSelector) {
84
+ if (s.indexOf('&', 1) == -1) {
85
+ if (s.at(0) == '&') {
86
+ if (s.at(1) == ' ') {
87
+ childSelectorCompound.push(s.slice(2));
88
+ }
89
+ else {
90
+ if (s == '&' || parentSelector) {
91
+ withCompound.push(s);
92
+ }
93
+ else {
94
+ withoutCompound.push(s.slice(1));
95
+ }
96
+ }
97
+ }
98
+ else {
99
+ withoutCompound.push(s);
100
+ }
101
+ }
102
+ else {
103
+ withCompound.push(s);
104
+ }
105
+ }
106
+ else {
107
+ withoutCompound.push(s);
108
+ }
109
+ }
110
+ const selectors = [];
111
+ const selector = rules.length > 1 ? ':is(' + rules.map(a => a.join('')).join(',') + ')' : rules[0].join('');
112
+ if (childSelectorCompound.length > 0) {
113
+ if (childSelectorCompound.length == 1) {
114
+ selectors.push(replaceCompound('& ' + childSelectorCompound[0].trim(), selector));
115
+ }
116
+ else {
117
+ selectors.push(replaceCompound('& :is(' + childSelectorCompound.reduce((acc, curr) => acc + (acc.length > 0 ? ',' : '') + curr.trim(), '') + ')', selector));
118
+ }
119
+ }
120
+ if (withCompound.length > 0) {
121
+ if (withCompound.every((t) => t[0] == '&' && t.indexOf('&', 1) == -1)) {
122
+ withoutCompound.push(...withCompound.map(t => t.slice(1)));
123
+ withCompound.length = 0;
124
+ }
125
+ }
126
+ if (withoutCompound.length > 0) {
127
+ if (withoutCompound.length == 1) {
128
+ const useIs = rules.length == 1 && selector.match(/^[a-zA-Z.:]/) != null && selector.includes(' ') && withoutCompound.length == 1 && withoutCompound[0].match(/^[a-zA-Z]+$/) != null;
129
+ const compound = useIs ? ':is(&)' : '&';
130
+ selectors.push(replaceCompound(rules.length == 1 ? (useIs ? withoutCompound[0] + ':is(&)' : (selector.match(/^[.:]/) && withoutCompound[0].match(/^[a-zA-Z]+$/) ? withoutCompound[0] + compound : compound + withoutCompound[0])) : (withoutCompound[0].match(/^[a-zA-Z:]+$/) ? withoutCompound[0].trim() + compound : '&' + (withoutCompound[0].match(/^\S+$/) ? withoutCompound[0].trim() : ':is(' + withoutCompound[0].trim() + ')')), selector));
131
+ }
132
+ else {
133
+ selectors.push(replaceCompound('&:is(' + withoutCompound.reduce((acc, curr) => acc + (acc.length > 0 ? ',' : '') + curr.trim(), '') + ')', selector));
134
+ }
135
+ }
136
+ if (withCompound.length > 0) {
137
+ if (withCompound.length == 1) {
138
+ selectors.push(replaceCompound(withCompound[0], selector));
139
+ }
140
+ else {
141
+ for (const w of withCompound) {
142
+ selectors.push(replaceCompound(w, selector));
143
+ }
144
+ }
145
+ }
146
+ rule.sel = selectors.reduce((acc, curr) => curr.length == 0 ? acc : acc + (acc.length > 0 ? ',' : '') + curr, '');
76
147
  }
77
148
  ast.chi.splice(i--, 1);
78
149
  result.push(...expandRule(rule));
@@ -125,9 +196,23 @@ function expandRule(node) {
125
196
  }
126
197
  function replaceCompound(input, replace) {
127
198
  const tokens = parseString(input);
199
+ let replacement = null;
128
200
  for (const t of walkValues(tokens)) {
129
201
  if (t.value.typ == EnumToken.LiteralTokenType) {
130
202
  if (t.value.val == '&') {
203
+ if (tokens.length == 2) {
204
+ if (replacement == null) {
205
+ replacement = parseString(replace);
206
+ }
207
+ if (tokens[1].typ == EnumToken.IdenTokenType) {
208
+ t.value.val = replacement.length == 1 || (!replace.includes(' ') && replace.charAt(0).match(/[:.]/)) ? tokens[1].val + replace : replaceCompoundLiteral(tokens[1].val + '&', replace);
209
+ tokens.splice(1, 1);
210
+ }
211
+ else {
212
+ t.value.val = replaceCompoundLiteral(t.value.val, replace);
213
+ }
214
+ continue;
215
+ }
131
216
  const rule = splitRule(replace);
132
217
  t.value.val = rule.length > 1 ? ':is(' + replace + ')' : replace;
133
218
  }
@@ -1,6 +1,8 @@
1
1
  import { EnumToken } from '../types.js';
2
- import { walkValues } from '../walk.js';
2
+ import { walkValues, WalkerValueEvent } from '../walk.js';
3
3
  import { evaluate } from '../math/expression.js';
4
+ import { renderToken } from '../../renderer/render.js';
5
+ import { mathFuncs } from '../../syntax/syntax.js';
4
6
 
5
7
  class ComputeCalcExpressionFeature {
6
8
  static get ordering() {
@@ -27,30 +29,92 @@ class ComputeCalcExpressionFeature {
27
29
  continue;
28
30
  }
29
31
  const set = new Set;
30
- for (const { value, parent } of walkValues(node.val)) {
31
- if (value != null && value.typ == EnumToken.FunctionTokenType && value.val == 'calc') {
32
- if (!set.has(parent)) {
32
+ for (const { value, parent } of walkValues(node.val, node, {
33
+ event: WalkerValueEvent.Enter,
34
+ fn(node, parent, event) {
35
+ if (parent != null &&
36
+ parent.typ == EnumToken.DeclarationNodeType &&
37
+ parent.val.length == 1 &&
38
+ node.typ == EnumToken.FunctionTokenType &&
39
+ mathFuncs.includes(node.val) &&
40
+ node.chi.length == 1 &&
41
+ node.chi[0].typ == EnumToken.IdenTokenType) {
42
+ return 'ignore';
43
+ }
44
+ if ((node.typ == EnumToken.FunctionTokenType && node.val == 'var') || (!mathFuncs.includes(parent.val) && [EnumToken.ColorTokenType, EnumToken.DeclarationNodeType, EnumToken.RuleNodeType, EnumToken.AtRuleNodeType, EnumToken.StyleSheetNodeType].includes(parent?.typ))) {
45
+ return null;
46
+ }
47
+ // @ts-ignore
48
+ const slice = (node.typ == EnumToken.FunctionTokenType ? node.chi : (node.typ == EnumToken.DeclarationNodeType ? node.val : node.chi))?.slice();
49
+ if (slice != null && node.typ == EnumToken.FunctionTokenType && mathFuncs.includes(node.val)) {
50
+ // @ts-ignore
51
+ const cp = (node.typ == EnumToken.FunctionTokenType && mathFuncs.includes(node.val) && node.val != 'calc' ? [node] : (node.typ == EnumToken.DeclarationNodeType ? node.val : node.chi)).slice();
52
+ const values = evaluate(cp);
53
+ const key = 'chi' in node ? 'chi' : 'val';
54
+ const str1 = renderToken({ ...node, [key]: slice });
55
+ const str2 = renderToken(node); // values.reduce((acc: string, curr: Token): string => acc + renderToken(curr), '');
56
+ if (str1.length <= str2.length) {
57
+ // @ts-ignore
58
+ node[key] = slice;
59
+ }
60
+ else {
61
+ // @ts-ignore
62
+ node[key] = values;
63
+ }
64
+ return 'ignore';
65
+ }
66
+ return null;
67
+ }
68
+ })) {
69
+ if (value != null && value.typ == EnumToken.FunctionTokenType && mathFuncs.includes(value.val)) {
70
+ if (!set.has(value)) {
33
71
  set.add(value);
34
- value.chi = evaluate(value.chi);
35
- if (value.chi.length == 1 && value.chi[0].typ != EnumToken.BinaryExpressionTokenType) {
36
- if (parent != null) {
72
+ if (parent != null) {
73
+ // @ts-ignore
74
+ const cp = value.typ == EnumToken.FunctionTokenType && mathFuncs.includes(value.val) && value.val != 'calc' ? [value] : (value.typ == EnumToken.DeclarationNodeType ? value.val : value.chi);
75
+ const values = evaluate(cp);
76
+ // @ts-ignore
77
+ const children = parent.typ == EnumToken.DeclarationNodeType ? parent.val : parent.chi;
78
+ if (values.length == 1 && values[0].typ != EnumToken.BinaryExpressionTokenType) {
37
79
  if (parent.typ == EnumToken.BinaryExpressionTokenType) {
38
80
  if (parent.l == value) {
39
- parent.l = value.chi[0];
81
+ parent.l = values[0];
40
82
  }
41
83
  else {
42
- parent.r = value.chi[0];
84
+ parent.r = values[0];
43
85
  }
44
86
  }
45
87
  else {
46
- for (let i = 0; i < parent.chi.length; i++) {
47
- if (parent.chi[i] == value) {
48
- parent.chi.splice(i, 1, value.chi[0]);
88
+ for (let i = 0; i < children.length; i++) {
89
+ if (children[i] == value) {
90
+ // @ts-ignore
91
+ children.splice(i, 1, !(parent.typ == EnumToken.FunctionTokenType && parent.val == 'calc') && typeof values[0].val != 'string' ? {
92
+ typ: EnumToken.FunctionTokenType,
93
+ val: 'calc',
94
+ chi: values
95
+ } : values[0]);
49
96
  break;
50
97
  }
51
98
  }
52
99
  }
53
100
  }
101
+ else {
102
+ for (let i = 0; i < children.length; i++) {
103
+ if (children[i] == value) {
104
+ if (parent.typ == EnumToken.FunctionTokenType && parent.val == 'calc') {
105
+ children.splice(i, 1, ...values);
106
+ }
107
+ else {
108
+ children.splice(i, 1, {
109
+ typ: EnumToken.FunctionTokenType,
110
+ val: 'calc',
111
+ chi: values
112
+ });
113
+ }
114
+ break;
115
+ }
116
+ }
117
+ }
54
118
  }
55
119
  }
56
120
  }
@@ -1,5 +1,6 @@
1
1
  import { EnumToken } from '../types.js';
2
2
  import { walkValues } from '../walk.js';
3
+ import { renderToken } from '../../renderer/render.js';
3
4
 
4
5
  function replace(node, variableScope) {
5
6
  for (const { value, parent: parentValue } of walkValues(node.val)) {
@@ -108,7 +109,11 @@ class InlineCssVariablesFeature {
108
109
  i = parent.chi?.length ?? 0;
109
110
  while (i--) {
110
111
  if (parent.chi[i].typ == EnumToken.DeclarationNodeType && parent.chi[i].nam == info.node.nam) {
111
- parent.chi.splice(i, 1);
112
+ // @ts-ignore
113
+ parent.chi.splice(i++, 1, {
114
+ typ: EnumToken.CommentTokenType,
115
+ val: `/* ${info.node.nam}: ${info.node.val.reduce((acc, curr) => acc + renderToken(curr), '')} */`
116
+ });
112
117
  }
113
118
  }
114
119
  if (parent.chi?.length == 0 && 'parent' in parent) {