From 8ec6de078a63f2b49d22b040d14996524feef4b3 Mon Sep 17 00:00:00 2001 From: "Joshua A. Horton" Date: Fri, 12 May 2023 08:19:20 +0700 Subject: [PATCH] change(web): reverts toolbar direct use of DomEventTracker --- web/src/app/browser/src/keymanEngine.ts | 1 + web/src/app/browser/src/utilApiEndpoint.ts | 75 ++++++++++++++++++++-- web/src/app/ui/kmwuitoolbar.ts | 10 +-- 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/web/src/app/browser/src/keymanEngine.ts b/web/src/app/browser/src/keymanEngine.ts index e00bd5927e..d613176b5e 100644 --- a/web/src/app/browser/src/keymanEngine.ts +++ b/web/src/app/browser/src/keymanEngine.ts @@ -477,5 +477,6 @@ export default class KeymanEngine extends KeymanEngineBase export class UtilApiEndpoint { readonly config: BrowserConfiguration; private readonly stylesheetManager: StylesheetManager; + private readonly domEventTracker: DomEventTracker; constructor(config: BrowserConfiguration) { this.config = config; this.stylesheetManager = new StylesheetManager(document.body, config.applyCacheBusting); + this.domEventTracker = new DomEventTracker(); } readonly getAbsoluteX = getAbsoluteX; @@ -129,10 +131,6 @@ export class UtilApiEndpoint { this.stylesheetManager.linkExternalSheet(s); } - shutdown() { - this.stylesheetManager?.unlinkAll(); - } - // Possible alternative: https://www.npmjs.com/package/language-tags // This would necessitate linking in a npm module into compiled KeymanWeb, though. getLanguageCodes(lgCode: string): string[] { @@ -143,5 +141,72 @@ export class UtilApiEndpoint { } } - readonly DomEventTracker = DomEventTracker; + /** + * Function attachDOMEvent: Note for most browsers, adds an event to a chain, doesn't stop existing events + * Scope Public + * @param {Object} Pelem Element (or IFrame-internal Document) to which event is being attached + * @param {string} Peventname Name of event without 'on' prefix + * @param {function(Object)} Phandler Event handler for event + * @param {boolean=} PuseCapture True only if event to be handled on way to target element + * Description Attaches event handler to element DOM event + */ + attachDOMEvent( + Pelem: Window, + Peventname: K, + Phandler: (ev: WindowEventMap[K]) => any, + PuseCapture?: boolean + ): void; + attachDOMEvent( + Pelem: Document, + Peventname: K, + Phandler: (ev: DocumentEventMap[K]) => any, + PuseCapture?: boolean + ): void; + attachDOMEvent( + Pelem: HTMLElement, + Peventname: K, + Phandler: (ev: HTMLElementEventMap[K]) => any, + PuseCapture?: boolean + ): void; + attachDOMEvent(Pelem: EventTarget, Peventname: string, Phandler: (Object) => boolean, PuseCapture?: boolean): void { + // TS can't quite track the type inference forwarding here. + this.domEventTracker.attachDOMEvent(Pelem as any, Peventname as any, Phandler, PuseCapture); + } + + /** + * Function detachDOMEvent + * Scope Public + * @param {Object} Pelem Element from which event is being detached + * @param {string} Peventname Name of event without 'on' prefix + * @param {function(Object)} Phandler Event handler for event + * @param {boolean=} PuseCapture True if event was being handled on way to target element + * Description Detaches event handler from element [to prevent memory leaks] + */ + detachDOMEvent( + Pelem: Window, + Peventname: K, + Phandler: (ev: WindowEventMap[K]) => any, + PuseCapture?: boolean + ): void; + detachDOMEvent( + Pelem: Document, + Peventname: K, + Phandler: (ev: DocumentEventMap[K]) => any, + PuseCapture?: boolean + ): void; + detachDOMEvent( + Pelem: HTMLElement, + Peventname: K, + Phandler: (ev: HTMLElementEventMap[K]) => any, + PuseCapture?: boolean + ): void; + detachDOMEvent(Pelem: EventTarget, Peventname: string, Phandler: (Object) => boolean, PuseCapture?: boolean): void { + // TS can't quite track the type inference forwarding here. + this.domEventTracker.detachDOMEvent(Pelem as any, Peventname as any, Phandler, PuseCapture); + } + + shutdown() { + this.stylesheetManager?.unlinkAll(); + this.domEventTracker?.shutdown(); + } } \ No newline at end of file diff --git a/web/src/app/ui/kmwuitoolbar.ts b/web/src/app/ui/kmwuitoolbar.ts index 57cdf71a4b..05574911fe 100644 --- a/web/src/app/ui/kmwuitoolbar.ts +++ b/web/src/app/ui/kmwuitoolbar.ts @@ -5,7 +5,6 @@ import type { KeymanEngine, KeyboardCookie, UIModule } from 'keyman/app/browser'; import { type StylesheetManager } from 'keyman/engine/dom-utils'; -import { type DomEventTracker } from 'keyman/engine/events'; declare var keyman: KeymanEngine @@ -182,8 +181,6 @@ if(!keyman?.ui?.name) { oc: 'Oceania' }; - private eventTracker: DomEventTracker; - /** * Create some of the controls but don't insert them into the document yet * This does not need or want to prevent loss of focus, so uses document.createElement @@ -385,8 +382,7 @@ if(!keyman?.ui?.name) { this.startTimer = window.setTimeout(this.addKeyboardsToMap, 0); // Ensure that popups are hidden by clicking elsewhere on document - this.eventTracker = new util.DomEventTracker(); - this.eventTracker.attachDOMEvent(document.body,'click', this.hideAllPopups, false); + util.attachDOMEvent(document.body,'click', this.hideAllPopups, false); // Set Europe to be the default region this.selectedRegion = 'eu'; @@ -407,10 +403,6 @@ if(!keyman?.ui?.name) { if(root) { root.parentNode.removeChild(root); } - - if(this.eventTracker) { - this.eventTracker.shutdown(); - } } /**