@@ -160,10 +160,49 @@ function localizeNode(node, context) {
160
160
return node ;
161
161
}
162
162
163
- function localizeDecl ( decl ) {
164
- if ( typeof decl . prop === "string" && / a n i m a t i o n ( - n a m e ) ? / . test ( decl . prop ) ) {
165
- decl . value = decl . value . replace ( / ( ^ | , ) ( \s * ) ( \w + ) / g, "$1$2:local($3)" ) ; // TODO
163
+ function localizeDeclNode ( node , context ) {
164
+ var newNode ;
165
+ switch ( node . type ) {
166
+ case "item" :
167
+ if ( context . localizeNextItem ) {
168
+ newNode = Object . create ( node ) ;
169
+ newNode . name = ":local(" + newNode . name + ")" ;
170
+ context . localizeNextItem = false ;
171
+ return newNode ;
172
+ }
173
+ break ;
174
+ case "url" :
175
+ if ( context . options . rewriteUrl ) {
176
+ newNode = Object . create ( node ) ;
177
+ newNode . url = context . options . rewriteUrl ( context . global , node . url ) ;
178
+ return newNode ;
179
+ }
180
+ break ;
166
181
}
182
+ return node ;
183
+ }
184
+
185
+ function localizeDeclValue ( valueNode , context ) {
186
+ var newValueNode = Object . create ( valueNode ) ;
187
+ newValueNode . nodes = valueNode . nodes . map ( function ( node ) {
188
+ return localizeDeclNode ( node , context ) ;
189
+ } ) ;
190
+ return newValueNode ;
191
+ }
192
+
193
+ function localizeDecl ( decl , context ) {
194
+ var valuesNode = Tokenizer . parseValues ( decl . value ) ;
195
+ var localizeName = / a n i m a t i o n ( - n a m e ) ? / . test ( decl . prop ) ;
196
+ var newValuesNode = Object . create ( valuesNode ) ;
197
+ newValuesNode . nodes = valuesNode . nodes . map ( function ( valueNode ) {
198
+ var subContext = {
199
+ options : context . options ,
200
+ global : context . global ,
201
+ localizeNextItem : localizeName && ! context . global
202
+ } ;
203
+ return localizeDeclValue ( valueNode , subContext ) ;
204
+ } ) ;
205
+ decl . value = Tokenizer . stringifyValues ( newValuesNode ) ;
167
206
}
168
207
169
208
module . exports = postcss . plugin ( 'postcss-modules-local-by-default' , function ( options ) {
@@ -181,7 +220,7 @@ module.exports = postcss.plugin('postcss-modules-local-by-default', function (op
181
220
var localMatch = / ^ \s * : l o c a l \s * \( ( .+ ) \) \s * $ / . exec ( atrule . params ) ;
182
221
if ( globalMatch ) {
183
222
if ( pureMode ) {
184
- throw new Error ( "@keyframes :global(...) is not allowed in pure mode" ) ;
223
+ throw atrule . error ( "@keyframes :global(...) is not allowed in pure mode" ) ;
185
224
}
186
225
atrule . params = globalMatch [ 1 ] ;
187
226
} else if ( localMatch ) {
@@ -194,22 +233,28 @@ module.exports = postcss.plugin('postcss-modules-local-by-default', function (op
194
233
css . eachRule ( function ( rule ) {
195
234
var selector = Tokenizer . parse ( rule . selector ) ;
196
235
var context = {
236
+ options : options ,
197
237
global : globalMode ,
198
238
hasPureGlobals : false ,
199
239
hasPureImplicitGlobals : false
200
240
} ;
201
- var newSelector = localizeNode ( selector , context ) ;
241
+ var newSelector ;
242
+ try {
243
+ newSelector = localizeNode ( selector , context ) ;
244
+ } catch ( e ) {
245
+ throw rule . error ( e . message ) ;
246
+ }
202
247
if ( pureMode && context . hasPureGlobals ) {
203
- throw new Error ( "Selector '" + Tokenizer . stringify ( selector ) + "' is not pure " +
248
+ throw rule . error ( "Selector '" + Tokenizer . stringify ( selector ) + "' is not pure " +
204
249
"(pure selectors must contain at least one local class or id)" ) ;
205
250
}
206
251
if ( ! globalMode && context . hasPureImplicitGlobals ) {
207
- throw new Error ( "Selector '" + Tokenizer . stringify ( selector ) + "' must be explicit flagged :global " +
252
+ throw rule . error ( "Selector '" + Tokenizer . stringify ( selector ) + "' must be explicit flagged :global " +
208
253
"(elsewise it would leak globally)" ) ;
209
254
}
210
- if ( ! context . global ) {
211
- rule . nodes . forEach ( localizeDecl ) ;
212
- }
255
+ rule . nodes . forEach ( function ( decl ) {
256
+ localizeDecl ( decl , context ) ;
257
+ } ) ;
213
258
rule . selector = Tokenizer . stringify ( newSelector ) ;
214
259
} ) ;
215
260
} ;
0 commit comments