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

Commit 2317af6

Browse files
committed
fix($animate): run CSS animations before JS animations to avoid style 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
1 parent 3bf8d6c commit 2317af6

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

src/ngAnimate/animate.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -332,9 +332,12 @@ angular.module('ngAnimate', ['ng'])
332332
//operation which performs CSS transition and keyframe
333333
//animations sniffing. This is always included for each
334334
//element animation procedure if the browser supports
335-
//transitions and/or keyframe animations
335+
//transitions and/or keyframe animations. The default
336+
//animation is added to the top of the list to prevent
337+
//any previous animations from affecting the element styling
338+
//prior to the element being animated.
336339
if ($sniffer.transitions || $sniffer.animations) {
337-
classes.push('');
340+
matches.push($injector.get(selectors['']));
338341
}
339342

340343
for(var i=0; i < classes.length; i++) {

test/ngAnimate/animateSpec.js

+31
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,37 @@ describe("ngAnimate", function() {
721721
})
722722
});
723723

724+
/* The CSS animation handler must always be rendered before the other JS animation
725+
handlers. This is important since the CSS animation handler may place temporary
726+
styling on the HTML element before the reflow commences which in turn may override
727+
other transition or keyframe styles that any former JS animations may have placed
728+
on the element: https://github.com/angular/angular.js/issues/6675 */
729+
it("should always perform the CSS animation before the JS animation", function() {
730+
var log = [];
731+
module(function($animateProvider) {
732+
//CSS animation handler
733+
$animateProvider.register('', function() {
734+
return {
735+
leave : function() { log.push('css'); }
736+
}
737+
});
738+
//custom JS animation handler
739+
$animateProvider.register('.js-animation', function() {
740+
return {
741+
leave : function() { log.push('js'); }
742+
}
743+
});
744+
});
745+
inject(function($animate, $rootScope, $compile, $sniffer) {
746+
if(!$sniffer.transitions) return;
747+
748+
element = $compile(html('<div class="js-animation"></div>'))($rootScope);
749+
$animate.leave(element);
750+
$rootScope.$digest();
751+
expect(log).toEqual(['css','js']);
752+
});
753+
});
754+
724755

725756
describe("Animations", function() {
726757

0 commit comments

Comments
 (0)