@@ -642,6 +642,10 @@ angular.module('ngAnimate', ['ng'])
642
642
animationIterationCountKey = 'IterationCount' ,
643
643
ELEMENT_NODE = 1 ;
644
644
645
+ var NG_ANIMATE_PARENT_KEY = '$ngAnimateKey' ;
646
+ var lookupCache = { } ;
647
+ var parentCounter = 0 ;
648
+
645
649
var animationReflowQueue = [ ] , animationTimer , timeOut = false ;
646
650
function afterReflow ( callback ) {
647
651
animationReflowQueue . push ( callback ) ;
@@ -652,65 +656,93 @@ angular.module('ngAnimate', ['ng'])
652
656
} ) ;
653
657
animationReflowQueue = [ ] ;
654
658
animationTimer = null ;
659
+ lookupCache = { } ;
655
660
} , 10 , false ) ;
656
661
}
657
662
658
- function animate ( element , className , done ) {
659
- if ( [ 'ng-enter' , 'ng-leave' , 'ng-move' ] . indexOf ( className ) == - 1 ) {
660
- var existingDuration = 0 ;
663
+ function getElementAnimationDetails ( element , cacheKey , onlyCheckTransition ) {
664
+ var data = lookupCache [ cacheKey ] ;
665
+ if ( ! data ) {
666
+ var transitionDuration = 0 , transitionDelay = 0 ,
667
+ animationDuration = 0 , animationDelay = 0 ;
668
+
669
+ //we want all the styles defined before and after
661
670
forEach ( element , function ( element ) {
662
671
if ( element . nodeType == ELEMENT_NODE ) {
663
672
var elementStyles = $window . getComputedStyle ( element ) || { } ;
664
- existingDuration = Math . max ( parseMaxTime ( elementStyles [ transitionProp + durationKey ] ) ,
665
- existingDuration ) ;
673
+
674
+ transitionDuration = Math . max ( parseMaxTime ( elementStyles [ transitionProp + durationKey ] ) , transitionDuration ) ;
675
+
676
+ if ( ! onlyCheckTransition ) {
677
+ transitionDelay = Math . max ( parseMaxTime ( elementStyles [ transitionProp + delayKey ] ) , transitionDelay ) ;
678
+
679
+ animationDelay = Math . max ( parseMaxTime ( elementStyles [ animationProp + delayKey ] ) , animationDelay ) ;
680
+
681
+ var aDuration = parseMaxTime ( elementStyles [ animationProp + durationKey ] ) ;
682
+
683
+ if ( aDuration > 0 ) {
684
+ aDuration *= parseInt ( elementStyles [ animationProp + animationIterationCountKey ] ) || 1 ;
685
+ }
686
+
687
+ animationDuration = Math . max ( aDuration , animationDuration ) ;
688
+ }
666
689
}
667
690
} ) ;
668
- if ( existingDuration > 0 ) {
669
- done ( ) ;
670
- return ;
671
- }
691
+ data = {
692
+ transitionDelay : transitionDelay ,
693
+ animationDelay : animationDelay ,
694
+ transitionDuration : transitionDuration ,
695
+ animationDuration : animationDuration
696
+ } ;
697
+ lookupCache [ cacheKey ] = data ;
672
698
}
699
+ return data ;
700
+ }
673
701
674
- element . addClass ( className ) ;
675
-
676
- //we want all the styles defined before and after
677
- var transitionDuration = 0 ,
678
- animationDuration = 0 ,
679
- transitionDelay = 0 ,
680
- animationDelay = 0 ;
681
- forEach ( element , function ( element ) {
682
- if ( element . nodeType == ELEMENT_NODE ) {
683
- var elementStyles = $window . getComputedStyle ( element ) || { } ;
702
+ function parseMaxTime ( str ) {
703
+ var total = 0 , values = angular . isString ( str ) ? str . split ( / \s * , \s * / ) : [ ] ;
704
+ forEach ( values , function ( value ) {
705
+ total = Math . max ( parseFloat ( value ) || 0 , total ) ;
706
+ } ) ;
707
+ return total ;
708
+ }
684
709
685
- transitionDelay = Math . max ( parseMaxTime ( elementStyles [ transitionProp + delayKey ] ) , transitionDelay ) ;
710
+ function getCacheKey ( element ) {
711
+ var parent = element . parent ( ) ;
712
+ var parentID = parent . data ( NG_ANIMATE_PARENT_KEY ) ;
713
+ if ( ! parentID ) {
714
+ parent . data ( NG_ANIMATE_PARENT_KEY , ++ parentCounter ) ;
715
+ parentID = parentCounter ;
716
+ }
717
+ return parentID + '-' + element [ 0 ] . className ;
718
+ }
686
719
687
- animationDelay = Math . max ( parseMaxTime ( elementStyles [ animationProp + delayKey ] ) , animationDelay ) ;
720
+ function animate ( element , className , done ) {
688
721
689
- transitionDuration = Math . max ( parseMaxTime ( elementStyles [ transitionProp + durationKey ] ) , transitionDuration ) ;
722
+ var cacheKey = getCacheKey ( element ) ;
723
+ if ( getElementAnimationDetails ( element , cacheKey , true ) . transitionDuration > 0 ) {
690
724
691
- var aDuration = parseMaxTime ( elementStyles [ animationProp + durationKey ] ) ;
725
+ done ( ) ;
726
+ return ;
727
+ }
692
728
693
- if ( aDuration > 0 ) {
694
- aDuration *= parseInt ( elementStyles [ animationProp + animationIterationCountKey ] ) || 1 ;
695
- }
729
+ element . addClass ( className ) ;
696
730
697
- animationDuration = Math . max ( aDuration , animationDuration ) ;
698
- }
699
- } ) ;
731
+ var timings = getElementAnimationDetails ( element , cacheKey + ' ' + className ) ;
700
732
701
733
/* there is no point in performing a reflow if the animation
702
734
timeout is empty (this would cause a flicker bug normally
703
735
in the page. There is also no point in performing an animation
704
736
that only has a delay and no duration */
705
- var maxDuration = Math . max ( transitionDuration , animationDuration ) ;
737
+ var maxDuration = Math . max ( timings . transitionDuration , timings . animationDuration ) ;
706
738
if ( maxDuration > 0 ) {
707
- var maxDelayTime = Math . max ( transitionDelay , animationDelay ) * 1000 ,
739
+ var maxDelayTime = Math . max ( timings . transitionDelay , timings . animationDelay ) * 1000 ,
708
740
startTime = Date . now ( ) ,
709
741
node = element [ 0 ] ;
710
742
711
743
//temporarily disable the transition so that the enter styles
712
744
//don't animate twice (this is here to avoid a bug in Chrome/FF).
713
- if ( transitionDuration > 0 ) {
745
+ if ( timings . transitionDuration > 0 ) {
714
746
node . style [ transitionProp + propertyKey ] = 'none' ;
715
747
}
716
748
@@ -723,7 +755,7 @@ angular.module('ngAnimate', ['ng'])
723
755
var css3AnimationEvents = animationendEvent + ' ' + transitionendEvent ;
724
756
725
757
afterReflow ( function ( ) {
726
- if ( transitionDuration > 0 ) {
758
+ if ( timings . transitionDuration > 0 ) {
727
759
node . style [ transitionProp + propertyKey ] = '' ;
728
760
}
729
761
element . addClass ( activeClassName ) ;
@@ -768,13 +800,6 @@ angular.module('ngAnimate', ['ng'])
768
800
}
769
801
}
770
802
771
- function parseMaxTime ( str ) {
772
- var total = 0 , values = angular . isString ( str ) ? str . split ( / \s * , \s * / ) : [ ] ;
773
- forEach ( values , function ( value ) {
774
- total = Math . max ( parseFloat ( value ) || 0 , total ) ;
775
- } ) ;
776
- return total ;
777
- }
778
803
}
779
804
780
805
return {
0 commit comments