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

fix($animate): prevent cancellation timestamp from being too far in the future #6793

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ngAnimate/animate.js
Original file line number Diff line number Diff line change
Expand Up @@ -1199,7 +1199,7 @@ angular.module('ngAnimate', ['ng'])

//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);
var futureTimestamp = Date.now() + totalTime;
if(futureTimestamp <= closingTimestamp) {
return;
}
Expand Down
36 changes: 29 additions & 7 deletions test/ngAnimate/animateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1390,24 +1390,44 @@ describe("ngAnimate", function() {
}));

it("should intelligently cancel former timeouts and close off a series of elements a final timeout", function() {
var currentTimestamp = Date.now();
spyOn(Date,'now').andCallFake(function() {
return currentTimestamp;
});

var cancellations = 0;
module(function($provide) {

$provide.decorator('$timeout', function($delegate) {
var _cancel = $delegate.cancel;
$delegate.cancel = function() {
cancellations++;
return _cancel.apply($delegate, arguments);
$delegate.cancel = function(timer) {
if(timer) {
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;' +
ss.addRule('.animate-me div', '-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);
ss.addRule('.animate-me-longer div', '-webkit-transition:1.5s linear all;' +
'transition:1.5s linear all;');

element = $compile(html('<div class="animate-me-longer">' +
'<div ng-repeat="item in items"></div>' +
'</div>'))($rootScope);
$rootScope.items = [0];
$rootScope.$digest();
$animate.triggerReflow();

currentTimestamp += 2250; //1.5 * 1500 = 2250

element[0].className = 'animate-me';

$rootScope.items = [1,2,3,4,5,6,7,8,9,10];
var totalOperations = $rootScope.items.length;
Expand All @@ -1416,9 +1436,11 @@ describe("ngAnimate", function() {

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

currentTimestamp += 1500; //1.5 * 1000 = 1500
$timeout.flush(1500);

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

Expand All @@ -1428,7 +1450,7 @@ describe("ngAnimate", function() {
$animate.triggerReflow();
$timeout.flush(1500);
expect(element.children().length).toBe(1);
expect(cancellations).toBeLessThan(totalOperations);
expect(cancellations).toBe(1);
});
});

Expand Down