Merge pull request #12793 from Snuffleupagus/Eventbus-once
Support the `once` option, when registering `EventBus` listeners
This commit is contained in:
commit
57bec090ae
@ -312,6 +312,30 @@ describe("ui_utils", function () {
|
|||||||
expect(count).toEqual(2);
|
expect(count).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("dispatch event to handlers with/without 'once' option", function () {
|
||||||
|
const eventBus = new EventBus();
|
||||||
|
let multipleCount = 0,
|
||||||
|
onceCount = 0;
|
||||||
|
|
||||||
|
eventBus.on("test", function () {
|
||||||
|
multipleCount++;
|
||||||
|
});
|
||||||
|
eventBus.on(
|
||||||
|
"test",
|
||||||
|
function () {
|
||||||
|
onceCount++;
|
||||||
|
},
|
||||||
|
{ once: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
eventBus.dispatch("test");
|
||||||
|
eventBus.dispatch("test");
|
||||||
|
eventBus.dispatch("test");
|
||||||
|
|
||||||
|
expect(multipleCount).toEqual(3);
|
||||||
|
expect(onceCount).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
it("should not re-dispatch to DOM", function (done) {
|
it("should not re-dispatch to DOM", function (done) {
|
||||||
if (isNodeJS) {
|
if (isNodeJS) {
|
||||||
pending("Document in not supported in Node.js.");
|
pending("Document in not supported in Node.js.");
|
||||||
|
12
web/app.js
12
web/app.js
@ -1497,11 +1497,13 @@ const PDFViewerApplication = {
|
|||||||
// It should be *extremely* rare for metadata to not have been resolved
|
// It should be *extremely* rare for metadata to not have been resolved
|
||||||
// when this code runs, but ensure that we handle that case here.
|
// when this code runs, but ensure that we handle that case here.
|
||||||
await new Promise(resolve => {
|
await new Promise(resolve => {
|
||||||
const metadataLoaded = () => {
|
this.eventBus._on(
|
||||||
this.eventBus._off("metadataloaded", metadataLoaded);
|
"metadataloaded",
|
||||||
resolve();
|
evt => {
|
||||||
};
|
resolve();
|
||||||
this.eventBus._on("metadataloaded", metadataLoaded);
|
},
|
||||||
|
{ once: true }
|
||||||
|
);
|
||||||
});
|
});
|
||||||
if (pdfDocument !== this.pdfDocument) {
|
if (pdfDocument !== this.pdfDocument) {
|
||||||
return; // The document was closed while the metadata resolved.
|
return; // The document was closed while the metadata resolved.
|
||||||
|
@ -76,11 +76,13 @@ class PDFHistory {
|
|||||||
this.eventBus._on("pagesinit", () => {
|
this.eventBus._on("pagesinit", () => {
|
||||||
this._isPagesLoaded = false;
|
this._isPagesLoaded = false;
|
||||||
|
|
||||||
const onPagesLoaded = evt => {
|
this.eventBus._on(
|
||||||
this.eventBus._off("pagesloaded", onPagesLoaded);
|
"pagesloaded",
|
||||||
this._isPagesLoaded = !!evt.pagesCount;
|
evt => {
|
||||||
};
|
this._isPagesLoaded = !!evt.pagesCount;
|
||||||
this.eventBus._on("pagesloaded", onPagesLoaded);
|
},
|
||||||
|
{ once: true }
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,24 +804,32 @@ class EventBus {
|
|||||||
this._listeners = Object.create(null);
|
this._listeners = Object.create(null);
|
||||||
|
|
||||||
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("MOZCENTRAL")) {
|
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("MOZCENTRAL")) {
|
||||||
this._isInAutomation = (options && options.isInAutomation) === true;
|
this._isInAutomation = options?.isInAutomation === true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} eventName
|
* @param {string} eventName
|
||||||
* @param {function} listener
|
* @param {function} listener
|
||||||
|
* @param {Object} [options]
|
||||||
*/
|
*/
|
||||||
on(eventName, listener) {
|
on(eventName, listener, options = null) {
|
||||||
this._on(eventName, listener, { external: true });
|
this._on(eventName, listener, {
|
||||||
|
external: true,
|
||||||
|
once: options?.once,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} eventName
|
* @param {string} eventName
|
||||||
* @param {function} listener
|
* @param {function} listener
|
||||||
|
* @param {Object} [options]
|
||||||
*/
|
*/
|
||||||
off(eventName, listener) {
|
off(eventName, listener, options = null) {
|
||||||
this._off(eventName, listener, { external: true });
|
this._off(eventName, listener, {
|
||||||
|
external: true,
|
||||||
|
once: options?.once,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(eventName) {
|
dispatch(eventName) {
|
||||||
@ -841,12 +849,12 @@ class EventBus {
|
|||||||
let externalListeners;
|
let externalListeners;
|
||||||
// Making copy of the listeners array in case if it will be modified
|
// Making copy of the listeners array in case if it will be modified
|
||||||
// during dispatch.
|
// during dispatch.
|
||||||
eventListeners.slice(0).forEach(function ({ listener, external }) {
|
eventListeners.slice(0).forEach(({ listener, external, once }) => {
|
||||||
|
if (once) {
|
||||||
|
this._off(eventName, listener);
|
||||||
|
}
|
||||||
if (external) {
|
if (external) {
|
||||||
if (!externalListeners) {
|
(externalListeners ||= []).push(listener);
|
||||||
externalListeners = [];
|
|
||||||
}
|
|
||||||
externalListeners.push(listener);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
listener.apply(null, args);
|
listener.apply(null, args);
|
||||||
@ -854,7 +862,7 @@ class EventBus {
|
|||||||
// Dispatch any "external" listeners *after* the internal ones, to give the
|
// Dispatch any "external" listeners *after* the internal ones, to give the
|
||||||
// viewer components time to handle events and update their state first.
|
// viewer components time to handle events and update their state first.
|
||||||
if (externalListeners) {
|
if (externalListeners) {
|
||||||
externalListeners.forEach(function (listener) {
|
externalListeners.forEach(listener => {
|
||||||
listener.apply(null, args);
|
listener.apply(null, args);
|
||||||
});
|
});
|
||||||
externalListeners = null;
|
externalListeners = null;
|
||||||
@ -871,13 +879,11 @@ class EventBus {
|
|||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
_on(eventName, listener, options = null) {
|
_on(eventName, listener, options = null) {
|
||||||
let eventListeners = this._listeners[eventName];
|
const eventListeners = (this._listeners[eventName] ||= []);
|
||||||
if (!eventListeners) {
|
|
||||||
this._listeners[eventName] = eventListeners = [];
|
|
||||||
}
|
|
||||||
eventListeners.push({
|
eventListeners.push({
|
||||||
listener,
|
listener,
|
||||||
external: (options && options.external) === true,
|
external: options?.external === true,
|
||||||
|
once: options?.once === true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user