Bug 1963014 - Add jsdoc to Timer.sys.mjs. r=firefox-desktop-core-reviewers ,mossop

Differential Revision: https://phabricator.services.mozilla.com/D246912
This commit is contained in:
Mark Banner
2025-04-29 19:57:01 +00:00
parent d884375715
commit a7476cfad0

View File

@@ -9,7 +9,15 @@
// This gives us >=2^30 unique timer IDs, enough for 1 per ms for 12.4 days. // 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 gNextId = 1; // setTimeout and setInterval must return a positive integer
var gTimerTable = new Map(); // int -> nsITimer or idleCallback /**
* @type {Map<number, nsITimer>}
*/
var gTimerTable = new Map();
/**
* @type {Map<number, (deadline: IdleDeadline) => void>}
*/
var gIdleTable = new Map();
// Don't generate this for every timer. // Don't generate this for every timer.
var setTimeout_timerCallbackQI = ChromeUtils.generateQI([ var setTimeout_timerCallbackQI = ChromeUtils.generateQI([
@@ -17,123 +25,172 @@ var setTimeout_timerCallbackQI = ChromeUtils.generateQI([
"nsINamed", "nsINamed",
]); ]);
/**
* @template {any[]} T
*
* @param {(...args: T) => any} callback
* @param {number} milliseconds
* @param {boolean} [isInterval]
* @param {nsIEventTarget} [target]
* @param {T} [args]
*/
function _setTimeoutOrIsInterval( function _setTimeoutOrIsInterval(
aCallback, callback,
aMilliseconds, milliseconds,
aIsInterval, isInterval,
aTarget, target,
aArgs args
) { ) {
if (typeof aCallback !== "function") { if (typeof callback !== "function") {
throw new Error( throw new Error(
`callback is not a function in ${ `callback is not a function in ${
aIsInterval ? "setInterval" : "setTimeout" isInterval ? "setInterval" : "setTimeout"
}` }`
); );
} }
let id = gNextId++; let id = gNextId++;
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
if (aTarget) { if (target) {
timer.target = aTarget; timer.target = target;
} }
let callback = { let callbackObj = {
QueryInterface: setTimeout_timerCallbackQI, QueryInterface: setTimeout_timerCallbackQI,
// nsITimerCallback // nsITimerCallback
notify() { notify() {
if (!aIsInterval) { if (!isInterval) {
gTimerTable.delete(id); gTimerTable.delete(id);
} }
aCallback.apply(null, aArgs); callback.apply(null, args);
}, },
// nsINamed // nsINamed
get name() { get name() {
return `${ return `${
aIsInterval ? "setInterval" : "setTimeout" isInterval ? "setInterval" : "setTimeout"
}() for ${Cu.getDebugName(aCallback)}`; }() for ${Cu.getDebugName(callback)}`;
}, },
}; };
timer.initWithCallback( timer.initWithCallback(
callback, callbackObj,
aMilliseconds, milliseconds,
aIsInterval ? timer.TYPE_REPEATING_SLACK : timer.TYPE_ONE_SHOT isInterval ? timer.TYPE_REPEATING_SLACK : timer.TYPE_ONE_SHOT
); );
gTimerTable.set(id, timer); gTimerTable.set(id, timer);
return id; return id;
} }
export function setTimeout(aCallback, aMilliseconds, ...aArgs) { /**
return _setTimeoutOrIsInterval(aCallback, aMilliseconds, false, null, aArgs); * Sets a timeout.
*
* @template {any[]} T
*
* @param {(...args: T) => any} callback
* @param {number} milliseconds
* @param {T} [args]
*/
export function setTimeout(callback, milliseconds, ...args) {
return _setTimeoutOrIsInterval(callback, milliseconds, false, null, args);
} }
export function setTimeoutWithTarget( /**
aCallback, * Sets a timeout with a given event target.
aMilliseconds, *
aTarget, * @template {any[]} T
...aArgs *
) { * @param {(...args: T) => any} callback
return _setTimeoutOrIsInterval( * @param {number} milliseconds
aCallback, * @param {nsIEventTarget} target
aMilliseconds, * @param {T} [args]
false, */
aTarget, export function setTimeoutWithTarget(callback, milliseconds, target, ...args) {
aArgs return _setTimeoutOrIsInterval(callback, milliseconds, false, target, args);
);
} }
export function setInterval(aCallback, aMilliseconds, ...aArgs) { /**
return _setTimeoutOrIsInterval(aCallback, aMilliseconds, true, null, aArgs); * Sets an interval timer.
*
* @template {any[]} T
*
* @param {(...args: T) => any} callback
* @param {number} milliseconds
* @param {T} [args]
*/
export function setInterval(callback, milliseconds, ...args) {
return _setTimeoutOrIsInterval(callback, milliseconds, true, null, args);
} }
export function setIntervalWithTarget( /**
aCallback, * Sets an interval timer.
aMilliseconds, *
aTarget, * @template {any[]} T
...aArgs *
) { * @param {(...args: T) => any} callback
return _setTimeoutOrIsInterval( * @param {number} milliseconds
aCallback, * @param {nsIEventTarget} target
aMilliseconds, * @param {T} [args]
true, */
aTarget, export function setIntervalWithTarget(callback, milliseconds, target, ...args) {
aArgs return _setTimeoutOrIsInterval(callback, milliseconds, true, target, args);
);
} }
function clear(aId) { /**
if (gTimerTable.has(aId)) { * Clears the given timer.
gTimerTable.get(aId).cancel(); *
gTimerTable.delete(aId); * @param {number} id
*/
function clear(id) {
if (gTimerTable.has(id)) {
gTimerTable.get(id).cancel();
gTimerTable.delete(id);
} }
} }
/**
* Clears the given timer.
*/
export var clearInterval = clear; export var clearInterval = clear;
/**
* Clears the given timer.
*/
export var clearTimeout = clear; export var clearTimeout = clear;
export function requestIdleCallback(aCallback, aOptions) { /**
if (typeof aCallback !== "function") { * Dispatches the given callback to the main thread when it would be otherwise
* idle. The callback may be canceled via `cancelIdleCallback` - the idle
* dispatch will still happen but it won't be called.
*
* @param {(deadline: IdleDeadline) => any} callback
* @param {object} options
*/
export function requestIdleCallback(callback, options) {
if (typeof callback !== "function") {
throw new Error("callback is not a function in requestIdleCallback"); throw new Error("callback is not a function in requestIdleCallback");
} }
let id = gNextId++; let id = gNextId++;
let callback = (...aArgs) => { ChromeUtils.idleDispatch(deadline => {
if (gTimerTable.has(id)) { if (gIdleTable.has(id)) {
gTimerTable.delete(id); gIdleTable.delete(id);
aCallback(...aArgs); callback(deadline);
} }
}; }, options);
gIdleTable.set(id, callback);
ChromeUtils.idleDispatch(callback, aOptions);
gTimerTable.set(id, callback);
return id; return id;
} }
export function cancelIdleCallback(aId) { /**
if (gTimerTable.has(aId)) { * Cancels the given idle callback
gTimerTable.delete(aId); *
* @param {number} id
*/
export function cancelIdleCallback(id) {
if (gIdleTable.has(id)) {
gIdleTable.delete(id);
} }
} }