// DOM events export interface PhilomenaAvailableEventsMap { dragstart: DragEvent, dragover: DragEvent, dragenter: DragEvent, dragleave: DragEvent, dragend: DragEvent, drop: DragEvent, click: MouseEvent, submit: Event, reset: Event } export interface PhilomenaEventElement { addEventListener( type: K, // eslint-disable-next-line @typescript-eslint/no-explicit-any listener: (this: Document | HTMLElement, ev: PhilomenaAvailableEventsMap[K]) => any, options?: boolean | AddEventListenerOptions | undefined ): void; } export function fire(el: El, event: string, detail: D) { el.dispatchEvent(new CustomEvent(event, { detail, bubbles: true, cancelable: true })); } export function on( node: PhilomenaEventElement, event: K, selector: string, func: ((e: PhilomenaAvailableEventsMap[K], target: Element) => boolean) ) { delegate(node, event, { [selector]: func }); } export function leftClick(func: (e: E, t: Target) => void) { return (event: E, target: Target) => { if (event.button === 0) return func(event, target); }; } export function delegate( node: PhilomenaEventElement, event: K, selectors: Record void | boolean)> ) { node.addEventListener(event, e => { for (const selector in selectors) { const evtTarget = e.target as EventTarget | Target | null; if (evtTarget && 'closest' in evtTarget && typeof evtTarget.closest === 'function') { const target = evtTarget.closest(selector) as Target; if (target && selectors[selector](e, target) === false) break; } } }); }