@tbela99/css-parser 0.6.0 → 0.7.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 (51) hide show
  1. package/README.md +106 -3
  2. package/dist/config.json.js +3 -1
  3. package/dist/index-umd-web.js +53876 -50
  4. package/dist/index.cjs +53876 -50
  5. package/dist/index.d.ts +113 -18
  6. package/dist/lib/ast/expand.js +8 -2
  7. package/dist/lib/ast/features/index.js +1 -0
  8. package/dist/lib/ast/features/prefix.js +118 -0
  9. package/dist/lib/ast/features/shorthand.js +1 -0
  10. package/dist/lib/ast/minify.js +44 -10
  11. package/dist/lib/ast/types.js +16 -1
  12. package/dist/lib/ast/walk.js +3 -1
  13. package/dist/lib/parser/declaration/list.js +1 -1
  14. package/dist/lib/parser/declaration/map.js +9 -4
  15. package/dist/lib/parser/declaration/set.js +2 -1
  16. package/dist/lib/parser/parse.js +239 -11
  17. package/dist/lib/parser/tokenize.js +19 -5
  18. package/dist/lib/parser/utils/config.js +1 -0
  19. package/dist/lib/parser/utils/declaration.js +2 -1
  20. package/dist/lib/parser/utils/syntax.js +1 -0
  21. package/dist/lib/parser/utils/type.js +1 -0
  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 +3 -2
  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/rec2020.js +1 -0
  34. package/dist/lib/renderer/color/relativecolor.js +1 -0
  35. package/dist/lib/renderer/color/rgb.js +1 -0
  36. package/dist/lib/renderer/color/srgb.js +1 -0
  37. package/dist/lib/renderer/color/utils/components.js +1 -0
  38. package/dist/lib/renderer/color/utils/constants.js +1 -0
  39. package/dist/lib/renderer/color/xyz.js +1 -0
  40. package/dist/lib/renderer/color/xyzd50.js +1 -0
  41. package/dist/lib/renderer/render.js +25 -5
  42. package/dist/lib/syntax/syntax.js +456 -0
  43. package/dist/lib/validation/config.js +9 -0
  44. package/dist/lib/validation/config.json.js +52883 -0
  45. package/dist/lib/validation/parser/parse.js +16 -0
  46. package/dist/lib/validation/parser/types.js +39 -0
  47. package/dist/lib/validation/selector.js +459 -0
  48. package/dist/node/index.js +1 -0
  49. package/dist/web/index.js +1 -0
  50. package/package.json +1 -1
  51. package/jsr.json +0 -29
