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

Commit 5d91d5c

Browse files
committed
fix($animate): clear class animations cache if animation is not started
Closes #12604 Closes #12603
1 parent f315efd commit 5d91d5c

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

src/ngAnimate/animate.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,10 +1194,19 @@ angular.module('ngAnimate', ['ng'])
11941194
}
11951195

11961196
return cache.promise = runAnimationPostDigest(function(done) {
1197-
var parentNode, parentElement, elementNode = extractElementNode(element);
1197+
var cache, parentNode, parentElement, elementNode = extractElementNode(element);
1198+
var DOM_FRAGMENT = 11;
11981199
if (elementNode) {
11991200
parentElement = element.parent();
12001201
parentNode = elementNode.parentNode;
1202+
1203+
// we can have an element animate on the document, but not on a fragment
1204+
if (parentNode && parentNode.nodeType === DOM_FRAGMENT) {
1205+
parentNode = null;
1206+
}
1207+
1208+
cache = element.data(STORAGE_KEY);
1209+
element.removeData(STORAGE_KEY);
12011210
}
12021211

12031212
// TODO(matsko): move this code into the animationsDisabled() function once #8092 is fixed
@@ -1206,9 +1215,6 @@ angular.module('ngAnimate', ['ng'])
12061215
return;
12071216
}
12081217

1209-
var cache = element.data(STORAGE_KEY);
1210-
element.removeData(STORAGE_KEY);
1211-
12121218
var state = element.data(NG_ANIMATE_STATE) || {};
12131219
var classes = resolveElementClasses(element, cache, state.active);
12141220
return !classes

test/ngAnimate/animateSpec.js

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,42 @@ describe("ngAnimate", function() {
543543
});
544544
});
545545

546+
it("should clear the setClass element animation cache before the next animation runs", function() {
547+
var animateSpy = jasmine.createSpy();
548+
module(function($animateProvider) {
549+
$animateProvider.register('.track-me', function() {
550+
return {
551+
addClass: animateSpy,
552+
removeClass: animateSpy,
553+
setClass: animateSpy
554+
};
555+
});
556+
});
557+
inject(function($animate, $rootScope, $sniffer, $$rAF) {
558+
element[0].removeChild(child[0]);
559+
560+
var orphanChild = jqLite('<div class="track-me"></div>');
561+
var doneSpy = jasmine.createSpy();
562+
563+
$animate.setClass(orphanChild, 'red', 'blue').then(doneSpy);
564+
$rootScope.$digest();
565+
$animate.triggerCallbacks();
566+
567+
expect(doneSpy).toHaveBeenCalled();
568+
expect(animateSpy).not.toHaveBeenCalled();
569+
570+
element.append(orphanChild);
571+
572+
$animate.setClass(orphanChild, 'blue', 'gold').then(doneSpy);
573+
$rootScope.$digest();
574+
$animate.triggerReflow();
575+
$animate.triggerCallbacks();
576+
577+
expect(animateSpy).toHaveBeenCalled();
578+
});
579+
});
580+
581+
546582
it("should exclusively animate the setClass animation event with native dom elements", function() {
547583
var count = 0, fallback = jasmine.createSpy('callback');
548584
module(function($animateProvider) {
@@ -4558,8 +4594,10 @@ describe("ngAnimate", function() {
45584594
};
45594595
});
45604596
});
4561-
inject(function($compile, $rootScope, $animate, $sniffer, $rootElement) {
4597+
inject(function($compile, $rootScope, $animate, $sniffer, $rootElement, $document) {
45624598

4599+
var body = jqLite($document[0].body);
4600+
body.append($rootElement);
45634601
$rootElement.addClass('animated');
45644602
$animate.addClass($rootElement, 'green');
45654603
$rootScope.$digest();
@@ -5417,9 +5455,11 @@ describe("ngAnimate", function() {
54175455
}
54185456

54195457

5420-
it('should defer class manipulation until end of digest', inject(function($rootScope, $animate, log) {
5458+
it('should defer class manipulation until end of digest', inject(function($rootScope, $animate, log, $document, $rootElement) {
54215459
setupClassManipulationLogger(log);
54225460
element = jqLite('<p>test</p>');
5461+
jqLite($document[0].body).append($rootElement);
5462+
$rootElement.append(element);
54235463

54245464
$rootScope.$apply(function() {
54255465
$animate.addClass(element, 'test-class1');
@@ -5446,9 +5486,11 @@ describe("ngAnimate", function() {
54465486
}));
54475487

54485488

5449-
it('should defer class manipulation until postDigest when outside of digest', inject(function($rootScope, $animate, log) {
5489+
it('should defer class manipulation until postDigest when outside of digest', inject(function($rootScope, $animate, log, $document, $rootElement) {
54505490
setupClassManipulationLogger(log);
54515491
element = jqLite('<p class="test-class4">test</p>');
5492+
jqLite($document[0].body).append($rootElement);
5493+
$rootElement.append(element);
54525494

54535495
$animate.addClass(element, 'test-class1');
54545496
$animate.removeClass(element, 'test-class1');
@@ -5467,8 +5509,10 @@ describe("ngAnimate", function() {
54675509
}));
54685510

54695511

5470-
it('should perform class manipulation in expected order at end of digest', inject(function($rootScope, $animate, log) {
5512+
it('should perform class manipulation in expected order at end of digest', inject(function($rootScope, $animate, log, $rootElement, $document) {
54715513
element = jqLite('<p class="test-class3">test</p>');
5514+
jqLite($document[0].body).append($rootElement);
5515+
$rootElement.append(element);
54725516

54735517
setupClassManipulationLogger(log);
54745518

0 commit comments

Comments
 (0)