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

Commit f687d10

Browse files
crisbetoThomasBurleson
authored andcommitted
fix(progress-circular): use a non-flushable requestAnimationFrame
Reverts to using the plain `requestAnimationFrame`, instead of `$$rAF`, in order to avoid infinite loops when calling `$animate.flush`. Closes #7936
1 parent 9aac20f commit f687d10

File tree

2 files changed

+15
-19
lines changed

2 files changed

+15
-19
lines changed

src/components/progressCircular/js/progressCircularDirective.js

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,13 @@ angular
4848
.directive('mdProgressCircular', MdProgressCircularDirective);
4949

5050
/* @ngInject */
51-
function MdProgressCircularDirective($$rAF, $window, $mdProgressCircular, $mdTheming,
51+
function MdProgressCircularDirective($window, $mdProgressCircular, $mdTheming,
5252
$mdUtil, $interval, $log) {
5353

54+
// Note that this shouldn't use use $$rAF, because it can cause an infinite loop
55+
// in any tests that call $animate.flush.
56+
var rAF = $window.requestAnimationFrame || angular.noop;
57+
var cAF = $window.cancelAnimationFrame || angular.noop;
5458
var DEGREE_IN_RADIANS = $window.Math.PI / 180;
5559
var MODE_DETERMINATE = 'determinate';
5660
var MODE_INDETERMINATE = 'indeterminate';
@@ -110,8 +114,12 @@ function MdProgressCircularDirective($$rAF, $window, $mdProgressCircular, $mdThe
110114
startIndeterminateAnimation();
111115
}
112116

113-
scope.$on('$destroy', function() {
114-
cleanupIndeterminateAnimation(true);
117+
scope.$on('$destroy', function(){
118+
cleanupIndeterminateAnimation();
119+
120+
if (lastDrawFrame) {
121+
cAF(lastDrawFrame);
122+
}
115123
});
116124

117125
scope.$watchGroup(['value', 'mdMode', function() {
@@ -147,7 +155,7 @@ function MdProgressCircularDirective($$rAF, $window, $mdProgressCircular, $mdThe
147155
} else {
148156
var newValue = clamp(newValues[0]);
149157

150-
cleanupIndeterminateAnimation( true );
158+
cleanupIndeterminateAnimation();
151159

152160
element.attr('aria-valuenow', newValue);
153161
renderCircle(clamp(oldValues[0]), newValue);
@@ -200,7 +208,7 @@ function MdProgressCircularDirective($$rAF, $window, $mdProgressCircular, $mdThe
200208
if (animateTo === animateFrom) {
201209
path.attr('d', getSvgArc(animateTo, diameter, pathDiameter, rotation));
202210
} else {
203-
lastDrawFrame = $$rAF(function animation(now) {
211+
lastDrawFrame = rAF(function animation(now) {
204212
var currentTime = $window.Math.max(0, $window.Math.min((now || $mdUtil.now()) - startTime, animationDuration));
205213

206214
path.attr('d', getSvgArc(
@@ -210,11 +218,9 @@ function MdProgressCircularDirective($$rAF, $window, $mdProgressCircular, $mdThe
210218
rotation
211219
));
212220

213-
lastDrawFrame && lastDrawFrame();
214-
215221
// Do not allow overlapping animations
216222
if (id === lastAnimationId && currentTime < animationDuration) {
217-
lastDrawFrame = $$rAF(animation);
223+
lastDrawFrame = rAF(animation);
218224
}
219225
});
220226
}
@@ -256,17 +262,12 @@ function MdProgressCircularDirective($$rAF, $window, $mdProgressCircular, $mdThe
256262
}
257263
}
258264

259-
function cleanupIndeterminateAnimation( clearLastFrames ) {
265+
function cleanupIndeterminateAnimation() {
260266
if (interval) {
261267
$interval.cancel(interval);
262268
interval = null;
263269
element.removeClass(INDETERMINATE_CLASS);
264270
}
265-
266-
if ( clearLastFrames === true ){
267-
lastDrawFrame && lastDrawFrame();
268-
lastDrawFrame = undefined;
269-
}
270271
}
271272
}
272273

src/components/progressCircular/progress-circular.spec.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,6 @@ describe('mdProgressCircular', function() {
106106
expect(element.hasClass('_md-progress-circular-disabled')).toBe(true);
107107
});
108108

109-
it('should not throw the browser in an infinite loop when flushing the animations', inject(function($animate) {
110-
var progress = buildIndicator('<md-progress-circular md-mode="indeterminate"></md-progress-circular>');
111-
$animate.flush();
112-
}));
113-
114109
it('should set the transform origin in all dimensions', function() {
115110
var svg = buildIndicator('<md-progress-circular md-diameter="42px"></md-progress-circular>').find('svg').eq(0);
116111
expect(svg.css('transform-origin')).toBe('21px 21px 21px');

0 commit comments

Comments
 (0)