mirror of
https://github.com/zen-browser/pdf.js.git
synced 2025-07-08 01:10:08 +02:00
Add signal
-support in the EventBus
, and utilize it in the viewer (PR 17964 follow-up)
This mimics the `signal` option that's available for `addEventListener`, see [MDN](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#signal).
This commit is contained in:
parent
5ad42c13ad
commit
702ee7b1e1
3 changed files with 148 additions and 130 deletions
|
@ -44,29 +44,21 @@ async function waitOnEventOrTimeout({ target, name, delay = 0 }) {
|
|||
throw new Error("waitOnEventOrTimeout - invalid parameters.");
|
||||
}
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
const ac = new AbortController();
|
||||
|
||||
function handler(type) {
|
||||
if (target instanceof EventBus) {
|
||||
target._off(name, eventHandler);
|
||||
} else {
|
||||
target.removeEventListener(name, eventHandler);
|
||||
}
|
||||
ac.abort(); // Remove event listener.
|
||||
clearTimeout(timeout);
|
||||
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
resolve(type);
|
||||
}
|
||||
|
||||
const eventHandler = handler.bind(null, WaitOnType.EVENT);
|
||||
if (target instanceof EventBus) {
|
||||
target._on(name, eventHandler);
|
||||
} else {
|
||||
target.addEventListener(name, eventHandler);
|
||||
}
|
||||
const evtMethod = target instanceof EventBus ? "_on" : "addEventListener";
|
||||
target[evtMethod](name, handler.bind(null, WaitOnType.EVENT), {
|
||||
signal: ac.signal,
|
||||
});
|
||||
|
||||
const timeoutHandler = handler.bind(null, WaitOnType.TIMEOUT);
|
||||
const timeout = setTimeout(timeoutHandler, delay);
|
||||
const timeout = setTimeout(handler.bind(null, WaitOnType.TIMEOUT), delay);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
@ -87,6 +79,7 @@ class EventBus {
|
|||
this._on(eventName, listener, {
|
||||
external: true,
|
||||
once: options?.once,
|
||||
signal: options?.signal,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -96,10 +89,7 @@ class EventBus {
|
|||
* @param {Object} [options]
|
||||
*/
|
||||
off(eventName, listener, options = null) {
|
||||
this._off(eventName, listener, {
|
||||
external: true,
|
||||
once: options?.once,
|
||||
});
|
||||
this._off(eventName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,11 +128,25 @@ class EventBus {
|
|||
* @ignore
|
||||
*/
|
||||
_on(eventName, listener, options = null) {
|
||||
let rmAbort = null;
|
||||
if (options?.signal instanceof AbortSignal) {
|
||||
const { signal } = options;
|
||||
if (signal.aborted) {
|
||||
console.error("Cannot use an `aborted` signal.");
|
||||
return;
|
||||
}
|
||||
const onAbort = () => this._off(eventName, listener);
|
||||
rmAbort = () => signal.removeEventListener("abort", onAbort);
|
||||
|
||||
signal.addEventListener("abort", onAbort);
|
||||
}
|
||||
|
||||
const eventListeners = (this.#listeners[eventName] ||= []);
|
||||
eventListeners.push({
|
||||
listener,
|
||||
external: options?.external === true,
|
||||
once: options?.once === true,
|
||||
rmAbort,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -155,7 +159,9 @@ class EventBus {
|
|||
return;
|
||||
}
|
||||
for (let i = 0, ii = eventListeners.length; i < ii; i++) {
|
||||
if (eventListeners[i].listener === listener) {
|
||||
const evt = eventListeners[i];
|
||||
if (evt.listener === listener) {
|
||||
evt.rmAbort?.(); // Ensure that the `AbortSignal` listener is removed.
|
||||
eventListeners.splice(i, 1);
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue