Skip to content

Commit 749610c

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 angular#7766
1 parent e4419da commit 749610c

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
@@ -1236,7 +1236,9 @@ angular.module('ngAnimate', ['ng'])
12361236
forEach(elements, function(element) {
12371237
var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
12381238
if(elementData) {
1239-
(elementData.closeAnimationFn || noop)();
1239+
forEach(elementData.closeAnimationFns, function(fn) {
1240+
fn();
1241+
});
12401242
}
12411243
});
12421244
}
@@ -1357,14 +1359,15 @@ angular.module('ngAnimate', ['ng'])
13571359
stagger.animationDelay > 0 &&
13581360
stagger.animationDuration === 0;
13591361

1362+
var closeAnimationFns = formerData.closeAnimationFns || [];
13601363
element.data(NG_ANIMATE_CSS_DATA_KEY, {
13611364
stagger : stagger,
13621365
cacheKey : eventCacheKey,
13631366
running : formerData.running || 0,
13641367
itemIndex : itemIndex,
13651368
blockTransition : blockTransition,
13661369
blockAnimation : blockAnimation,
1367-
closeAnimationFn : noop
1370+
closeAnimationFns : closeAnimationFns
13681371
});
13691372

13701373
var node = extractElementNode(element);
@@ -1456,10 +1459,10 @@ angular.module('ngAnimate', ['ng'])
14561459
var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
14571460

14581461
element.on(css3AnimationEvents, onAnimationProgress);
1459-
elementData.closeAnimationFn = function() {
1462+
elementData.closeAnimationFns.push(function() {
14601463
onEnd();
14611464
activeAnimationComplete();
1462-
};
1465+
});
14631466

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

test/ngAnimate/animateSpec.js

+26
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,32 @@ describe("ngAnimate", function() {
15691569
});
15701570
});
15711571

1572+
it('should apply a closing timeout to close all parallel class-based animations on the same element',
1573+
inject(function($sniffer, $compile, $rootScope, $rootElement, $animate, $timeout) {
1574+
1575+
if (!$sniffer.transitions) return;
1576+
1577+
ss.addRule('.base-class', '-webkit-transition:2s linear all;' +
1578+
'transition:2s linear all;');
1579+
1580+
var element = $compile('<div class="base-class"></div>')($rootScope);
1581+
$rootElement.append(element);
1582+
jqLite($document[0].body).append($rootElement);
1583+
1584+
$animate.addClass(element, 'one');
1585+
$animate.addClass(element, 'two');
1586+
1587+
$animate.triggerReflow();
1588+
1589+
$timeout.flush(3000); //2s * 1.5
1590+
1591+
expect(element.hasClass('one-add')).toBeFalsy();
1592+
expect(element.hasClass('one-add-active')).toBeFalsy();
1593+
expect(element.hasClass('two-add')).toBeFalsy();
1594+
expect(element.hasClass('two-add-active')).toBeFalsy();
1595+
expect(element.hasClass('ng-animate')).toBeFalsy();
1596+
}));
1597+
15721598
it("apply a closing timeout with respect to a staggering animation",
15731599
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
15741600

0 commit comments

Comments
 (0)