From 781e5d7e1516a7fc122b82ae668cfe1d77feb9cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matias=20Niemel=C3=A4?= Date: Mon, 4 May 2015 16:56:45 -0700 Subject: [PATCH] fix(ngAnimate): ensure that the temporary CSS classes are applied before detection Prior to 1.4 the `ng-animate` CSS class was applied before the CSS getComputedStyle detection was issued. This was lost in the 1.4 refactor, however, this patch restores the functionality. Closes #11769 --- src/ngAnimate/animation.js | 26 +++++++++++++++----------- test/ngAnimate/animationSpec.js | 23 +++++++++++++++++++++++ 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/ngAnimate/animation.js b/src/ngAnimate/animation.js index 0c52760d56bd..f8ab98aefaa5 100644 --- a/src/ngAnimate/animation.js +++ b/src/ngAnimate/animation.js @@ -62,7 +62,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) { event: event, structural: isStructural, options: options, - start: start, + beforeStart: beforeStart, close: close }); @@ -88,15 +88,19 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) { animationQueue.length = 0; forEach(groupAnimations(animations), function(animationEntry) { - var startFn = animationEntry.start; - var closeFn = animationEntry.close; + // it's important that we apply the `ng-animate` CSS class and the + // temporary classes before we do any driver invoking since these + // CSS classes may be required for proper CSS detection. + animationEntry.beforeStart(); + var operation = invokeFirstDriver(animationEntry); - var startAnimation = operation && operation.start; /// TODO(matsko): only recognize operation.start() - if (!startAnimation) { + var triggerAnimationStart = operation && operation.start; /// TODO(matsko): only recognize operation.start() + + var closeFn = animationEntry.close; + if (!triggerAnimationStart) { closeFn(); } else { - startFn(); - var animationRunner = startAnimation(); + var animationRunner = triggerAnimationStart(); animationRunner.done(function(status) { closeFn(!status); }); @@ -173,9 +177,9 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) { if (!anchorGroups[lookupKey]) { var group = anchorGroups[lookupKey] = { // TODO(matsko): double-check this code - start: function() { - fromAnimation.start(); - toAnimation.start(); + beforeStart: function() { + fromAnimation.beforeStart(); + toAnimation.beforeStart(); }, close: function() { fromAnimation.close(); @@ -241,7 +245,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) { } } - function start() { + function beforeStart() { element.addClass(NG_ANIMATE_CLASSNAME); if (tempClasses) { $$jqLite.addClass(element, tempClasses); diff --git a/test/ngAnimate/animationSpec.js b/test/ngAnimate/animationSpec.js index c38f6efd8ea4..11dddf886ba9 100644 --- a/test/ngAnimate/animationSpec.js +++ b/test/ngAnimate/animationSpec.js @@ -734,6 +734,29 @@ describe('$$animation', function() { expect(element).not.toHaveClass('ng-animate'); })); + + it('should apply the `ng-animate` and temporary CSS classes before the driver is invoked', function() { + var capturedElementClasses; + + module(function($provide) { + $provide.factory('mockedTestDriver', function() { + return function(details) { + capturedElementClasses = details.element.attr('class'); + }; + }); + }); + + inject(function($$animation, $rootScope) { + $$animation(element, 'enter', { + tempClasses: 'temp-class-name' + }); + $rootScope.$digest(); + + expect(capturedElementClasses).toMatch(/\bng-animate\b/); + expect(capturedElementClasses).toMatch(/\btemp-class-name\b/); + }); + }); + it('should perform the DOM operation at the end of the animation if the driver doesn\'t run it already', inject(function($$animation, $rootScope) {