Bug 1144797 - Add setInterval and clearInterval to Timer.jsm. r=smacleod.

--HG--
extra : rebase_source : 6e85d29f1e96bddd5b61173bc8a26afdd10c8436
This commit is contained in:
Mike Conley 2015-03-27 18:38:17 -04:00
parent 73800cd3df
commit 50d9077cde
2 changed files with 64 additions and 25 deletions

View File

@ -8,7 +8,7 @@
* JS module implementation of nsIDOMJSWindow.setTimeout and clearTimeout.
*/
this.EXPORTED_SYMBOLS = ["setTimeout", "clearTimeout"];
this.EXPORTED_SYMBOLS = ["setTimeout", "clearTimeout", "setInterval", "clearInterval"];
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -17,26 +17,38 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
// This gives us >=2^30 unique timer IDs, enough for 1 per ms for 12.4 days.
let gNextTimeoutId = 1; // setTimeout must return a positive integer
let gNextId = 1; // setTimeout and setInterval must return a positive integer
let gTimeoutTable = new Map(); // int -> nsITimer
let gTimerTable = new Map(); // int -> nsITimer
this.setTimeout = function setTimeout(aCallback, aMilliseconds) {
let id = gNextTimeoutId++;
let id = gNextId++;
let args = Array.slice(arguments, 2);
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(function setTimeout_timer() {
gTimeoutTable.delete(id);
gTimerTable.delete(id);
aCallback.apply(null, args);
}, aMilliseconds, timer.TYPE_ONE_SHOT);
gTimeoutTable.set(id, timer);
gTimerTable.set(id, timer);
return id;
}
this.clearTimeout = function clearTimeout(aId) {
if (gTimeoutTable.has(aId)) {
gTimeoutTable.get(aId).cancel();
gTimeoutTable.delete(aId);
this.setInterval = function setInterval(aCallback, aMilliseconds) {
let id = gNextId++;
let args = Array.slice(arguments, 2);
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(function setInterval_timer() {
aCallback.apply(null, args);
}, aMilliseconds, timer.TYPE_REPEATING_SLACK);
gTimerTable.set(id, timer);
return id;
}
this.clearInterval = this.clearTimeout = function clearTimeout(aId) {
if (gTimerTable.has(aId)) {
gTimerTable.get(aId).cancel();
gTimerTable.delete(aId);
}
}

View File

@ -8,23 +8,50 @@
let imported = {};
Components.utils.import("resource://gre/modules/Timer.jsm", imported);
function run_test(browser, tab, document) {
do_test_pending();
function run_test() {
run_next_test();
}
let timeout1 = imported.setTimeout(function() do_throw("Should not be called"), 100);
add_task(function* test_setTimeout() {
let timeout1 = imported.setTimeout(() => do_throw("Should not be called"), 100);
do_check_eq(typeof timeout1, "number", "setTimeout returns a number");
do_check_true(timeout1 > 0, "setTimeout returns a positive number");
let timeout2 = imported.setTimeout(function(param1, param2) {
do_check_true(true, "Should be called");
do_check_eq(param1, 5, "first parameter is correct");
do_check_eq(param2, "test", "second parameter is correct");
do_test_finished();
}, 100, 5, "test");
do_check_eq(typeof timeout2, "number", "setTimeout returns a number");
do_check_true(timeout2 > 0, "setTimeout returns a positive number");
do_check_neq(timeout1, timeout2, "Calling setTimeout again returns a different value");
imported.clearTimeout(timeout1);
}
yield new Promise((resolve) => {
let timeout2 = imported.setTimeout((param1, param2) => {
do_check_true(true, "Should be called");
do_check_eq(param1, 5, "first parameter is correct");
do_check_eq(param2, "test", "second parameter is correct");
resolve();
}, 100, 5, "test");
do_check_eq(typeof timeout2, "number", "setTimeout returns a number");
do_check_true(timeout2 > 0, "setTimeout returns a positive number");
do_check_neq(timeout1, timeout2, "Calling setTimeout again returns a different value");
});
});
add_task(function* test_setInterval() {
let interval1 = imported.setInterval(function() do_throw("Should not be called!"), 100);
do_check_eq(typeof interval1, "number", "setInterval returns a number");
do_check_true(interval1 > 0, "setTimeout returns a positive number");
imported.clearInterval(interval1);
const EXPECTED_CALLS = 5;
let calls = 0;
yield new Promise((resolve) => {
let interval2 = imported.setInterval((param1, param2) => {
do_check_true(true, "Should be called");
do_check_eq(param1, 15, "first parameter is correct");
do_check_eq(param2, "hola", "second parameter is correct");
if (calls >= EXPECTED_CALLS) {
resolve();
}
calls++;
}, 100, 15, "hola");
});
});