Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit f07af61

Browse files
committed
fix($animate): ensure that parallel class-based animations are all eventually closed
When multiple classes are added/removed in parallel then $animate only closes off the last animation when the fallback timer has expired. Now all animations are closed off. Fixes #7766
1 parent b0ca519 commit f07af61

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

src/ngAnimate/animate.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -1310,7 +1310,9 @@ angular.module('ngAnimate', ['ng'])
13101310
forEach(elements, function(element) {
13111311
var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
13121312
if(elementData) {
1313-
(elementData.closeAnimationFn || noop)();
1313+
forEach(elementData.closeAnimationFns, function(fn) {
1314+
fn();
1315+
});
13141316
}
13151317
});
13161318
}
@@ -1431,14 +1433,15 @@ angular.module('ngAnimate', ['ng'])
14311433
stagger.animationDelay > 0 &&
14321434
stagger.animationDuration === 0;
14331435

1436+
var closeAnimationFns = formerData.closeAnimationFns || [];
14341437
element.data(NG_ANIMATE_CSS_DATA_KEY, {
14351438
stagger : stagger,
14361439
cacheKey : eventCacheKey,
14371440
running : formerData.running || 0,
14381441
itemIndex : itemIndex,
14391442
blockTransition : blockTransition,
14401443
blockAnimation : blockAnimation,
1441-
closeAnimationFn : noop
1444+
closeAnimationFns : closeAnimationFns
14421445
});
14431446

14441447
var node = extractElementNode(element);
@@ -1530,10 +1533,10 @@ angular.module('ngAnimate', ['ng'])
15301533
var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
15311534

15321535
element.on(css3AnimationEvents, onAnimationProgress);
1533-
elementData.closeAnimationFn = function() {
1536+
elementData.closeAnimationFns.push(function() {
15341537
onEnd();
15351538
activeAnimationComplete();
1536-
};
1539+
});
15371540

15381541
var staggerTime = itemIndex * (Math.max(stagger.animationDelay, stagger.transitionDelay) || 0);
15391542
var animationTime = (maxDelay + maxDuration) * CLOSING_TIME_BUFFER;

test/ngAnimate/animateSpec.js

+26
Original file line numberDiff line numberDiff line change
@@ -1702,6 +1702,32 @@ describe("ngAnimate", function() {
17021702
});
17031703
});
17041704

1705+
it('should apply a closing timeout to close all parallel class-based animations on the same element',
1706+
inject(function($sniffer, $compile, $rootScope, $rootElement, $animate, $timeout) {
1707+
1708+
if (!$sniffer.transitions) return;
1709+
1710+
ss.addRule('.base-class', '-webkit-transition:2s linear all;' +
1711+
'transition:2s linear all;');
1712+
1713+
var element = $compile('<div class="base-class"></div>')($rootScope);
1714+
$rootElement.append(element);
1715+
jqLite($document[0].body).append($rootElement);
1716+
1717+
$animate.addClass(element, 'one');
1718+
$animate.addClass(element, 'two');
1719+
1720+
$animate.triggerReflow();
1721+
1722+
$timeout.flush(3000); //2s * 1.5
1723+
1724+
expect(element.hasClass('one-add')).toBeFalsy();
1725+
expect(element.hasClass('one-add-active')).toBeFalsy();
1726+
expect(element.hasClass('two-add')).toBeFalsy();
1727+
expect(element.hasClass('two-add-active')).toBeFalsy();
1728+
expect(element.hasClass('ng-animate')).toBeFalsy();
1729+
}));
1730+
17051731
it("apply a closing timeout with respect to a staggering animation",
17061732
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
17071733

0 commit comments

Comments
 (0)