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

Commit 7f0767a

Browse files
committed
fix($animate): ensure former nodes are fully cleaned up when a follow-up structural animation takes place
Closes #4435
1 parent 3d4c80c commit 7f0767a

File tree

2 files changed

+42
-6
lines changed

2 files changed

+42
-6
lines changed

src/ngAnimate/animate.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ angular.module('ngAnimate', ['ng'])
588588
//if an animation is currently running on the element then lets take the steps
589589
//to cancel that animation and fire any required callbacks
590590
$timeout.cancel(ngAnimateState.flagTimer);
591+
cleanup(element);
591592
cancelAnimations(ngAnimateState.animations);
592593
(ngAnimateState.done || noop)();
593594
}
@@ -700,25 +701,24 @@ angular.module('ngAnimate', ['ng'])
700701
return rootAnimateState.disabled || rootAnimateState.running;
701702
}
702703

703-
var validState;
704704
do {
705705
//the element did not reach the root element which means that it
706706
//is not apart of the DOM. Therefore there is no reason to do
707707
//any animations on it
708-
if(parent.length === 0) return true;
708+
if(parent.length === 0) break;
709709

710710
var isRoot = parent[0] == $rootElement[0];
711711
var state = isRoot ? rootAnimateState : parent.data(NG_ANIMATE_STATE);
712-
if(state && (state.disabled != null || state.running != null)) {
713-
validState = state;
714-
break;
712+
var result = state && (!!state.disabled || !!state.running);
713+
if(isRoot || result) {
714+
return result;
715715
}
716716

717717
if(isRoot) return true;
718718
}
719719
while(parent = parent.parent());
720720

721-
return validState ? (validState.disabled || validState.running) : true;
721+
return true;
722722
}
723723
}]);
724724

test/ngAnimate/animateSpec.js

+36
Original file line numberDiff line numberDiff line change
@@ -1817,6 +1817,42 @@ describe("ngAnimate", function() {
18171817
// expect(element.hasClass('hiding')).toBe(false);
18181818
// });
18191819
// });
1820+
it("should remove all the previous classes when the next animation is applied before a reflow", function() {
1821+
var fn, interceptedClass;
1822+
module(function($animateProvider) {
1823+
$animateProvider.register('.three', function() {
1824+
return {
1825+
move : function(element, done) {
1826+
fn = function() {
1827+
done();
1828+
}
1829+
return function() {
1830+
interceptedClass = element.attr('class');
1831+
}
1832+
}
1833+
}
1834+
});
1835+
});
1836+
inject(function($compile, $rootScope, $animate, $timeout) {
1837+
var parent = html($compile('<div class="parent"></div>')($rootScope));
1838+
var one = $compile('<div class="one"></div>')($rootScope);
1839+
var two = $compile('<div class="two"></div>')($rootScope);
1840+
var three = $compile('<div class="three klass"></div>')($rootScope);
1841+
1842+
parent.append(one);
1843+
parent.append(two);
1844+
parent.append(three);
1845+
1846+
$animate.move(three, null, two);
1847+
$rootScope.$digest();
1848+
1849+
$animate.move(three, null, one);
1850+
$rootScope.$digest();
1851+
1852+
//this means that the former animation was cleaned up before the new one starts
1853+
expect(interceptedClass.indexOf('ng-animate') >= 0).toBe(false);
1854+
});
1855+
});
18201856

18211857
it("should provide the correct CSS class to the addClass and removeClass callbacks within a JS animation", function() {
18221858
module(function($animateProvider) {

0 commit comments

Comments
 (0)