Skip to content

Commit

Permalink
fix(ngAnimate): don't normalize classes on follow-up animations to jo…
Browse files Browse the repository at this point in the history
…ined animations

This allows follow-up animations to remove a class that is currently
being added.

Fixes angular#13339
Fixes angular#13380
Closes angular#13414
  • Loading branch information
matsko committed Dec 9, 2015
1 parent 5328ccd commit 4cfbae9
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
43 changes: 39 additions & 4 deletions src/ngAnimate/animateQueue.js
Expand Up @@ -12,6 +12,14 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
join: []
};

function makeTruthyMapFromKeys(keys) {
var map = Object.create(null);
forEach(keys, function(key) {
map[key] = true;
});
return map;
}

function isAllowed(ruleType, element, currentAnimation, previousAnimation) {
return rules[ruleType].some(function(fn) {
return fn(element, currentAnimation, previousAnimation);
Expand Down Expand Up @@ -59,11 +67,38 @@ var $$AnimateQueueProvider = ['$animateProvider', function($animateProvider) {
});

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

var nA = newAnimation.options.addClass;
var nR = newAnimation.options.removeClass;
var cA = currentAnimation.options.addClass;
var cR = currentAnimation.options.removeClass;

// early detection to save the global CPU shortage :)
if ((!isDefined(nA) && !isDefined(nR)) || (!isDefined(cA) && !isDefined(cR))) {
return false;
}

var cancelSomething = false;

cA = cA ? makeTruthyMapFromKeys(cA.split(ONE_SPACE)) : null;
cR = cR ? makeTruthyMapFromKeys(cR.split(ONE_SPACE)) : null;

if (cR && nA) {
cancelSomething = nA.split(ONE_SPACE).some(function(className) {
return cR[className];
});

if (cancelSomething) return true;
}

if (cA && nR) {
cancelSomething = nR.split(ONE_SPACE).some(function(className) {
return cA[className];
});
}

// 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);
return cancelSomething;
});

this.$get = ['$$rAF', '$rootScope', '$rootElement', '$document', '$$HashMap',
Expand Down
1 change: 1 addition & 0 deletions test/ngAnimate/integrationSpec.js
Expand Up @@ -377,6 +377,7 @@ describe('ngAnimate integration tests', function() {
$rootScope.$digest();
$$rAF.flush();

expect(element).not.toHaveClass('hide-add hide-add-active');
expect(element).toHaveClass('hide-remove hide-remove-active');

//End the animation process
Expand Down

0 comments on commit 4cfbae9

Please sign in to comment.