aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatias Niemelä2014-02-24 14:47:12 -0500
committerMatias Niemelä2014-02-26 14:23:47 -0500
commit99720fb5ab7259af37f708bc4eeda7cbbe790a69 (patch)
treeec032b6e4245e16310ebf5702f733b6531687508
parent332e935048d161764046b43fe6599e1db2afc3b6 (diff)
downloadangular.js-99720fb5ab7259af37f708bc4eeda7cbbe790a69.tar.bz2
fix($animate): ensure all animated elements are taken care of during the closing timeout
Closes #6395
-rw-r--r--src/ngAnimate/animate.js13
-rw-r--r--test/ngAnimate/animateSpec.js43
2 files changed, 52 insertions, 4 deletions
diff --git a/src/ngAnimate/animate.js b/src/ngAnimate/animate.js
index 6b7fbcce..c09e714e 100644
--- a/src/ngAnimate/animate.js
+++ b/src/ngAnimate/animate.js
@@ -1063,6 +1063,15 @@ 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;
@@ -1070,10 +1079,6 @@ angular.module('ngAnimate', ['ng'])
$timeout.cancel(closingTimer);
- var node = extractElementNode(element);
- element = angular.element(node);
- animationElementQueue.push(element);
-
closingTimestamp = futureTimestamp;
closingTimer = $timeout(function() {
closeAllAnimations(animationElementQueue);
diff --git a/test/ngAnimate/animateSpec.js b/test/ngAnimate/animateSpec.js
index 47e7afff..27eeb112 100644
--- a/test/ngAnimate/animateSpec.js
+++ b/test/ngAnimate/animateSpec.js
@@ -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) {