|
|
/*! * Bootstrap event-handler.js v5.1.3 (https://getbootstrap.com/)
* Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.EventHandler = factory()); })(this, (function () { 'use strict';
/** * -------------------------------------------------------------------------- * Bootstrap (v5.1.3): util/index.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- */
const getjQuery = () => { const { jQuery } = window;
if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) { return jQuery; }
return null; };
/** * -------------------------------------------------------------------------- * Bootstrap (v5.1.3): dom/event-handler.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* -------------------------------------------------------------------------- */ /** * ------------------------------------------------------------------------ * Constants * ------------------------------------------------------------------------ */
const namespaceRegex = /[^.]*(?=\..*)\.|.*/; const stripNameRegex = /\..*/; const stripUidRegex = /::\d+$/; const eventRegistry = {}; // Events storage
let uidEvent = 1; const customEvents = { mouseenter: 'mouseover', mouseleave: 'mouseout' }; const customEventsRegex = /^(mouseenter|mouseleave)/i; const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']); /** * ------------------------------------------------------------------------ * Private methods * ------------------------------------------------------------------------ */
function getUidEvent(element, uid) { return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++; }
function getEvent(element) { const uid = getUidEvent(element); element.uidEvent = uid; eventRegistry[uid] = eventRegistry[uid] || {}; return eventRegistry[uid]; }
function bootstrapHandler(element, fn) { return function handler(event) { event.delegateTarget = element;
if (handler.oneOff) { EventHandler.off(element, event.type, fn); }
return fn.apply(element, [event]); }; }
function bootstrapDelegationHandler(element, selector, fn) { return function handler(event) { const domElements = element.querySelectorAll(selector);
for (let { target } = event; target && target !== this; target = target.parentNode) { for (let i = domElements.length; i--;) { if (domElements[i] === target) { event.delegateTarget = target;
if (handler.oneOff) { EventHandler.off(element, event.type, selector, fn); }
return fn.apply(target, [event]); } } } // To please ESLint
return null; }; }
function findHandler(events, handler, delegationSelector = null) { const uidEventList = Object.keys(events);
for (let i = 0, len = uidEventList.length; i < len; i++) { const event = events[uidEventList[i]];
if (event.originalHandler === handler && event.delegationSelector === delegationSelector) { return event; } }
return null; }
function normalizeParams(originalTypeEvent, handler, delegationFn) { const delegation = typeof handler === 'string'; const originalHandler = delegation ? delegationFn : handler; let typeEvent = getTypeEvent(originalTypeEvent); const isNative = nativeEvents.has(typeEvent);
if (!isNative) { typeEvent = originalTypeEvent; }
return [delegation, originalHandler, typeEvent]; }
function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) { if (typeof originalTypeEvent !== 'string' || !element) { return; }
if (!handler) { handler = delegationFn; delegationFn = null; } // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
// this prevents the handler from being dispatched the same way as mouseover or mouseout does
if (customEventsRegex.test(originalTypeEvent)) { const wrapFn = fn => { return function (event) { if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) { return fn.call(this, event); } }; };
if (delegationFn) { delegationFn = wrapFn(delegationFn); } else { handler = wrapFn(handler); } }
const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn); const events = getEvent(element); const handlers = events[typeEvent] || (events[typeEvent] = {}); const previousFn = findHandler(handlers, originalHandler, delegation ? handler : null);
if (previousFn) { previousFn.oneOff = previousFn.oneOff && oneOff; return; }
const uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, '')); const fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler); fn.delegationSelector = delegation ? handler : null; fn.originalHandler = originalHandler; fn.oneOff = oneOff; fn.uidEvent = uid; handlers[uid] = fn; element.addEventListener(typeEvent, fn, delegation); }
function removeHandler(element, events, typeEvent, handler, delegationSelector) { const fn = findHandler(events[typeEvent], handler, delegationSelector);
if (!fn) { return; }
element.removeEventListener(typeEvent, fn, Boolean(delegationSelector)); delete events[typeEvent][fn.uidEvent]; }
function removeNamespacedHandlers(element, events, typeEvent, namespace) { const storeElementEvent = events[typeEvent] || {}; Object.keys(storeElementEvent).forEach(handlerKey => { if (handlerKey.includes(namespace)) { const event = storeElementEvent[handlerKey]; removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector); } }); }
function getTypeEvent(event) { // allow to get the native events from namespaced events ('click.bs.button' --> 'click')
event = event.replace(stripNameRegex, ''); return customEvents[event] || event; }
const EventHandler = { on(element, event, handler, delegationFn) { addHandler(element, event, handler, delegationFn, false); },
one(element, event, handler, delegationFn) { addHandler(element, event, handler, delegationFn, true); },
off(element, originalTypeEvent, handler, delegationFn) { if (typeof originalTypeEvent !== 'string' || !element) { return; }
const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn); const inNamespace = typeEvent !== originalTypeEvent; const events = getEvent(element); const isNamespace = originalTypeEvent.startsWith('.');
if (typeof originalHandler !== 'undefined') { // Simplest case: handler is passed, remove that listener ONLY.
if (!events || !events[typeEvent]) { return; }
removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null); return; }
if (isNamespace) { Object.keys(events).forEach(elementEvent => { removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)); }); }
const storeElementEvent = events[typeEvent] || {}; Object.keys(storeElementEvent).forEach(keyHandlers => { const handlerKey = keyHandlers.replace(stripUidRegex, '');
if (!inNamespace || originalTypeEvent.includes(handlerKey)) { const event = storeElementEvent[keyHandlers]; removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector); } }); },
trigger(element, event, args) { if (typeof event !== 'string' || !element) { return null; }
const $ = getjQuery(); const typeEvent = getTypeEvent(event); const inNamespace = event !== typeEvent; const isNative = nativeEvents.has(typeEvent); let jQueryEvent; let bubbles = true; let nativeDispatch = true; let defaultPrevented = false; let evt = null;
if (inNamespace && $) { jQueryEvent = $.Event(event, args); $(element).trigger(jQueryEvent); bubbles = !jQueryEvent.isPropagationStopped(); nativeDispatch = !jQueryEvent.isImmediatePropagationStopped(); defaultPrevented = jQueryEvent.isDefaultPrevented(); }
if (isNative) { evt = document.createEvent('HTMLEvents'); evt.initEvent(typeEvent, bubbles, true); } else { evt = new CustomEvent(event, { bubbles, cancelable: true }); } // merge custom information in our event
if (typeof args !== 'undefined') { Object.keys(args).forEach(key => { Object.defineProperty(evt, key, { get() { return args[key]; }
}); }); }
if (defaultPrevented) { evt.preventDefault(); }
if (nativeDispatch) { element.dispatchEvent(evt); }
if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') { jQueryEvent.preventDefault(); }
return evt; }
};
return EventHandler;
})); //# sourceMappingURL=event-handler.js.map
|