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

Commit 861636c

Browse files
committed
fix($animate): make sure to run a post-digest reflow for parentless animations
Closes #12400 Closes #12401
1 parent e742316 commit 861636c

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

src/ngAnimate/animation.js

+26-5
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,16 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
106106
result = result.concat(row);
107107
}
108108

109-
return result;
109+
var terminalAnimations = [];
110+
var parentAnimations = [];
111+
forEach(result, function(result) {
112+
if (result.terminal) {
113+
terminalAnimations.push(result.fn);
114+
} else {
115+
parentAnimations.push(result.fn);
116+
}
117+
});
118+
return [parentAnimations, terminalAnimations];
110119
}
111120
}
112121

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

223-
forEach(anim, function(entry) {
224-
if (!entry.terminal) {
232+
// sortAnimations will return two lists of animations. The first list
233+
// is all of the parent animations that are likely class-based and the
234+
// second list is a collection of the rest. Before we run the second
235+
// list we must ensure that atleast one reflow has been passed such that
236+
// the preparation classes (ng-enter, class-add, etc...) have been applied
237+
// to their associated element.
238+
if (anim[0].length) {
239+
forEach(anim[0], function(triggerAnimation) {
225240
$$forceReflow();
226-
}
227-
entry.fn();
241+
triggerAnimation();
242+
});
243+
} else {
244+
$$forceReflow();
245+
}
246+
247+
forEach(anim[1], function(triggerAnimation) {
248+
triggerAnimation();
228249
});
229250
});
230251

test/ngAnimate/integrationSpec.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ describe('ngAnimate integration tests', function() {
306306
});
307307
});
308308

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

329329
$rootScope.exp = true;
330330
$rootScope.$digest();
331-
expect($animate.reflows).toBe(0);
331+
expect($animate.reflows).toBe(1);
332332

333333
$rootScope.exp2 = true;
334334
$rootScope.$digest();
335+
expect($animate.reflows).toBe(2);
336+
});
337+
});
338+
339+
it('should always issue atleast one reflow incase there are no parent class-based animations', function() {
340+
module('ngAnimateMock');
341+
inject(function($animate, $compile, $rootScope, $rootElement, $$rAF, $document) {
342+
element = jqLite(
343+
'<div ng-repeat="item in items" ng-class="{someAnimation:exp}">' +
344+
'{{ item }}' +
345+
'</div>'
346+
);
347+
348+
$rootElement.append(element);
349+
jqLite($document[0].body).append($rootElement);
350+
351+
$compile(element)($rootScope);
352+
$rootScope.$digest();
335353
expect($animate.reflows).toBe(0);
354+
355+
$rootScope.exp = true;
356+
$rootScope.items = [1,2,3,4,5,6,7,8,9,10];
357+
$rootScope.$digest();
358+
359+
expect($animate.reflows).toBe(1);
336360
});
337361
});
338362
});

0 commit comments

Comments
 (0)