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

Commit 3105b2c

Browse files
Narretzmgol
authored andcommitted
fix(ngAnimate): remove prepare classes with multiple structural animations
Closes #16681 Closes #16677
1 parent bc5a48d commit 3105b2c

File tree

2 files changed

+83
-3
lines changed

2 files changed

+83
-3
lines changed

src/ngAnimate/animation.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,6 @@ var $$AnimationProvider = ['$animateProvider', /** @this */ function($animatePro
113113

114114
// TODO(matsko): document the signature in a better way
115115
return function(element, event, options) {
116-
var node = getDomNode(element);
117-
118116
options = prepareAnimationOptions(options);
119117
var isStructural = ['enter', 'move', 'leave'].indexOf(event) >= 0;
120118

@@ -186,8 +184,9 @@ var $$AnimationProvider = ['$animateProvider', /** @this */ function($animatePro
186184
forEach(groupedAnimations, function(animationEntry) {
187185
var element = animationEntry.from ? animationEntry.from.element : animationEntry.element;
188186
var extraClasses = options.addClass;
187+
189188
extraClasses = (extraClasses ? (extraClasses + ' ') : '') + NG_ANIMATE_CLASSNAME;
190-
var cacheKey = $$animateCache.cacheKey(node, event, extraClasses, options.removeClass);
189+
var cacheKey = $$animateCache.cacheKey(element[0], animationEntry.event, extraClasses, options.removeClass);
191190

192191
toBeSortedAnimations.push({
193192
element: element,

test/ngAnimate/integrationSpec.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe('ngAnimate integration tests', function() {
2525
ss.destroy();
2626
});
2727

28+
2829
it('should cancel a running and started removeClass animation when a follow-up addClass animation adds the same class',
2930
inject(function($animate, $rootScope, $$rAF, $document, $rootElement) {
3031

@@ -362,6 +363,7 @@ describe('ngAnimate integration tests', function() {
362363
});
363364
});
364365

366+
365367
it('should add the preparation class for an enter animation before a parent class-based animation is applied', function() {
366368
module('ngAnimateMock');
367369
inject(function($animate, $compile, $rootScope, $rootElement, $document) {
@@ -397,6 +399,7 @@ describe('ngAnimate integration tests', function() {
397399
});
398400
});
399401

402+
400403
it('should avoid adding the ng-enter-prepare method to a parent structural animation that contains child animations', function() {
401404
module('ngAnimateMock');
402405
inject(function($animate, $compile, $rootScope, $rootElement, $document, $$rAF) {
@@ -468,6 +471,84 @@ describe('ngAnimate integration tests', function() {
468471
});
469472
});
470473

474+
475+
it('should remove the prepare classes when different structural animations happen in the same digest', function() {
476+
module('ngAnimateMock');
477+
inject(function($animate, $compile, $rootScope, $rootElement, $document, $$animateCache) {
478+
element = jqLite(
479+
// Class animation on parent element is neeeded so the child elements get the prepare class
480+
'<div id="outer" ng-class="{blue: cond}" ng-switch="cond">' +
481+
'<div id="default" ng-switch-default></div>' +
482+
'<div id="truthy" ng-switch-when="true"></div>' +
483+
'</div>'
484+
);
485+
486+
$rootElement.append(element);
487+
jqLite($document[0].body).append($rootElement);
488+
489+
$compile(element)($rootScope);
490+
$rootScope.cond = false;
491+
$rootScope.$digest();
492+
493+
$rootScope.cond = true;
494+
$rootScope.$digest();
495+
496+
var parent = element;
497+
var truthySwitch = jqLite(parent[0].querySelector('#truthy'));
498+
var defaultSwitch = jqLite(parent[0].querySelector('#default'));
499+
500+
expect(parent).not.toHaveClass('blue');
501+
expect(parent).toHaveClass('blue-add');
502+
expect(truthySwitch).toHaveClass('ng-enter-prepare');
503+
expect(defaultSwitch).toHaveClass('ng-leave-prepare');
504+
505+
$animate.flush();
506+
507+
expect(parent).toHaveClass('blue');
508+
expect(parent).not.toHaveClass('blue-add');
509+
expect(truthySwitch).not.toHaveClass('ng-enter-prepare');
510+
expect(defaultSwitch).not.toHaveClass('ng-leave-prepare');
511+
});
512+
});
513+
514+
it('should respect the element node for caching when animations with the same type happen in the same digest', function() {
515+
module('ngAnimateMock');
516+
inject(function($animate, $compile, $rootScope, $rootElement, $document, $$animateCache) {
517+
ss.addRule('.animate.ng-enter', 'transition:2s linear all;');
518+
519+
element = jqLite(
520+
'<div>' +
521+
'<div>' +
522+
'<div id="noanimate" ng-if="cond"></div>' +
523+
'</div>' +
524+
'<div>' +
525+
'<div id="animate" class="animate" ng-if="cond"></div>' +
526+
'</div>' +
527+
'</div>'
528+
);
529+
530+
$rootElement.append(element);
531+
jqLite($document[0].body).append($rootElement);
532+
533+
$compile(element)($rootScope);
534+
$rootScope.cond = true;
535+
$rootScope.$digest();
536+
537+
var parent = element;
538+
var noanimate = jqLite(parent[0].querySelector('#noanimate'));
539+
var animate = jqLite(parent[0].querySelector('#animate'));
540+
541+
expect(noanimate).not.toHaveClass('ng-enter');
542+
expect(animate).toHaveClass('ng-enter');
543+
544+
$animate.closeAndFlush();
545+
546+
expect(noanimate).not.toHaveClass('ng-enter');
547+
expect(animate).not.toHaveClass('ng-enter');
548+
});
549+
});
550+
551+
471552
it('should pack level elements into their own RAF flush', function() {
472553
module('ngAnimateMock');
473554
inject(function($animate, $compile, $rootScope, $rootElement, $document) {

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy