1- ' use strict' ;
1+ " use strict" ;
22
3- const postcss = require ( ' postcss' ) ;
4- const ICSSUtils = require ( ' icss-utils' ) ;
3+ const postcss = require ( " postcss" ) ;
4+ const ICSSUtils = require ( " icss-utils" ) ;
55
66const matchImports = / ^ ( .+ ?| \( [ \s \S ] + ?\) ) \s + f r o m \s + ( " [ ^ " ] * " | ' [ ^ ' ] * ' | [ \w - ] + ) $ / ;
77const matchValueDefinition = / (?: \s + | ^ ) ( [ \w - ] + ) : ? \s + ( .+ ?) \s * $ / g;
@@ -12,107 +12,124 @@ let importIndex = 0;
1212let createImportedName =
1313 ( options && options . createImportedName ) ||
1414 ( ( importName /*, path*/ ) =>
15- `i__const_${ importName . replace ( / \W / g, '_' ) } _${ importIndex ++ } ` ) ;
16-
17- module . exports = postcss . plugin (
18- 'postcss-modules-values' ,
19- ( ) => ( css , result ) => {
20- const importAliases = [ ] ;
21- const definitions = { } ;
22-
23- const addDefinition = atRule => {
24- let matches ;
25- while ( ( matches = matchValueDefinition . exec ( atRule . params ) ) ) {
26- let [ , /*match*/ key , value ] = matches ;
27- // Add to the definitions, knowing that values can refer to each other
28- definitions [ key ] = ICSSUtils . replaceValueSymbols ( value , definitions ) ;
29- atRule . remove ( ) ;
30- }
31- } ;
32-
33- const addImport = atRule => {
34- const matches = matchImports . exec ( atRule . params ) ;
35- if ( matches ) {
36- let [ , /*match*/ aliases , path ] = matches ;
37- // We can use constants for path names
38- if ( definitions [ path ] ) {
39- path = definitions [ path ] ;
15+ `i__const_${ importName . replace ( / \W / g, "_" ) } _${ importIndex ++ } ` ) ;
16+
17+ module . exports = ( ) => {
18+ return {
19+ postcssPlugin : "postcss-modules-values" ,
20+ prepare ( result ) {
21+ const importAliases = [ ] ;
22+ const definitions = { } ;
23+ const addDefinition = ( atRule ) => {
24+ let matches ;
25+
26+ while ( ( matches = matchValueDefinition . exec ( atRule . params ) ) ) {
27+ let [ , /*match*/ key , value ] = matches ;
28+
29+ // Add to the definitions, knowing that values can refer to each other
30+ definitions [ key ] = ICSSUtils . replaceValueSymbols ( value , definitions ) ;
31+ atRule . remove ( ) ;
4032 }
41- const imports = aliases
42- . replace ( / ^ \( \s * ( [ \s \S ] + ) \s * \) $ / , '$1' )
43- . split ( / \s * , \s * / )
44- . map ( alias => {
45- const tokens = matchImport . exec ( alias ) ;
46- if ( tokens ) {
47- const [ , /*match*/ theirName , myName = theirName ] = tokens ;
48- const importedName = createImportedName ( myName ) ;
49- definitions [ myName ] = importedName ;
50- return { theirName, importedName } ;
33+ } ;
34+ const addImport = ( atRule ) => {
35+ const matches = matchImports . exec ( atRule . params ) ;
36+
37+ if ( matches ) {
38+ let [ , /*match*/ aliases , path ] = matches ;
39+
40+ // We can use constants for path names
41+ if ( definitions [ path ] ) {
42+ path = definitions [ path ] ;
43+ }
44+
45+ const imports = aliases
46+ . replace ( / ^ \( \s * ( [ \s \S ] + ) \s * \) $ / , "$1" )
47+ . split ( / \s * , \s * / )
48+ . map ( ( alias ) => {
49+ const tokens = matchImport . exec ( alias ) ;
50+
51+ if ( tokens ) {
52+ const [ , /*match*/ theirName , myName = theirName ] = tokens ;
53+ const importedName = createImportedName ( myName ) ;
54+ definitions [ myName ] = importedName ;
55+ return { theirName, importedName } ;
56+ } else {
57+ throw new Error ( `@import statement "${ alias } " is invalid!` ) ;
58+ }
59+ } ) ;
60+
61+ importAliases . push ( { path, imports } ) ;
62+
63+ atRule . remove ( ) ;
64+ }
65+ } ;
66+
67+ return {
68+ /* Look at all the @value statements and treat them as locals or as imports */
69+ AtRule : {
70+ value ( atRule ) {
71+ if ( matchImports . exec ( atRule . params ) ) {
72+ addImport ( atRule ) ;
5173 } else {
52- throw new Error ( `@import statement "${ alias } " is invalid!` ) ;
74+ if ( atRule . params . indexOf ( "@value" ) !== - 1 ) {
75+ result . warn ( "Invalid value definition: " + atRule . params ) ;
76+ }
77+
78+ addDefinition ( atRule ) ;
5379 }
80+ } ,
81+ } ,
82+ RootExit ( root ) {
83+ /* We want to export anything defined by now, but don't add it to the CSS yet or it well get picked up by the replacement stuff */
84+ const exportDeclarations = Object . keys ( definitions ) . map ( ( key ) =>
85+ postcss . decl ( {
86+ value : definitions [ key ] ,
87+ prop : key ,
88+ raws : { before : "\n " } ,
89+ } )
90+ ) ;
91+
92+ /* If we have no definitions, don't continue */
93+ if ( ! Object . keys ( definitions ) . length ) {
94+ return ;
95+ }
96+
97+ /* Perform replacements */
98+ ICSSUtils . replaceSymbols ( root , definitions ) ;
99+
100+ /* Add export rules if any */
101+ if ( exportDeclarations . length > 0 ) {
102+ const exportRule = postcss . rule ( {
103+ selector : ":export" ,
104+ raws : { after : "\n" } ,
105+ } ) ;
106+
107+ exportRule . append ( exportDeclarations ) ;
108+
109+ root . prepend ( exportRule ) ;
110+ }
111+
112+ /* Add import rules */
113+ importAliases . reverse ( ) . forEach ( ( { path, imports } ) => {
114+ const importRule = postcss . rule ( {
115+ selector : `:import(${ path } )` ,
116+ raws : { after : "\n" } ,
117+ } ) ;
118+
119+ imports . forEach ( ( { theirName, importedName } ) => {
120+ importRule . append ( {
121+ value : theirName ,
122+ prop : importedName ,
123+ raws : { before : "\n " } ,
124+ } ) ;
125+ } ) ;
126+
127+ root . prepend ( importRule ) ;
54128 } ) ;
55- importAliases . push ( { path, imports } ) ;
56- atRule . remove ( ) ;
57- }
58- } ;
59-
60- /* Look at all the @value statements and treat them as locals or as imports */
61- css . walkAtRules ( 'value' , atRule => {
62- if ( matchImports . exec ( atRule . params ) ) {
63- addImport ( atRule ) ;
64- } else {
65- if ( atRule . params . indexOf ( '@value' ) !== - 1 ) {
66- result . warn ( 'Invalid value definition: ' + atRule . params ) ;
67- }
129+ } ,
130+ } ;
131+ } ,
132+ } ;
133+ } ;
68134
69- addDefinition ( atRule ) ;
70- }
71- } ) ;
72-
73- /* We want to export anything defined by now, but don't add it to the CSS yet or
74- it well get picked up by the replacement stuff */
75- const exportDeclarations = Object . keys ( definitions ) . map ( key =>
76- postcss . decl ( {
77- value : definitions [ key ] ,
78- prop : key ,
79- raws : { before : '\n ' }
80- } )
81- ) ;
82-
83- /* If we have no definitions, don't continue */
84- if ( ! Object . keys ( definitions ) . length ) {
85- return ;
86- }
87-
88- /* Perform replacements */
89- ICSSUtils . replaceSymbols ( css , definitions ) ;
90-
91- /* Add export rules if any */
92- if ( exportDeclarations . length > 0 ) {
93- const exportRule = postcss . rule ( {
94- selector : ':export' ,
95- raws : { after : '\n' }
96- } ) ;
97- exportRule . append ( exportDeclarations ) ;
98- css . prepend ( exportRule ) ;
99- }
100-
101- /* Add import rules */
102- importAliases . reverse ( ) . forEach ( ( { path, imports } ) => {
103- const importRule = postcss . rule ( {
104- selector : `:import(${ path } )` ,
105- raws : { after : '\n' }
106- } ) ;
107- imports . forEach ( ( { theirName, importedName } ) => {
108- importRule . append ( {
109- value : theirName ,
110- prop : importedName ,
111- raws : { before : '\n ' }
112- } ) ;
113- } ) ;
114-
115- css . prepend ( importRule ) ;
116- } ) ;
117- }
118- ) ;
135+ module . exports . postcss = true ;
0 commit comments