@@ -304,33 +304,6 @@ function getCssTransitionDurationStyle(duration, applyOnlyDuration) {
304304 return [ style , value ] ;
305305}
306306
307- function createLocalCacheLookup ( ) {
308- var cache = Object . create ( null ) ;
309- return {
310- flush : function ( ) {
311- cache = Object . create ( null ) ;
312- } ,
313-
314- count : function ( key ) {
315- var entry = cache [ key ] ;
316- return entry ? entry . total : 0 ;
317- } ,
318-
319- get : function ( key ) {
320- var entry = cache [ key ] ;
321- return entry && entry . value ;
322- } ,
323-
324- put : function ( key , value ) {
325- if ( ! cache [ key ] ) {
326- cache [ key ] = { total : 1 , value : value } ;
327- } else {
328- cache [ key ] . total ++ ;
329- }
330- }
331- } ;
332- }
333-
334307// we do not reassign an already present style value since
335308// if we detect the style property value again we may be
336309// detecting styles that were added via the `from` styles.
@@ -349,26 +322,16 @@ function registerRestorableStyles(backup, node, properties) {
349322}
350323
351324var $AnimateCssProvider = [ '$animateProvider' , /** @this */ function ( $animateProvider ) {
352- var gcsLookup = createLocalCacheLookup ( ) ;
353- var gcsStaggerLookup = createLocalCacheLookup ( ) ;
354325
355- this . $get = [ '$window' , '$$jqLite' , '$$AnimateRunner' , '$timeout' ,
326+ this . $get = [ '$window' , '$$jqLite' , '$$AnimateRunner' , '$timeout' , '$$animateCache' ,
356327 '$$forceReflow' , '$sniffer' , '$$rAFScheduler' , '$$animateQueue' ,
357- function ( $window , $$jqLite , $$AnimateRunner , $timeout ,
328+ function ( $window , $$jqLite , $$AnimateRunner , $timeout , $$animateCache ,
358329 $$forceReflow , $sniffer , $$rAFScheduler , $$animateQueue ) {
359330
360331 var applyAnimationClasses = applyAnimationClassesFactory ( $$jqLite ) ;
361332
362- var parentCounter = 0 ;
363- function gcsHashFn ( node , extraClasses ) {
364- var KEY = '$$ngAnimateParentKey' ;
365- var parentNode = node . parentNode ;
366- var parentID = parentNode [ KEY ] || ( parentNode [ KEY ] = ++ parentCounter ) ;
367- return parentID + '-' + node . getAttribute ( 'class' ) + '-' + extraClasses ;
368- }
369-
370- function computeCachedCssStyles ( node , className , cacheKey , properties ) {
371- var timings = gcsLookup . get ( cacheKey ) ;
333+ function computeCachedCssStyles ( node , className , cacheKey , allowNoDuration , properties ) {
334+ var timings = $$animateCache . get ( cacheKey ) ;
372335
373336 if ( ! timings ) {
374337 timings = computeCssStyles ( $window , node , properties ) ;
@@ -377,20 +340,26 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
377340 }
378341 }
379342
343+ // if a css animation has no duration we
344+ // should mark that so that repeated addClass/removeClass calls are skipped
345+ var hasDuration = allowNoDuration || ( timings . transitionDuration > 0 || timings . animationDuration > 0 ) ;
346+
380347 // we keep putting this in multiple times even though the value and the cacheKey are the same
381348 // because we're keeping an internal tally of how many duplicate animations are detected.
382- gcsLookup . put ( cacheKey , timings ) ;
349+ $$animateCache . put ( cacheKey , timings , hasDuration ) ;
350+
383351 return timings ;
384352 }
385353
386354 function computeCachedCssStaggerStyles ( node , className , cacheKey , properties ) {
387355 var stagger ;
356+ var staggerCacheKey = 'stagger-' + cacheKey ;
388357
389358 // if we have one or more existing matches of matching elements
390359 // containing the same parent + CSS styles (which is how cacheKey works)
391360 // then staggering is possible
392- if ( gcsLookup . count ( cacheKey ) > 0 ) {
393- stagger = gcsStaggerLookup . get ( cacheKey ) ;
361+ if ( $$animateCache . count ( cacheKey ) > 0 ) {
362+ stagger = $$animateCache . get ( staggerCacheKey ) ;
394363
395364 if ( ! stagger ) {
396365 var staggerClassName = pendClasses ( className , '-stagger' ) ;
@@ -405,7 +374,7 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
405374
406375 $$jqLite . removeClass ( node , staggerClassName ) ;
407376
408- gcsStaggerLookup . put ( cacheKey , stagger ) ;
377+ $$animateCache . put ( staggerCacheKey , stagger , true ) ;
409378 }
410379 }
411380
@@ -416,8 +385,7 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
416385 function waitUntilQuiet ( callback ) {
417386 rafWaitQueue . push ( callback ) ;
418387 $$rAFScheduler . waitUntilQuiet ( function ( ) {
419- gcsLookup . flush ( ) ;
420- gcsStaggerLookup . flush ( ) ;
388+ $$animateCache . flush ( ) ;
421389
422390 // DO NOT REMOVE THIS LINE OR REFACTOR OUT THE `pageWidth` variable.
423391 // PLEASE EXAMINE THE `$$forceReflow` service to understand why.
@@ -432,8 +400,8 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
432400 } ) ;
433401 }
434402
435- function computeTimings ( node , className , cacheKey ) {
436- var timings = computeCachedCssStyles ( node , className , cacheKey , DETECT_CSS_PROPERTIES ) ;
403+ function computeTimings ( node , className , cacheKey , allowNoDuration ) {
404+ var timings = computeCachedCssStyles ( node , className , cacheKey , allowNoDuration , DETECT_CSS_PROPERTIES ) ;
437405 var aD = timings . animationDelay ;
438406 var tD = timings . transitionDelay ;
439407 timings . maxDelay = aD && tD
@@ -520,7 +488,6 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
520488
521489 var preparationClasses = [ structuralClassName , addRemoveClassName ] . join ( ' ' ) . trim ( ) ;
522490 var fullClassName = classes + ' ' + preparationClasses ;
523- var activeClasses = pendClasses ( preparationClasses , ACTIVE_CLASS_SUFFIX ) ;
524491 var hasToStyles = styles . to && Object . keys ( styles . to ) . length > 0 ;
525492 var containsKeyframeAnimation = ( options . keyframeStyle || '' ) . length > 0 ;
526493
@@ -533,7 +500,12 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
533500 return closeAndReturnNoopAnimator ( ) ;
534501 }
535502
536- var cacheKey , stagger ;
503+ var stagger , cacheKey = $$animateCache . cacheKey ( node , method , options . addClass , options . removeClass ) ;
504+ if ( $$animateCache . containsCachedAnimationWithoutDuration ( cacheKey ) ) {
505+ preparationClasses = null ;
506+ return closeAndReturnNoopAnimator ( ) ;
507+ }
508+
537509 if ( options . stagger > 0 ) {
538510 var staggerVal = parseFloat ( options . stagger ) ;
539511 stagger = {
@@ -543,7 +515,6 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
543515 animationDuration : 0
544516 } ;
545517 } else {
546- cacheKey = gcsHashFn ( node , fullClassName ) ;
547518 stagger = computeCachedCssStaggerStyles ( node , preparationClasses , cacheKey , DETECT_STAGGER_CSS_PROPERTIES ) ;
548519 }
549520
@@ -577,7 +548,7 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
577548 var itemIndex = stagger
578549 ? options . staggerIndex >= 0
579550 ? options . staggerIndex
580- : gcsLookup . count ( cacheKey )
551+ : $$animateCache . count ( cacheKey )
581552 : 0 ;
582553
583554 var isFirst = itemIndex === 0 ;
@@ -592,7 +563,7 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
592563 blockTransitions ( node , SAFE_FAST_FORWARD_DURATION_VALUE ) ;
593564 }
594565
595- var timings = computeTimings ( node , fullClassName , cacheKey ) ;
566+ var timings = computeTimings ( node , fullClassName , cacheKey , ! isStructural ) ;
596567 var relativeDelay = timings . maxDelay ;
597568 maxDelay = Math . max ( relativeDelay , 0 ) ;
598569 maxDuration = timings . maxDuration ;
@@ -630,6 +601,8 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
630601 return closeAndReturnNoopAnimator ( ) ;
631602 }
632603
604+ var activeClasses = pendClasses ( preparationClasses , ACTIVE_CLASS_SUFFIX ) ;
605+
633606 if ( options . delay != null ) {
634607 var delayStyle ;
635608 if ( typeof options . delay !== 'boolean' ) {
@@ -717,10 +690,13 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
717690 animationClosed = true ;
718691 animationPaused = false ;
719692
720- if ( ! options . $$skipPreparationClasses ) {
693+ if ( preparationClasses && ! options . $$skipPreparationClasses ) {
721694 $$jqLite . removeClass ( element , preparationClasses ) ;
722695 }
723- $$jqLite . removeClass ( element , activeClasses ) ;
696+
697+ if ( activeClasses ) {
698+ $$jqLite . removeClass ( element , activeClasses ) ;
699+ }
724700
725701 blockKeyframeAnimations ( node , false ) ;
726702 blockTransitions ( node , false ) ;
@@ -904,9 +880,9 @@ var $AnimateCssProvider = ['$animateProvider', /** @this */ function($animatePro
904880
905881 if ( flags . recalculateTimingStyles ) {
906882 fullClassName = node . getAttribute ( 'class' ) + ' ' + preparationClasses ;
907- cacheKey = gcsHashFn ( node , fullClassName ) ;
883+ cacheKey = $$animateCache . cacheKey ( node , method , options . addClass , options . removeClass ) ;
908884
909- timings = computeTimings ( node , fullClassName , cacheKey ) ;
885+ timings = computeTimings ( node , fullClassName , cacheKey , false ) ;
910886 relativeDelay = timings . maxDelay ;
911887 maxDelay = Math . max ( relativeDelay , 0 ) ;
912888 maxDuration = timings . maxDuration ;
0 commit comments