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

Commit 99720fb

Browse files
committed
fix($animate): ensure all animated elements are taken care of during the closing timeout
Closes #6395
1 parent 332e935 commit 99720fb

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

src/ngAnimate/animate.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -1063,17 +1063,22 @@ angular.module('ngAnimate', ['ng'])
10631063
var closingTimestamp = 0;
10641064
var animationElementQueue = [];
10651065
function animationCloseHandler(element, totalTime) {
1066+
var node = extractElementNode(element);
1067+
element = angular.element(node);
1068+
1069+
//this item will be garbage collected by the closing
1070+
//animation timeout
1071+
animationElementQueue.push(element);
1072+
1073+
//but it may not need to cancel out the existing timeout
1074+
//if the timestamp is less than the previous one
10661075
var futureTimestamp = Date.now() + (totalTime * 1000);
10671076
if(futureTimestamp <= closingTimestamp) {
10681077
return;
10691078
}
10701079

10711080
$timeout.cancel(closingTimer);
10721081

1073-
var node = extractElementNode(element);
1074-
element = angular.element(node);
1075-
animationElementQueue.push(element);
1076-
10771082
closingTimestamp = futureTimestamp;
10781083
closingTimer = $timeout(function() {
10791084
closeAllAnimations(animationElementQueue);

test/ngAnimate/animateSpec.js

+43
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,49 @@ describe("ngAnimate", function() {
11811181
expect(element.hasClass('some-class-add-active')).toBe(false);
11821182
}));
11831183

1184+
it("should intelligently cancel former timeouts and close off a series of elements a final timeout", function() {
1185+
var cancellations = 0;
1186+
module(function($provide) {
1187+
$provide.decorator('$timeout', function($delegate) {
1188+
var _cancel = $delegate.cancel;
1189+
$delegate.cancel = function() {
1190+
cancellations++;
1191+
return _cancel.apply($delegate, arguments);
1192+
};
1193+
return $delegate;
1194+
});
1195+
})
1196+
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
1197+
if (!$sniffer.transitions) return;
1198+
1199+
ss.addRule('.animate-me', '-webkit-transition:1s linear all;' +
1200+
'transition:1s linear all;');
1201+
1202+
element = $compile(html('<div><div class="animate-me" ng-repeat="item in items"></div></div>'))($rootScope);
1203+
1204+
$rootScope.items = [1,2,3,4,5,6,7,8,9,10];
1205+
var totalOperations = $rootScope.items.length;
1206+
1207+
$rootScope.$digest();
1208+
1209+
$rootScope.items = [0];
1210+
$animate.triggerReflow();
1211+
$timeout.flush(1500);
1212+
1213+
expect(cancellations).toBeLessThan(totalOperations);
1214+
expect(element.children().length).toBe(10);
1215+
cancellations = 0;
1216+
1217+
$rootScope.items = [1];
1218+
$rootScope.$digest();
1219+
1220+
$animate.triggerReflow();
1221+
$timeout.flush(1500);
1222+
expect(element.children().length).toBe(1);
1223+
expect(cancellations).toBeLessThan(totalOperations);
1224+
});
1225+
});
1226+
11841227
it("apply a closing timeout with respect to a staggering animation",
11851228
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
11861229

0 commit comments

Comments
 (0)