Commit 35c2dfb0 authored by Felipe Gomes's avatar Felipe Gomes
Browse files

Bug 827976 - Add requestIdleCallback support to Timer.jsm. r=mconley

Differential Revision: https://phabricator.services.mozilla.com/D21084

--HG--
extra : moz-landing-system : lando
parent 178783f9
......@@ -9,12 +9,13 @@
*/
var EXPORTED_SYMBOLS = ["setTimeout", "setTimeoutWithTarget", "clearTimeout",
"setInterval", "setIntervalWithTarget", "clearInterval"];
"setInterval", "setIntervalWithTarget", "clearInterval",
"requestIdleCallback", "cancelIdleCallback"];
// This gives us >=2^30 unique timer IDs, enough for 1 per ms for 12.4 days.
var gNextId = 1; // setTimeout and setInterval must return a positive integer
var gTimerTable = new Map(); // int -> nsITimer
var gTimerTable = new Map(); // int -> nsITimer or idleCallback
// Don't generate this for every timer.
var setTimeout_timerCallbackQI = ChromeUtils.generateQI([Ci.nsITimerCallback, Ci.nsINamed]);
......@@ -86,3 +87,27 @@ var clearInterval = this.clearTimeout = function clearTimeout(aId) {
gTimerTable.delete(aId);
}
};
function requestIdleCallback(aCallback, aOptions) {
if (typeof aCallback !== "function") {
throw new Error("callback is not a function in requestIdleCallback");
}
let id = gNextId++;
let callback = (...aArgs) => {
if (gTimerTable.has(id)) {
gTimerTable.delete(id);
aCallback(...aArgs);
}
};
ChromeUtils.idleDispatch(callback, aOptions);
gTimerTable.set(id, callback);
return id;
}
function cancelIdleCallback(aId) {
if (gTimerTable.has(aId)) {
gTimerTable.delete(aId);
}
}
......@@ -63,11 +63,12 @@ add_task(async function test_setInterval() {
let calls = 0;
await new Promise((resolve) => {
imported.setInterval((param1, param2) => {
let interval2 = imported.setInterval((param1, param2) => {
Assert.ok(true, "Should be called");
Assert.equal(param1, 15, "first parameter is correct");
Assert.equal(param2, "hola", "second parameter is correct");
if (calls >= EXPECTED_CALLS) {
imported.clearInterval(interval2);
resolve();
}
calls++;
......@@ -88,11 +89,12 @@ add_task(async function test_setIntervalWithTarget() {
let calls = 0;
await new Promise((resolve) => {
imported.setIntervalWithTarget((param1, param2) => {
let interval2 = imported.setIntervalWithTarget((param1, param2) => {
Assert.ok(true, "Should be called");
Assert.equal(param1, 15, "first parameter is correct");
Assert.equal(param2, "hola", "second parameter is correct");
if (calls >= EXPECTED_CALLS) {
imported.clearInterval(interval2);
resolve();
}
calls++;
......@@ -119,3 +121,24 @@ add_task(async function test_setIntervalWithTargetNonFunction() {
Assert.throws(() => { imported.setIntervalWithTarget({}, 0); },
/callback is not a function in setInterval/);
});
add_task(async function test_requestIdleCallback() {
let request1 = imported.requestIdleCallback(() => do_throw("Should not be called"));
Assert.equal(typeof request1, "number", "requestIdleCallback returns a number");
Assert.ok(request1 > 0, "setTimeout returns a positive number");
imported.cancelIdleCallback(request1);
await new Promise((resolve) => {
let request2 = imported.requestIdleCallback((deadline) => {
Assert.ok(true, "Should be called");
Assert.equal(typeof deadline.didTimeout, "boolean", "deadline parameter has .didTimeout property");
Assert.equal(typeof deadline.timeRemaining(), "number", "deadline parameter has .timeRemaining() function");
resolve();
}, {timeout: 100});
Assert.equal(typeof request2, "number", "requestIdleCallback returns a number");
Assert.ok(request2 > 0, "requestIdleCallback returns a positive number");
Assert.notEqual(request1, request2, "Calling requestIdleCallback again returns a different value");
});
});
......@@ -225,7 +225,7 @@
"test.jsm": ["Foo"],
"test2.jsm": ["Bar"],
"test_bug883784.jsm": ["Test"],
"Timer.jsm": ["setTimeout", "setTimeoutWithTarget", "clearTimeout", "setInterval", "setIntervalWithTarget", "clearInterval"],
"Timer.jsm": ["setTimeout", "setTimeoutWithTarget", "clearTimeout", "setInterval", "setIntervalWithTarget", "clearInterval", "requestIdleCallback", "cancelIdleCallback"],
"TippyTopProvider.jsm": ["TippyTopProvider", "getDomain"],
"Tokenize.jsm": ["tokenize", "toksToTfIdfVector"],
"tokenserverclient.js": ["TokenServerClient", "TokenServerClientError", "TokenServerClientNetworkError", "TokenServerClientServerError"],
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment