@@ -6,18 +6,6 @@ const { extractICSS } = require("icss-utils");
66
77const isSpacing = ( node ) => node . type === "combinator" && node . value === " " ;
88
9- function getImportLocalAliases ( icssImports ) {
10- const localAliases = new Map ( ) ;
11-
12- Object . keys ( icssImports ) . forEach ( ( key ) => {
13- Object . keys ( icssImports [ key ] ) . forEach ( ( prop ) => {
14- localAliases . set ( prop , icssImports [ key ] [ prop ] ) ;
15- } ) ;
16- } ) ;
17-
18- return localAliases ;
19- }
20-
219function normalizeNodeArray ( nodes ) {
2210 const array = [ ] ;
2311
@@ -432,6 +420,8 @@ function localizeDecl(decl, context) {
432420 }
433421}
434422
423+ const isVisited = Symbol ( "isVisited" ) ;
424+
435425module . exports = ( options = { } ) => {
436426 if ( options && options . mode ) {
437427 if (
@@ -450,85 +440,108 @@ module.exports = (options = {}) => {
450440
451441 return {
452442 postcssPlugin : "postcss-modules-local-by-default" ,
453- RootExit ( root ) {
454- const { icssImports } = extractICSS ( root , false ) ;
455- const localAliasMap = getImportLocalAliases ( icssImports ) ;
443+ prepare ( ) {
444+ const localAliasMap = new Map ( ) ;
456445
457- root . walkAtRules ( function ( atrule ) {
458- if ( / k e y f r a m e s $ / i. test ( atrule . name ) ) {
459- const globalMatch = / ^ \s * : g l o b a l \s * \( ( .+ ) \) \s * $ / . exec ( atrule . params ) ;
460- const localMatch = / ^ \s * : l o c a l \s * \( ( .+ ) \) \s * $ / . exec ( atrule . params ) ;
446+ return {
447+ Once ( root ) {
448+ const { icssImports } = extractICSS ( root , false ) ;
461449
462- let globalKeyframes = globalMode ;
450+ Object . keys ( icssImports ) . forEach ( ( key ) => {
451+ Object . keys ( icssImports [ key ] ) . forEach ( ( prop ) => {
452+ localAliasMap . set ( prop , icssImports [ key ] [ prop ] ) ;
453+ } ) ;
454+ } ) ;
455+ } ,
456+ AtRule ( atRule ) {
457+ if ( atRule [ isVisited ] ) {
458+ return ;
459+ }
463460
464- if ( globalMatch ) {
465- if ( pureMode ) {
466- throw atrule . error (
467- "@keyframes :global(...) is not allowed in pure mode"
468- ) ;
469- }
470- atrule . params = globalMatch [ 1 ] ;
471- globalKeyframes = true ;
472- } else if ( localMatch ) {
473- atrule . params = localMatch [ 0 ] ;
474- globalKeyframes = false ;
475- } else if ( ! globalMode ) {
476- if ( atrule . params && ! localAliasMap . has ( atrule . params ) ) {
477- atrule . params = ":local(" + atrule . params + ")" ;
461+ if ( / k e y f r a m e s $ / i. test ( atRule . name ) ) {
462+ const globalMatch = / ^ \s * : g l o b a l \s * \( ( .+ ) \) \s * $ / . exec (
463+ atRule . params
464+ ) ;
465+ const localMatch = / ^ \s * : l o c a l \s * \( ( .+ ) \) \s * $ / . exec ( atRule . params ) ;
466+
467+ let globalKeyframes = globalMode ;
468+
469+ if ( globalMatch ) {
470+ if ( pureMode ) {
471+ throw atRule . error (
472+ "@keyframes :global(...) is not allowed in pure mode"
473+ ) ;
474+ }
475+ atRule . params = globalMatch [ 1 ] ;
476+ globalKeyframes = true ;
477+ } else if ( localMatch ) {
478+ atRule . params = localMatch [ 0 ] ;
479+ globalKeyframes = false ;
480+ } else if ( ! globalMode ) {
481+ if ( atRule . params && ! localAliasMap . has ( atRule . params ) ) {
482+ atRule . params = ":local(" + atRule . params + ")" ;
483+ }
478484 }
479- }
480485
481- atrule . walkDecls ( function ( decl ) {
482- localizeDecl ( decl , {
483- localAliasMap,
484- options : options ,
485- global : globalKeyframes ,
486- } ) ;
487- } ) ;
488- } else if ( atrule . nodes ) {
489- atrule . nodes . forEach ( function ( decl ) {
490- if ( decl . type === "decl" ) {
486+ atRule . walkDecls ( function ( decl ) {
491487 localizeDecl ( decl , {
492488 localAliasMap,
493489 options : options ,
494- global : globalMode ,
490+ global : globalKeyframes ,
495491 } ) ;
496- }
497- } ) ;
498- }
499- } ) ;
492+ } ) ;
493+ } else if ( atRule . nodes ) {
494+ atRule . nodes . forEach ( function ( decl ) {
495+ if ( decl . type === "decl" ) {
496+ localizeDecl ( decl , {
497+ localAliasMap,
498+ options : options ,
499+ global : globalMode ,
500+ } ) ;
501+ }
502+ } ) ;
503+ }
500504
501- root . walkRules ( function ( rule ) {
502- if (
503- rule . parent &&
504- rule . parent . type === "atrule" &&
505- / k e y f r a m e s $ / i. test ( rule . parent . name )
506- ) {
507- // ignore keyframe rules
508- return ;
509- }
505+ atRule [ isVisited ] = true ;
506+ } ,
507+ Rule ( rule ) {
508+ if ( rule [ isVisited ] ) {
509+ return ;
510+ }
510511
511- const context = localizeNode ( rule , options . mode , localAliasMap ) ;
512+ if (
513+ rule . parent &&
514+ rule . parent . type === "atrule" &&
515+ / k e y f r a m e s $ / i. test ( rule . parent . name )
516+ ) {
517+ // ignore keyframe rules
518+ return ;
519+ }
512520
513- context . options = options ;
514- context . localAliasMap = localAliasMap ;
521+ const context = localizeNode ( rule , options . mode , localAliasMap ) ;
515522
516- if ( pureMode && context . hasPureGlobals ) {
517- throw rule . error (
518- 'Selector "' +
519- rule . selector +
520- '" is not pure ' +
521- "(pure selectors must contain at least one local class or id)"
522- ) ;
523- }
523+ context . options = options ;
524+ context . localAliasMap = localAliasMap ;
525+
526+ if ( pureMode && context . hasPureGlobals ) {
527+ throw rule . error (
528+ 'Selector "' +
529+ rule . selector +
530+ '" is not pure ' +
531+ "(pure selectors must contain at least one local class or id)"
532+ ) ;
533+ }
524534
525- rule . selector = context . selector ;
535+ rule . selector = context . selector ;
526536
527- // Less-syntax mixins parse as rules with no nodes
528- if ( rule . nodes ) {
529- rule . nodes . forEach ( ( decl ) => localizeDecl ( decl , context ) ) ;
530- }
531- } ) ;
537+ // Less-syntax mixins parse as rules with no nodes
538+ if ( rule . nodes ) {
539+ rule . nodes . forEach ( ( decl ) => localizeDecl ( decl , context ) ) ;
540+ }
541+
542+ rule [ isVisited ] = true ;
543+ } ,
544+ } ;
532545 } ,
533546 } ;
534547} ;
0 commit comments