@@ -26,20 +26,17 @@ function normalizeNodeArray(nodes) {
26
26
}
27
27
28
28
function localizeNode ( rule , mode , localAliasMap ) {
29
- const isScopePseudo = ( node ) =>
30
- node . value === ":local" || node . value === ":global" ;
31
- const isImportExportPseudo = ( node ) =>
32
- node . value === ":import" || node . value === ":export" ;
33
-
34
29
const transform = ( node , context ) => {
35
30
if ( context . ignoreNextSpacing && ! isSpacing ( node ) ) {
36
31
throw new Error ( "Missing whitespace after " + context . ignoreNextSpacing ) ;
37
32
}
33
+
38
34
if ( context . enforceNoSpacing && isSpacing ( node ) ) {
39
35
throw new Error ( "Missing whitespace before " + context . enforceNoSpacing ) ;
40
36
}
41
37
42
38
let newNodes ;
39
+
43
40
switch ( node . type ) {
44
41
case "root" : {
45
42
let resultingGlobal ;
@@ -101,8 +98,9 @@ function localizeNode(rule, mode, localAliasMap) {
101
98
case "pseudo" : {
102
99
let childContext ;
103
100
const isNested = ! ! node . length ;
104
- const isScoped = isScopePseudo ( node ) ;
105
- const isImportExport = isImportExportPseudo ( node ) ;
101
+ const isScoped = node . value === ":local" || node . value === ":global" ;
102
+ const isImportExport =
103
+ node . value === ":import" || node . value === ":export" ;
106
104
107
105
if ( isImportExport ) {
108
106
context . hasLocals = true ;
@@ -303,91 +301,9 @@ function isWordAFunctionArgument(wordNode, functionNode) {
303
301
: false ;
304
302
}
305
303
306
- function localizeAnimationShorthandDeclValues ( decl , context ) {
307
- const validIdent = / ^ - ? [ _ a - z ] [ _ a - z 0 - 9 - ] * $ / i;
308
-
309
- /*
310
- The spec defines some keywords that you can use to describe properties such as the timing
311
- function. These are still valid animation names, so as long as there is a property that accepts
312
- a keyword, it is given priority. Only when all the properties that can take a keyword are
313
- exhausted can the animation name be set to the keyword. I.e.
314
-
315
- animation: infinite infinite;
316
-
317
- The animation will repeat an infinite number of times from the first argument, and will have an
318
- animation name of infinite from the second.
319
- */
320
- const animationKeywords = {
321
- $alternate : 1 ,
322
- "$alternate-reverse" : 1 ,
323
- $backwards : 1 ,
324
- $both : 1 ,
325
- $ease : 1 ,
326
- "$ease-in" : 1 ,
327
- "$ease-in-out" : 1 ,
328
- "$ease-out" : 1 ,
329
- $forwards : 1 ,
330
- $infinite : 1 ,
331
- $linear : 1 ,
332
- $none : Infinity , // No matter how many times you write none, it will never be an animation name
333
- $normal : 1 ,
334
- $paused : 1 ,
335
- $reverse : 1 ,
336
- $running : 1 ,
337
- "$step-end" : 1 ,
338
- "$step-start" : 1 ,
339
- $initial : Infinity ,
340
- $inherit : Infinity ,
341
- $unset : Infinity ,
342
- } ;
343
-
344
- const didParseAnimationName = false ;
345
- let parsedAnimationKeywords = { } ;
346
- let stepsFunctionNode = null ;
347
- const valueNodes = valueParser ( decl . value ) . walk ( ( node ) => {
348
- /* If div-token appeared (represents as comma ','), a possibility of an animation-keywords should be reflesh. */
349
- if ( node . type === "div" ) {
350
- parsedAnimationKeywords = { } ;
351
- }
352
- if ( node . type === "function" && node . value . toLowerCase ( ) === "steps" ) {
353
- stepsFunctionNode = node ;
354
- }
355
- const value =
356
- node . type === "word" && ! isWordAFunctionArgument ( node , stepsFunctionNode )
357
- ? node . value . toLowerCase ( )
358
- : null ;
359
-
360
- let shouldParseAnimationName = false ;
361
-
362
- if ( ! didParseAnimationName && value && validIdent . test ( value ) ) {
363
- if ( "$" + value in animationKeywords ) {
364
- parsedAnimationKeywords [ "$" + value ] =
365
- "$" + value in parsedAnimationKeywords
366
- ? parsedAnimationKeywords [ "$" + value ] + 1
367
- : 0 ;
368
-
369
- shouldParseAnimationName =
370
- parsedAnimationKeywords [ "$" + value ] >=
371
- animationKeywords [ "$" + value ] ;
372
- } else {
373
- shouldParseAnimationName = true ;
374
- }
375
- }
376
-
377
- const subContext = {
378
- options : context . options ,
379
- global : context . global ,
380
- localizeNextItem : shouldParseAnimationName && ! context . global ,
381
- localAliasMap : context . localAliasMap ,
382
- } ;
383
- return localizeDeclNode ( node , subContext ) ;
384
- } ) ;
385
-
386
- decl . value = valueNodes . toString ( ) ;
387
- }
388
-
389
304
function localizeDeclValues ( localize , decl , context ) {
390
305
const valueNodes = valueParser ( decl . value ) ;
306
+
391
307
valueNodes . walk ( ( node , index , nodes ) => {
392
308
const subContext = {
393
309
options : context . options ,
@@ -404,7 +320,89 @@ function localizeDecl(decl, context) {
404
320
const isAnimation = / a n i m a t i o n $ / i. test ( decl . prop ) ;
405
321
406
322
if ( isAnimation ) {
407
- return localizeAnimationShorthandDeclValues ( decl , context ) ;
323
+ const validIdent = / ^ - ? [ _ a - z ] [ _ a - z 0 - 9 - ] * $ / i;
324
+
325
+ /*
326
+ The spec defines some keywords that you can use to describe properties such as the timing
327
+ function. These are still valid animation names, so as long as there is a property that accepts
328
+ a keyword, it is given priority. Only when all the properties that can take a keyword are
329
+ exhausted can the animation name be set to the keyword. I.e.
330
+
331
+ animation: infinite infinite;
332
+
333
+ The animation will repeat an infinite number of times from the first argument, and will have an
334
+ animation name of infinite from the second.
335
+ */
336
+ const animationKeywords = {
337
+ $alternate : 1 ,
338
+ "$alternate-reverse" : 1 ,
339
+ $backwards : 1 ,
340
+ $both : 1 ,
341
+ $ease : 1 ,
342
+ "$ease-in" : 1 ,
343
+ "$ease-in-out" : 1 ,
344
+ "$ease-out" : 1 ,
345
+ $forwards : 1 ,
346
+ $infinite : 1 ,
347
+ $linear : 1 ,
348
+ $none : Infinity , // No matter how many times you write none, it will never be an animation name
349
+ $normal : 1 ,
350
+ $paused : 1 ,
351
+ $reverse : 1 ,
352
+ $running : 1 ,
353
+ "$step-end" : 1 ,
354
+ "$step-start" : 1 ,
355
+ $initial : Infinity ,
356
+ $inherit : Infinity ,
357
+ $unset : Infinity ,
358
+ } ;
359
+
360
+ const didParseAnimationName = false ;
361
+ let parsedAnimationKeywords = { } ;
362
+ let stepsFunctionNode = null ;
363
+ const valueNodes = valueParser ( decl . value ) . walk ( ( node ) => {
364
+ /* If div-token appeared (represents as comma ','), a possibility of an animation-keywords should be reflesh. */
365
+ if ( node . type === "div" ) {
366
+ parsedAnimationKeywords = { } ;
367
+ }
368
+ if ( node . type === "function" && node . value . toLowerCase ( ) === "steps" ) {
369
+ stepsFunctionNode = node ;
370
+ }
371
+ const value =
372
+ node . type === "word" &&
373
+ ! isWordAFunctionArgument ( node , stepsFunctionNode )
374
+ ? node . value . toLowerCase ( )
375
+ : null ;
376
+
377
+ let shouldParseAnimationName = false ;
378
+
379
+ if ( ! didParseAnimationName && value && validIdent . test ( value ) ) {
380
+ if ( "$" + value in animationKeywords ) {
381
+ parsedAnimationKeywords [ "$" + value ] =
382
+ "$" + value in parsedAnimationKeywords
383
+ ? parsedAnimationKeywords [ "$" + value ] + 1
384
+ : 0 ;
385
+
386
+ shouldParseAnimationName =
387
+ parsedAnimationKeywords [ "$" + value ] >=
388
+ animationKeywords [ "$" + value ] ;
389
+ } else {
390
+ shouldParseAnimationName = true ;
391
+ }
392
+ }
393
+
394
+ const subContext = {
395
+ options : context . options ,
396
+ global : context . global ,
397
+ localizeNextItem : shouldParseAnimationName && ! context . global ,
398
+ localAliasMap : context . localAliasMap ,
399
+ } ;
400
+ return localizeDeclNode ( node , subContext ) ;
401
+ } ) ;
402
+
403
+ decl . value = valueNodes . toString ( ) ;
404
+
405
+ return ;
408
406
}
409
407
410
408
const isAnimationName = / a n i m a t i o n ( - n a m e ) ? $ / i. test ( decl . prop ) ;
@@ -444,7 +442,7 @@ module.exports = (options = {}) => {
444
442
const localAliasMap = new Map ( ) ;
445
443
446
444
return {
447
- Once ( root ) {
445
+ Root ( root ) {
448
446
const { icssImports } = extractICSS ( root , false ) ;
449
447
450
448
Object . keys ( icssImports ) . forEach ( ( key ) => {
0 commit comments