Skip to content

Commit

Permalink
fix($animate): ensure all animated elements are taken care of during …
Browse files Browse the repository at this point in the history
…the closing timeout

Closes angular#6395
  • Loading branch information
matsko committed Feb 26, 2014
1 parent 332e935 commit 89e7130
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 4 deletions.
13 changes: 9 additions & 4 deletions src/ngAnimate/animate.js
Original file line number Diff line number Diff line change
Expand Up @@ -1063,17 +1063,22 @@ angular.module('ngAnimate', ['ng'])
var closingTimestamp = 0;
var animationElementQueue = [];
function animationCloseHandler(element, totalTime) {
var node = extractElementNode(element);
element = angular.element(node);

//this item will be garbage collected by the closing
//animation timeout
animationElementQueue.push(element);

//but it may not need to cancel out the existing timeout
//if the timestamp is less than the previous one
var futureTimestamp = Date.now() + (totalTime * 1000);
if(futureTimestamp <= closingTimestamp) {
return;
}

$timeout.cancel(closingTimer);

var node = extractElementNode(element);
element = angular.element(node);
animationElementQueue.push(element);

closingTimestamp = futureTimestamp;
closingTimer = $timeout(function() {
closeAllAnimations(animationElementQueue);
Expand Down
43 changes: 43 additions & 0 deletions test/ngAnimate/animateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,49 @@ describe("ngAnimate", function() {
expect(element.hasClass('some-class-add-active')).toBe(false);
}));

it("should intelligently cancel former timeouts and close off a series of elements a final timeout", function() {
var cancellations = 0;
module(function($provide) {
$provide.decorator('$timeout', function($delegate) {
var _cancel = $delegate.cancel;
$delegate.cancel = function() {
cancellations++;
return _cancel.apply($delegate, arguments);
};
return $delegate;
});
})
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {
if (!$sniffer.transitions) return;

ss.addRule('.animate-me', '-webkit-transition:1s linear all;' +
'transition:1s linear all;');

element = $compile(html('<div><div class="animate-me" ng-repeat="item in items"></div></div>'))($rootScope);

$rootScope.items = [1,2,3,4,5,6,7,8,9,10];
var totalOperations = $rootScope.items.length;

$rootScope.$digest();

$rootScope.items = [0];
$animate.triggerReflow();
$timeout.flush(1500);

expect(cancellations).toBeLessThan(totalOperations);
expect(element.children().length).toBe(10);
cancellations = 0;

$rootScope.items = [1];
$rootScope.$digest();

$animate.triggerReflow();
$timeout.flush(1500);
expect(element.children().length).toBe(1);
expect(cancellations).toBeLessThan(totalOperations);
});
});

it("apply a closing timeout with respect to a staggering animation",
inject(function($animate, $rootScope, $compile, $sniffer, $timeout) {

Expand Down

0 comments on commit 89e7130

Please sign in to comment.