diff --git a/src/ng/raf.js b/src/ng/raf.js index f4eb31c0bf7e..e07adbfed5ce 100644 --- a/src/ng/raf.js +++ b/src/ng/raf.js @@ -1,7 +1,7 @@ 'use strict'; function $$RAFProvider(){ //rAF - this.$get = ['$window', function($window) { + this.$get = ['$window', '$timeout', function($window, $timeout) { var requestAnimationFrame = $window.requestAnimationFrame || $window.webkitRequestAnimationFrame || $window.mozRequestAnimationFrame; @@ -10,14 +10,22 @@ function $$RAFProvider(){ //rAF $window.webkitCancelAnimationFrame || $window.mozCancelAnimationFrame; - var raf = function(fn) { - var id = requestAnimationFrame(fn); - return function() { - cancelAnimationFrame(id); - }; - }; + var rafSupported = !!requestAnimationFrame; + var raf = rafSupported + ? function(fn) { + var id = requestAnimationFrame(fn); + return function() { + cancelAnimationFrame(id); + }; + } + : function(fn) { + var timer = $timeout(fn, 16.66, false); // 1000 / 60 = 16.666 + return function() { + $timeout.cancel(timer); + }; + }; - raf.supported = !!requestAnimationFrame; + raf.supported = rafSupported; return raf; }]; diff --git a/test/ng/rafSpec.js b/test/ng/rafSpec.js index 6c15e2d2984c..8bf76efd03b0 100644 --- a/test/ng/rafSpec.js +++ b/test/ng/rafSpec.js @@ -31,6 +31,38 @@ describe('$$rAF', function() { expect(present).toBe(true); })); + describe('$timeout fallback', function() { + it("it should use a $timeout incase native rAF isn't suppored", function() { + var timeoutSpy = jasmine.createSpy('callback'); + + //we need to create our own injector to work around the ngMock overrides + var injector = createInjector(['ng', function($provide) { + $provide.value('$timeout', timeoutSpy); + $provide.decorator('$window', function($delegate) { + $delegate.requestAnimationFrame = false; + $delegate.webkitRequestAnimationFrame = false; + $delegate.mozRequestAnimationFrame = false; + return $delegate; + }); + }]); + + var $$rAF = injector.get('$$rAF'); + expect($$rAF.supported).toBe(false); + + var message; + $$rAF(function() { + message = 'on'; + }); + + expect(message).toBeUndefined(); + expect(timeoutSpy).toHaveBeenCalled(); + + timeoutSpy.mostRecentCall.args[0](); + + expect(message).toBe('on'); + }); + }); + describe('mocks', function() { it('should throw an error if no frames are present', inject(function($$rAF) { if($$rAF.supported) {