/*! * @thednp/shorty ESM v2.0.14 (https://github.com/thednp/shorty) * Copyright 2026 © thednp * Licensed under MIT (https://github.com/thednp/shorty/blob/master/LICENSE) */ //#region package.json var version = "2.0.14"; //#endregion //#region src/strings/ariaChecked.ts /** * A global namespace for aria-checked. */ const ariaChecked = "aria-checked"; //#endregion //#region src/strings/ariaDescription.ts /** * A global namespace for aria-description. */ const ariaDescription = "aria-description"; //#endregion //#region src/strings/ariaDescribedBy.ts /** * A global namespace for aria-describedby. */ const ariaDescribedBy = "aria-describedby"; //#endregion //#region src/strings/ariaExpanded.ts /** * A global namespace for aria-expanded. */ const ariaExpanded = "aria-expanded"; //#endregion //#region src/strings/ariaHasPopup.ts /** * A global namespace for aria-haspopup. */ const ariaHasPopup = "aria-haspopup"; //#endregion //#region src/strings/ariaHidden.ts /** * A global namespace for aria-hidden. */ const ariaHidden = "aria-hidden"; //#endregion //#region src/strings/ariaLabel.ts /** * A global namespace for aria-label. */ const ariaLabel = "aria-label"; //#endregion //#region src/strings/ariaLabelledBy.ts /** * A global namespace for aria-labelledby. */ const ariaLabelledBy = "aria-labelledby"; //#endregion //#region src/strings/ariaModal.ts /** * A global namespace for aria-modal. */ const ariaModal = "aria-modal"; //#endregion //#region src/strings/ariaPressed.ts /** * A global namespace for aria-pressed. */ const ariaPressed = "aria-pressed"; //#endregion //#region src/strings/ariaSelected.ts /** * A global namespace for aria-selected. */ const ariaSelected = "aria-selected"; //#endregion //#region src/strings/ariaValueMin.ts /** * A global namespace for aria-valuemin. */ const ariaValueMin = "aria-valuemin"; //#endregion //#region src/strings/ariaValueMax.ts /** * A global namespace for aria-valuemax. */ const ariaValueMax = "aria-valuemax"; //#endregion //#region src/strings/ariaValueNow.ts /** * A global namespace for aria-valuenow. */ const ariaValueNow = "aria-valuenow"; //#endregion //#region src/strings/ariaValueText.ts /** * A global namespace for aria-valuetext. */ const ariaValueText = "aria-valuetext"; //#endregion //#region src/strings/abortEvent.ts /** * A global namespace for `abort` event. */ const abortEvent = "abort"; //#endregion //#region src/strings/beforeunloadEvent.ts /** * A global namespace for `beforeunload` event. */ const beforeunloadEvent = "beforeunload"; //#endregion //#region src/strings/blurEvent.ts /** * A global namespace for `blur` event. */ const blurEvent = "blur"; //#endregion //#region src/strings/changeEvent.ts /** * A global namespace for `change` event. */ const changeEvent = "change"; //#endregion //#region src/strings/contextmenuEvent.ts /** * A global namespace for `contextmenu` event. */ const contextmenuEvent = "contextmenu"; //#endregion //#region src/strings/DOMContentLoadedEvent.ts /** * A global namespace for `DOMContentLoaded` event. */ const DOMContentLoadedEvent = "DOMContentLoaded"; //#endregion //#region src/strings/DOMMouseScrollEvent.ts /** * A global namespace for `DOMMouseScroll` event. */ const DOMMouseScrollEvent = "DOMMouseScroll"; //#endregion //#region src/strings/errorEvent.ts /** * A global namespace for `error` event. */ const errorEvent = "error"; //#endregion //#region src/strings/focusEvent.ts /** * A global namespace for `focus` event. */ const focusEvent = "focus"; //#endregion //#region src/strings/focusinEvent.ts /** * A global namespace for `focusin` event. */ const focusinEvent = "focusin"; //#endregion //#region src/strings/focusoutEvent.ts /** * A global namespace for `focusout` event. */ const focusoutEvent = "focusout"; //#endregion //#region src/strings/gesturechangeEvent.ts /** * A global namespace for `gesturechange` event. */ const gesturechangeEvent = "gesturechange"; //#endregion //#region src/strings/gestureendEvent.ts /** * A global namespace for `gestureend` event. */ const gestureendEvent = "gestureend"; //#endregion //#region src/strings/gesturestartEvent.ts /** * A global namespace for `gesturestart` event. */ const gesturestartEvent = "gesturestart"; //#endregion //#region src/strings/keydownEvent.ts /** * A global namespace for `keydown` event. */ const keydownEvent = "keydown"; //#endregion //#region src/strings/keypressEvent.ts /** * A global namespace for `keypress` event. */ const keypressEvent = "keypress"; //#endregion //#region src/strings/keyupEvent.ts /** * A global namespace for `keyup` event. */ const keyupEvent = "keyup"; //#endregion //#region src/strings/loadEvent.ts /** * A global namespace for `load` event. */ const loadEvent = "load"; //#endregion //#region src/strings/mouseclickEvent.ts /** * A global namespace for `click` event. */ const mouseclickEvent = "click"; //#endregion //#region src/strings/mousedblclickEvent.ts /** * A global namespace for `dblclick` event. */ const mousedblclickEvent = "dblclick"; //#endregion //#region src/strings/mousedownEvent.ts /** * A global namespace for `mousedown` event. */ const mousedownEvent = "mousedown"; //#endregion //#region src/strings/mouseupEvent.ts /** * A global namespace for `mouseup` event. */ const mouseupEvent = "mouseup"; //#endregion //#region src/strings/mousehoverEvent.ts /** * A global namespace for `hover` event. */ const mousehoverEvent = "hover"; //#endregion //#region src/strings/mouseenterEvent.ts /** * A global namespace for `mouseenter` event. */ const mouseenterEvent = "mouseenter"; //#endregion //#region src/strings/mouseleaveEvent.ts /** * A global namespace for `mouseleave` event. */ const mouseleaveEvent = "mouseleave"; //#endregion //#region src/strings/mouseinEvent.ts /** * A global namespace for `mousein` event. */ const mouseinEvent = "mousein"; //#endregion //#region src/strings/mouseoutEvent.ts /** * A global namespace for `mouseout` event. */ const mouseoutEvent = "mouseout"; //#endregion //#region src/strings/mouseoverEvent.ts /** * A global namespace for `mouseover` event. */ const mouseoverEvent = "mouseover"; //#endregion //#region src/strings/mousemoveEvent.ts /** * A global namespace for `mousemove` event. */ const mousemoveEvent = "mousemove"; //#endregion //#region src/strings/mousewheelEvent.ts /** * A global namespace for `mousewheel` event. */ const mousewheelEvent = "mousewheel"; //#endregion //#region src/strings/moveEvent.ts /** * A global namespace for `move` event. */ const moveEvent = "move"; //#endregion //#region src/strings/orientationchangeEvent.ts /** * A global namespace for `orientationchange` event. */ const orientationchangeEvent = "orientationchange"; //#endregion //#region src/strings/pointercancelEvent.ts /** * A global namespace for `pointercancel` event. */ const pointercancelEvent = "pointercancel"; //#endregion //#region src/strings/pointerdownEvent.ts /** * A global namespace for `pointerdown` event. */ const pointerdownEvent = "pointerdown"; //#endregion //#region src/strings/pointerleaveEvent.ts /** * A global namespace for `pointerleave` event. */ const pointerleaveEvent = "pointerleave"; //#endregion //#region src/strings/pointermoveEvent.ts /** * A global namespace for `pointermove` event. */ const pointermoveEvent = "pointermove"; //#endregion //#region src/strings/pointerupEvent.ts /** * A global namespace for `pointerup` event. */ const pointerupEvent = "pointerup"; //#endregion //#region src/strings/readystatechangeEvent.ts /** * A global namespace for `readystatechange` event. */ const readystatechangeEvent = "readystatechange"; //#endregion //#region src/strings/resetEvent.ts /** * A global namespace for `reset` event. */ const resetEvent = "reset"; //#endregion //#region src/strings/resizeEvent.ts /** * A global namespace for `resize` event. */ const resizeEvent = "resize"; //#endregion //#region src/strings/selectEvent.ts /** * A global namespace for `select` event. */ const selectEvent = "select"; //#endregion //#region src/strings/selectendEvent.ts /** * A global namespace for the `selectend` event. */ const selectendEvent = "selectend"; //#endregion //#region src/strings/selectstartEvent.ts /** * A global namespace for the `selectstart` event. */ const selectstartEvent = "selectstart"; //#endregion //#region src/strings/scrollEvent.ts /** * A global namespace for `scroll` event. */ const scrollEvent = "scroll"; //#endregion //#region src/strings/submitEvent.ts /** * A global namespace for `submit` event. */ const submitEvent = "submit"; //#endregion //#region src/strings/touchstartEvent.ts /** * A global namespace for `touchstart` event. */ const touchstartEvent = "touchstart"; //#endregion //#region src/strings/touchmoveEvent.ts /** * A global namespace for `touchmove` event. */ const touchmoveEvent = "touchmove"; //#endregion //#region src/strings/touchcancelEvent.ts /** * A global namespace for `touchcancel` event. */ const touchcancelEvent = "touchcancel"; //#endregion //#region src/strings/touchendEvent.ts /** * A global namespace for `touchend` event. */ const touchendEvent = "touchend"; //#endregion //#region src/strings/unloadEvent.ts /** * A global namespace for `unload` event. */ const unloadEvent = "unload"; //#endregion //#region src/strings/nativeEvents.ts /** * A global namespace for all browser native events. */ const nativeEvents = { DOMContentLoaded: DOMContentLoadedEvent, DOMMouseScroll: DOMMouseScrollEvent, abort: abortEvent, beforeunload: beforeunloadEvent, blur: blurEvent, change: changeEvent, click: mouseclickEvent, contextmenu: contextmenuEvent, dblclick: mousedblclickEvent, error: errorEvent, focus: focusEvent, focusin: focusinEvent, focusout: focusoutEvent, gesturechange: gesturechangeEvent, gestureend: gestureendEvent, gesturestart: gesturestartEvent, hover: mousehoverEvent, keydown: keydownEvent, keypress: keypressEvent, keyup: keyupEvent, load: loadEvent, mousedown: mousedownEvent, mousemove: mousemoveEvent, mousein: mouseinEvent, mouseout: mouseoutEvent, mouseenter: mouseenterEvent, mouseleave: mouseleaveEvent, mouseover: mouseoverEvent, mouseup: mouseupEvent, mousewheel: mousewheelEvent, move: moveEvent, orientationchange: orientationchangeEvent, pointercancel: pointercancelEvent, pointerdown: pointerdownEvent, pointerleave: pointerleaveEvent, pointermove: pointermoveEvent, pointerup: pointerupEvent, readystatechange: readystatechangeEvent, reset: resetEvent, resize: resizeEvent, scroll: scrollEvent, select: selectEvent, selectend: selectendEvent, selectstart: selectstartEvent, submit: submitEvent, touchcancel: touchcancelEvent, touchend: touchendEvent, touchmove: touchmoveEvent, touchstart: touchstartEvent, unload: unloadEvent }; //#endregion //#region src/strings/dragEvent.ts /** * A global namespace for `drag` event. */ const dragEvent = "drag"; //#endregion //#region src/strings/dragstartEvent.ts /** * A global namespace for `dragstart` event. */ const dragstartEvent = "dragstart"; //#endregion //#region src/strings/dragenterEvent.ts /** * A global namespace for `dragenter` event. */ const dragenterEvent = "dragenter"; //#endregion //#region src/strings/dragleaveEvent.ts /** * A global namespace for `dragleave` event. */ const dragleaveEvent = "dragleave"; //#endregion //#region src/strings/dragoverEvent.ts /** * A global namespace for `dragover` event. */ const dragoverEvent = "dragover"; //#endregion //#region src/strings/dragendEvent.ts /** * A global namespace for `dragend` event. */ const dragendEvent = "dragend"; //#endregion //#region src/strings/loadstartEvent.ts /** * A global namespace for `loadstart` event. */ const loadstartEvent = "loadstart"; //#endregion //#region src/strings/mouseSwipeEvents.ts /** * A global namespace for mouse events equivalent to touch events. */ const mouseSwipeEvents = { start: "mousedown", end: "mouseup", move: "mousemove", cancel: "mouseleave" }; //#endregion //#region src/strings/mouseClickEvents.ts /** * A global namespace for mouse click events. */ const mouseClickEvents = { down: "mousedown", up: "mouseup" }; //#endregion //#region src/strings/mouseHoverEvents.ts /** * A global namespace for mouse hover events. */ const mouseHoverEvents = "onmouseleave" in document ? ["mouseenter", "mouseleave"] : ["mouseover", "mouseout"]; //#endregion //#region src/strings/touchEvents.ts /** * A global namespace for touch events. */ const touchEvents = { start: "touchstart", end: "touchend", move: "touchmove", cancel: "touchcancel" }; //#endregion //#region src/strings/focusEvents.ts /** * A global namespace for focus event names. */ const focusEvents = { in: "focusin", out: "focusout" }; //#endregion //#region src/strings/focusableSelector.ts const focusableSelector = "a[href], button, input, textarea, select, details, [tabindex]:not([tabindex=\"-1\"]"; //#endregion //#region src/strings/keyboardEventKeys.ts /** * A global namespace for keyboard event keys. */ const keyboardEventKeys = { Backspace: "Backspace", Tab: "Tab", Enter: "Enter", Shift: "Shift", Control: "Control", Alt: "Alt", Pause: "Pause", CapsLock: "CapsLock", Escape: "Escape", Scape: "Space", ArrowLeft: "ArrowLeft", ArrowUp: "ArrowUp", ArrowRight: "ArrowRight", ArrowDown: "ArrowDown", Insert: "Insert", Delete: "Delete", Meta: "Meta", ContextMenu: "ContextMenu", ScrollLock: "ScrollLock" }; //#endregion //#region src/strings/keyAlt.ts /** * A global namespace for `Alt` key. * e.which = 18 */ const keyAlt = "Alt"; //#endregion //#region src/strings/keyArrowDown.ts /** * A global namespace for `ArrowDown` key. * e.which = 40 equivalent */ const keyArrowDown = "ArrowDown"; //#endregion //#region src/strings/keyArrowUp.ts /** * A global namespace for `ArrowUp` key. * e.which = 38 equivalent */ const keyArrowUp = "ArrowUp"; //#endregion //#region src/strings/keyArrowLeft.ts /** * A global namespace for `ArrowLeft` key. * e.which = 37 equivalent */ const keyArrowLeft = "ArrowLeft"; //#endregion //#region src/strings/keyArrowRight.ts /** * A global namespace for `ArrowRight` key. * e.which = 39 equivalent */ const keyArrowRight = "ArrowRight"; //#endregion //#region src/strings/keyBackspace.ts /** * A global namespace for `Backspace` key. * e.which === 8 equivalent */ const keyBackspace = "Backspace"; //#endregion //#region src/strings/keyCapsLock.ts /** * A global namespace for `CapsLock` key. * e.which = 20 equivalent */ const keyCapsLock = "CapsLock"; //#endregion //#region src/strings/keyControl.ts /** * A global namespace for `Control` key. * e.which = 17 */ const keyControl = "Control"; //#endregion //#region src/strings/keyDelete.ts /** * A global namespace for `Delete` key. * e.which = 46 equivalent */ const keyDelete = "Delete"; //#endregion //#region src/strings/keyEnter.ts /** * A global namespace for `Enter` key. * e.which = 13 equivalent */ const keyEnter = "Enter"; //#endregion //#region src/strings/keyNumpadEnter.ts /** * A global namespace for `Enter` key. * e.which = 13 equivalent */ const keyNumpadEnter = "NumpadEnter"; //#endregion //#region src/strings/keyEscape.ts /** * A global namespace for `Escape` key. * e.which = 27 equivalent */ const keyEscape = "Escape"; //#endregion //#region src/strings/keyInsert.ts /** * A global namespace for `Insert` key. * e.which = 45 equivalent */ const keyInsert = "Insert"; //#endregion //#region src/strings/keyMeta.ts /** * A global namespace for `Meta` key. * e.which = 93 equivalent */ const keyMeta = "Meta"; //#endregion //#region src/strings/keyPause.ts /** * A global namespace for `Pause` key. * e.which = 19 */ const keyPause = "Pause"; //#endregion //#region src/strings/keyScrollLock.ts /** * A global namespace for `ScrollLock` key. * e.which = 145 equivalent */ const keyScrollLock = "ScrollLock"; //#endregion //#region src/strings/keyShift.ts /** * A global namespace for `Shift` key. * e.which = 16 */ const keyShift = "Shift"; //#endregion //#region src/strings/keySpace.ts /** * A global namespace for `Space` key. * e.which = 32 equivalent */ const keySpace = "Space"; //#endregion //#region src/strings/keyTab.ts /** * A global namespace for `Tab` key. * e.which = 9 equivalent */ const keyTab = "Tab"; //#endregion //#region src/strings/animationDuration.ts /** * A global namespace for 'animationDuration' string. */ const animationDuration = "animationDuration"; //#endregion //#region src/strings/animationDelay.ts /** * A global namespace for 'animationDelay' string. */ const animationDelay = "animationDelay"; //#endregion //#region src/strings/animationName.ts /** * A global namespace for 'animationName' string. */ const animationName = "animationName"; //#endregion //#region src/strings/animationEndEvent.ts /** * A global namespace for 'animationend' string. */ const animationEndEvent = "animationend"; //#endregion //#region src/strings/transitionDuration.ts /** * A global namespace for 'transitionDuration' string. */ const transitionDuration = "transitionDuration"; //#endregion //#region src/strings/transitionDelay.ts /** * A global namespace for 'transitionDelay' string. */ const transitionDelay = "transitionDelay"; //#endregion //#region src/strings/transitionEndEvent.ts /** * A global namespace for 'transitionend' string. */ const transitionEndEvent = "transitionend"; //#endregion //#region src/strings/transitionProperty.ts /** * A global namespace for `transitionProperty` string for modern browsers. */ const transitionProperty = "transitionProperty"; //#endregion //#region src/strings/addEventListener.ts /** * A global namespace for 'addEventListener' string. */ const addEventListener = "addEventListener"; //#endregion //#region src/strings/removeEventListener.ts /** * A global namespace for 'removeEventListener' string. */ const removeEventListener = "removeEventListener"; //#endregion //#region src/strings/bezierEasings.ts /** * A global namespace for predefined * CSS3 'cubic-bezier()' easing functions. */ const bezierEasings = { linear: "linear", easingSinusoidalIn: "cubic-bezier(0.47,0,0.745,0.715)", easingSinusoidalOut: "cubic-bezier(0.39,0.575,0.565,1)", easingSinusoidalInOut: "cubic-bezier(0.445,0.05,0.55,0.95)", easingQuadraticIn: "cubic-bezier(0.550,0.085,0.680,0.530)", easingQuadraticOut: "cubic-bezier(0.250,0.460,0.450,0.940)", easingQuadraticInOut: "cubic-bezier(0.455,0.030,0.515,0.955)", easingCubicIn: "cubic-bezier(0.55,0.055,0.675,0.19)", easingCubicOut: "cubic-bezier(0.215,0.61,0.355,1)", easingCubicInOut: "cubic-bezier(0.645,0.045,0.355,1)", easingQuarticIn: "cubic-bezier(0.895,0.03,0.685,0.22)", easingQuarticOut: "cubic-bezier(0.165,0.84,0.44,1)", easingQuarticInOut: "cubic-bezier(0.77,0,0.175,1)", easingQuinticIn: "cubic-bezier(0.755,0.05,0.855,0.06)", easingQuinticOut: "cubic-bezier(0.23,1,0.32,1)", easingQuinticInOut: "cubic-bezier(0.86,0,0.07,1)", easingExponentialIn: "cubic-bezier(0.95,0.05,0.795,0.035)", easingExponentialOut: "cubic-bezier(0.19,1,0.22,1)", easingExponentialInOut: "cubic-bezier(1,0,0,1)", easingCircularIn: "cubic-bezier(0.6,0.04,0.98,0.335)", easingCircularOut: "cubic-bezier(0.075,0.82,0.165,1)", easingCircularInOut: "cubic-bezier(0.785,0.135,0.15,0.86)", easingBackIn: "cubic-bezier(0.6,-0.28,0.735,0.045)", easingBackOut: "cubic-bezier(0.175,0.885,0.32,1.275)", easingBackInOut: "cubic-bezier(0.68,-0.55,0.265,1.55)" }; //#endregion //#region src/strings/offsetHeight.ts /** * A global namespace for `offsetHeight` property. */ const offsetHeight = "offsetHeight"; //#endregion //#region src/strings/offsetWidth.ts /** * A global namespace for `offsetWidth` property. */ const offsetWidth = "offsetWidth"; //#endregion //#region src/strings/scrollHeight.ts /** * A global namespace for `scrollHeight` property. */ const scrollHeight = "scrollHeight"; //#endregion //#region src/strings/scrollWidth.ts /** * A global namespace for `scrollWidth` property. */ const scrollWidth = "scrollWidth"; //#endregion //#region src/strings/tabindex.ts /** * A global namespace for `touchcancel` event. */ const tabindex = "tabindex"; //#endregion //#region src/strings/userAgentData.ts /** * A global namespace for `userAgentData` object. */ const userAgentData = navigator.userAgentData; //#endregion //#region src/strings/userAgent.ts const { userAgent: userAgentString } = navigator; /** * A global namespace for `navigator.userAgent` string. */ const userAgent = userAgentString; //#endregion //#region src/boolean/isMobile.ts /** * An accessor that checks for mobile detection. */ const isMobile = () => { const mobileBrands = /iPhone|iPad|iPod|Android/i; return navigator?.userAgentData?.brands.some((x) => mobileBrands.test(x.brand)) || mobileBrands.test(navigator?.userAgent) || false; }; //#endregion //#region src/boolean/isApple.ts /** * An accessor that checks for Apple browsers. */ const isApple = () => { const appleBrands = /(iPhone|iPod|iPad)/; return navigator?.userAgentData?.brands.some((x) => appleBrands.test(x.brand)) || appleBrands.test(navigator?.userAgent) || false; }; //#endregion //#region src/boolean/isFirefox.ts /** * An accessor that checks for Gecko browsers. When writing this file, * Gecko was not supporting `userAgentData`. */ const isFirefox = () => navigator?.userAgent?.includes("Firefox") || false; //#endregion //#region src/boolean/isWebKit.ts const isWebKit = () => { if (typeof CSS === "undefined" || !CSS.supports) return false; return CSS.supports("-webkit-backdrop-filter", "none"); }; //#endregion //#region src/boolean/support3DTransform.ts /** * An accessor that checks for CSS3 3D transform support. */ const support3DTransform = () => ["webkitPerspective", "perspective"].some((p) => p in document.head.style); //#endregion //#region src/misc/noop.ts /** A generic function with empty body. */ const noop = () => {}; //#endregion //#region src/event/on.ts /** * Add eventListener to an `EventTarget` object. */ const on = (element, eventName, listener, options) => { const ops = options || false; element.addEventListener(eventName, listener, ops); }; //#endregion //#region src/event/off.ts /** * Remove eventListener from an `EventTarget` object. */ const off = (element, eventName, listener, options) => { const ops = options || false; element.removeEventListener(eventName, listener, ops); }; //#endregion //#region src/event/one.ts /** * Add an `eventListener` to an `EventTarget` * element and remove it once callback is called. */ const one = (element, eventName, listener, options) => { /** Wrap the listener for easy on -> off */ const handlerWrapper = (e) => { if (e.target === element || e.currentTarget === element) { listener.apply(element, [e]); off(element, eventName, handlerWrapper, options); } }; on(element, eventName, handlerWrapper, options); }; //#endregion //#region src/boolean/supportPassive.ts /** * An accessor that checks for passive events support, * in general event options are not suited for scroll prevention. * * @see https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection */ const supportPassive = () => { let result = false; try { const opts = Object.defineProperty({}, "passive", { get: () => { result = true; return result; } }); one(document, DOMContentLoadedEvent, noop, opts); } catch (_e) {} return result; }; //#endregion //#region src/boolean/supportTransform.ts /** * An accessor that checks for CSS3 transform support. */ const supportTransform = () => ["webkitTransform", "transform"].some((p) => p in document.head.style); //#endregion //#region src/boolean/supportTouch.ts /** * An accessor that checks for touch events support. */ const supportTouch = () => "ontouchstart" in window || "msMaxTouchPoints" in navigator; //#endregion //#region src/boolean/supportAnimation.ts /** * An accessor that checks for CSS3 animation support. */ const supportAnimation = () => ["webkitAnimation", "animation"].some((p) => p in document.head.style); //#endregion //#region src/boolean/supportTransition.ts /** * An accessor that checks for CSS3 transition support. */ const supportTransition = () => ["webkitTransition", "transition"].some((p) => p in document.head.style); //#endregion //#region src/attr/getAttribute.ts /** * Shortcut for `Element.getAttribute()` method. * * @param element target element * @param att attribute name * @returns attribute value */ const getAttribute = (element, att) => element.getAttribute(att); //#endregion //#region src/attr/getAttributeNS.ts /** * Shortcut for `Element.getAttributeNS()` method. * * @param ns attribute namespace * @param element target element * @param att attribute name * @returns attribute value */ const getAttributeNS = (ns, element, att) => element.getAttributeNS(ns, att); //#endregion //#region src/attr/hasAttribute.ts /** * Shortcut for `Element.hasAttribute()` method. * * @param element target element * @param att attribute name * @returns the query result */ const hasAttribute = (element, att) => element.hasAttribute(att); //#endregion //#region src/attr/hasAttributeNS.ts /** * Shortcut for `Element.hasAttributeNS()` method. * * @param ns attribute namespace * @param element target element * @param att attribute name * @returns the query result */ const hasAttributeNS = (ns, element, att) => element.hasAttributeNS(ns, att); //#endregion //#region src/attr/setAttribute.ts /** * Shortcut for `Element.setAttribute()` method. * * @param element target element * @param att attribute name * @param value attribute value */ const setAttribute = (element, att, value) => element.setAttribute(att, value); //#endregion //#region src/attr/setAttributeNS.ts /** * Shortcut for `Element.setAttributeNS()` method. * * @param ns attribute namespace * @param element target element * @param att attribute name * @param value attribute value */ const setAttributeNS = (ns, element, att, value) => element.setAttributeNS(ns, att, value); //#endregion //#region src/attr/removeAttribute.ts /** * Shortcut for `Element.removeAttribute()` method. * * @param element target element * @param att attribute name */ const removeAttribute = (element, att) => element.removeAttribute(att); //#endregion //#region src/attr/removeAttributeNS.ts /** * Shortcut for `Element.removeAttributeNS()` method. * * @param ns attribute namespace * @param element target element * @param att attribute name */ const removeAttributeNS = (ns, element, att) => element.removeAttributeNS(ns, att); //#endregion //#region src/class/addClass.ts /** * Add one or more CSS classes to `Element.classList`. * * @param element target * @param classNAME to add */ const addClass = (element, ...classNAME) => { element.classList.add(...classNAME); }; //#endregion //#region src/class/removeClass.ts /** * Remove one or more classes from `Element.classList`. * * @param element target * @param classNAME to remove */ const removeClass = (element, ...classNAME) => { element.classList.remove(...classNAME); }; //#endregion //#region src/class/hasClass.ts /** * Check class in `Element.classList`. * * @param element target * @param classNAME to check */ const hasClass = (element, classNAME) => { return element.classList.contains(classNAME); }; //#endregion //#region src/blocks/documentBody.ts /** * A global namespace for `document.body`. */ const { body: documentBody } = document; //#endregion //#region src/blocks/documentElement.ts /** * A global namespace for `document.documentElement` or the ``. */ const { documentElement } = document; //#endregion //#region src/blocks/documentHead.ts /** * A global namespace for `document.head`. */ const { head: documentHead } = document; //#endregion //#region src/misc/ArrayFrom.ts /** * Shortie for `Array.from()` static method. * The utility should also work with any typed arrays * like Float64Array or Int32Array. * * @param arr array-like iterable object * @returns a new array from iterable object */ const ArrayFrom = (arr) => Array.from(arr); //#endregion //#region src/is/isObject.ts /** * Checks if a value is an `Object`. * * @param obj the target object * @returns the query result */ const isObject = (obj) => obj !== null && obj !== void 0 && typeof obj === "object" || false; //#endregion //#region src/is/isNode.ts /** * Checks if an object is a `Node`. * * @param node the target object * @see https://dom.spec.whatwg.org/#node * * ``` * ELEMENT_NODE = 1; * ATTRIBUTE_NODE = 2; * TEXT_NODE = 3; * CDATA_SECTION_NODE = 4; * ENTITY_REFERENCE_NODE = 5; // legacy * ENTITY_NODE = 6; // legacy * PROCESSING_INSTRUCTION_NODE = 7; * COMMENT_NODE = 8; * DOCUMENT_NODE = 9; * DOCUMENT_TYPE_NODE = 10; * DOCUMENT_FRAGMENT_NODE = 11; * @returns the query result */ const isNode = (node) => isObject(node) && typeof node.nodeType === "number" && [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ].some((x) => node.nodeType === x) || false; //#endregion //#region src/is/isElement.ts /** * Checks if an object is an `Element`. * * @param element the target object * @returns the query result */ const isElement = (element) => isNode(element) && element.nodeType === 1 || false; //#endregion //#region src/misc/data.ts const componentData = /* @__PURE__ */ new Map(); /** * An interface for web components background data. * * @see https://github.com/thednp/bootstrap.native/blob/master/src/components/base-component.js */ const Data = { data: componentData, set: (element, component, instance) => { if (!isElement(element)) return; if (!componentData.has(component)) componentData.set(component, /* @__PURE__ */ new Map()); componentData.get(component).set(element, instance); }, getAllFor: (component) => { return componentData.get(component) || null; }, get: (element, component) => { if (!isElement(element) || !component) return null; const instanceMap = Data.getAllFor(component); return element && instanceMap && instanceMap.get(element) || null; }, remove: (element, component) => { const instanceMap = Data.getAllFor(component); if (!instanceMap || !isElement(element)) return; instanceMap.delete(element); if (instanceMap.size === 0) componentData.delete(component); } }; //#endregion //#region src/misc/getInstance.ts /** * An alias for `Data.get()`. */ const getInstance = (target, component) => Data.get(target, component); //#endregion //#region src/misc/capitalize.ts /** * Capitalize first character in a string. * @param input source string */ const capitalize = (input) => input?.charAt(0).toUpperCase() + input?.slice(1); //#endregion //#region src/misc/camelCase.ts /** * Transform a string to camel case. * @param input source string */ const camelCase = (input) => input?.trim().replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => index === 0 ? word.toLowerCase() : word.toUpperCase()).replace(/\s+/g, ""); //#endregion //#region src/is/isString.ts /** * Shortie for `typeof SOMETHING === "string"`. * * @param str input value * @returns the query result */ const isString = (str) => typeof str === "string" || false; //#endregion //#region src/is/isWindow.ts /** * Check if a target object is `Window`. * => equivalent to `object instanceof Window` * * @param obj the target object * @returns the query result */ const isWindow = (obj) => isObject(obj) && obj.constructor.name === "Window" || false; //#endregion //#region src/is/isDocument.ts /** * Checks if an object is a `Document`. * * @see https://dom.spec.whatwg.org/#node * * @param obj the target object * @returns the query result */ const isDocument = (obj) => isNode(obj) && obj.nodeType === 9 || false; //#endregion //#region src/get/getDocument.ts /** * Returns the `document` or the `#document` element. * * @see https://github.com/floating-ui/floating-ui * * @param node the reference node * @returns the parent document of the given node */ const getDocument = (node) => { if (isDocument(node)) return node; if (isNode(node)) return node.ownerDocument; if (isWindow(node)) return node.document; return globalThis.document; }; //#endregion //#region src/misc/ObjectAssign.ts /** * Shortcut for `Object.assign()` static method. * * @param obj a target object * @param source source object(s) * @see https://github.com/devinrhode2/ObjectTyped/blob/master/src/index.ts */ const ObjectAssign = (obj, ...source) => Object.assign(obj, ...source); //#endregion //#region src/misc/createElement.ts /** * Shortie for `document.createElement` method * which allows you to create a new `HTMLElement` for a given `tagName` * or based on an object with specific non-readonly attributes with string values: * `id`, `className`, `textContent`, `style`, etc. * * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement * * @param param `tagName` or object * @return a new `HTMLElement` */ const createElement = (param) => { if (!param) return void 0; if (isString(param)) return getDocument().createElement(param); const { tagName } = param; const newElement = createElement(tagName); if (!newElement) return void 0; const attr = { ...param }; delete attr.tagName; return ObjectAssign(newElement, attr); }; //#endregion //#region src/misc/createElementNS.ts /** * Shortie for `document.createElementNS` method * which allows you to create a new `Element` for a given `tagName` * or based on an object with specific non-readonly attributes with string values: * `id`, `className`, `textContent`, `style`, etc. * Note: some elements resulted from this function call may not be compatible with * some attributes. * * @see https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS * * @param ns `namespaceURI` to associate with the new `Element` * @param param `tagName` or object * @return a new `Element` */ const createElementNS = (ns, param) => { if (!ns || !param) return void 0; if (isString(param)) return getDocument().createElementNS(ns, param); const { tagName } = param; const newElement = createElementNS(ns, tagName); if (!newElement) return void 0; const attr = { ...param }; delete attr.tagName; return ObjectAssign(newElement, attr); }; //#endregion //#region src/misc/dispatchEvent.ts /** * Shortcut for the `Element.dispatchEvent(Event)` method. * * @param element is the target * @param event is the `Event` object */ const dispatchEvent = (element, event) => element.dispatchEvent(event); //#endregion //#region src/misc/distinct.ts /** * JavaScript `Array` distinct. * * @see https://codeburst.io/javascript-array-distinct-5edc93501dc4 * * @example * ``` * [0,1,1,2].filter(distinct) * // => [0,1,2] * ``` * @param value array item value * @param index array item index * @param arr a clone of the target array * @returns the query result */ const distinct = (value, index, arr) => arr.indexOf(value) === index; //#endregion //#region src/get/getElementStyle.ts /** * Shortcut for `window.getComputedStyle(element).propertyName` * static method. * * * If `element` parameter is not an `Element`, `getComputedStyle` * throws a `ReferenceError`. * * @param element target `Element` * @param property the css property * @param pseudoElt pseudo-elements * @return the css property value */ const getElementStyle = (element, property, pseudoElt) => { const computedStyle = getComputedStyle(element, pseudoElt); const prop = property.replace("webkit", "Webkit").replace(/([A-Z])/g, "-$1").toLowerCase(); return computedStyle.getPropertyValue(prop); }; //#endregion //#region src/get/getElementAnimationDelay.ts /** * Utility to get the computed `animationDelay` * from Element in miliseconds. * * @param element target * @return the `animationDelay` value in miliseconds */ const getElementAnimationDelay = (element) => { const propertyValue = getElementStyle(element, animationName); const durationValue = getElementStyle(element, animationDelay); const durationScale = durationValue.includes("ms") ? 1 : 1e3; const duration = propertyValue && propertyValue !== "none" ? parseFloat(durationValue) * durationScale : 0; return !Number.isNaN(duration) ? duration : 0; }; //#endregion //#region src/get/getElementAnimationDuration.ts /** * Utility to get the computed `animationDuration` * from `Element` in miliseconds. * * @param element target * @return the `animationDuration` value in miliseconds */ const getElementAnimationDuration = (element) => { const propertyValue = getElementStyle(element, animationName); const durationValue = getElementStyle(element, animationDuration); const durationScale = durationValue.includes("ms") ? 1 : 1e3; const duration = propertyValue && propertyValue !== "none" ? parseFloat(durationValue) * durationScale : 0; return !Number.isNaN(duration) ? duration : 0; }; //#endregion //#region src/misc/emulateAnimationEnd.ts /** * Utility to make sure callbacks are consistently * called when animation ends. * * @param element target * @param handler `animationend` callback */ const emulateAnimationEnd = (element, handler) => { let called = 0; const endEvent = new Event(animationEndEvent); const duration = getElementAnimationDuration(element); const delay = getElementAnimationDelay(element); if (duration) { const animationEndWrapper = (e) => { if (e.target === element) { handler.apply(element, [e]); element.removeEventListener(animationEndEvent, animationEndWrapper); called = 1; } }; element.addEventListener(animationEndEvent, animationEndWrapper); setTimeout(() => { if (!called) dispatchEvent(element, endEvent); }, duration + delay + 17); } else handler.apply(element, [endEvent]); }; //#endregion //#region src/get/getElementTransitionDelay.ts /** * Utility to get the computed `transitionDelay` * from Element in miliseconds. * * @param element target * @return the `transitionDelay` value in miliseconds */ const getElementTransitionDelay = (element) => { const propertyValue = getElementStyle(element, transitionProperty); const delayValue = getElementStyle(element, transitionDelay); const delayScale = delayValue.includes("ms") ? 1 : 1e3; const duration = propertyValue && propertyValue !== "none" ? parseFloat(delayValue) * delayScale : 0; return !Number.isNaN(duration) ? duration : 0; }; //#endregion //#region src/get/getElementTransitionDuration.ts /** * Utility to get the computed `transitionDuration` * from Element in miliseconds. * * @param element target * @return the `transitionDuration` value in miliseconds */ const getElementTransitionDuration = (element) => { const propertyValue = getElementStyle(element, transitionProperty); const durationValue = getElementStyle(element, transitionDuration); const durationScale = durationValue.includes("ms") ? 1 : 1e3; const duration = propertyValue && propertyValue !== "none" ? parseFloat(durationValue) * durationScale : 0; return !Number.isNaN(duration) ? duration : 0; }; //#endregion //#region src/misc/emulateTransitionEnd.ts /** * Utility to make sure callbacks are consistently * called when transition ends. * * @param element element target * @param handler `transitionend` callback */ const emulateTransitionEnd = (element, handler) => { let called = 0; const endEvent = new Event(transitionEndEvent); const duration = getElementTransitionDuration(element); const delay = getElementTransitionDelay(element); if (duration) { const transitionEndWrapper = (e) => { if (e.target === element) { handler.apply(element, [e]); element.removeEventListener(transitionEndEvent, transitionEndWrapper); called = 1; } }; element.addEventListener(transitionEndEvent, transitionEndWrapper); setTimeout(() => { if (!called) dispatchEvent(element, endEvent); }, duration + delay + 17); } else handler.apply(element, [endEvent]); }; //#endregion //#region src/misc/Float32ArrayFrom.ts /** * Shortcut for `Float32Array.from()` static method. * * @param arr array-like iterable object * @returns a new Float32Array */ const Float32ArrayFrom = (arr) => Float32Array.from(Array.from(arr)); //#endregion //#region src/misc/Float64ArrayFrom.ts /** * Shortcut for `Float64Array.from()` static method. * * @param arr array-like iterable object * @returns a new Float64Array */ const Float64ArrayFrom = (arr) => Float64Array.from(Array.from(arr)); //#endregion //#region src/misc/focus.ts /** * Shortie for `HTMLOrSVGElement.focus()` method. * * @param element is the target * @param options allows to pass additional options such as `preventScroll: boolean` */ const focus = (element, options) => element.focus(options); //#endregion //#region src/misc/kebabCase.ts /** * Transform a string to kebab case. * @param input source string */ const kebabCase = (input) => input?.trim().replace(/([a-z])([A-Z])/g, "$1-$2").replace(/\s+/g, "-").toLowerCase(); //#endregion //#region src/misc/normalizeValue.ts /** * Utility to normalize component options * * @param value the input value * @return the normalized value */ const normalizeValue = (value) => { if (["true", true].includes(value)) return true; if (["false", false].includes(value)) return false; if ([ "null", "", null, void 0 ].includes(value)) return null; if (value !== "" && !Number.isNaN(+value)) return +value; return value; }; //#endregion //#region src/misc/ObjectEntries.ts /** * Shortcut for `Object.entries()` static method. * * @param obj a target object * @returns the entries of an object in an array format [key, value][] * @see https://github.com/devinrhode2/ObjectTyped/blob/master/src/index.ts */ const ObjectEntries = (obj) => Object.entries(obj); //#endregion //#region src/misc/normalizeOptions.ts /** * Utility to normalize component options. * * @param element target * @param defaultOps component default options * @param inputOps component instance options * @param ns component namespace * @return normalized component options object */ const normalizeOptions = (element, defaultOps, inputOps, ns) => { if (!isElement(element)) return defaultOps; const INPUT = { ...inputOps }; const data = { ...element.dataset }; const normalOps = { ...defaultOps }; const dataOps = {}; const title = "title"; ObjectEntries(data).forEach(([k, v]) => { const key = ns && typeof k === "string" && k.includes(ns) ? camelCase(k.replace(ns, "")) : camelCase(k); dataOps[key] = normalizeValue(v); }); ObjectEntries(INPUT).forEach(([k, v]) => { INPUT[k] = normalizeValue(v); }); ObjectEntries(defaultOps).forEach(([k, v]) => { if (k in INPUT) normalOps[k] = INPUT[k]; else if (k in dataOps) normalOps[k] = dataOps[k]; else normalOps[k] = k === title ? getAttribute(element, title) : v; }); return normalOps; }; //#endregion //#region src/misc/ObjectHasOwn.ts /** * A shortcut to `Object.hasOwn()` static method to work * with regular `Object` elements. * * @see https://fettblog.eu/typescript-hasownproperty/ * @param obj the target object * @param prop the property to check * @returns the query result */ const ObjectHasOwn = (obj, prop) => isObject(obj) && (Object.hasOwn(obj, prop) || prop in obj); //#endregion //#region src/misc/ObjectKeys.ts /** * Shortcut for `Object.keys()` static method. * * @param obj a target object * @returns an array with object keys * @see https://github.com/devinrhode2/ObjectTyped/blob/master/src/index.ts */ const ObjectKeys = (obj) => Object.keys(obj); //#endregion //#region src/misc/ObjectValues.ts /** * Shortcut for `Object.values()` static method. * * @param obj a target object * @returns an array with the object values * @see https://github.com/devinrhode2/ObjectTyped/blob/master/src/index.ts */ const ObjectValues = (obj) => Object.values(obj); //#endregion //#region src/misc/ObjectFromEntries.ts /** * Shortcut for `Object.fromEntries()` static method. * * @param entries a target entries object * @returns a new Object created from the specified entries in array format [key, value][] * @see https://github.com/devinrhode2/ObjectTyped/blob/master/src/index.ts */ const ObjectFromEntries = (entries) => Object.fromEntries(entries); //#endregion //#region src/misc/createCustomEvent.ts /** * Returns a namespaced `CustomEvent` specific to each component. * * @param eventType Event.type * @param config Event.options | Event.properties * @returns a new namespaced event */ const createCustomEvent = (eventType, config) => { const OriginalCustomEvent = new CustomEvent(eventType, { cancelable: true, bubbles: true }); if (isObject(config)) ObjectAssign(OriginalCustomEvent, config); return OriginalCustomEvent; }; //#endregion //#region src/misc/passiveHandler.ts /** * A global namespace for most scroll event listeners. */ const passiveHandler = { passive: true }; //#endregion //#region src/misc/reflow.ts /** * Utility to force re-paint of an `HTMLElement` target. * * @param element is the target * @return the `Element.offsetHeight` value */ const reflow = (element) => element.offsetHeight; //#endregion //#region src/misc/setElementStyle.ts /** * Shortcut for multiple uses of `HTMLElement.style.propertyName` method. * * @param element target element * @param styles attribute value */ const setElementStyle = (element, styles) => { ObjectEntries(styles).forEach(([key, value]) => { if (value && isString(key) && key.includes("--")) element.style.setProperty(key, value); else { const propObject = {}; propObject[key] = value; ObjectAssign(element.style, propObject); } }); }; //#endregion //#region src/is/isMap.ts /** * Checks if an element is a `Map`. * * @param obj the target object * @returns the query result */ const isMap = (obj) => isObject(obj) && obj.constructor.name === "Map" || false; //#endregion //#region src/is/isNumber.ts /** * Shortie for `typeof SOMETHING === "number"`. * * @param num input value * @returns the query result */ const isNumber = (num) => typeof num === "number" || false; //#endregion //#region src/misc/timer.ts const TimeCache = /* @__PURE__ */ new Map(); /** * An interface for one or more `TimerHandler`s per `Element`. * * @see https://github.com/thednp/navbar/ */ const Timer = { set: (element, callback, delay, key) => { if (!isElement(element)) return; // @license test comment /* @license comment */ /* test @license comment */ if (key && key.length) { if (!TimeCache.has(element)) TimeCache.set(element, /* @__PURE__ */ new Map()); TimeCache.get(element).set(key, setTimeout(callback, delay)); } else TimeCache.set(element, setTimeout(callback, delay)); }, get: (element, key) => { if (!isElement(element)) return null; const keyTimers = TimeCache.get(element); if (key && keyTimers && isMap(keyTimers)) return keyTimers.get(key) || null; else if (isNumber(keyTimers)) return keyTimers; return null; }, clear: (element, key) => { if (!isElement(element)) return; const keyTimers = TimeCache.get(element); if (key && key.length && isMap(keyTimers)) { clearTimeout(keyTimers.get(key)); keyTimers.delete(key); if (keyTimers.size === 0) TimeCache.delete(element); } else { clearTimeout(keyTimers); TimeCache.delete(element); } } }; //#endregion //#region src/misc/toLowerCase.ts /** * Shortcut for `String.toLowerCase()`. * * @param source input string * @returns lowercase output string */ const toLowerCase = (source) => source.toLowerCase(); //#endregion //#region src/misc/toUpperCase.ts /** * Shortcut for `String.toUpperCase()`. * * @param source input string * @returns uppercase output string */ const toUpperCase = (source) => source.toUpperCase(); //#endregion //#region src/selectors/querySelectorAll.ts /** * A shortcut for `(document|Element).querySelectorAll`. * * @param selector the input selector * @param parent optional node to look into * @return the query result */ const querySelectorAll = (selector, parent) => { return (isNode(parent) ? parent : getDocument()).querySelectorAll(selector); }; //#endregion //#region src/misc/focusTrap.ts const focusTrapMap = /* @__PURE__ */ new Map(); function handleKeyboardNavigation(event) { const { shiftKey, code } = event; const doc = getDocument(this); const focusableElements = [...querySelectorAll(focusableSelector, this)].filter((el) => !hasAttribute(el, "disabled") && !getAttribute(el, "aria-hidden")); if (!focusableElements.length) return; const firstFocusable = focusableElements[0]; const lastFocusable = focusableElements[focusableElements.length - 1]; if (code === "Tab") { if (shiftKey && doc.activeElement === firstFocusable) { lastFocusable.focus(); event.preventDefault(); } else if (!shiftKey && doc.activeElement === lastFocusable) { firstFocusable.focus(); event.preventDefault(); } } } /** * Utility to check if a designated element is affected by focus trap; * @param target */ const hasFocusTrap = (target) => focusTrapMap.has(target) === true; /** * Utility to add focus trap inside a designated target element; * @param target */ const addFocusTrap = (target) => { if (hasFocusTrap(target)) return; on(target, "keydown", handleKeyboardNavigation); focusTrapMap.set(target, true); }; /** * Utility to remove focus trap inside a designated target element; * @param target */ const removeFocusTrap = (target) => { if (!hasFocusTrap(target)) return; off(target, "keydown", handleKeyboardNavigation); focusTrapMap.delete(target); }; /** * Utility to toggle focus trap inside a designated target element; * @param target */ const toggleFocusTrap = (target) => { if (hasFocusTrap(target)) removeFocusTrap(target); else addFocusTrap(target); }; //#endregion //#region src/is/isHTMLElement.ts /** * Checks if an element is an `HTMLElement`. * * @see https://dom.spec.whatwg.org/#node * * @param element the target object * @returns the query result */ const isHTMLElement = (element) => isElement(element) && "offsetWidth" in element || false; //#endregion //#region src/get/getBoundingClientRect.ts /** * Returns the bounding client rect of a target `Element`. * * @see https://github.com/floating-ui/floating-ui * * @param element event.target * @param includeScale when *true*, the target scale is also computed * @returns the bounding client rect object */ const getBoundingClientRect = (element, includeScale) => { const { width, height, top, right, bottom, left } = element.getBoundingClientRect(); let scaleX = 1; let scaleY = 1; if (includeScale && isHTMLElement(element)) { const { offsetWidth, offsetHeight } = element; scaleX = offsetWidth > 0 ? Math.round(width) / offsetWidth : 1; scaleY = offsetHeight > 0 ? Math.round(height) / offsetHeight : 1; } return { width: width / scaleX, height: height / scaleY, top: top / scaleY, right: right / scaleX, bottom: bottom / scaleY, left: left / scaleX, x: left / scaleX, y: top / scaleY }; }; //#endregion //#region src/get/getDocumentBody.ts /** * Returns the `document.body` or the `` element. * * @param node the reference node * @returns the parent `` of the specified node */ const getDocumentBody = (node) => { return getDocument(node).body; }; //#endregion //#region src/get/getDocumentElement.ts /** * Returns the `document.documentElement` or the `` element. * * @param node the reference node * @returns the parent `` of the node's parent document */ const getDocumentElement = (node) => { return getDocument(node).documentElement; }; //#endregion //#region src/get/getDocumentHead.ts /** * Returns the `document.head` or the `` element. * * @param node the reference node * @returns the `` of the node's parent document */ const getDocumentHead = (node) => { return getDocument(node).head; }; //#endregion //#region src/get/getNodeName.ts /** * Returns the value of `node.nodeName` for the given node. * @param node target node * @returns the node name */ const getNodeName = (node) => { if (isNode(node)) return (node.nodeName || "").toLowerCase(); return "#document"; }; //#endregion //#region src/get/getNodeScroll.ts /** * Returns an `{x, y}` object with the target * `Element` / `Node` scroll position. * * @see https://github.com/floating-ui/floating-ui * * @param element target node / element * @returns the scroll tuple */ const getNodeScroll = (element) => { const isWin = isWindow(element); return { x: isWin ? element.scrollX : element.scrollLeft, y: isWin ? element.scrollY : element.scrollTop }; }; //#endregion //#region src/is/isShadowRoot.ts /** * Check if target is a `ShadowRoot`. * * @param element target * @returns the query result */ const isShadowRoot = (element) => isNode(element) && element.constructor.name === "ShadowRoot" || false; //#endregion //#region src/get/getParentNode.ts /** * Returns the `parentNode` also going through `ShadowRoot`. * * @see https://github.com/floating-ui/floating-ui * * @param node the target node * @returns the apropriate parent node */ const getParentNode = (node) => { if (node.nodeName === "HTML") return node; return isElement(node) && node.assignedSlot || isNode(node) && node.parentNode || isShadowRoot(node) && node.host || getDocumentElement(node); }; //#endregion //#region src/get/getWindow.ts /** * Returns the `Window` object of a target node. * * @see https://github.com/floating-ui/floating-ui * * @param node target node * @returns the `Window` object */ const getWindow = (node) => { if (!node) return window; if (isDocument(node)) return node.defaultView; if (isNode(node)) return node?.ownerDocument?.defaultView; return node; }; //#endregion //#region src/is/isTableElement.ts /** * Check if a target element is a ``, `
` or ``. * This specific check is important for determining * the `offsetParent` of a given element. * * @param element the target element * @returns the query result */ const isTableElement = (element) => isNode(element) && [ "TABLE", "TD", "TH" ].includes(element.nodeName) || false; //#endregion //#region src/selectors/matches.ts /** * Check if element matches a CSS selector. * * @param target the target element * @param selector the selector to match * @returns the query result */ const matches = (target, selector) => target.matches(selector); //#endregion //#region src/get/getOffsetParent.ts const isStaticPositioned = (element) => { return getElementStyle(element, "position") === "static"; }; const isFixedPositioned = (element) => { return getElementStyle(element, "position") === "fixed"; }; const isTopLayer = (element) => { return [":popover-open", ":modal"].some((selector) => { try { return matches(element, selector); } catch (_) { return false; } }); }; const isContainingBlock = (elementOrCss) => { const webkit = isWebKit(); const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss; return css.transform !== "none" || css.perspective !== "none" || (css.containerType ? css.containerType !== "normal" : false) || !webkit && (css.backdropFilter ? css.backdropFilter !== "none" : false) || !webkit && (css.filter ? css.filter !== "none" : false) || [ "transform", "perspective", "filter" ].some((value) => (css.willChange || "").includes(value)) || [ "paint", "layout", "strict", "content" ].some((value) => (css.contain || "").includes(value)); }; const getContainingBlock = (element) => { let currentNode = getParentNode(element); while (isElement(currentNode) && !isLastTraversableNode(currentNode)) { if (isContainingBlock(currentNode)) return currentNode; else if (isTopLayer(currentNode)) return null; currentNode = getParentNode(currentNode); } return null; }; const isLastTraversableNode = (node) => { return [ "html", "body", "#document" ].includes(getNodeName(node)); }; const getTrueOffsetParent = (element) => { if (!isHTMLElement(element) || isFixedPositioned(element)) return null; let rawOffsetParent = element.offsetParent; if (getDocumentElement(element) === rawOffsetParent) rawOffsetParent = rawOffsetParent.ownerDocument.body; return rawOffsetParent; }; /** * Returns the `offsetParent` for a given target. * * @see https://github.com/floating-ui/floating-ui * * @param element the target node * @returns the offset parent node */ const getOffsetParent = (element) => { const win = getWindow(element); if (!isNode(element) || isTopLayer(element)) return win; if (!isHTMLElement(element)) { let svgOffsetParent = getParentNode(element); while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) { if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) return svgOffsetParent; svgOffsetParent = getParentNode(svgOffsetParent); } return win; } let offsetParent = getTrueOffsetParent(element); while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) offsetParent = getTrueOffsetParent(offsetParent); if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) return win; return offsetParent || getContainingBlock(element) || win; }; //#endregion //#region src/is/isScaledElement.ts /** * Checks if a target `Element` is affected by scale. * * @see https://github.com/floating-ui/floating-ui * * @param element target * @returns the query result */ const isScaledElement = (element) => { if (!isHTMLElement(element)) return false; const { width, height } = getBoundingClientRect(element); const { offsetWidth, offsetHeight } = element; return Math.round(width) !== offsetWidth || Math.round(height) !== offsetHeight; }; //#endregion //#region src/get/getRectRelativeToOffsetParent.ts /** * Returns the rect relative to a given offset parent and its scroll position. * * @see https://github.com/floating-ui/floating-ui * * @param element target * @param offsetParent the container / offset parent * @param scroll the offsetParent scroll position * @returns a DOMRect like object */ const getRectRelativeToOffsetParent = (element, offsetParent, scroll) => { const isParentAnElement = isHTMLElement(offsetParent); const rect = getBoundingClientRect(element, isParentAnElement && isScaledElement(offsetParent)); const offsets = { x: 0, y: 0 }; if (isParentAnElement) { const offsetRect = getBoundingClientRect(offsetParent, true); offsets.x = offsetRect.x + offsetParent.clientLeft; offsets.y = offsetRect.y + offsetParent.clientTop; } return { x: rect.left + scroll.x - offsets.x, y: rect.top + scroll.y - offsets.y, width: rect.width, height: rect.height }; }; //#endregion //#region src/get/getUID.ts let elementUID = 0; let elementMapUID = 0; const elementIDMap = /* @__PURE__ */ new Map(); /** * Returns a unique identifier for popover, tooltip, scrollspy. * * @param element target element * @param key optional identifier key * @returns an existing or new unique ID */ const getUID = (element, key) => { let result = key ? elementUID : elementMapUID; if (key) { const elID = getUID(element); const elMap = elementIDMap.get(elID) || /* @__PURE__ */ new Map(); if (!elementIDMap.has(elID)) elementIDMap.set(elID, elMap); if (isMap(elMap) && !elMap.has(key)) { elMap.set(key, result); elementUID += 1; } else result = elMap.get(key); } else { const elkey = element.id || element; if (!elementIDMap.has(elkey)) { elementIDMap.set(elkey, result); elementMapUID += 1; } else result = elementIDMap.get(elkey); } return result; }; //#endregion //#region src/is/isArray.ts /** * Shortie for the `Array.isArray()` static method. * * @param obj array-like iterable object * @returns the query result */ const isArray = (obj) => Array.isArray(obj) || false; //#endregion //#region src/is/isCanvas.ts /** * Checks if an element is an `HTMLCanvasElement` or ``. * * @param element the target element * @returns the query result */ const isCanvas = (element) => isNode(element) && element.nodeName === "CANVAS" || false; //#endregion //#region src/is/isCustomElement.ts /** * Checks if an object is a `CustomElement`. * * @param element the target object * @returns the query result */ const isCustomElement = (element) => isHTMLElement(element) && !!element.shadowRoot || false; //#endregion //#region src/is/isElementInScrollRange.ts /** * Utility to determine if an `Element` * is partially visible in viewport. * * @param element target * @return the query result */ const isElementInScrollRange = (element) => { if (!isNode(element)) return false; const { top, bottom } = getBoundingClientRect(element); const { clientHeight } = getDocumentElement(element); return top <= clientHeight && bottom >= 0; }; //#endregion //#region src/is/isElementInViewport.ts /** * Utility to determine if an `Element` * is fully visible in the viewport. * * @param element target * @return the query result */ const isElementInViewport = (element) => { if (!isElement(element)) return false; const { clientWidth, clientHeight } = getDocumentElement(element); const { top, left, bottom, right } = getBoundingClientRect(element, true); return top >= 0 && left >= 0 && bottom <= clientHeight && right <= clientWidth; }; //#endregion //#region src/is/isElementsArray.ts /** * Checks if an object is an `Array` in which all items are `Element`. * * @param obj the target object * @returns the query result */ const isElementsArray = (obj) => isArray(obj) && obj.every(isElement) || false; //#endregion //#region src/is/isFunction.ts /** * Checks if an object is a `Function`. * * @param fn the target object * @returns the query result */ const isFunction = (fn) => typeof fn === "function" || false; //#endregion //#region src/is/isHTMLCollection.ts /** * Checks if an object is an `HTMLCollection`. * * @param obj the target object * @returns the query result */ const isHTMLCollection = (obj) => isObject(obj) && obj.constructor.name === "HTMLCollection" || false; //#endregion //#region src/is/isHTMLImageElement.ts /** * Check if a target element is an ``. * * @param element the target element * @returns the query result */ const isHTMLImageElement = (element) => isHTMLElement(element) && element.tagName === "IMG" || false; //#endregion //#region src/is/isJSON.ts /** * Checks if a string is a `JSON` string. * * @param str the target string * @returns the query result */ const isJSON = (str) => { if (!isString(str)) return false; try { JSON.parse(str); } catch (_e) { return false; } return true; }; //#endregion //#region src/is/isWeakMap.ts /** * Checks if an element is a `WeakMap`. * * @param obj the target object * @returns the query result */ const isWeakMap = (obj) => isObject(obj) && obj.constructor.name === "WeakMap" || false; //#endregion //#region src/is/isMedia.ts /** * Checks if an element is an `` (or any type of SVG element), * ``, `