prependJqListener.ts
1 import type { Logger } from '@/utils/logger'; 2 3 interface EventHandler { 4 (eventObject: JQueryEventObject, ...args: unknown[]): unknown; 5 wrappedJSObject?: Omit<EventHandler, 'wrappedJSObject'>; 6 } 7 8 interface JQueryEvent { 9 handler: EventHandler; 10 } 11 12 export const prependJqListener = ( 13 logger: Logger, 14 node: JQuery, 15 event: string, 16 eventKey: string, 17 handler: EventHandler, 18 ) => { 19 node.on(event, handler); 20 21 const newEvents = tryGetEventListeners(logger, node, eventKey); 22 23 if (!newEvents) { 24 return; 25 } 26 27 const addedEvents: JQueryEvent[] = []; 28 const addedEventsIndexes: number[] = []; 29 const waivedHandler = handler.wrappedJSObject || handler; 30 31 for (const [i, e] of newEvents.entries()) { 32 if (e.handler === waivedHandler) { 33 addedEvents.push(e); 34 addedEventsIndexes.push(i); 35 } 36 } 37 38 if (!addedEvents.length || addedEvents.length === newEvents.length) { 39 return; 40 } 41 42 { 43 let i = addedEvents.length; 44 while (i--) { 45 newEvents.splice(addedEventsIndexes[i], 1); 46 } 47 } 48 49 newEvents.unshift(...addedEvents); 50 }; 51 52 const tryGetEventListeners = ( 53 logger: Logger, 54 node: JQuery, 55 eventKey: string, 56 ): JQueryEvent[] | undefined => { 57 try { 58 const maybeEvents = node.data('events')?.[eventKey]; 59 return Array.isArray(maybeEvents) ? maybeEvents : undefined; 60 } catch (err) { 61 logger 62 .getChildLogger('prependJqListener') 63 .error('failed to get', eventKey, 'jQuery events:', err); 64 } 65 };