UNPKG

@lookwe/lui

Version:

Lookwe UI web components

63 lines (60 loc) 2.14 kB
import { nextMicrotask } from '@lookwe/utils/event-loop'; function isActivationClick(event) { // Event must start at the event target. if (event.currentTarget !== event.target) { return false; } // Event must not be retargeted from shadowRoot. if (event.composedPath()[0] !== event.target) { return false; } // Target must not be disabled; this should only occur for a synthetically // dispatched click. if (event.target.disabled) { return false; } return true; } function dispatchActivationClick(element) { const event = new MouseEvent('click', { bubbles: true }); element.dispatchEvent(event); return event; } function addActivationListener(root, delegateElement, options = {}) { root.addEventListener('click', (event) => { if (options.check?.(event) === false) return; if (event.defaultPrevented) return; const element = delegateElement(); if (!isActivationClick(event) || squelchEventFix(event) || !element) return; if (options.focus !== false) root.focus(); dispatchActivationClick(element); }, { capture: true }); } // TODO(https://bugzilla.mozilla.org/show_bug.cgi?id=1804576) // Remove when Firefox bug is addressed. const isSquelchingEventTargets = new Set(); function squelchEventFix(event) { // `Event.explicitOriginalTarget` only exists in Firefox const eventTarget = event.explicitOriginalTarget ?? null; if (!eventTarget) return false; const squelched = isSquelchingEventTargets.has(eventTarget); if (squelched) { event.preventDefault(); event.stopImmediatePropagation(); } squelchEventsForMicrotask(eventTarget); return squelched; } // Ignore events for one microtask only. async function squelchEventsForMicrotask(eventTarget) { isSquelchingEventTargets.add(eventTarget); // Need to pause for just one microtask. await nextMicrotask(); isSquelchingEventTargets.delete(eventTarget); } export { addActivationListener, dispatchActivationClick, isActivationClick };