@@ -502,6 +502,130 @@ export const cssModules = {
502
502
*/
503
503
export type CssModule = keyof typeof cssModules ;
504
504
505
+ /**
506
+ * Maps pseudo-classes and pseudo-elements to their CSS Level or CSS Module
507
+ */
508
+ export interface PseudoLocationIndex {
509
+ pseudoClasses : Record < string , string [ ] > ;
510
+ pseudoElements : Record < string , string [ ] > ;
511
+ }
512
+
513
+ /**
514
+ * Builds an index of where each pseudo-class and pseudo-element is defined
515
+ * (in which CSS Level or CSS Module)
516
+ */
517
+ export function buildPseudoLocationIndex ( ) : PseudoLocationIndex {
518
+ const index : PseudoLocationIndex = {
519
+ pseudoClasses : { } ,
520
+ pseudoElements : { }
521
+ } ;
522
+
523
+ // Add CSS Levels (excluding 'latest' and 'progressive')
524
+ const cssLevels : CssLevel [ ] = [ 'css1' , 'css2' , 'css3' , 'selectors-3' , 'selectors-4' ] ;
525
+
526
+ for ( const level of cssLevels ) {
527
+ const syntax = cssSyntaxDefinitions [ level ] ;
528
+
529
+ // Process pseudo-classes
530
+ if ( syntax . pseudoClasses && typeof syntax . pseudoClasses === 'object' ) {
531
+ const { definitions } = syntax . pseudoClasses ;
532
+ if ( definitions ) {
533
+ for ( const [ type , names ] of Object . entries ( definitions ) ) {
534
+ for ( const name of names ) {
535
+ if ( ! index . pseudoClasses [ name ] ) {
536
+ index . pseudoClasses [ name ] = [ ] ;
537
+ }
538
+ if ( ! index . pseudoClasses [ name ] . includes ( level ) ) {
539
+ index . pseudoClasses [ name ] . push ( level ) ;
540
+ }
541
+ }
542
+ }
543
+ }
544
+ }
545
+
546
+ // Process pseudo-elements
547
+ if ( syntax . pseudoElements && typeof syntax . pseudoElements === 'object' ) {
548
+ const { definitions } = syntax . pseudoElements ;
549
+ if ( definitions ) {
550
+ if ( Array . isArray ( definitions ) ) {
551
+ for ( const name of definitions ) {
552
+ if ( ! index . pseudoElements [ name ] ) {
553
+ index . pseudoElements [ name ] = [ ] ;
554
+ }
555
+ if ( ! index . pseudoElements [ name ] . includes ( level ) ) {
556
+ index . pseudoElements [ name ] . push ( level ) ;
557
+ }
558
+ }
559
+ } else {
560
+ for ( const [ type , names ] of Object . entries ( definitions ) ) {
561
+ for ( const name of names ) {
562
+ if ( ! index . pseudoElements [ name ] ) {
563
+ index . pseudoElements [ name ] = [ ] ;
564
+ }
565
+ if ( ! index . pseudoElements [ name ] . includes ( level ) ) {
566
+ index . pseudoElements [ name ] . push ( level ) ;
567
+ }
568
+ }
569
+ }
570
+ }
571
+ }
572
+ }
573
+ }
574
+
575
+ // Add CSS Modules
576
+ for ( const [ moduleName , moduleSyntax ] of Object . entries ( cssModules ) ) {
577
+ // Process pseudo-classes
578
+ if ( moduleSyntax . pseudoClasses && typeof moduleSyntax . pseudoClasses === 'object' ) {
579
+ const { definitions } = moduleSyntax . pseudoClasses ;
580
+ if ( definitions ) {
581
+ for ( const [ type , names ] of Object . entries ( definitions ) ) {
582
+ for ( const name of names ) {
583
+ if ( ! index . pseudoClasses [ name ] ) {
584
+ index . pseudoClasses [ name ] = [ ] ;
585
+ }
586
+ if ( ! index . pseudoClasses [ name ] . includes ( moduleName ) ) {
587
+ index . pseudoClasses [ name ] . push ( moduleName ) ;
588
+ }
589
+ }
590
+ }
591
+ }
592
+ }
593
+
594
+ // Process pseudo-elements
595
+ if ( moduleSyntax . pseudoElements && typeof moduleSyntax . pseudoElements === 'object' ) {
596
+ const { definitions } = moduleSyntax . pseudoElements ;
597
+ if ( definitions ) {
598
+ if ( Array . isArray ( definitions ) ) {
599
+ for ( const name of definitions ) {
600
+ if ( ! index . pseudoElements [ name ] ) {
601
+ index . pseudoElements [ name ] = [ ] ;
602
+ }
603
+ if ( ! index . pseudoElements [ name ] . includes ( moduleName ) ) {
604
+ index . pseudoElements [ name ] . push ( moduleName ) ;
605
+ }
606
+ }
607
+ } else {
608
+ for ( const [ type , names ] of Object . entries ( definitions ) ) {
609
+ for ( const name of names ) {
610
+ if ( ! index . pseudoElements [ name ] ) {
611
+ index . pseudoElements [ name ] = [ ] ;
612
+ }
613
+ if ( ! index . pseudoElements [ name ] . includes ( moduleName ) ) {
614
+ index . pseudoElements [ name ] . push ( moduleName ) ;
615
+ }
616
+ }
617
+ }
618
+ }
619
+ }
620
+ }
621
+ }
622
+
623
+ return index ;
624
+ }
625
+
626
+ // Pre-build the index for faster lookup
627
+ export const pseudoLocationIndex = buildPseudoLocationIndex ( ) ;
628
+
505
629
const latestSyntaxDefinition = {
506
630
...selectors4SyntaxDefinition ,
507
631
modules : ( Object . entries ( cssModules ) as [ CssModule , SyntaxDefinition & { latest ?: boolean } ] [ ] )
0 commit comments