chore(core): introduce a wrapper for requestAnimationFrame

This commit is contained in:
Matias Niemelä
2014-02-24 18:14:29 -05:00
parent 2cd87dbb93
commit 04d7317cdd
5 changed files with 103 additions and 1 deletions
+1
View File
@@ -26,6 +26,7 @@ angularFiles = {
'src/ng/log.js',
'src/ng/parse.js',
'src/ng/q.js',
'src/ng/raf.js',
'src/ng/rootScope.js',
'src/ng/sanitizeUri.js',
'src/ng/sce.js',
+4 -1
View File
@@ -72,6 +72,8 @@
$SnifferProvider,
$TemplateCacheProvider,
$TimeoutProvider,
$$RAFProvider,
$AsyncCallbackProvider,
$WindowProvider
*/
@@ -211,7 +213,8 @@ function publishExternalAPI(angular){
$sniffer: $SnifferProvider,
$templateCache: $TemplateCacheProvider,
$timeout: $TimeoutProvider,
$window: $WindowProvider
$window: $WindowProvider,
$$rAF: $$RAFProvider
});
}
]);
+22
View File
@@ -0,0 +1,22 @@
'use strict';
function $$RAFProvider(){ //rAF
this.$get = ['$window', function($window) {
var requestAnimationFrame = $window.requestAnimationFrame ||
$window.webkitRequestAnimationFrame;
var cancelAnimationFrame = $window.cancelAnimationFrame ||
$window.webkitCancelAnimationFrame;
var raf = function(fn) {
var id = requestAnimationFrame(fn);
return function() {
cancelAnimationFrame(id);
};
};
raf.supported = !!requestAnimationFrame;
return raf;
}];
}
+29
View File
@@ -1656,6 +1656,34 @@ angular.mock.$TimeoutDecorator = function($delegate, $browser) {
return $delegate;
};
angular.mock.$RAFDecorator = function($delegate) {
var queue = [];
var rafFn = function(fn) {
var index = queue.length;
queue.push(fn);
return function() {
queue.splice(index, 1);
};
};
rafFn.supported = $delegate.supported;
rafFn.flush = function() {
if(queue.length === 0) {
throw new Error('No rAF callbacks present');
}
var length = queue.length;
for(var i=0;i<length;i++) {
queue[i]();
}
queue = [];
};
return rafFn;
};
/**
*
*/
@@ -1689,6 +1717,7 @@ angular.module('ngMock', ['ng']).provider({
$rootElement: angular.mock.$RootElementProvider
}).config(['$provide', function($provide) {
$provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
$provide.decorator('$$rAF', angular.mock.$RAFDecorator);
}]);
/**
+47
View File
@@ -0,0 +1,47 @@
'use strict';
describe('$$rAF', function() {
it('should queue and block animation frames', inject(function($$rAF) {
if(!$$rAF.supported) return;
var message;
$$rAF(function() {
message = 'yes';
});
expect(message).toBeUndefined();
$$rAF.flush();
expect(message).toBe('yes');
}));
it('should provide a cancellation method', inject(function($$rAF) {
if(!$$rAF.supported) return;
var present = true;
var cancel = $$rAF(function() {
present = false;
});
expect(present).toBe(true);
cancel();
try {
$$rAF.flush();
} catch(e) {};
expect(present).toBe(true);
}));
describe('mocks', function() {
it('should throw an error if no frames are present', inject(function($$rAF) {
if($$rAF.supported) {
var failed = false;
try {
$$rAF.flush();
} catch(e) {
failed = true;
}
expect(failed).toBe(true);
}
}));
});
});