forked from aFarkas/requestIdleCallback
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
aFarkas
committed
Nov 1, 2015
0 parents
commit f6dfd5d
Showing
4 changed files
with
262 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
}, | ||
}; | ||
})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}); | ||
}); | ||
}); |