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

fix($animate): run CSS animations before JS animations to avoid style inheritance #6799

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add a reason in a comment?

something like:

// this order is important so that js animations can't change element style and confuse us
// when computing styles to figure out transition duration

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

otherwise only you know why this test is here and even you might forget the reason in the future :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

/* 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 */

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