From ff5cf736e5b8073c8121295743873ccd04cc7d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Fri, 21 Mar 2014 16:32:53 -0400 Subject: [PATCH] fix($animate): prevent cancellation timestamp from being too far in the future Closes #6748 --- src/ngAnimate/animate.js | 2 +- test/ngAnimate/animateSpec.js | 35 ++++++++++++++++++++++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js index a5a1c13bee4d..8357df8cb584 100644 --- a/src/ngAnimate/animate.js +++ b/src/ngAnimate/animate.js @@ -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; } diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js index b7bc212da34d..1f5e88f3ac68 100644 --- a/test/ngAnimate/animateSpec.js +++ b/test/ngAnimate/animateSpec.js @@ -1390,13 +1390,20 @@ 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; }); @@ -1404,10 +1411,22 @@ describe("ngAnimate", function() { 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('
'))($rootScope); + ss.addRule('.animate-me-longer div', '-webkit-transition:1.5s linear all;' + + 'transition:1.5s linear all;'); + + element = $compile(html('
' + + '
' + + '
'))($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; @@ -1416,9 +1435,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; @@ -1428,7 +1449,7 @@ describe("ngAnimate", function() { $animate.triggerReflow(); $timeout.flush(1500); expect(element.children().length).toBe(1); - expect(cancellations).toBeLessThan(totalOperations); + expect(cancellations).toBe(1); }); });