11/**
2- * @license AngularJS v1.2.4
2+ * @license AngularJS v1.2.6
33 * (c) 2010-2014 Google, Inc. http://angularjs.org
44 * License: MIT
55 */
@@ -294,6 +294,13 @@ angular.module('ngAnimate', ['ng'])
294294 } ) ;
295295 } ) ;
296296
297+ var classNameFilter = $animateProvider . classNameFilter ( ) ;
298+ var isAnimatableClassName = ! classNameFilter
299+ ? function ( ) { return true ; }
300+ : function ( className ) {
301+ return classNameFilter . test ( className ) ;
302+ } ;
303+
297304 function lookup ( name ) {
298305 if ( name ) {
299306 var matches = [ ] ,
@@ -575,17 +582,20 @@ angular.module('ngAnimate', ['ng'])
575582 and the onComplete callback will be fired once the animation is fully complete.
576583 */
577584 function performAnimation ( animationEvent , className , element , parentElement , afterElement , domOperation , doneCallback ) {
578- var node = extractElementNode ( element ) ;
585+ var currentClassName , classes , node = extractElementNode ( element ) ;
586+ if ( node ) {
587+ currentClassName = node . className ;
588+ classes = currentClassName + ' ' + className ;
589+ }
590+
579591 //transcluded directives may sometimes fire an animation using only comment nodes
580592 //best to catch this early on to prevent any animation operations from occurring
581- if ( ! node ) {
593+ if ( ! node || ! isAnimatableClassName ( classes ) ) {
582594 fireDOMOperation ( ) ;
583595 closeAnimation ( ) ;
584596 return ;
585597 }
586598
587- var currentClassName = node . className ;
588- var classes = currentClassName + ' ' + className ;
589599 var animationLookup = ( ' ' + classes ) . replace ( / \s + / g, '.' ) ;
590600 if ( ! parentElement ) {
591601 parentElement = afterElement ? afterElement . parent ( ) : element . parent ( ) ;
@@ -887,27 +897,73 @@ angular.module('ngAnimate', ['ng'])
887897 var ANIMATION_ITERATION_COUNT_KEY = 'IterationCount' ;
888898 var NG_ANIMATE_PARENT_KEY = '$$ngAnimateKey' ;
889899 var NG_ANIMATE_CSS_DATA_KEY = '$$ngAnimateCSS3Data' ;
890- var NG_ANIMATE_FALLBACK_CLASS_NAME = 'ng-animate-start' ;
891- var NG_ANIMATE_FALLBACK_ACTIVE_CLASS_NAME = 'ng-animate-active' ;
892900 var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3 ;
901+ var CLOSING_TIME_BUFFER = 1.5 ;
902+ var ONE_SECOND = 1000 ;
893903
904+ var animationCounter = 0 ;
894905 var lookupCache = { } ;
895906 var parentCounter = 0 ;
907+ var animationReflowQueue = [ ] ;
908+ var animationElementQueue = [ ] ;
909+ var animationTimer ;
910+ var closingAnimationTime = 0 ;
911+ var timeOut = false ;
912+ function afterReflow ( element , callback ) {
913+ $timeout . cancel ( animationTimer ) ;
896914
897- var animationReflowQueue = [ ] , animationTimer , timeOut = false ;
898- function afterReflow ( callback ) {
899915 animationReflowQueue . push ( callback ) ;
900- $timeout . cancel ( animationTimer ) ;
916+
917+ var node = extractElementNode ( element ) ;
918+ element = angular . element ( node ) ;
919+ animationElementQueue . push ( element ) ;
920+
921+ var elementData = element . data ( NG_ANIMATE_CSS_DATA_KEY ) ;
922+ closingAnimationTime = Math . max ( closingAnimationTime ,
923+ ( elementData . maxDelay + elementData . maxDuration ) * CLOSING_TIME_BUFFER * ONE_SECOND ) ;
924+
925+ //by placing a counter we can avoid an accidental
926+ //race condition which may close an animation when
927+ //a follow-up animation is midway in its animation
928+ elementData . animationCount = animationCounter ;
929+
901930 animationTimer = $timeout ( function ( ) {
902931 forEach ( animationReflowQueue , function ( fn ) {
903932 fn ( ) ;
904933 } ) ;
934+
935+ //copy the list of elements so that successive
936+ //animations won't conflict if they're added before
937+ //the closing animation timeout has run
938+ var elementQueueSnapshot = [ ] ;
939+ var animationCounterSnapshot = animationCounter ;
940+ forEach ( animationElementQueue , function ( elm ) {
941+ elementQueueSnapshot . push ( elm ) ;
942+ } ) ;
943+
944+ $timeout ( function ( ) {
945+ closeAllAnimations ( elementQueueSnapshot , animationCounterSnapshot ) ;
946+ elementQueueSnapshot = null ;
947+ } , closingAnimationTime , false ) ;
948+
905949 animationReflowQueue = [ ] ;
950+ animationElementQueue = [ ] ;
906951 animationTimer = null ;
907952 lookupCache = { } ;
953+ closingAnimationTime = 0 ;
954+ animationCounter ++ ;
908955 } , 10 , false ) ;
909956 }
910957
958+ function closeAllAnimations ( elements , count ) {
959+ forEach ( elements , function ( element ) {
960+ var elementData = element . data ( NG_ANIMATE_CSS_DATA_KEY ) ;
961+ if ( elementData && elementData . animationCount == count ) {
962+ ( elementData . closeAnimationFn || noop ) ( ) ;
963+ }
964+ } ) ;
965+ }
966+
911967 function getElementAnimationDetails ( element , cacheKey ) {
912968 var data = cacheKey ? lookupCache [ cacheKey ] : null ;
913969 if ( ! data ) {
@@ -1013,6 +1069,7 @@ angular.module('ngAnimate', ['ng'])
10131069 timeout is empty (this would cause a flicker bug normally
10141070 in the page. There is also no point in performing an animation
10151071 that only has a delay and no duration */
1072+ var maxDelay = Math . max ( timings . transitionDelay , timings . animationDelay ) ;
10161073 var maxDuration = Math . max ( timings . transitionDuration , timings . animationDuration ) ;
10171074 if ( maxDuration === 0 ) {
10181075 element . removeClass ( className ) ;
@@ -1022,13 +1079,9 @@ angular.module('ngAnimate', ['ng'])
10221079 //temporarily disable the transition so that the enter styles
10231080 //don't animate twice (this is here to avoid a bug in Chrome/FF).
10241081 var activeClassName = '' ;
1025- if ( timings . transitionDuration > 0 ) {
1026- element . addClass ( NG_ANIMATE_FALLBACK_CLASS_NAME ) ;
1027- activeClassName += NG_ANIMATE_FALLBACK_ACTIVE_CLASS_NAME + ' ' ;
1028- blockTransitions ( element ) ;
1029- } else {
1082+ timings . transitionDuration > 0 ?
1083+ blockTransitions ( element ) :
10301084 blockKeyframeAnimations ( element ) ;
1031- }
10321085
10331086 forEach ( className . split ( ' ' ) , function ( klass , i ) {
10341087 activeClassName += ( i > 0 ? ' ' : '' ) + klass + '-active' ;
@@ -1038,6 +1091,7 @@ angular.module('ngAnimate', ['ng'])
10381091 className : className ,
10391092 activeClassName : activeClassName ,
10401093 maxDuration : maxDuration ,
1094+ maxDelay : maxDelay ,
10411095 classes : className + ' ' + activeClassName ,
10421096 timings : timings ,
10431097 stagger : stagger ,
@@ -1072,30 +1126,28 @@ angular.module('ngAnimate', ['ng'])
10721126 }
10731127
10741128 function animateRun ( element , className , activeAnimationComplete ) {
1075- var data = element . data ( NG_ANIMATE_CSS_DATA_KEY ) ;
1129+ var elementData = element . data ( NG_ANIMATE_CSS_DATA_KEY ) ;
10761130 var node = extractElementNode ( element ) ;
1077- if ( node . className . indexOf ( className ) == - 1 || ! data ) {
1131+ if ( node . className . indexOf ( className ) == - 1 || ! elementData ) {
10781132 activeAnimationComplete ( ) ;
10791133 return ;
10801134 }
10811135
1082- var timings = data . timings ;
1083- var stagger = data . stagger ;
1084- var maxDuration = data . maxDuration ;
1085- var activeClassName = data . activeClassName ;
1086- var maxDelayTime = Math . max ( timings . transitionDelay , timings . animationDelay ) * 1000 ;
1136+ var timings = elementData . timings ;
1137+ var stagger = elementData . stagger ;
1138+ var maxDuration = elementData . maxDuration ;
1139+ var activeClassName = elementData . activeClassName ;
1140+ var maxDelayTime = Math . max ( timings . transitionDelay , timings . animationDelay ) * ONE_SECOND ;
10871141 var startTime = Date . now ( ) ;
10881142 var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT ;
1089- var ii = data . ii ;
1143+ var ii = elementData . ii ;
10901144
1091- var applyFallbackStyle , style = '' , appliedStyles = [ ] ;
1145+ var style = '' , appliedStyles = [ ] ;
10921146 if ( timings . transitionDuration > 0 ) {
10931147 var propertyStyle = timings . transitionPropertyStyle ;
10941148 if ( propertyStyle . indexOf ( 'all' ) == - 1 ) {
1095- applyFallbackStyle = true ;
1096- var fallbackProperty = $sniffer . msie ? '-ms-zoom' : 'border-spacing' ;
1097- style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ', ' + fallbackProperty + '; ' ;
1098- style += CSS_PREFIX + 'transition-duration: ' + timings . transitionDurationStyle + ', ' + timings . transitionDuration + 's; ' ;
1149+ style += CSS_PREFIX + 'transition-property: ' + propertyStyle + ';' ;
1150+ style += CSS_PREFIX + 'transition-duration: ' + timings . transitionDurationStyle + 's;' ;
10991151 appliedStyles . push ( CSS_PREFIX + 'transition-property' ) ;
11001152 appliedStyles . push ( CSS_PREFIX + 'transition-duration' ) ;
11011153 }
@@ -1104,10 +1156,6 @@ angular.module('ngAnimate', ['ng'])
11041156 if ( ii > 0 ) {
11051157 if ( stagger . transitionDelay > 0 && stagger . transitionDuration === 0 ) {
11061158 var delayStyle = timings . transitionDelayStyle ;
1107- if ( applyFallbackStyle ) {
1108- delayStyle += ', ' + timings . transitionDelay + 's' ;
1109- }
1110-
11111159 style += CSS_PREFIX + 'transition-delay: ' +
11121160 prepareStaggerDelay ( delayStyle , stagger . transitionDelay , ii ) + '; ' ;
11131161 appliedStyles . push ( CSS_PREFIX + 'transition-delay' ) ;
@@ -1130,19 +1178,24 @@ angular.module('ngAnimate', ['ng'])
11301178
11311179 element . on ( css3AnimationEvents , onAnimationProgress ) ;
11321180 element . addClass ( activeClassName ) ;
1181+ elementData . closeAnimationFn = function ( ) {
1182+ onEnd ( ) ;
1183+ activeAnimationComplete ( ) ;
1184+ } ;
1185+ return onEnd ;
11331186
11341187 // This will automatically be called by $animate so
11351188 // there is no need to attach this internally to the
11361189 // timeout done method.
1137- return function onEnd ( cancelled ) {
1190+ function onEnd ( cancelled ) {
11381191 element . off ( css3AnimationEvents , onAnimationProgress ) ;
11391192 element . removeClass ( activeClassName ) ;
11401193 animateClose ( element , className ) ;
11411194 var node = extractElementNode ( element ) ;
11421195 for ( var i in appliedStyles ) {
11431196 node . style . removeProperty ( appliedStyles [ i ] ) ;
11441197 }
1145- } ;
1198+ }
11461199
11471200 function onAnimationProgress ( event ) {
11481201 event . stopPropagation ( ) ;
@@ -1208,7 +1261,7 @@ angular.module('ngAnimate', ['ng'])
12081261 //data from the element which will not make the 2nd animation
12091262 //happen in the first place
12101263 var cancel = preReflowCancellation ;
1211- afterReflow ( function ( ) {
1264+ afterReflow ( element , function ( ) {
12121265 unblockTransitions ( element ) ;
12131266 unblockKeyframeAnimations ( element ) ;
12141267 //once the reflow is complete then we point cancel to
@@ -1224,7 +1277,6 @@ angular.module('ngAnimate', ['ng'])
12241277
12251278 function animateClose ( element , className ) {
12261279 element . removeClass ( className ) ;
1227- element . removeClass ( NG_ANIMATE_FALLBACK_CLASS_NAME ) ;
12281280 element . removeData ( NG_ANIMATE_CSS_DATA_KEY ) ;
12291281 }
12301282
@@ -1243,7 +1295,7 @@ angular.module('ngAnimate', ['ng'])
12431295 //make the element super hidden and override any CSS style values
12441296 clone . attr ( 'style' , 'position:absolute; top:-9999px; left:-9999px' ) ;
12451297 clone . removeAttr ( 'id' ) ;
1246- clone . html ( '' ) ;
1298+ clone . empty ( ) ;
12471299
12481300 forEach ( oldClasses . split ( ' ' ) , function ( klass ) {
12491301 clone . removeClass ( klass ) ;
@@ -1274,7 +1326,7 @@ angular.module('ngAnimate', ['ng'])
12741326 beforeAddClass : function ( element , className , animationCompleted ) {
12751327 var cancellationMethod = animateBefore ( element , suffixClasses ( className , '-add' ) ) ;
12761328 if ( cancellationMethod ) {
1277- afterReflow ( function ( ) {
1329+ afterReflow ( element , function ( ) {
12781330 unblockTransitions ( element ) ;
12791331 unblockKeyframeAnimations ( element ) ;
12801332 animationCompleted ( ) ;
@@ -1291,7 +1343,7 @@ angular.module('ngAnimate', ['ng'])
12911343 beforeRemoveClass : function ( element , className , animationCompleted ) {
12921344 var cancellationMethod = animateBefore ( element , suffixClasses ( className , '-remove' ) ) ;
12931345 if ( cancellationMethod ) {
1294- afterReflow ( function ( ) {
1346+ afterReflow ( element , function ( ) {
12951347 unblockTransitions ( element ) ;
12961348 unblockKeyframeAnimations ( element ) ;
12971349 animationCompleted ( ) ;
0 commit comments