mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-30 14:57:59 +01:00
56 lines
1.9 KiB
TypeScript
56 lines
1.9 KiB
TypeScript
// DOM events
|
|
|
|
import '../../types/ujs';
|
|
|
|
export interface PhilomenaAvailableEventsMap {
|
|
dragstart: DragEvent,
|
|
dragover: DragEvent,
|
|
dragenter: DragEvent,
|
|
dragleave: DragEvent,
|
|
dragend: DragEvent,
|
|
drop: DragEvent,
|
|
click: MouseEvent,
|
|
submit: Event,
|
|
reset: Event,
|
|
fetchcomplete: FetchcompleteEvent
|
|
}
|
|
|
|
export interface PhilomenaEventElement {
|
|
addEventListener<K extends keyof PhilomenaAvailableEventsMap>(
|
|
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 extends Element, D>(el: El, event: string, detail: D) {
|
|
el.dispatchEvent(new CustomEvent<D>(event, { detail, bubbles: true, cancelable: true }));
|
|
}
|
|
|
|
export function on<K extends keyof PhilomenaAvailableEventsMap>(
|
|
node: PhilomenaEventElement,
|
|
event: K, selector: string, func: ((e: PhilomenaAvailableEventsMap[K], target: Element) => boolean)
|
|
) {
|
|
delegate(node, event, { [selector]: func });
|
|
}
|
|
|
|
export function leftClick<E extends MouseEvent, Target extends EventTarget>(func: (e: E, t: Target) => void) {
|
|
return (event: E, target: Target) => { if (event.button === 0) return func(event, target); };
|
|
}
|
|
|
|
export function delegate<K extends keyof PhilomenaAvailableEventsMap, Target extends Element>(
|
|
node: PhilomenaEventElement,
|
|
event: K,
|
|
selectors: Record<string, ((e: PhilomenaAvailableEventsMap[K], target: Target) => 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;
|
|
}
|
|
}
|
|
});
|
|
}
|