1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-21 23:58:07 +02:00

Add general support for re-dispatching events, on EventBus instances, to the DOM

This patch is the first step to be able to eventually get rid of the `attachDOMEventsToEventBus` function, by allowing `EventBus` instances to simply re-dispatch most[1] events to the DOM.
Note that the re-dispatching is purposely implemented to occur *after* all registered `EventBus` listeners have been serviced, to prevent the ordering issues that necessitated the duplicated page/scale-change events.

The DOM events are currently necessary for the `mozilla-central` tests, see https://hg.mozilla.org/mozilla-central/file/tip/browser/extensions/pdfjs/test, and perhaps also for custom deployments of the PDF.js default viewer.

Once this have landed, and been successfully uplifted to `mozilla-central`, I intent to submit a patch to update the test-code to utilize the new preference. This will thus, eventually, make it possible to remove the `attachDOMEventsToEventBus` functionality.

*Please note:* I've successfully ran all `mozilla-central` tests locally, with these patches applied.

---
[1] The exception being events that originated on the `window` or `document`, since those are already globally available anyway.
This commit is contained in:
Jonas Jenwald 2018-08-28 10:26:18 +02:00
parent 7bc4bfcc8b
commit 0b1f41c5b3
7 changed files with 91 additions and 7 deletions

View file

@ -288,7 +288,8 @@ let PDFViewerApplication = {
return new Promise((resolve, reject) => {
this.overlayManager = new OverlayManager();
let eventBus = appConfig.eventBus || getGlobalEventBus();
const dispatchToDOM = AppOptions.get('eventBusDispatchToDOM');
let eventBus = appConfig.eventBus || getGlobalEventBus(dispatchToDOM);
this.eventBus = eventBus;
let pdfRenderingQueue = new PDFRenderingQueue();

View file

@ -68,6 +68,11 @@ const defaultOptions = {
value: false,
kind: OptionKind.VIEWER,
},
eventBusDispatchToDOM: {
/** @type {boolean} */
value: false,
kind: OptionKind.VIEWER,
},
externalLinkRel: {
/** @type {string} */
value: 'noopener noreferrer nofollow',

View file

@ -4,6 +4,7 @@
"sidebarViewOnLoad": 0,
"cursorToolOnLoad": 0,
"enableWebGL": false,
"eventBusDispatchToDOM": false,
"pdfBugEnabled": false,
"disableRange": false,
"disableStream": false,

View file

@ -129,12 +129,13 @@ function attachDOMEventsToEventBus(eventBus) {
}
let globalEventBus = null;
function getGlobalEventBus() {
if (globalEventBus) {
return globalEventBus;
function getGlobalEventBus(dispatchToDOM = false) {
if (!globalEventBus) {
globalEventBus = new EventBus({ dispatchToDOM, });
if (!dispatchToDOM) {
attachDOMEventsToEventBus(globalEventBus);
}
}
globalEventBus = new EventBus();
attachDOMEventsToEventBus(globalEventBus);
return globalEventBus;
}

View file

@ -683,8 +683,9 @@ let animationStarted = new Promise(function (resolve) {
* used.
*/
class EventBus {
constructor() {
constructor({ dispatchToDOM = false, } = {}) {
this._listeners = Object.create(null);
this._dispatchToDOM = dispatchToDOM === true;
}
on(eventName, listener) {
@ -708,6 +709,9 @@ class EventBus {
dispatch(eventName) {
let eventListeners = this._listeners[eventName];
if (!eventListeners || eventListeners.length === 0) {
if (this._dispatchToDOM) {
this._dispatchDOMEvent(eventName);
}
return;
}
// Passing all arguments after the eventName to the listeners.
@ -717,6 +721,35 @@ class EventBus {
eventListeners.slice(0).forEach(function (listener) {
listener.apply(null, args);
});
if (this._dispatchToDOM) {
this._dispatchDOMEvent(eventName, args);
}
}
/**
* @private
*/
_dispatchDOMEvent(eventName, args = null) {
if (!this._dispatchToDOM) {
return;
}
const details = Object.create(null);
if (args && args.length > 0) {
const obj = args[0];
for (let key in obj) {
const value = obj[key];
if (key === 'source') {
if (value === window || value === document) {
return; // No need to re-dispatch (already) global events.
}
continue; // Ignore the `source` property.
}
details[key] = value;
}
}
const event = document.createEvent('CustomEvent');
event.initCustomEvent(eventName, true, true, details);
document.dispatchEvent(event);
}
}