Merge pull request #17964 from Snuffleupagus/addEventListener-signal

Remove *some* event listeners with `signal` in the viewer
This commit is contained in:
Tim van der Meij 2024-04-18 19:13:32 +02:00 committed by GitHub
commit 5ad42c13ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 140 additions and 148 deletions

View file

@ -158,6 +158,7 @@ const PDFViewerApplication = {
baseUrl: "", baseUrl: "",
_downloadUrl: "", _downloadUrl: "",
_boundEvents: Object.create(null), _boundEvents: Object.create(null),
_windowAbortController: null,
documentInfo: null, documentInfo: null,
metadata: null, metadata: null,
_contentDispositionFilename: null, _contentDispositionFilename: null,
@ -176,8 +177,6 @@ const PDFViewerApplication = {
_nimbusDataPromise: null, _nimbusDataPromise: null,
_caretBrowsing: null, _caretBrowsing: null,
_isScrolling: false, _isScrolling: false,
_lastScrollTop: 0,
_lastScrollLeft: 0,
// Called once when the document is loaded. // Called once when the document is loaded.
async initialize(appConfig) { async initialize(appConfig) {
@ -1906,10 +1905,15 @@ const PDFViewerApplication = {
}, },
bindWindowEvents() { bindWindowEvents() {
if (this._windowAbortController) {
return;
}
this._windowAbortController = new AbortController();
const { const {
eventBus, eventBus,
_boundEvents,
appConfig: { mainContainer }, appConfig: { mainContainer },
_windowAbortController: { signal },
} = this; } = this;
function addWindowResolutionChange(evt = null) { function addWindowResolutionChange(evt = null) {
@ -1921,58 +1925,73 @@ const PDFViewerApplication = {
); );
mediaQueryList.addEventListener("change", addWindowResolutionChange, { mediaQueryList.addEventListener("change", addWindowResolutionChange, {
once: true, once: true,
signal,
}); });
_boundEvents.removeWindowResolutionChange ||= function () {
mediaQueryList.removeEventListener("change", addWindowResolutionChange);
_boundEvents.removeWindowResolutionChange = null;
};
} }
addWindowResolutionChange(); addWindowResolutionChange();
_boundEvents.windowResize = () => { window.addEventListener("visibilitychange", webViewerVisibilityChange, {
signal,
});
window.addEventListener("wheel", webViewerWheel, {
passive: false,
signal,
});
window.addEventListener("touchstart", webViewerTouchStart, {
passive: false,
signal,
});
window.addEventListener("touchmove", webViewerTouchMove, {
passive: false,
signal,
});
window.addEventListener("touchend", webViewerTouchEnd, {
passive: false,
signal,
});
window.addEventListener("click", webViewerClick, { signal });
window.addEventListener("keydown", webViewerKeyDown, { signal });
window.addEventListener("keyup", webViewerKeyUp, { signal });
window.addEventListener(
"resize",
() => {
eventBus.dispatch("resize", { source: window }); eventBus.dispatch("resize", { source: window });
}; },
_boundEvents.windowHashChange = () => { { signal }
);
window.addEventListener(
"hashchange",
() => {
eventBus.dispatch("hashchange", { eventBus.dispatch("hashchange", {
source: window, source: window,
hash: document.location.hash.substring(1), hash: document.location.hash.substring(1),
}); });
}; },
_boundEvents.windowBeforePrint = () => { { signal }
);
window.addEventListener(
"beforeprint",
() => {
eventBus.dispatch("beforeprint", { source: window }); eventBus.dispatch("beforeprint", { source: window });
}; },
_boundEvents.windowAfterPrint = () => { { signal }
);
window.addEventListener(
"afterprint",
() => {
eventBus.dispatch("afterprint", { source: window }); eventBus.dispatch("afterprint", { source: window });
}; },
_boundEvents.windowUpdateFromSandbox = event => { { signal }
);
window.addEventListener(
"updatefromsandbox",
event => {
eventBus.dispatch("updatefromsandbox", { eventBus.dispatch("updatefromsandbox", {
source: window, source: window,
detail: event.detail, detail: event.detail,
}); });
}; },
{ signal }
window.addEventListener("visibilitychange", webViewerVisibilityChange);
window.addEventListener("wheel", webViewerWheel, { passive: false });
window.addEventListener("touchstart", webViewerTouchStart, {
passive: false,
});
window.addEventListener("touchmove", webViewerTouchMove, {
passive: false,
});
window.addEventListener("touchend", webViewerTouchEnd, {
passive: false,
});
window.addEventListener("click", webViewerClick);
window.addEventListener("keydown", webViewerKeyDown);
window.addEventListener("keyup", webViewerKeyUp);
window.addEventListener("resize", _boundEvents.windowResize);
window.addEventListener("hashchange", _boundEvents.windowHashChange);
window.addEventListener("beforeprint", _boundEvents.windowBeforePrint);
window.addEventListener("afterprint", _boundEvents.windowAfterPrint);
window.addEventListener(
"updatefromsandbox",
_boundEvents.windowUpdateFromSandbox
); );
if ( if (
@ -1981,39 +2000,51 @@ const PDFViewerApplication = {
) { ) {
return; return;
} }
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
// Using the values lastScrollTop and lastScrollLeft is a workaround to // Using the values lastScrollTop and lastScrollLeft is a workaround to
// https://bugzilla.mozilla.org/show_bug.cgi?id=1881974. // https://bugzilla.mozilla.org/show_bug.cgi?id=1881974.
// TODO: remove them once the bug is fixed. // TODO: remove them once the bug is fixed.
({ scrollTop: this._lastScrollTop, scrollLeft: this._lastScrollLeft } = ({ scrollTop: this._lastScrollTop, scrollLeft: this._lastScrollLeft } =
mainContainer); mainContainer);
const scrollend = (_boundEvents.mainContainerScrollend = () => { }
const scrollend = () => {
if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
({ scrollTop: this._lastScrollTop, scrollLeft: this._lastScrollLeft } = ({ scrollTop: this._lastScrollTop, scrollLeft: this._lastScrollLeft } =
mainContainer); mainContainer);
}
this._isScrolling = false; this._isScrolling = false;
mainContainer.addEventListener("scroll", scroll, { mainContainer.addEventListener("scroll", scroll, {
passive: true, passive: true,
signal,
}); });
mainContainer.removeEventListener("scrollend", scrollend); mainContainer.removeEventListener("scrollend", scrollend, { signal });
mainContainer.removeEventListener("blur", scrollend); mainContainer.removeEventListener("blur", scrollend, { signal });
}); };
const scroll = (_boundEvents.mainContainerScroll = () => { const scroll = () => {
if (this._isCtrlKeyDown) {
return;
}
if ( if (
this._isCtrlKeyDown || (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) &&
(this._lastScrollTop === mainContainer.scrollTop && this._lastScrollTop === mainContainer.scrollTop &&
this._lastScrollLeft === mainContainer.scrollLeft) this._lastScrollLeft === mainContainer.scrollLeft
) { ) {
return; return;
} }
mainContainer.removeEventListener("scroll", scroll, { mainContainer.removeEventListener("scroll", scroll, {
passive: true, passive: true,
signal,
}); });
this._isScrolling = true; this._isScrolling = true;
mainContainer.addEventListener("scrollend", scrollend); mainContainer.addEventListener("scrollend", scrollend, { signal });
mainContainer.addEventListener("blur", scrollend); mainContainer.addEventListener("blur", scrollend, { signal });
}); };
mainContainer.addEventListener("scroll", scroll, { mainContainer.addEventListener("scroll", scroll, {
passive: true, passive: true,
signal,
}); });
}, },
@ -2077,54 +2108,8 @@ const PDFViewerApplication = {
}, },
unbindWindowEvents() { unbindWindowEvents() {
const { this._windowAbortController?.abort();
_boundEvents, this._windowAbortController = null;
appConfig: { mainContainer },
} = this;
window.removeEventListener("visibilitychange", webViewerVisibilityChange);
window.removeEventListener("wheel", webViewerWheel, { passive: false });
window.removeEventListener("touchstart", webViewerTouchStart, {
passive: false,
});
window.removeEventListener("touchmove", webViewerTouchMove, {
passive: false,
});
window.removeEventListener("touchend", webViewerTouchEnd, {
passive: false,
});
window.removeEventListener("click", webViewerClick);
window.removeEventListener("keydown", webViewerKeyDown);
window.removeEventListener("keyup", webViewerKeyUp);
window.removeEventListener("resize", _boundEvents.windowResize);
window.removeEventListener("hashchange", _boundEvents.windowHashChange);
window.removeEventListener("beforeprint", _boundEvents.windowBeforePrint);
window.removeEventListener("afterprint", _boundEvents.windowAfterPrint);
window.removeEventListener(
"updatefromsandbox",
_boundEvents.windowUpdateFromSandbox
);
mainContainer.removeEventListener(
"scroll",
_boundEvents.mainContainerScroll
);
mainContainer.removeEventListener(
"scrollend",
_boundEvents.mainContainerScrollend
);
mainContainer.removeEventListener(
"blur",
_boundEvents.mainContainerScrollend
);
_boundEvents.removeWindowResolutionChange?.();
_boundEvents.windowResize = null;
_boundEvents.windowHashChange = null;
_boundEvents.windowBeforePrint = null;
_boundEvents.windowAfterPrint = null;
_boundEvents.windowUpdateFromSandbox = null;
_boundEvents.mainContainerScroll = null;
_boundEvents.mainContainerScrollend = null;
}, },
_accumulateTicks(ticks, prop) { _accumulateTicks(ticks, prop) {

View file

@ -49,6 +49,10 @@ class PDFPresentationMode {
#args = null; #args = null;
#fullscreenChangeAbortController = null;
#windowAbortController = null;
/** /**
* @param {PDFPresentationModeOptions} options * @param {PDFPresentationModeOptions} options
*/ */
@ -346,59 +350,62 @@ class PDFPresentationMode {
} }
#addWindowListeners() { #addWindowListeners() {
this.showControlsBind = this.#showControls.bind(this); if (this.#windowAbortController) {
this.mouseDownBind = this.#mouseDown.bind(this); return;
this.mouseWheelBind = this.#mouseWheel.bind(this); }
this.resetMouseScrollStateBind = this.#resetMouseScrollState.bind(this); this.#windowAbortController = new AbortController();
this.contextMenuBind = this.#contextMenu.bind(this); const { signal } = this.#windowAbortController;
this.touchSwipeBind = this.#touchSwipe.bind(this);
window.addEventListener("mousemove", this.showControlsBind); const touchSwipeBind = this.#touchSwipe.bind(this);
window.addEventListener("mousedown", this.mouseDownBind);
window.addEventListener("wheel", this.mouseWheelBind, { passive: false }); window.addEventListener("mousemove", this.#showControls.bind(this), {
window.addEventListener("keydown", this.resetMouseScrollStateBind); signal,
window.addEventListener("contextmenu", this.contextMenuBind); });
window.addEventListener("touchstart", this.touchSwipeBind); window.addEventListener("mousedown", this.#mouseDown.bind(this), {
window.addEventListener("touchmove", this.touchSwipeBind); signal,
window.addEventListener("touchend", this.touchSwipeBind); });
window.addEventListener("wheel", this.#mouseWheel.bind(this), {
passive: false,
signal,
});
window.addEventListener("keydown", this.#resetMouseScrollState.bind(this), {
signal,
});
window.addEventListener("contextmenu", this.#contextMenu.bind(this), {
signal,
});
window.addEventListener("touchstart", touchSwipeBind, { signal });
window.addEventListener("touchmove", touchSwipeBind, { signal });
window.addEventListener("touchend", touchSwipeBind, { signal });
} }
#removeWindowListeners() { #removeWindowListeners() {
window.removeEventListener("mousemove", this.showControlsBind); this.#windowAbortController?.abort();
window.removeEventListener("mousedown", this.mouseDownBind); this.#windowAbortController = null;
window.removeEventListener("wheel", this.mouseWheelBind, {
passive: false,
});
window.removeEventListener("keydown", this.resetMouseScrollStateBind);
window.removeEventListener("contextmenu", this.contextMenuBind);
window.removeEventListener("touchstart", this.touchSwipeBind);
window.removeEventListener("touchmove", this.touchSwipeBind);
window.removeEventListener("touchend", this.touchSwipeBind);
delete this.showControlsBind;
delete this.mouseDownBind;
delete this.mouseWheelBind;
delete this.resetMouseScrollStateBind;
delete this.contextMenuBind;
delete this.touchSwipeBind;
} }
#fullscreenChange() { #addFullscreenChangeListeners() {
if (this.#fullscreenChangeAbortController) {
return;
}
this.#fullscreenChangeAbortController = new AbortController();
window.addEventListener(
"fullscreenchange",
() => {
if (/* isFullscreen = */ document.fullscreenElement) { if (/* isFullscreen = */ document.fullscreenElement) {
this.#enter(); this.#enter();
} else { } else {
this.#exit(); this.#exit();
} }
} },
{ signal: this.#fullscreenChangeAbortController.signal }
#addFullscreenChangeListeners() { );
this.fullscreenChangeBind = this.#fullscreenChange.bind(this);
window.addEventListener("fullscreenchange", this.fullscreenChangeBind);
} }
#removeFullscreenChangeListeners() { #removeFullscreenChangeListeners() {
window.removeEventListener("fullscreenchange", this.fullscreenChangeBind); this.#fullscreenChangeAbortController?.abort();
delete this.fullscreenChangeBind; this.#fullscreenChangeAbortController = null;
} }
} }