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

Commit

Permalink
fix($animate): make sure to run a post-digest reflow for parentless a…
Browse files Browse the repository at this point in the history
…nimations

Closes #12400
Closes #12401
  • Loading branch information
matsko committed Jul 27, 2015
1 parent e742316 commit 861636c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
31 changes: 26 additions & 5 deletions src/ngAnimate/animation.js
Expand Up @@ -106,7 +106,16 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
result = result.concat(row);
}

return result;
var terminalAnimations = [];
var parentAnimations = [];
forEach(result, function(result) {
if (result.terminal) {
terminalAnimations.push(result.fn);
} else {
parentAnimations.push(result.fn);
}
});
return [parentAnimations, terminalAnimations];
}
}

Expand Down Expand Up @@ -220,11 +229,23 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
var anim = sortAnimations(toBeSortedAnimations);
var finalLevel = anim.length - 1;

forEach(anim, function(entry) {
if (!entry.terminal) {
// sortAnimations will return two lists of animations. The first list
// is all of the parent animations that are likely class-based and the
// second list is a collection of the rest. Before we run the second
// list we must ensure that atleast one reflow has been passed such that
// the preparation classes (ng-enter, class-add, etc...) have been applied
// to their associated element.
if (anim[0].length) {
forEach(anim[0], function(triggerAnimation) {
$$forceReflow();
}
entry.fn();
triggerAnimation();
});
} else {
$$forceReflow();
}

forEach(anim[1], function(triggerAnimation) {
triggerAnimation();
});
});

Expand Down
28 changes: 26 additions & 2 deletions test/ngAnimate/integrationSpec.js
Expand Up @@ -306,7 +306,7 @@ describe('ngAnimate integration tests', function() {
});
});

it('should not issue any reflows for class-based animations if none of them have children with queued animations', function() {
it('should only issue one reflow for class-based animations if none of them have children with queued animations', function() {
module('ngAnimateMock');
inject(function($animate, $compile, $rootScope, $rootElement, $$rAF, $document) {
element = jqLite(
Expand All @@ -328,11 +328,35 @@ describe('ngAnimate integration tests', function() {

$rootScope.exp = true;
$rootScope.$digest();
expect($animate.reflows).toBe(0);
expect($animate.reflows).toBe(1);

$rootScope.exp2 = true;
$rootScope.$digest();
expect($animate.reflows).toBe(2);
});
});

it('should always issue atleast one reflow incase there are no parent class-based animations', function() {
module('ngAnimateMock');
inject(function($animate, $compile, $rootScope, $rootElement, $$rAF, $document) {
element = jqLite(
'<div ng-repeat="item in items" ng-class="{someAnimation:exp}">' +
'{{ item }}' +
'</div>'
);

$rootElement.append(element);
jqLite($document[0].body).append($rootElement);

$compile(element)($rootScope);
$rootScope.$digest();
expect($animate.reflows).toBe(0);

$rootScope.exp = true;
$rootScope.items = [1,2,3,4,5,6,7,8,9,10];
$rootScope.$digest();

expect($animate.reflows).toBe(1);
});
});
});
Expand Down

0 comments on commit 861636c

Please sign in to comment.