Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
aFarkas committed Nov 1, 2015
0 parents commit f6dfd5d
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 0 deletions.
108 changes: 108 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
(function (factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
window.idleCallbackShim = factory();
}
}(function(){
'use strict';
var scheduleStart, throttleDelay;
var tasks = [];
var runAttemptes = 0;
var isRunning = false;
var remainingTime = 6;
var throttle = 66;
var index = 0;
var taskStart = 0;
var tasklength = 0;
var IdleDeadline = {
get didTimeout(){
return false;
},
timeRemaining: function(){
var timeRemaining = remainingTime - (Date.now() - taskStart);
return timeRemaining < 0 ? 0 : timeRemaining;
},
};

function scheduleAfterRaf() {
setTimeout(runTasks, 0);
}

function scheduleRaf(){
requestAnimationFrame(scheduleAfterRaf);
}

function scheduleLazy(){

if(isRunning){return;}
throttleDelay = throttle - (Date.now() - taskStart);

scheduleStart = Date.now();

isRunning = true;

if(throttleDelay > 0){
setTimeout(scheduleRaf, throttleDelay);
} else {
throttleDelay = 0;
scheduleRaf();
}
}

function runTasks(){
var task, i, len;
taskStart = Date.now();
isRunning = false;

if(runAttemptes > 9 || taskStart - throttleDelay - 51 < scheduleStart){
for(i = 0, len = tasks.length; i < len && IdleDeadline.timeRemaining(); i++){
task = tasks.shift();
tasklength++;
if(task){
task(IdleDeadline);
}
}
}

if(tasks.length){
scheduleLazy();
} else {
runAttemptes = 0;
}
}

function requestIdleCallback(task){
index++;
tasks.push(task);
scheduleLazy();
return index;
}

function cancelIdleCallback(id){
var index = id - 1 - tasklength;
if(tasks[index]){
tasks[index] = null;
}
}

if(!window.requestIdleCallback || !window.cancelIdleCallback){
window.requestIdleCallback = requestIdleCallback;
window.cancelIdleCallback = cancelIdleCallback;
}

return {
request: requestIdleCallback,
cancel: cancelIdleCallback,
cfg: function(name, value){
if(typeof value != number || value < 1){return;}
if(name == 'throttle'){
throttle = value;
} else if(name == 'remainingTime'){
remainingTime = value;
}
},
};
}));
18 changes: 18 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "requestidlecallback",
"version": "0.1.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "MIT",
"devDependencies": {
"chai": "^3.4.0",
"jshint": "^2.8.0",
"mocha": "^2.3.3",
"mocha-phantomjs": "^4.0.1",
"sinon": "^1.17.2"
}
}
22 changes: 22 additions & 0 deletions test/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link rel="stylesheet" href="../node_modules/mocha/mocha.css" />
</head>
<body>
<div id="mocha"></div>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/sinon/pkg/sinon.js"></script>
<script>mocha.setup('tdd')</script>
<script src="../index.js"></script>
<script src="test.js"></script>
<script>
mocha.checkLeaks();
if (window.mochaPhantomJS) mochaPhantomJS.run();
else mocha.run();
</script>
</body>
</html>
114 changes: 114 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
suite('idleCallbackShim', function() {
test('should have api methods', function(){
chai.assert(idleCallbackShim.request);
chai.assert(idleCallbackShim.cancel);
chai.assert(idleCallbackShim.cfg);
});

test('should invoke callback async', function(done){
var isRun = false;
var callback = sinon.spy();
var timeoutCall = sinon.spy();
var run = function(){
if(isRun){return;}
isRun = true;
chai.assert(timeoutCall.calledBefore(callback));
done();
};

idleCallbackShim.request(callback);
setTimeout(timeoutCall, 0);

idleCallbackShim.request(run);
setTimeout(run, 999);
});

test('should schedule nested callback later', function(done){
idleCallbackShim.request(function(){
var isRun = false;
var callback = sinon.spy();
var timeoutCall = sinon.spy();
var run = function(){
if(isRun){return;}
isRun = true;
chai.assert(timeoutCall.calledBefore(callback));
done();
};

idleCallbackShim.request(callback);
setTimeout(timeoutCall, 0);

idleCallbackShim.request(run);
setTimeout(run, 999);
});
});

test('should invoke with the deadline argument', function(done){
idleCallbackShim.request(function(deadline){
chai.assert('didTimeout' in deadline);
chai.assert(!deadline.didTimeout);
try {
deadline.didTimeout = true;
} catch(e){}
chai.assert(!deadline.didTimeout);

chai.assert(typeof deadline.timeRemaining() == 'number');
chai.assert(deadline.timeRemaining() >= 0 && deadline.timeRemaining() <= 50);
done();
});
});

test('timeRemaining counts down', function(done){
idleCallbackShim.request(function(deadline){
var now = Date.now();
var timeRemaining = deadline.timeRemaining();
while(Date.now() - now <= 2){

}
chai.assert(timeRemaining > deadline.timeRemaining());
done();
});
});

test('cancels callback', function(done){
var canceledID1, canceledID2, canceledID3;
var run1 = sinon.spy();
var run2 = sinon.spy();
var run3 = sinon.spy();
var canceled1 = sinon.spy();
var canceled2 = sinon.spy();
var canceled3 = sinon.spy();

idleCallbackShim.request(run1);
canceledID1 = idleCallbackShim.request(canceled1);


idleCallbackShim.request(function(){
idleCallbackShim.request(run3);
idleCallbackShim.cancel(canceledID2);

canceledID3 = idleCallbackShim.request(canceled3);

idleCallbackShim.cancel(canceledID3);

idleCallbackShim.request(function(){
chai.assert(run1.called);
chai.assert(run2.called);
chai.assert(run3.called);

chai.assert(!canceled1.called);
chai.assert(!canceled2.called);
chai.assert(!canceled3.called);
done();
});
});

idleCallbackShim.request(run2);
canceledID2 = idleCallbackShim.request(canceled2);


setTimeout(function(){
idleCallbackShim.cancel(canceledID1);
});
});
});

0 comments on commit f6dfd5d

Please sign in to comment.