package/dist/index.d.ts CHANGED
@@ -72,6 +72,16 @@ declare enum EnumToken {
72
72
  IdenListTokenType = 70,
73
73
  GridTemplateFuncTokenType = 71,
74
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,
75
85
  Time = 25,
76
86
  Iden = 7,
77
87
  EOF = 47,
@@ -119,18 +129,29 @@ declare function parseString(src: string, options?: {
119
129
  }): Token[];
120
130
  declare function parseTokens(tokens: Token[], options?: ParseTokenOptions): Token[];
121
131
 
122
- export declare interface BaseToken {
132
+ export declare interface LiteralToken extends BaseToken {
123
133
 
124
- typ: EnumToken;
125
- loc?: Location;
134
+ typ: EnumToken.LiteralTokenType;
135
+ val: string;
126
136
  }
127
137
 
128
- export declare interface LiteralToken extends BaseToken {
138
+ export declare interface ClassSelectorToken extends BaseToken {
129
139
 
130
- typ: EnumToken.LiteralTokenType;
140
+ typ: EnumToken.ClassSelectorTokenType;
141
+ val: string;
142
+ }
143
+
144
+ export declare interface InvalidClassSelectorToken extends BaseToken {
145
+
146
+ typ: EnumToken.InvalidClassSelectorTokenType;
131
147
  val: string;
132
148
  }
133
149
 
150
+ export declare interface UniversalSelectorToken extends BaseToken {
151
+
152
+ typ: EnumToken.UniversalSelectorTokenType;
153
+ }
154
+
134
155
 
135
156
  export declare interface IdentToken extends BaseToken {
136
157
 
@@ -165,6 +186,11 @@ export declare interface SemiColonToken extends BaseToken {
165
186
  typ: EnumToken.SemiColonTokenType
166
187
  }
167
188
 
189
+ export declare interface NestingSelectorToken extends BaseToken {
190
+
191
+ typ: EnumToken.NestingSelectorTokenType
192
+ }
193
+
168
194
  export declare interface NumberToken extends BaseToken {
169
195
 
170
196
  typ: EnumToken.NumberTokenType,
@@ -434,7 +460,6 @@ export declare interface PseudoClassFunctionToken extends BaseToken {
434
460
  export declare interface DelimToken extends BaseToken {
435
461
 
436
462
  typ: EnumToken.DelimTokenType;
437
- val: '=';
438
463
  }
439
464
 
440
465
  export declare interface BadUrlToken extends BaseToken {
@@ -459,7 +484,23 @@ export declare interface ImportantToken extends BaseToken {
459
484
  typ: EnumToken.ImportantTokenType;
460
485
  }
461
486
 
462
- export declare type ColorKind = 'sys' | 'dpsys' | 'lit' | 'hex' | 'rgb' | 'rgba' | 'hsl' | 'hsla' | 'hwb' | 'device-cmyk' | 'oklab' | 'oklch' | 'lab' | 'lch' | 'color' | 'light-dark';
487
+ export declare type ColorKind =
488
+ 'sys'
489
+ | 'dpsys'
490
+ | 'lit'
491
+ | 'hex'
492
+ | 'rgb'
493
+ | 'rgba'
494
+ | 'hsl'
495
+ | 'hsla'
496
+ | 'hwb'
497
+ | 'device-cmyk'
498
+ | 'oklab'
499
+ | 'oklch'
500
+ | 'lab'
501
+ | 'lch'
502
+ | 'color'
503
+ | 'light-dark';
463
504
 
464
505
  // export declare type HueInterpolationMethod = 'shorter' | 'longer' | 'increasing' | 'decreasing';
465
506
 
@@ -479,6 +520,32 @@ export declare interface AttrToken extends BaseToken {
479
520
  chi: Token[]
480
521
  }
481
522
 
523
+ export declare interface InvalidAttrToken extends BaseToken {
524
+
525
+ typ: EnumToken.InvalidAttrTokenType,
526
+ chi: Token[]
527
+ }
528
+
529
+ export declare interface ChildCombinatorToken extends BaseToken {
530
+
531
+ typ: EnumToken.ChildCombinatorTokenType
532
+ }
533
+
534
+ export declare interface DescendantCombinatorToken extends BaseToken {
535
+
536
+ typ: EnumToken.DescendantCombinatorTokenType
537
+ }
538
+
539
+ export declare interface NextSiblingCombinatorToken extends BaseToken {
540
+
541
+ typ: EnumToken.NextSiblingCombinatorTokenType
542
+ }
543
+
544
+ export declare interface SubsequentCombinatorToken extends BaseToken {
545
+
546
+ typ: EnumToken.SubsequentSiblingCombinatorTokenType
547
+ }
548
+
482
549
  export declare interface AddToken extends BaseToken {
483
550
 
484
551
  typ: EnumToken.Add;
@@ -556,6 +623,9 @@ export declare type BinaryExpressionNode = NumberToken | DimensionToken | Percen
556
623
  AngleToken | LengthToken | FrequencyToken | BinaryExpressionToken | FunctionToken | ParensToken;
557
624
 
558
625
  export declare type Token =
626
+ InvalidClassSelectorToken
627
+ | InvalidAttrToken
628
+ |
559
629
  LiteralToken
560
630
  | IdentToken
561
631
  | IdentListToken
@@ -563,6 +633,14 @@ export declare type Token =
563
633
  | CommaToken
564
634
  | ColonToken
565
635
  | SemiColonToken
636
+ | ClassSelectorToken
637
+ | UniversalSelectorToken
638
+ | ChildCombinatorToken
639
+ | DescendantCombinatorToken
640
+ | NextSiblingCombinatorToken
641
+ | SubsequentCombinatorToken
642
+ | ColumnCombinatorToken
643
+ | NestingSelectorToken
566
644
  |
567
645
  NumberToken
568
646
  | AtRuleToken
@@ -603,14 +681,15 @@ export declare type Token =
603
681
  | IncludeMatchToken
604
682
  | StartMatchToken
605
683
  | EndMatchToken
606
- | ContainMatchToken | MatchExpressionToken | NameSpaceAttributeToken
684
+ | ContainMatchToken
685
+ | MatchExpressionToken
686
+ | NameSpaceAttributeToken
607
687
  |
608
688
  DashMatchToken
609
689
  | LessThanToken
610
690
  | LessThanOrEqualToken
611
691
  | GreaterThanToken
612
692
  | GreaterThanOrEqualToken
613
- | ColumnCombinatorToken
614
693
  |
615
694
  ListToken
616
695
  | PseudoClassToken
@@ -646,19 +725,19 @@ export declare interface Location {
646
725
  src: string;
647
726
  }
648
727
 
649
- export declare interface Node {
728
+ export declare interface BaseToken {
650
729
 
651
730
  typ: EnumToken;
652
731
  loc?: Location;
653
732
  }
654
733
 
655
- export declare interface AstComment extends Node {
734
+ export declare interface AstComment extends BaseToken {
656
735
 
657
736
  typ: EnumToken.CommentNodeType | EnumToken.CDOCOMMNodeType,
658
737
  val: string;
659
738
  }
660
739
 
661
- export declare interface AstDeclaration extends Node {
740
+ export declare interface AstDeclaration extends BaseToken {
662
741
 
663
742
  nam: string,
664
743
  val: Token[];
@@ -666,7 +745,7 @@ export declare interface AstDeclaration extends Node {
666
745
  }
667
746
 
668
747
 
669
- export declare interface AstRule extends Node {
748
+ export declare interface AstRule extends BaseToken {
670
749
 
671
750
  typ: EnumToken.RuleNodeType;
672
751
  sel: string;
@@ -684,7 +763,7 @@ export declare interface OptimizedSelector {
684
763
  reducible: boolean;
685
764
  }
686
765
 
687
- export declare interface AstAtRule extends Node {
766
+ export declare interface AstAtRule extends BaseToken {
688
767
 
689
768
  typ: AtRuleNodeType,
690
769
  nam: string;
@@ -692,10 +771,10 @@ export declare interface AstAtRule extends Node {
692
771
  chi?: Array<AstDeclaration | AstComment> | Array<AstRule | AstComment>
693
772
  }
694
773
 
695
- export declare interface AstRuleList extends Node {
774
+ export declare interface AstRuleList extends BaseToken {
696
775
 
697
776
  typ: StyleSheetNodeType | RuleNodeType | AtRuleNodeType,
698
- chi: Array<Node | AstComment>
777
+ chi: Array<BaseToken | AstComment>
699
778
  }
700
779
 
701
780
  export declare interface AstRuleStyleSheet extends AstRuleList {
@@ -739,6 +818,14 @@ export declare interface VisitorNodeMap {
739
818
  Value?: Record<EnumToken, ValueVisitorHandler> | ValueVisitorHandler;
740
819
  }
741
820
 
821
+ declare class SourceMap {
822
+ #private;
823
+ lastLocation: Location | null;
824
+ add(source: Location, original: Location): void;
825
+ toUrl(): string;
826
+ toJSON(): SourceMapObject;
827
+ }
828
+
742
829
  export declare type WalkerOption = 'ignore' | 'stop' | 'children' | 'ignore-children' | null;
743
830
  /**
744
831
  * returned value:
@@ -766,6 +853,8 @@ export declare interface WalkResult {
766
853
 
767
854
  export declare interface WalkAttributesResult {
768
855
  value: Token;
856
+ previousValue: Token | null;
857
+ nextValue: AstNode | null;
769
858
  root?: AstNode;
770
859
  parent: FunctionToken | ParensToken | BinaryExpressionToken | null;
771
860
  }
@@ -783,7 +872,12 @@ export declare interface ErrorDescription {
783
872
  error?: Error;
784
873
  }
785
874
 
786
- export declare interface ParserOptions extends PropertyListOptions {
875
+ interface ValidationOptions {
876
+
877
+ validation?: boolean;
878
+ }
879
+
880
+ export declare interface ParserOptions extends ValidationOptions, PropertyListOptions {
787
881
 
788
882
  minify?: boolean;
789
883
  src?: string;
@@ -798,6 +892,7 @@ export declare interface ParserOptions extends PropertyListOptions {
798
892
  parseColor?: boolean;
799
893
  removeDuplicateDeclarations?: boolean;
800
894
  computeShorthand?: boolean;
895
+ removePrefix?: boolean;
801
896
  inlineCssVariables?: boolean;
802
897
  computeCalcExpression?: boolean;
803
898
  load?: (url: string, currentUrl: string) => Promise<string>;
@@ -882,7 +977,7 @@ export declare interface RenderResult {
882
977
  stats: {
883
978
  total: string;
884
979
  },
885
- map?: SourceMapObject
980
+ map?: SourceMap
886
981
  }
887
982
 
888
983
  export declare interface TransformResult extends ParseResult, RenderResult {
@@ -1,9 +1,10 @@
1
1
  import { splitRule, combinators } from './minify.js';
2
2
  import { parseString } from '../parser/parse.js';
3
- import { renderToken } from '../renderer/render.js';
4
3
  import { EnumToken } from './types.js';
5
4
  import { walkValues } from './walk.js';
5
+ import { renderToken } from '../renderer/render.js';
6
6
  import '../renderer/color/utils/constants.js';
7
+ import '../parser/utils/config.js';
7
8
 
8
9
  function expand(ast) {
9
10
  //
@@ -154,7 +155,12 @@ function replaceCompoundLiteral(selector, replace) {
154
155
  return 1;
155
156
  }
156
157
  return b == '&' ? -1 : 0;
157
- }).reduce((acc, curr) => acc + (curr == '&' ? replace : curr), '');
158
+ }).reduce((acc, curr) => {
159
+ if (acc.length > 0 && curr == '&' && (replace.charAt(0) != '.' || replace.includes(' '))) {
160
+ return acc + ':is(' + replace + ')';
161
+ }
162
+ return acc + (curr == '&' ? replace : curr);
163
+ }, '');
158
164
  }
159
165
 
160
166
  export { expand, replaceCompound };
@@ -1,3 +1,4 @@
1
+ export { ComputePrefixFeature } from './prefix.js';
1
2
  export { InlineCssVariablesFeature } from './inlinecssvariables.js';
2
3
  export { ComputeShorthandFeature } from './shorthand.js';
3
4
  export { ComputeCalcExpressionFeature } from './calc.js';
@@ -0,0 +1,118 @@
1
+ import { EnumToken } from '../types.js';
2
+ import { getConfig } from '../../validation/config.js';
3
+ import { walkValues } from '../walk.js';
4
+ import { ValidationTokenEnum } from '../../validation/parser/types.js';
5
+ import '../../validation/parser/parse.js';
6
+
7
+ const config = getConfig();
8
+ class ComputePrefixFeature {
9
+ static get ordering() {
10
+ return 2;
11
+ }
12
+ static register(options) {
13
+ if (options.removePrefix) {
14
+ for (const feature of options.features) {
15
+ if (feature instanceof ComputePrefixFeature) {
16
+ return;
17
+ }
18
+ }
19
+ // @ts-ignore
20
+ options.features.push(new ComputePrefixFeature(options));
21
+ }
22
+ }
23
+ run(ast) {
24
+ // @ts-ignore
25
+ const j = ast.chi.length;
26
+ let k = 0;
27
+ // @ts-ignore
28
+ for (; k < j; k++) {
29
+ // @ts-ignore
30
+ const node = ast.chi[k];
31
+ if (node.typ == EnumToken.DeclarationNodeType) {
32
+ if (node.nam.charAt(0) == '-') {
33
+ const match = node.nam.match(/^-(.*?)-(.*)$/);
34
+ if (match != null) {
35
+ const nam = match[2];
36
+ if (nam.toLowerCase() in config.declarations) {
37
+ node.nam = nam;
38
+ }
39
+ }
40
+ }
41
+ if (node.nam.toLowerCase() in config.declarations) {
42
+ for (const { value } of walkValues(node.val)) {
43
+ if (value.typ == EnumToken.IdenTokenType && value.val.charAt(0) == '-' && value.val.charAt(1) != '-') {
44
+ // @ts-ignore
45
+ const values = config.declarations[node.nam].ast.slice();
46
+ const match = value.val.match(/^-(.*?)-(.*)$/);
47
+ if (match != null) {
48
+ const val = matchToken({ ...value, val: match[2] }, values);
49
+ if (val != null) {
50
+ // @ts-ignore
51
+ value.val = val.val;
52
+ }
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+ return ast;
60
+ }
61
+ }
62
+ function matchToken(token, matches) {
63
+ let result;
64
+ for (let i = 0; i < matches.length; i++) {
65
+ switch (matches[i].typ) {
66
+ case ValidationTokenEnum.Whitespace:
67
+ case ValidationTokenEnum.Comma:
68
+ break;
69
+ case ValidationTokenEnum.Keyword:
70
+ console.error(matches[i], token);
71
+ if (token.typ == EnumToken.IdenTokenType && token.val == matches[i].val) {
72
+ return token;
73
+ }
74
+ break;
75
+ case ValidationTokenEnum.PropertyType:
76
+ if (['ident', 'custom-ident'].includes(matches[i].val)) {
77
+ if (token.typ == EnumToken.IdenTokenType && token.val == matches[i].val) {
78
+ return token;
79
+ }
80
+ }
81
+ else {
82
+ const val = matches[i].val;
83
+ if (val in config.declarations || val in config.syntaxes) {
84
+ // @ts-ignore
85
+ result = matchToken(token, (config.syntaxes[val] ?? config.declarations[val]).ast.slice());
86
+ if (result != null) {
87
+ return result;
88
+ }
89
+ }
90
+ }
91
+ break;
92
+ case ValidationTokenEnum.PipeToken:
93
+ case ValidationTokenEnum.ColumnToken:
94
+ case ValidationTokenEnum.AmpersandToken:
95
+ result = matchToken(token, matches[i].l);
96
+ if (result == null) {
97
+ result = matchToken(token, matches[i].r);
98
+ }
99
+ if (result != null) {
100
+ return result;
101
+ }
102
+ break;
103
+ case ValidationTokenEnum.Bracket:
104
+ result = matchToken(token, matches[i].chi);
105
+ if (result != null) {
106
+ return result;
107
+ }
108
+ break;
109
+ // default:
110
+ //
111
+ // console.error(token, matches[i]);
112
+ // throw new Error('bar bar');
113
+ }
114
+ }
115
+ return null;
116
+ }
117
+
118
+ export { ComputePrefixFeature };
@@ -4,6 +4,7 @@ import '../minify.js';
4
4
  import '../../parser/parse.js';
5
5
  import '../../renderer/color/utils/constants.js';
6
6
  import '../../renderer/sourcemap/lib/encode.js';
7
+ import '../../parser/utils/config.js';
7
8
 
8
9
  class ComputeShorthandFeature {
9
10
  static get ordering() {
@@ -1,13 +1,14 @@
1
1
  import { parseString } from '../parser/parse.js';
2
- import { isWhiteSpace, isIdent, isFunction, isIdentStart } from '../parser/utils/syntax.js';
3
2
  import { EnumToken } from './types.js';
4
3
  import { walkValues } from './walk.js';
5
4
  import { replaceCompound } from './expand.js';
5
+ import { isWhiteSpace, isIdent, isFunction, isIdentStart } from '../syntax/syntax.js';
6
+ import '../parser/utils/config.js';
6
7
  import { eq } from '../parser/utils/eq.js';
7
8
  import { renderToken, doRender } from '../renderer/render.js';
8
9
  import * as index from './features/index.js';
9
10
 
10
- const combinators = ['+', '>', '~', '||'];
11
+ const combinators = ['+', '>', '~', '||', '|'];
11
12
  const definedPropertySettings = { configurable: true, enumerable: false, writable: true };
12
13
  const notEndingWith = ['(', '['].concat(combinators);
13
14
  // @ts-ignore
@@ -26,6 +27,7 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
26
27
  removeDuplicateDeclarations: true,
27
28
  computeShorthand: true,
28
29
  computeCalcExpression: true,
30
+ removePrefix: false,
29
31
  features: [], ...options
30
32
  };
31
33
  // @ts-ignore
@@ -275,12 +277,17 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
275
277
  }
276
278
  else {
277
279
  // @ts-ignore
278
- ast.chi.splice(i, 1, intersect.node1);
280
+ ast.chi.splice(i--, 1, intersect.node1);
279
281
  // node = ast.chi intersect.node1;
280
282
  }
281
283
  if (intersect.node2.chi.length == 0) {
282
284
  // @ts-ignore
283
285
  ast.chi.splice(nodeIndex, 1, intersect.result);
286
+ i--;
287
+ // @ts-ignore
288
+ if (nodeIndex == i) {
289
+ nodeIndex = i;
290
+ }
284
291
  }
285
292
  else {
286
293
  // @ts-ignore
@@ -289,6 +296,11 @@ function minify(ast, options = {}, recursive = false, errors, nestingContent, co
289
296
  i = (nodeIndex ?? 0) + 1;
290
297
  }
291
298
  reduceRuleSelector(intersect.result);
299
+ // @ts-ignore
300
+ if (node != ast.chi[i]) {
301
+ // @ts-ignore
302
+ node = ast.chi[i];
303
+ }
292
304
  previous = intersect.result;
293
305
  nodeIndex = i;
294
306
  }
@@ -389,6 +401,25 @@ function reduceSelector(selector) {
389
401
  if (selector.length == 0) {
390
402
  return null;
391
403
  }
404
+ selector = selector.reduce((acc, curr) => {
405
+ // @ts-ignore
406
+ if (curr.length > 0 && curr.at(-1).startsWith(':is(')) {
407
+ // @ts-ignore
408
+ const rules = splitRule(curr.at(-1).slice(4, -1)).map(x => {
409
+ if (x[0] == '&' && x.length > 1) {
410
+ return x.slice(x[1] == ' ' ? 2 : 1);
411
+ }
412
+ return x;
413
+ });
414
+ const part = curr.slice(0, -1);
415
+ for (const rule of rules) {
416
+ acc.push(part.concat(rule));
417
+ }
418
+ return acc;
419
+ }
420
+ acc.push(curr);
421
+ return acc;
422
+ }, []);
392
423
  const optimized = [];
393
424
  const k = selector.reduce((acc, curr) => acc == 0 ? curr.length : (curr.length == 0 ? acc : Math.min(acc, curr.length)), 0);
394
425
  let i = 0;
@@ -427,9 +458,6 @@ function reduceSelector(selector) {
427
458
  if (optimized[1] == ' ') {
428
459
  optimized.splice(0, 2);
429
460
  }
430
- // else if (combinators.includes(optimized[1])) {
431
- //
432
- // }
433
461
  }
434
462
  if (optimized.length == 0 ||
435
463
  (optimized[0].charAt(0) == '&' ||
@@ -937,18 +965,24 @@ function reduceRuleSelector(node) {
937
965
  }
938
966
  if (optimized != null && optimized.match && optimized.reducible && optimized.selector.length > 1) {
939
967
  for (const selector of optimized.selector) {
940
- if (selector.length > 1 && selector[0] == '&' && combinators.includes(selector[1])) {
968
+ if (selector.length > 1 && selector[0] == '&' &&
969
+ (combinators.includes(selector[1]) || !/^[a-zA-Z:]/.test(selector[1]))) {
941
970
  selector.shift();
942
971
  }
943
972
  }
973
+ const unique = new Set;
944
974
  const raw = [
945
975
  [
946
976
  optimized.optimized[0], ':is('
947
977
  ].concat(optimized.selector.reduce((acc, curr) => {
948
- if (acc.length > 0) {
949
- acc.push(',');
978
+ const sig = curr.join('');
979
+ if (!unique.has(sig)) {
980
+ if (acc.length > 0) {
981
+ acc.push(',');
982
+ }
983
+ unique.add(sig);
984
+ acc.push(...curr);
950
985
  }
951
- acc.push(...curr);
952
986
  return acc;
953
987
  }, [])).concat(')')
954
988
  ];
@@ -1,3 +1,8 @@
1
+ var ValidationLevel;
2
+ (function (ValidationLevel) {
3
+ ValidationLevel[ValidationLevel["Valid"] = 0] = "Valid";
4
+ ValidationLevel[ValidationLevel["Drop"] = 1] = "Drop";
5
+ })(ValidationLevel || (ValidationLevel = {}));
1
6
  var EnumToken;
2
7
  (function (EnumToken) {
3
8
  EnumToken[EnumToken["CommentTokenType"] = 0] = "CommentTokenType";
@@ -76,6 +81,16 @@ var EnumToken;
76
81
  EnumToken[EnumToken["IdenListTokenType"] = 70] = "IdenListTokenType";
77
82
  EnumToken[EnumToken["GridTemplateFuncTokenType"] = 71] = "GridTemplateFuncTokenType";
78
83
  EnumToken[EnumToken["KeyFrameRuleNodeType"] = 72] = "KeyFrameRuleNodeType";
84
+ EnumToken[EnumToken["ClassSelectorTokenType"] = 73] = "ClassSelectorTokenType";
85
+ EnumToken[EnumToken["UniversalSelectorTokenType"] = 74] = "UniversalSelectorTokenType";
86
+ EnumToken[EnumToken["ChildCombinatorTokenType"] = 75] = "ChildCombinatorTokenType";
87
+ EnumToken[EnumToken["DescendantCombinatorTokenType"] = 76] = "DescendantCombinatorTokenType";
88
+ EnumToken[EnumToken["NextSiblingCombinatorTokenType"] = 77] = "NextSiblingCombinatorTokenType";
89
+ EnumToken[EnumToken["SubsequentSiblingCombinatorTokenType"] = 78] = "SubsequentSiblingCombinatorTokenType";
90
+ EnumToken[EnumToken["NestingSelectorTokenType"] = 79] = "NestingSelectorTokenType";
91
+ EnumToken[EnumToken["InvalidRuleTokenType"] = 80] = "InvalidRuleTokenType";
92
+ EnumToken[EnumToken["InvalidClassSelectorTokenType"] = 81] = "InvalidClassSelectorTokenType";
93
+ EnumToken[EnumToken["InvalidAttrTokenType"] = 82] = "InvalidAttrTokenType";
79
94
  /* aliases */
80
95
  EnumToken[EnumToken["Time"] = 25] = "Time";
81
96
  EnumToken[EnumToken["Iden"] = 7] = "Iden";
@@ -117,4 +132,4 @@ const funcLike = [
117
132
  EnumToken.GridTemplateFuncTokenType
118
133
  ];
119
134
 
120
- export { EnumToken, funcLike };
135
+ export { EnumToken, ValidationLevel, funcLike };
@@ -32,6 +32,7 @@ function* walkValues(values, root = null, filter) {
32
32
  const stack = values.slice();
33
33
  const map = new Map;
34
34
  let value;
35
+ let previous = null;
35
36
  while ((value = stack.shift())) {
36
37
  let option = null;
37
38
  if (filter != null) {
@@ -46,7 +47,7 @@ function* walkValues(values, root = null, filter) {
46
47
  // @ts-ignore
47
48
  if (option !== 'children') {
48
49
  // @ts-ignore
49
- yield { value, parent: map.get(value), root };
50
+ yield { value, parent: map.get(value), previousValue: previous, nextValue: stack[0] ?? null, root };
50
51
  }
51
52
  if (option !== 'ignore-children' && 'chi' in value) {
52
53
  for (const child of value.chi.slice()) {
@@ -59,6 +60,7 @@ function* walkValues(values, root = null, filter) {
59
60
  map.set(value.r, value);
60
61
  stack.unshift(value.l, value.r);
61
62
  }
63
+ previous = value;
62
64
  }
63
65
  }
64
66
 
@@ -1,10 +1,10 @@
1
1
  import { PropertySet } from './set.js';
2
+ import { getConfig } from '../utils/config.js';
2
3
  import { EnumToken } from '../../ast/types.js';
3
4
  import '../../ast/minify.js';
4
5
  import { parseString } from '../parse.js';
5
6
  import '../../renderer/color/utils/constants.js';
6
7
  import '../../renderer/sourcemap/lib/encode.js';
7
- import { getConfig } from '../utils/config.js';
8
8
  import { PropertyMap } from './map.js';
9
9
 
10
10
  const config = getConfig();
@@ -1,11 +1,11 @@
1
1
  import { eq } from '../utils/eq.js';
2
- import { renderToken } from '../../renderer/render.js';
2
+ import { getConfig } from '../utils/config.js';
3
+ import { matchType } from '../utils/type.js';
3
4
  import { EnumToken } from '../../ast/types.js';
4
5
  import '../../ast/minify.js';
5
6
  import { parseString } from '../parse.js';
7
+ import { renderToken } from '../../renderer/render.js';
6
8
  import '../../renderer/color/utils/constants.js';
7
- import { getConfig } from '../utils/config.js';
8
- import { matchType } from '../utils/type.js';
9
9
  import { PropertySet } from './set.js';
10
10
 
11
11
  const propertiesConfig = getConfig();
@@ -248,7 +248,9 @@ class PropertyMap {
248
248
  // @ts-ignore
249
249
  let typ = (EnumToken[this.config.separator?.typ] ?? EnumToken.CommaTokenType);
250
250
  // @ts-ignore
251
- let separator = this.config.separator ? renderToken(this.config.separator) : ',';
251
+ const sep = this.config.separator == null ? null : { ...this.config.separator, typ: EnumToken[this.config.separator.typ] };
252
+ // @ts-ignore
253
+ const separator = this.config.separator ? renderToken({ ...this.config.separator, typ: EnumToken[this.config.separator.typ] }) : ',';
252
254
  this.matchTypes(declaration);
253
255
  values.push(value);
254
256
  for (i = 0; i < declaration.val.length; i++) {
@@ -281,6 +283,9 @@ class PropertyMap {
281
283
  }
282
284
  this.removeDefaults(map, value);
283
285
  declaration.val = values.reduce((acc, curr) => {
286
+ if (sep != null && acc.length > 0) {
287
+ acc.push({ ...sep });
288
+ }
284
289
  for (const cr of curr) {
285
290
  if (cr.typ == EnumToken.WhitespaceTokenType && acc.at(-1)?.typ == cr.typ) {
286
291
  continue;
@@ -1,8 +1,9 @@
1
1
  import { eq } from '../utils/eq.js';
2
- import { isLength } from '../utils/syntax.js';
3
2
  import { EnumToken } from '../../ast/types.js';
4
3
  import '../../ast/minify.js';
5
4
  import '../parse.js';
5
+ import { isLength } from '../../syntax/syntax.js';
6
+ import '../utils/config.js';
6
7
  import '../../renderer/color/utils/constants.js';
7
8
  import '../../renderer/sourcemap/lib/encode.js';
8
9