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

Commit

Permalink
fix($animate): run CSS animations before JS animations to avoid style…
Browse files Browse the repository at this point in the history
… inheritance

If a JS animation is run before a CSS animation then the JS animation may end up writing style
data to the element. If any transition or animation style data is written then it may end up
being accidentally inherited into the CSS animation hanlder that ngAnimate uses. This may result
in an unexpected outcome due to the tweaks and hacks that the CSS handler places on the element.
If the CSS animation is run before the JS animation then, if there are no transitions on the style
attribute nor within the global CSS on the page then nothing will happen and the JS animation can
work as expected.

Closes #6675
  • Loading branch information
matsko committed Mar 26, 2014
1 parent 3bf8d6c commit 2317af6
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
7 changes: 5 additions & 2 deletions src/ngAnimate/animate.js
Original file line number Diff line number Diff line change
Expand Up @@ -332,9 +332,12 @@ angular.module('ngAnimate', ['ng'])
//operation which performs CSS transition and keyframe
//animations sniffing. This is always included for each
//element animation procedure if the browser supports
//transitions and/or keyframe animations
//transitions and/or keyframe animations. The default
//animation is added to the top of the list to prevent
//any previous animations from affecting the element styling
//prior to the element being animated.
if ($sniffer.transitions || $sniffer.animations) {
classes.push('');
matches.push($injector.get(selectors['']));
}

for(var i=0; i < classes.length; i++) {
Expand Down
31 changes: 31 additions & 0 deletions test/ngAnimate/animateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,37 @@ describe("ngAnimate", function() {
})
});

/* The CSS animation handler must always be rendered before the other JS animation
handlers. This is important since the CSS animation handler may place temporary
styling on the HTML element before the reflow commences which in turn may override
other transition or keyframe styles that any former JS animations may have placed
on the element: https://github.com/angular/angular.js/issues/6675 */
it("should always perform the CSS animation before the JS animation", function() {
var log = [];
module(function($animateProvider) {
//CSS animation handler
$animateProvider.register('', function() {
return {
leave : function() { log.push('css'); }
}
});
//custom JS animation handler
$animateProvider.register('.js-animation', function() {
return {
leave : function() { log.push('js'); }
}
});
});
inject(function($animate, $rootScope, $compile, $sniffer) {
if(!$sniffer.transitions) return;

element = $compile(html('<div class="js-animation"></div>'))($rootScope);
$animate.leave(element);
$rootScope.$digest();
expect(log).toEqual(['css','js']);
});
});


describe("Animations", function() {

Expand Down

0 comments on commit 2317af6

Please sign in to comment.