diff --git a/src/modules/search/Popup.ts b/src/modules/search/Popup.ts index 88b18f2e..c02a1b46 100644 --- a/src/modules/search/Popup.ts +++ b/src/modules/search/Popup.ts @@ -151,16 +151,21 @@ export class Popup { return; } let self = this; - win.onclick = function (ev) { - if (event.target !== ev.target) { - if (d2popover.parentElement) { - self.hidePopover(); - if (win) { - win.onclick = null; + win.addEventListener( + "click", + function (ev) { + if (event.target !== ev.target) { + if (d2popover.parentElement) { + self.hidePopover(); + ev.stopImmediatePropagation(); } } + }, + { + once: true, + capture: true, } - }; + ); } } else if (src) { let absolute = getAbsoluteHref(src); @@ -207,16 +212,21 @@ export class Popup { return; } let self = this; - win.onclick = function (ev) { - if (event.target !== ev.target) { - if (d2popover.parentElement) { - self.hidePopover(); - if (win) { - win.onclick = null; + win.addEventListener( + "click", + function (ev) { + if (event.target !== ev.target) { + if (d2popover.parentElement) { + self.hidePopover(); + ev.stopImmediatePropagation(); } } + }, + { + once: true, + capture: true, } - }; + ); } } } diff --git a/src/navigator/IFrameNavigator.ts b/src/navigator/IFrameNavigator.ts index 311a535f..f1900d99 100644 --- a/src/navigator/IFrameNavigator.ts +++ b/src/navigator/IFrameNavigator.ts @@ -97,6 +97,7 @@ import { ConsumptionModule, ConsumptionModuleConfig, } from "../modules/consumption/ConsumptionModule"; +import KeyDownEvent = JQuery.KeyDownEvent; export type GetContent = (href: string) => Promise; export type GetContentBytesLength = ( @@ -117,6 +118,8 @@ export interface NavigatorAPI { resourceAtEnd: any; resourceFitsScreen: any; updateCurrentLocation: any; + keydownFallthrough: any; + clickThrough: any; direction: any; onError?: (e: Error) => void; } @@ -999,11 +1002,16 @@ export class IFrameNavigator extends EventEmitter implements Navigator { this.nextChapterBottomAnchorElement.style.display = "none"; if (this.previousChapterTopAnchorElement) this.previousChapterTopAnchorElement.style.display = "none"; + if (this.eventHandler) { + this.eventHandler.onClickThrough = this.handleClickThrough.bind(this); + } if (this.keyboardEventHandler) { this.keyboardEventHandler.onBackwardSwipe = this.handlePreviousChapterClick.bind(this); this.keyboardEventHandler.onForwardSwipe = this.handleNextChapterClick.bind(this); + this.keyboardEventHandler.onKeydown = + this.handleKeydownFallthrough.bind(this); } if (this.touchEventHandler) { this.touchEventHandler.onBackwardSwipe = @@ -1048,6 +1056,8 @@ export class IFrameNavigator extends EventEmitter implements Navigator { this.handlePreviousPageClick.bind(this); this.keyboardEventHandler.onForwardSwipe = this.handleNextPageClick.bind(this); + this.keyboardEventHandler.onKeydown = + this.handleKeydownFallthrough.bind(this); } } else { if (this.infoBottom) this.infoBottom.style.display = "none"; @@ -1168,6 +1178,8 @@ export class IFrameNavigator extends EventEmitter implements Navigator { this.handlePreviousPageClick.bind(this); this.keyboardEventHandler.onForwardSwipe = this.handleNextPageClick.bind(this); + this.keyboardEventHandler.onKeydown = + this.handleKeydownFallthrough.bind(this); } } }); @@ -1696,8 +1708,8 @@ export class IFrameNavigator extends EventEmitter implements Navigator { e instanceof Error ? e : typeof e === "string" - ? new Error(e) - : new Error("An unknown error occurred in the IFrameNavigator."); + ? new Error(e) + : new Error("An unknown error occurred in the IFrameNavigator."); this.api.onError(trueError); } else { // otherwise just display the standard error UI @@ -2483,7 +2495,10 @@ export class IFrameNavigator extends EventEmitter implements Navigator { } } - private handleClickThrough(_event: MouseEvent | TouchEvent) {} + private handleClickThrough(event: MouseEvent | TouchEvent) { + if (this.api?.clickThrough) this.api?.clickThrough(event); + this.emit("click", event); + } private handleInternalLink(event: MouseEvent | TouchEvent) { const element = event.target; @@ -2815,6 +2830,11 @@ export class IFrameNavigator extends EventEmitter implements Navigator { } } + private handleKeydownFallthrough(event: KeyDownEvent | undefined): void { + if (this.api?.keydownFallthrough) this.api?.keydownFallthrough(event); + this.emit("keydown", event); + } + private hideView(): void { if (this.view?.layout !== "fixed") { if (this.view?.isScrollMode()) { diff --git a/src/utils/EventHandler.ts b/src/utils/EventHandler.ts index 3e3be158..6ef95771 100644 --- a/src/utils/EventHandler.ts +++ b/src/utils/EventHandler.ts @@ -68,7 +68,7 @@ export default class EventHandler { // Most click handling is done in the touchend and mouseup event handlers, // but if there's a click on an external link we need to cancel the click // event to prevent it from opening in the iframe. - element.addEventListener("click", this.handleLinks.bind(this)); + element.addEventListener("click", this.handleLinks.bind(this), true); } else { throw "cannot setup events for null"; } diff --git a/src/utils/KeyboardEventHandler.ts b/src/utils/KeyboardEventHandler.ts index 6ec58714..7ea49b72 100644 --- a/src/utils/KeyboardEventHandler.ts +++ b/src/utils/KeyboardEventHandler.ts @@ -29,6 +29,7 @@ export default class KeyboardEventHandler { public onBackwardSwipe: (event: UIEvent) => void = () => {}; public onForwardSwipe: (event: UIEvent) => void = () => {}; + public onKeydown: (event: UIEvent) => void = () => {}; public setupEvents = (element: HTMLElement | Document | null): void => { if (element) { @@ -93,20 +94,22 @@ export default class KeyboardEventHandler { switch (key) { case "ArrowRight": self.rtl ? self.onBackwardSwipe(event) : self.onForwardSwipe(event); - break; + return; case "ArrowLeft": self.rtl ? self.onForwardSwipe(event) : self.onBackwardSwipe(event); - break; + return; } switch (event.code) { case "Space": if (event.ctrlKey) { self.onBackwardSwipe(event); + return; } else { self.onForwardSwipe(event); + return; } - break; } + self.onKeydown(event); }) ); } diff --git a/viewer/index_dita.html b/viewer/index_dita.html index 0f6b0be0..d6277591 100644 --- a/viewer/index_dita.html +++ b/viewer/index_dita.html @@ -1402,6 +1402,12 @@ ); }); }, + keydownFallthrough: function(event) { + console.log("api.keydownFallthrough:" + event.key); + }, + clickThrough: function(event) { + console.log("api.clickThrough"); + }, onError: function(error) { console.log(error); }, @@ -1449,6 +1455,12 @@ instance.addEventListener("resource.ready", () => { console.log("listener ready"); }); + instance.addEventListener("keydown", (event) => { + console.log("keydown: " + event.key); + }); + instance.addEventListener("click", (event) => { + console.log("click through: " + event.detail); + }); }).catch(error => { console.error(error);