Bug 840360 - Extract reftest-content.js's setTimeout implementation into new Timer.jsm [r=jwalker r=cjones sr=gavin]

--HG--
rename : browser/devtools/shared/Browser.jsm => toolkit/modules/Timer.jsm
rename : browser/devtools/shared/test/browser_browser_basic.js => toolkit/modules/tests/xpcshell/test_timer.js
This commit is contained in:
Matt Brubeck 2013-02-25 11:08:33 -08:00
Родитель 6e8068798d
Коммит f14c84f591
7 изменённых файлов: 80 добавлений и 113 удалений

Просмотреть файл

@ -20,73 +20,9 @@ this.EXPORTED_SYMBOLS = [ "Node", "HTMLElement", "setTimeout", "clearTimeout" ];
this.Node = Components.interfaces.nsIDOMNode;
this.HTMLElement = Components.interfaces.nsIDOMHTMLElement;
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
/**
* The next value to be returned by setTimeout
/*
* Import and re-export the timeout functions from Timer.jsm.
*/
let nextID = 1;
/**
* The map of outstanding timeouts
*/
const timers = {};
/**
* Object to be passed to Timer.initWithCallback()
*/
function TimerCallback(callback) {
this._callback = callback;
const interfaces = [ Components.interfaces.nsITimerCallback ];
this.QueryInterface = XPCOMUtils.generateQI(interfaces);
}
TimerCallback.prototype.notify = function(timer) {
try {
for (let timerID in timers) {
if (timers[timerID] === timer) {
delete timers[timerID];
break;
}
}
this._callback.apply(null, []);
}
catch (ex) {
dump(ex + '\n');
}
};
/**
* Executes a code snippet or a function after specified delay.
* This is designed to have the same interface contract as the browser
* function.
* @param callback is the function you want to execute after the delay.
* @param delay is the number of milliseconds that the function call should
* be delayed by. Note that the actual delay may be longer, see Notes below.
* @return the ID of the timeout, which can be used later with
* window.clearTimeout.
*/
this.setTimeout = function setTimeout(callback, delay) {
const timer = Components.classes["@mozilla.org/timer;1"]
.createInstance(Components.interfaces.nsITimer);
let timerID = nextID++;
timers[timerID] = timer;
timer.initWithCallback(new TimerCallback(callback), delay, timer.TYPE_ONE_SHOT);
return timerID;
};
/**
* Clears the delay set by window.setTimeout() and prevents the callback from
* being executed (if it hasn't been executed already)
* @param timerID the ID of the timeout you wish to clear, as returned by
* window.setTimeout().
*/
this.clearTimeout = function clearTimeout(timerID) {
let timer = timers[timerID];
if (timer) {
timer.cancel();
delete timers[timerID];
}
};
let Timer = Components.utils.import("resource://gre/modules/Timer.jsm", {});
this.setTimeout = Timer.setTimeout;
this.clearTimeout = Timer.clearTimeout;

Просмотреть файл

@ -19,19 +19,10 @@ function test() {
}
function runTest(browser, tab, document) {
let timeout = imported.setTimeout(shouldNotBeCalled, 100);
imported.clearTimeout(timeout);
var p = document.getElementById("id");
ok(p instanceof imported.Node, "Node correctly defined");
ok(p instanceof imported.HTMLElement, "HTMLElement correctly defined");
let timeout = imported.setTimeout(function() {
finish();
}, 100);
}
function shouldNotBeCalled() {
ok(false, "Timeout cleared");
finish();
}

Просмотреть файл

@ -7,40 +7,7 @@
const CC = Components.classes;
const CI = Components.interfaces;
const CR = Components.results;
/**
* FIXME/bug 622224: work around lack of reliable setTimeout available
* to frame scripts.
*/
// This gives us >=2^30 unique timer IDs, enough for 1 per ms for 12.4
// days. Should be fine as a temporary workaround.
var gNextTimeoutId = 0;
var gTimeoutTable = { }; // int -> nsITimer
function setTimeout(callbackFn, delayMs) {
var id = gNextTimeoutId++;
var timer = CC["@mozilla.org/timer;1"].createInstance(CI.nsITimer);
timer.initWithCallback({
notify: function notify_callback() {
clearTimeout(id);
callbackFn();
}
},
delayMs,
timer.TYPE_ONE_SHOT);
gTimeoutTable[id] = timer;
return id;
}
function clearTimeout(id) {
var timer = gTimeoutTable[id];
if (timer) {
timer.cancel();
delete gTimeoutTable[id];
}
}
const CU = Components.utils;
const XHTML_NS = "http://www.w3.org/1999/xhtml";
@ -50,6 +17,8 @@ const PRINTSETTINGS_CONTRACTID = "@mozilla.org/gfx/printsettings-service;1";
// "<!--CLEAR-->"
const BLANK_URL_FOR_CLEARING = "data:text/html;charset=UTF-8,%3C%21%2D%2DCLEAR%2D%2D%3E";
CU.import("resource://gre/modules/Timer.jsm");
var gBrowserIsRemote;
var gHaveCanvasSnapshot = false;
// Plugin layers can be updated asynchronously, so to make sure that all

Просмотреть файл

@ -13,6 +13,7 @@ EXTRA_JS_MODULES := \
NewTabUtils.jsm \
Sqlite.jsm \
TelemetryTimestamps.jsm \
Timer.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk

41
toolkit/modules/Timer.jsm Normal file
Просмотреть файл

@ -0,0 +1,41 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* JS module implementation of nsIDOMJSWindow.setTimeout and clearTimeout.
*/
this.EXPORTED_SYMBOLS = ["setTimeout", "clearTimeout"];
const Cc = Components.classes;
const Ci = Components.interfaces;
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 gTimeoutTable = new Map(); // int -> nsITimer
this.setTimeout = function setTimeout(aCallback, aMilliseconds) {
let id = gNextTimeoutId++;
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(function setTimeout_timer() {
gTimeoutTable.delete(id);
aCallback();
}, aMilliseconds, timer.TYPE_ONE_SHOT);
gTimeoutTable.set(id, timer);
return id;
}
this.clearTimeout = function clearTimeout(aId) {
if (gTimeoutTable.has(aId)) {
gTimeoutTable.get(aId).cancel();
gTimeoutTable.delete(aId);
}
}

Просмотреть файл

@ -0,0 +1,28 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Tests exports from Timer.jsm
let imported = {};
Components.utils.import("resource://gre/modules/Timer.jsm", imported);
function run_test(browser, tab, document) {
do_test_pending();
let timeout1 = imported.setTimeout(function() 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() {
do_check_true(true, "Should be called");
do_test_finished();
}, 100);
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);
}

Просмотреть файл

@ -5,3 +5,4 @@ tail =
[test_newtab-migrate-v1.js]
[test_sqlite.js]
[test_TelemetryTimestamps.js]
[test_timer.js]