fix($animate): ensure that class-based animations only consider the most recent DOM operations

Prior to this fix $animate would maintain a count of each time a class was
added and removed within $animate. With this fix, $animate instead only cares
about the most recent addClass or removeClass operation and will only perform
that operation (depending on what was last called).

```
// before
addClass    => +1
removeClass => 0
addClass    => +1
addClass    => +2
removeClass => +1
// this will cause an addClass animation

// now
addClass    => add
removeClass => remove
addClass    => add
addClass    => add
removeClass => remove
// this will cause a removeClass animation
```

Closes #8946
Closes #9458
This commit is contained in:
Matias Niemelä
2014-10-07 11:25:46 +03:00
committed by Igor Minar
parent a84480affb
commit c93924ed27
2 changed files with 93 additions and 27 deletions

View File

@@ -3408,11 +3408,76 @@ describe("ngAnimate", function() {
$animate.triggerReflow();
expect(log.length).toBe(2);
expect(log[0]).toEqual({ name : 'addClass', className : 'one five' });
expect(log[0]).toEqual({ name : 'addClass', className : 'one four five' });
expect(log[1]).toEqual({ name : 'removeClass', className : 'three' });
});
});
it('should intelligently cancel out redundant class-based animations', function() {
var log = [];
var track = function(name) {
return function() {
log.push({ name : name, className : arguments[1] });
};
};
module(function($animateProvider) {
$animateProvider.register('.animate', function() {
return {
addClass : track('addClass'),
removeClass : track('removeClass')
};
});
});
inject(function($rootScope, $animate, $compile, $rootElement, $document) {
$animate.enabled(true);
var element = $compile('<div class="animate three four"></div>')($rootScope);
$rootElement.append(element);
angular.element($document[0].body).append($rootElement);
$animate.removeClass(element, 'one');
$rootScope.$digest();
$animate.triggerReflow();
expect(log.length).toBe(0);
$animate.triggerCallbacks();
$animate.addClass(element, 'two');
$animate.addClass(element, 'two');
$animate.removeClass(element, 'two');
$rootScope.$digest();
$animate.triggerReflow();
expect(log.length).toBe(0);
$animate.triggerCallbacks();
$animate.removeClass(element, 'three');
$animate.addClass(element, 'three');
$rootScope.$digest();
$animate.triggerReflow();
expect(log.length).toBe(0);
$animate.triggerCallbacks();
$animate.removeClass(element, 'four');
$animate.addClass(element, 'four');
$animate.removeClass(element, 'four');
$rootScope.$digest();
$animate.triggerReflow();
expect(log.length).toBe(1);
$animate.triggerCallbacks();
expect(log[0]).toEqual({ name : 'removeClass', className : 'four' });
$animate.addClass(element, 'five');
$animate.addClass(element, 'five');
$animate.addClass(element, 'five');
$animate.removeClass(element, 'five');
$animate.addClass(element, 'five');
$rootScope.$digest();
$animate.triggerReflow();
expect(log.length).toBe(2);
$animate.triggerCallbacks();
expect(log[1]).toEqual({ name : 'addClass', className : 'five' });
});
});
it('should skip class-based animations if the element is removed before the digest occurs', function() {
var spy = jasmine.createSpy();
module(function($animateProvider) {