@@ -549,13 +549,16 @@ angular.module('ngAnimate', ['ng'])
549
549
//one day all browsers will have these properties
550
550
var w3cAnimationProp = 'animation' ;
551
551
var w3cTransitionProp = 'transition' ;
552
+ var w3cAnimationEvent = 'animationend' ;
553
+ var w3cTransitionEvent = 'transitionend' ;
552
554
553
555
//but some still use vendor-prefixed styles
554
556
var vendorAnimationProp = $sniffer . vendorPrefix + 'Animation' ;
555
557
var vendorTransitionProp = $sniffer . vendorPrefix + 'Transition' ;
558
+ var vendorAnimationEvent = $sniffer . vendorPrefix . toLowerCase ( ) + 'AnimationEnd' ;
559
+ var vendorTransitionEvent = $sniffer . vendorPrefix . toLowerCase ( ) + 'TransitionEnd' ;
556
560
557
561
var durationKey = 'Duration' ,
558
- delayKey = 'Delay' ,
559
562
propertyKey = 'Property' ,
560
563
animationIterationCountKey = 'IterationCount' ,
561
564
ELEMENT_NODE = 1 ;
@@ -584,17 +587,12 @@ angular.module('ngAnimate', ['ng'])
584
587
element . addClass ( className ) ;
585
588
586
589
//we want all the styles defined before and after
587
- var duration = 0 ;
590
+ var transitionTime = 0 ,
591
+ animationTime = 0 ;
588
592
forEach ( element , function ( element ) {
589
593
if ( element . nodeType == ELEMENT_NODE ) {
590
594
var elementStyles = $window . getComputedStyle ( element ) || { } ;
591
595
592
- var transitionDelay = Math . max ( parseMaxTime ( elementStyles [ w3cTransitionProp + delayKey ] ) ,
593
- parseMaxTime ( elementStyles [ vendorTransitionProp + delayKey ] ) ) ;
594
-
595
- var animationDelay = Math . max ( parseMaxTime ( elementStyles [ w3cAnimationProp + delayKey ] ) ,
596
- parseMaxTime ( elementStyles [ vendorAnimationProp + delayKey ] ) ) ;
597
-
598
596
var transitionDuration = Math . max ( parseMaxTime ( elementStyles [ w3cTransitionProp + durationKey ] ) ,
599
597
parseMaxTime ( elementStyles [ vendorTransitionProp + durationKey ] ) ) ;
600
598
@@ -607,16 +605,16 @@ angular.module('ngAnimate', ['ng'])
607
605
1 ) ;
608
606
}
609
607
610
- duration = Math . max ( animationDelay + animationDuration ,
611
- transitionDelay + transitionDuration ,
612
- duration ) ;
608
+ transitionTime = Math . max ( transitionDuration , transitionTime ) ;
609
+ animationTime = Math . max ( animationDuration , animationTime ) ;
613
610
}
614
611
} ) ;
615
612
616
613
/* there is no point in performing a reflow if the animation
617
614
timeout is empty (this would cause a flicker bug normally
618
615
in the page */
619
- if ( duration > 0 ) {
616
+ var totalTime = Math . max ( transitionTime , animationTime ) ;
617
+ if ( totalTime > 0 ) {
620
618
var node = element [ 0 ] ;
621
619
622
620
//temporarily disable the transition so that the enter styles
@@ -635,12 +633,15 @@ angular.module('ngAnimate', ['ng'])
635
633
node . style [ vendorTransitionProp + propertyKey ] = '' ;
636
634
element . addClass ( activeClassName ) ;
637
635
638
- $timeout ( done , duration * 1000 , false ) ;
636
+ var css3AnimationEvents = [ w3cAnimationEvent , vendorAnimationEvent ,
637
+ w3cTransitionEvent , vendorTransitionEvent ] . join ( ' ' ) ;
638
+ element . on ( css3AnimationEvents , onAnimationProgress ) ;
639
639
640
640
//this will automatically be called by $animate so
641
641
//there is no need to attach this internally to the
642
642
//timeout done method
643
643
return function onEnd ( cancelled ) {
644
+ element . off ( css3AnimationEvents , onAnimationProgress ) ;
644
645
element . removeClass ( className ) ;
645
646
element . removeClass ( activeClassName ) ;
646
647
@@ -657,6 +658,10 @@ angular.module('ngAnimate', ['ng'])
657
658
done ( ) ;
658
659
}
659
660
661
+ function onAnimationProgress ( event ) {
662
+ event . originalEvent . elapsedTime >= totalTime && done ( ) ;
663
+ }
664
+
660
665
function parseMaxTime ( str ) {
661
666
var total = 0 , values = angular . isString ( str ) ? str . split ( / \s * , \s * / ) : [ ] ;
662
667
forEach ( values , function ( value ) {
0 commit comments