diff --git a/web/app.js b/web/app.js index 0441e8f21..12e62eb01 100644 --- a/web/app.js +++ b/web/app.js @@ -1597,45 +1597,45 @@ const PDFViewerApplication = { _boundEvents.beforePrint = this.beforePrint.bind(this); _boundEvents.afterPrint = this.afterPrint.bind(this); - eventBus.on("resize", webViewerResize); - eventBus.on("hashchange", webViewerHashchange); - eventBus.on("beforeprint", _boundEvents.beforePrint); - eventBus.on("afterprint", _boundEvents.afterPrint); - eventBus.on("pagerendered", webViewerPageRendered); - eventBus.on("updateviewarea", webViewerUpdateViewarea); - eventBus.on("pagechanging", webViewerPageChanging); - eventBus.on("scalechanging", webViewerScaleChanging); - eventBus.on("rotationchanging", webViewerRotationChanging); - eventBus.on("sidebarviewchanged", webViewerSidebarViewChanged); - eventBus.on("pagemode", webViewerPageMode); - eventBus.on("namedaction", webViewerNamedAction); - eventBus.on("presentationmodechanged", webViewerPresentationModeChanged); - eventBus.on("presentationmode", webViewerPresentationMode); - eventBus.on("openfile", webViewerOpenFile); - eventBus.on("print", webViewerPrint); - eventBus.on("download", webViewerDownload); - eventBus.on("firstpage", webViewerFirstPage); - eventBus.on("lastpage", webViewerLastPage); - eventBus.on("nextpage", webViewerNextPage); - eventBus.on("previouspage", webViewerPreviousPage); - eventBus.on("zoomin", webViewerZoomIn); - eventBus.on("zoomout", webViewerZoomOut); - eventBus.on("zoomreset", webViewerZoomReset); - eventBus.on("pagenumberchanged", webViewerPageNumberChanged); - eventBus.on("scalechanged", webViewerScaleChanged); - eventBus.on("rotatecw", webViewerRotateCw); - eventBus.on("rotateccw", webViewerRotateCcw); - eventBus.on("switchscrollmode", webViewerSwitchScrollMode); - eventBus.on("scrollmodechanged", webViewerScrollModeChanged); - eventBus.on("switchspreadmode", webViewerSwitchSpreadMode); - eventBus.on("spreadmodechanged", webViewerSpreadModeChanged); - eventBus.on("documentproperties", webViewerDocumentProperties); - eventBus.on("find", webViewerFind); - eventBus.on("findfromurlhash", webViewerFindFromUrlHash); - eventBus.on("updatefindmatchescount", webViewerUpdateFindMatchesCount); - eventBus.on("updatefindcontrolstate", webViewerUpdateFindControlState); + eventBus._on("resize", webViewerResize); + eventBus._on("hashchange", webViewerHashchange); + eventBus._on("beforeprint", _boundEvents.beforePrint); + eventBus._on("afterprint", _boundEvents.afterPrint); + eventBus._on("pagerendered", webViewerPageRendered); + eventBus._on("updateviewarea", webViewerUpdateViewarea); + eventBus._on("pagechanging", webViewerPageChanging); + eventBus._on("scalechanging", webViewerScaleChanging); + eventBus._on("rotationchanging", webViewerRotationChanging); + eventBus._on("sidebarviewchanged", webViewerSidebarViewChanged); + eventBus._on("pagemode", webViewerPageMode); + eventBus._on("namedaction", webViewerNamedAction); + eventBus._on("presentationmodechanged", webViewerPresentationModeChanged); + eventBus._on("presentationmode", webViewerPresentationMode); + eventBus._on("openfile", webViewerOpenFile); + eventBus._on("print", webViewerPrint); + eventBus._on("download", webViewerDownload); + eventBus._on("firstpage", webViewerFirstPage); + eventBus._on("lastpage", webViewerLastPage); + eventBus._on("nextpage", webViewerNextPage); + eventBus._on("previouspage", webViewerPreviousPage); + eventBus._on("zoomin", webViewerZoomIn); + eventBus._on("zoomout", webViewerZoomOut); + eventBus._on("zoomreset", webViewerZoomReset); + eventBus._on("pagenumberchanged", webViewerPageNumberChanged); + eventBus._on("scalechanged", webViewerScaleChanged); + eventBus._on("rotatecw", webViewerRotateCw); + eventBus._on("rotateccw", webViewerRotateCcw); + eventBus._on("switchscrollmode", webViewerSwitchScrollMode); + eventBus._on("scrollmodechanged", webViewerScrollModeChanged); + eventBus._on("switchspreadmode", webViewerSwitchSpreadMode); + eventBus._on("spreadmodechanged", webViewerSpreadModeChanged); + eventBus._on("documentproperties", webViewerDocumentProperties); + eventBus._on("find", webViewerFind); + eventBus._on("findfromurlhash", webViewerFindFromUrlHash); + eventBus._on("updatefindmatchescount", webViewerUpdateFindMatchesCount); + eventBus._on("updatefindcontrolstate", webViewerUpdateFindControlState); if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { - eventBus.on("fileinputchange", webViewerFileInputChange); + eventBus._on("fileinputchange", webViewerFileInputChange); } }, @@ -1671,45 +1671,45 @@ const PDFViewerApplication = { unbindEvents() { const { eventBus, _boundEvents } = this; - eventBus.off("resize", webViewerResize); - eventBus.off("hashchange", webViewerHashchange); - eventBus.off("beforeprint", _boundEvents.beforePrint); - eventBus.off("afterprint", _boundEvents.afterPrint); - eventBus.off("pagerendered", webViewerPageRendered); - eventBus.off("updateviewarea", webViewerUpdateViewarea); - eventBus.off("pagechanging", webViewerPageChanging); - eventBus.off("scalechanging", webViewerScaleChanging); - eventBus.off("rotationchanging", webViewerRotationChanging); - eventBus.off("sidebarviewchanged", webViewerSidebarViewChanged); - eventBus.off("pagemode", webViewerPageMode); - eventBus.off("namedaction", webViewerNamedAction); - eventBus.off("presentationmodechanged", webViewerPresentationModeChanged); - eventBus.off("presentationmode", webViewerPresentationMode); - eventBus.off("openfile", webViewerOpenFile); - eventBus.off("print", webViewerPrint); - eventBus.off("download", webViewerDownload); - eventBus.off("firstpage", webViewerFirstPage); - eventBus.off("lastpage", webViewerLastPage); - eventBus.off("nextpage", webViewerNextPage); - eventBus.off("previouspage", webViewerPreviousPage); - eventBus.off("zoomin", webViewerZoomIn); - eventBus.off("zoomout", webViewerZoomOut); - eventBus.off("zoomreset", webViewerZoomReset); - eventBus.off("pagenumberchanged", webViewerPageNumberChanged); - eventBus.off("scalechanged", webViewerScaleChanged); - eventBus.off("rotatecw", webViewerRotateCw); - eventBus.off("rotateccw", webViewerRotateCcw); - eventBus.off("switchscrollmode", webViewerSwitchScrollMode); - eventBus.off("scrollmodechanged", webViewerScrollModeChanged); - eventBus.off("switchspreadmode", webViewerSwitchSpreadMode); - eventBus.off("spreadmodechanged", webViewerSpreadModeChanged); - eventBus.off("documentproperties", webViewerDocumentProperties); - eventBus.off("find", webViewerFind); - eventBus.off("findfromurlhash", webViewerFindFromUrlHash); - eventBus.off("updatefindmatchescount", webViewerUpdateFindMatchesCount); - eventBus.off("updatefindcontrolstate", webViewerUpdateFindControlState); + eventBus._off("resize", webViewerResize); + eventBus._off("hashchange", webViewerHashchange); + eventBus._off("beforeprint", _boundEvents.beforePrint); + eventBus._off("afterprint", _boundEvents.afterPrint); + eventBus._off("pagerendered", webViewerPageRendered); + eventBus._off("updateviewarea", webViewerUpdateViewarea); + eventBus._off("pagechanging", webViewerPageChanging); + eventBus._off("scalechanging", webViewerScaleChanging); + eventBus._off("rotationchanging", webViewerRotationChanging); + eventBus._off("sidebarviewchanged", webViewerSidebarViewChanged); + eventBus._off("pagemode", webViewerPageMode); + eventBus._off("namedaction", webViewerNamedAction); + eventBus._off("presentationmodechanged", webViewerPresentationModeChanged); + eventBus._off("presentationmode", webViewerPresentationMode); + eventBus._off("openfile", webViewerOpenFile); + eventBus._off("print", webViewerPrint); + eventBus._off("download", webViewerDownload); + eventBus._off("firstpage", webViewerFirstPage); + eventBus._off("lastpage", webViewerLastPage); + eventBus._off("nextpage", webViewerNextPage); + eventBus._off("previouspage", webViewerPreviousPage); + eventBus._off("zoomin", webViewerZoomIn); + eventBus._off("zoomout", webViewerZoomOut); + eventBus._off("zoomreset", webViewerZoomReset); + eventBus._off("pagenumberchanged", webViewerPageNumberChanged); + eventBus._off("scalechanged", webViewerScaleChanged); + eventBus._off("rotatecw", webViewerRotateCw); + eventBus._off("rotateccw", webViewerRotateCcw); + eventBus._off("switchscrollmode", webViewerSwitchScrollMode); + eventBus._off("scrollmodechanged", webViewerScrollModeChanged); + eventBus._off("switchspreadmode", webViewerSwitchSpreadMode); + eventBus._off("spreadmodechanged", webViewerSpreadModeChanged); + eventBus._off("documentproperties", webViewerDocumentProperties); + eventBus._off("find", webViewerFind); + eventBus._off("findfromurlhash", webViewerFindFromUrlHash); + eventBus._off("updatefindmatchescount", webViewerUpdateFindMatchesCount); + eventBus._off("updatefindcontrolstate", webViewerUpdateFindControlState); if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) { - eventBus.off("fileinputchange", webViewerFileInputChange); + eventBus._off("fileinputchange", webViewerFileInputChange); } _boundEvents.beforePrint = null; diff --git a/web/base_viewer.js b/web/base_viewer.js index 77146eb9b..21141bd52 100644 --- a/web/base_viewer.js +++ b/web/base_viewer.js @@ -426,7 +426,7 @@ class BaseViewer { // evicted from the buffer and destroyed even if we pause its rendering. this._buffer.push(pageView); }; - this.eventBus.on("pagerender", this._onBeforeDraw); + this.eventBus._on("pagerender", this._onBeforeDraw); this._onAfterDraw = evt => { if (evt.cssTransform || onePageRenderedCapability.settled) { @@ -434,10 +434,10 @@ class BaseViewer { } onePageRenderedCapability.resolve(); - this.eventBus.off("pagerendered", this._onAfterDraw); + this.eventBus._off("pagerendered", this._onAfterDraw); this._onAfterDraw = null; }; - this.eventBus.on("pagerendered", this._onAfterDraw); + this.eventBus._on("pagerendered", this._onAfterDraw); // Fetch a single page so we can get a viewport that will be the default // viewport for all pages @@ -582,11 +582,11 @@ class BaseViewer { this._spreadMode = SpreadMode.NONE; if (this._onBeforeDraw) { - this.eventBus.off("pagerender", this._onBeforeDraw); + this.eventBus._off("pagerender", this._onBeforeDraw); this._onBeforeDraw = null; } if (this._onAfterDraw) { - this.eventBus.off("pagerendered", this._onAfterDraw); + this.eventBus._off("pagerendered", this._onAfterDraw); this._onAfterDraw = null; } // Remove the pages from the DOM... diff --git a/web/pdf_attachment_viewer.js b/web/pdf_attachment_viewer.js index a7e6a2411..5df8703bf 100644 --- a/web/pdf_attachment_viewer.js +++ b/web/pdf_attachment_viewer.js @@ -43,7 +43,7 @@ class PDFAttachmentViewer { this.reset(); - this.eventBus.on( + this.eventBus._on( "fileattachmentannotation", this._appendAttachment.bind(this) ); diff --git a/web/pdf_cursor_tools.js b/web/pdf_cursor_tools.js index c9e23f996..1b9ef6f43 100644 --- a/web/pdf_cursor_tools.js +++ b/web/pdf_cursor_tools.js @@ -122,11 +122,11 @@ class PDFCursorTools { * @private */ _addEventListeners() { - this.eventBus.on("switchcursortool", evt => { + this.eventBus._on("switchcursortool", evt => { this.switchTool(evt.tool); }); - this.eventBus.on("presentationmodechanged", evt => { + this.eventBus._on("presentationmodechanged", evt => { if (evt.switchInProgress) { return; } diff --git a/web/pdf_document_properties.js b/web/pdf_document_properties.js index 10c00a879..d55e30202 100644 --- a/web/pdf_document_properties.js +++ b/web/pdf_document_properties.js @@ -84,10 +84,10 @@ class PDFDocumentProperties { ); if (eventBus) { - eventBus.on("pagechanging", evt => { + eventBus._on("pagechanging", evt => { this._currentPageNumber = evt.pageNumber; }); - eventBus.on("rotationchanging", evt => { + eventBus._on("rotationchanging", evt => { this._pagesRotation = evt.pagesRotation; }); } diff --git a/web/pdf_find_bar.js b/web/pdf_find_bar.js index 5ace2fc74..2a42d8573 100644 --- a/web/pdf_find_bar.js +++ b/web/pdf_find_bar.js @@ -83,7 +83,7 @@ class PDFFindBar { this.dispatchEvent("entirewordchange"); }); - this.eventBus.on("resize", this._adjustWidth.bind(this)); + this.eventBus._on("resize", this._adjustWidth.bind(this)); } reset() { diff --git a/web/pdf_find_controller.js b/web/pdf_find_controller.js index 53a560260..6e46f6331 100644 --- a/web/pdf_find_controller.js +++ b/web/pdf_find_controller.js @@ -72,7 +72,7 @@ class PDFFindController { this._eventBus = eventBus || getGlobalEventBus(); this._reset(); - eventBus.on("findbarclose", this._onFindBarClose.bind(this)); + eventBus._on("findbarclose", this._onFindBarClose.bind(this)); } get highlightMatches() { diff --git a/web/pdf_history.js b/web/pdf_history.js index cf1e35fed..4e8127b15 100644 --- a/web/pdf_history.js +++ b/web/pdf_history.js @@ -69,17 +69,17 @@ class PDFHistory { this._isViewerInPresentationMode = false; // Ensure that we don't miss either a 'presentationmodechanged' or a // 'pagesinit' event, by registering the listeners immediately. - this.eventBus.on("presentationmodechanged", evt => { + this.eventBus._on("presentationmodechanged", evt => { this._isViewerInPresentationMode = evt.active || evt.switchInProgress; }); - this.eventBus.on("pagesinit", () => { + this.eventBus._on("pagesinit", () => { this._isPagesLoaded = false; const onPagesLoaded = evt => { - this.eventBus.off("pagesloaded", onPagesLoaded); + this.eventBus._off("pagesloaded", onPagesLoaded); this._isPagesLoaded = !!evt.pagesCount; }; - this.eventBus.on("pagesloaded", onPagesLoaded); + this.eventBus._on("pagesloaded", onPagesLoaded); }); } @@ -684,7 +684,7 @@ class PDFHistory { pageHide: this._pageHide.bind(this), }; - this.eventBus.on("updateviewarea", this._boundEvents.updateViewarea); + this.eventBus._on("updateviewarea", this._boundEvents.updateViewarea); window.addEventListener("popstate", this._boundEvents.popState); window.addEventListener("pagehide", this._boundEvents.pageHide); } @@ -696,7 +696,7 @@ class PDFHistory { if (!this._boundEvents) { return; // The event listeners were already removed. } - this.eventBus.off("updateviewarea", this._boundEvents.updateViewarea); + this.eventBus._off("updateviewarea", this._boundEvents.updateViewarea); window.removeEventListener("popstate", this._boundEvents.popState); window.removeEventListener("pagehide", this._boundEvents.pageHide); diff --git a/web/pdf_outline_viewer.js b/web/pdf_outline_viewer.js index a50cb977e..672e3b76c 100644 --- a/web/pdf_outline_viewer.js +++ b/web/pdf_outline_viewer.js @@ -40,7 +40,7 @@ class PDFOutlineViewer { this.reset(); - eventBus.on("toggleoutlinetree", this.toggleOutlineTree.bind(this)); + eventBus._on("toggleoutlinetree", this.toggleOutlineTree.bind(this)); } reset() { diff --git a/web/pdf_sidebar.js b/web/pdf_sidebar.js index a06d5a8aa..a10358b67 100644 --- a/web/pdf_sidebar.js +++ b/web/pdf_sidebar.js @@ -430,7 +430,7 @@ class PDFSidebar { }); // Disable/enable views. - this.eventBus.on("outlineloaded", evt => { + this.eventBus._on("outlineloaded", evt => { const outlineCount = evt.outlineCount; this.outlineButton.disabled = !outlineCount; @@ -444,7 +444,7 @@ class PDFSidebar { } }); - this.eventBus.on("attachmentsloaded", evt => { + this.eventBus._on("attachmentsloaded", evt => { if (evt.attachmentsCount) { this.attachmentsButton.disabled = false; @@ -473,7 +473,7 @@ class PDFSidebar { }); // Update the thumbnailViewer, if visible, when exiting presentation mode. - this.eventBus.on("presentationmodechanged", evt => { + this.eventBus._on("presentationmodechanged", evt => { if (!evt.active && !evt.switchInProgress && this.isThumbnailViewVisible) { this._updateThumbnailViewer(); } diff --git a/web/pdf_sidebar_resizer.js b/web/pdf_sidebar_resizer.js index 77b0a4516..668c59dcb 100644 --- a/web/pdf_sidebar_resizer.js +++ b/web/pdf_sidebar_resizer.js @@ -151,11 +151,11 @@ class PDFSidebarResizer { window.addEventListener("mouseup", _boundEvents.mouseUp); }); - this.eventBus.on("sidebarviewchanged", evt => { + this.eventBus._on("sidebarviewchanged", evt => { this.sidebarOpen = !!(evt && evt.view); }); - this.eventBus.on("resize", evt => { + this.eventBus._on("resize", evt => { // When the *entire* viewer is resized, such that it becomes narrower, // ensure that the sidebar doesn't end up being too wide. if (!evt || evt.source !== window) { diff --git a/web/pdf_single_page_viewer.js b/web/pdf_single_page_viewer.js index e6dabb391..3db66f3b1 100644 --- a/web/pdf_single_page_viewer.js +++ b/web/pdf_single_page_viewer.js @@ -20,7 +20,7 @@ class PDFSinglePageViewer extends BaseViewer { constructor(options) { super(options); - this.eventBus.on("pagesinit", evt => { + this.eventBus._on("pagesinit", evt => { // Since the pages are placed in a `DocumentFragment`, make sure that // the current page becomes visible upon loading of the document. this._ensurePageViewVisible(); diff --git a/web/secondary_toolbar.js b/web/secondary_toolbar.js index 32bc4601f..0dd75f815 100644 --- a/web/secondary_toolbar.js +++ b/web/secondary_toolbar.js @@ -159,11 +159,11 @@ class SecondaryToolbar { this._bindSpreadModeListener(options); // Bind the event listener for adjusting the 'max-height' of the toolbar. - this.eventBus.on("resize", this._setMaxHeight.bind(this)); + this.eventBus._on("resize", this._setMaxHeight.bind(this)); // Hide the Scroll/Spread mode buttons, when they're not applicable to the // current `BaseViewer` instance (in particular `PDFSinglePageViewer`). - this.eventBus.on("baseviewerinit", evt => { + this.eventBus._on("baseviewerinit", evt => { if (evt.source instanceof PDFSinglePageViewer) { this.toolbarButtonContainer.classList.add( "hiddenScrollModeButtons", @@ -233,7 +233,7 @@ class SecondaryToolbar { } _bindCursorToolsListener(buttons) { - this.eventBus.on("cursortoolchanged", function({ tool }) { + this.eventBus._on("cursortoolchanged", function({ tool }) { buttons.cursorSelectToolButton.classList.toggle( "toggled", tool === CursorTool.SELECT @@ -267,9 +267,9 @@ class SecondaryToolbar { buttons.spreadOddButton.disabled = isScrollModeHorizontal; buttons.spreadEvenButton.disabled = isScrollModeHorizontal; } - this.eventBus.on("scrollmodechanged", scrollModeChanged); + this.eventBus._on("scrollmodechanged", scrollModeChanged); - this.eventBus.on("secondarytoolbarreset", evt => { + this.eventBus._on("secondarytoolbarreset", evt => { if (evt.source === this) { scrollModeChanged({ mode: ScrollMode.VERTICAL }); } @@ -291,9 +291,9 @@ class SecondaryToolbar { mode === SpreadMode.EVEN ); } - this.eventBus.on("spreadmodechanged", spreadModeChanged); + this.eventBus._on("spreadmodechanged", spreadModeChanged); - this.eventBus.on("secondarytoolbarreset", evt => { + this.eventBus._on("secondarytoolbarreset", evt => { if (evt.source === this) { spreadModeChanged({ mode: SpreadMode.NONE }); } diff --git a/web/text_layer_builder.js b/web/text_layer_builder.js index ec56a376c..6c3be2f54 100644 --- a/web/text_layer_builder.js +++ b/web/text_layer_builder.js @@ -123,7 +123,7 @@ class TextLayerBuilder { this._updateMatches(); } }; - this.eventBus.on( + this.eventBus._on( "updatetextlayermatches", this._onUpdateTextLayerMatches ); @@ -139,7 +139,7 @@ class TextLayerBuilder { this.textLayerRenderTask = null; } if (this._onUpdateTextLayerMatches) { - this.eventBus.off( + this.eventBus._off( "updatetextlayermatches", this._onUpdateTextLayerMatches ); diff --git a/web/toolbar.js b/web/toolbar.js index bd6fe5484..1937292ee 100644 --- a/web/toolbar.js +++ b/web/toolbar.js @@ -159,7 +159,7 @@ class Toolbar { // Suppress context menus for some controls. scaleSelect.oncontextmenu = noContextMenuHandler; - this.eventBus.on("localized", () => { + this.eventBus._on("localized", () => { this._wasLocalized = true; this._adjustScaleWidth(); this._updateUIState(true); diff --git a/web/ui_utils.js b/web/ui_utils.js index e258080d2..d43564141 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -766,22 +766,20 @@ class EventBus { this._dispatchToDOM = dispatchToDOM === true; } + /** + * @param {string} eventName + * @param {function} listener + */ on(eventName, listener) { - let eventListeners = this._listeners[eventName]; - if (!eventListeners) { - eventListeners = []; - this._listeners[eventName] = eventListeners; - } - eventListeners.push(listener); + this._on(eventName, listener, { external: true }); } + /** + * @param {string} eventName + * @param {function} listener + */ off(eventName, listener) { - const eventListeners = this._listeners[eventName]; - let i; - if (!eventListeners || (i = eventListeners.indexOf(listener)) < 0) { - return; - } - eventListeners.splice(i, 1); + this._off(eventName, listener, { external: true }); } dispatch(eventName) { @@ -795,16 +793,62 @@ class EventBus { } // Passing all arguments after the eventName to the listeners. const args = Array.prototype.slice.call(arguments, 1); + let externalListeners; // Making copy of the listeners array in case if it will be modified // during dispatch. - eventListeners.slice(0).forEach(function(listener) { + eventListeners.slice(0).forEach(function({ listener, external }) { + if (external) { + if (!externalListeners) { + externalListeners = []; + } + externalListeners.push(listener); + return; + } listener.apply(null, args); }); + // Dispatch any "external" listeners *after* the internal ones, to give the + // viewer components time to handle events and update their state first. + if (externalListeners) { + externalListeners.forEach(function(listener) { + listener.apply(null, args); + }); + externalListeners = null; + } if (this._dispatchToDOM) { this._dispatchDOMEvent(eventName, args); } } + /** + * @ignore + */ + _on(eventName, listener, options = null) { + let eventListeners = this._listeners[eventName]; + if (!eventListeners) { + this._listeners[eventName] = eventListeners = []; + } + eventListeners.push({ + listener, + external: options ? options.external : false, + }); + } + + /** + * @ignore + */ + _off(eventName, listener, options = null) { + const eventListeners = this._listeners[eventName]; + if (!eventListeners) { + return; + } + for (let i = 0, ii = eventListeners.length; i < ii; i++) { + if (eventListeners[i].listener === listener) { + eventListeners.splice(i, 1); + return; + } + } + } + /** * @private */