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

Commit

Permalink
fix(ngAnimate): close follow-up class-based animations when the same …
Browse files Browse the repository at this point in the history
…class is added/removed when removed/added

This patch ensures that if the same CSS class is added/removed within a
follow-up digest then the previous class-based animation is cancelled
beforehand.

Closes #11717
  • Loading branch information
matsko committed May 26, 2015
1 parent 72edd4d commit db246eb
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/ngAnimate/animateQueue.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
return currentAnimation.state === RUNNING_STATE && newAnimation.structural;
});

rules.cancel.push(function(element, newAnimation, currentAnimation) {
var nO = newAnimation.options;
var cO = currentAnimation.options;

// if the exact same CSS class is added/removed then it's safe to cancel it
return (nO.addClass && nO.addClass === cO.removeClass) || (nO.removeClass && nO.removeClass === cO.addClass);
});

this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap',
'$$animation', '$$AnimateRunner', '$templateRequest', '$$jqLite',
function($$rAF, $rootScope, $rootElement, $document, $$HashMap,
Expand Down Expand Up @@ -358,6 +366,7 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {

if (!isValidAnimation) {
close();
clearElementAnimationState(element);
return runner;
}

Expand Down
41 changes: 41 additions & 0 deletions test/ngAnimate/animateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,47 @@ describe("animations", function() {
expect(enterDone).toHaveBeenCalled();
}));

it('should cancel the previously running addClass animation if a follow-up removeClass animation is using the same class value',
inject(function($animate, $rootScope, $$rAF) {

parent.append(element);
var runner = $animate.addClass(element, 'active-class');
$rootScope.$digest();

var doneHandler = jasmine.createSpy('addClass done');
runner.done(doneHandler);

$$rAF.flush();

expect(doneHandler).not.toHaveBeenCalled();

$animate.removeClass(element, 'active-class');
$rootScope.$digest();

expect(doneHandler).toHaveBeenCalled();
}));

it('should cancel the previously running removeClass animation if a follow-up addClass animation is using the same class value',
inject(function($animate, $rootScope, $$rAF) {

element.addClass('active-class');
parent.append(element);
var runner = $animate.removeClass(element, 'active-class');
$rootScope.$digest();

var doneHandler = jasmine.createSpy('addClass done');
runner.done(doneHandler);

$$rAF.flush();

expect(doneHandler).not.toHaveBeenCalled();

$animate.addClass(element, 'active-class');
$rootScope.$digest();

expect(doneHandler).toHaveBeenCalled();
}));

it('should skip the class-based animation entirely if there is an active structural animation',
inject(function($animate, $rootScope) {

Expand Down

0 comments on commit db246eb

Please sign in to comment.