overlayscrollbars
Version:
A javascript scrollbar plugin that hides the native scrollbars, provides custom styleable overlay scrollbars, and preserves the native functionality and feel.
1 lines • 364 kB
Source Map (JSON)
{"version":3,"file":"overlayscrollbars.cjs","sources":["../src/support/cache.ts","../src/support/compatibility/isBrowser.ts","../src/support/utils/alias.ts","../src/support/compatibility/apis.ts","../src/support/utils/types.ts","../src/support/utils/animation.ts","../src/support/utils/array.ts","../src/support/utils/strings.ts","../src/support/utils/equal.ts","../src/support/utils/function.ts","../src/support/utils/object.ts","../src/support/utils/noop.ts","../src/support/utils/math.ts","../src/support/dom/attribute.ts","../src/support/dom/class.ts","../src/support/dom/traversal.ts","../src/support/dom/manipulation.ts","../src/trustedTypePolicy.ts","../src/support/dom/create.ts","../src/support/dom/style.ts","../src/support/dom/dimensions.ts","../src/support/dom/events.ts","../src/support/dom/scroll.ts","../src/support/dom/focus.ts","../src/support/eventListeners.ts","../src/plugins/plugins.ts","../src/plugins/optionsValidationPlugin/optionsValidationPlugin.ts","../src/classnames.ts","../src/plugins/sizeObserverPlugin/sizeObserverPlugin.ts","../src/setups/structureSetup/structureSetup.utils.ts","../src/plugins/scrollbarsHidingPlugin/scrollbarsHidingPlugin.ts","../src/plugins/clickScrollPlugin/clickScrollPlugin.ts","../src/options.ts","../src/nonce.ts","../src/environment.ts","../src/observers/domObserver.ts","../src/observers/sizeObserver.ts","../src/observers/trinsicObserver.ts","../src/setups/observersSetup/observersSetup.ts","../src/initialization.ts","../src/setups/scrollbarsSetup/scrollbarsSetup.elements.ts","../src/setups/scrollbarsSetup/scrollbarsSetup.events.ts","../src/setups/scrollbarsSetup/scrollbarsSetup.ts","../src/setups/structureSetup/structureSetup.elements.ts","../src/setups/structureSetup/updateSegments/trinsicUpdateSegment.ts","../src/setups/structureSetup/updateSegments/paddingUpdateSegment.ts","../src/setups/structureSetup/updateSegments/overflowUpdateSegment.ts","../src/setups/structureSetup/structureSetup.ts","../src/setups/setups.ts","../src/instances.ts","../src/overlayscrollbars.ts"],"sourcesContent":["export interface CacheOptions<Value> {\r\n // initial value of _value.\r\n _initialValue: Value;\r\n // Custom comparison function if shallow compare isn't enough. Returns true if nothing changed.\r\n _equal?: EqualCachePropFunction<Value>;\r\n // If true always updates _value and _previous, otherwise they update only when they changed.\r\n _alwaysUpdateValues?: boolean;\r\n}\r\n\r\nexport type CacheValues<T> = [value: T, changed: boolean, previous?: T];\r\n\r\nexport type EqualCachePropFunction<Value> = (currentVal: Value, newVal: Value) => boolean;\r\n\r\nexport type CacheUpdater<Value> = (current: Value, previous?: Value) => Value;\r\n\r\nexport type UpdateCacheContextual<Value> = (newValue: Value, force?: boolean) => CacheValues<Value>;\r\n\r\nexport type UpdateCache<Value> = (force?: boolean) => CacheValues<Value>;\r\n\r\nexport type GetCurrentCache<Value> = (force?: boolean) => CacheValues<Value>;\r\n\r\nexport type Cache<Value> = [UpdateCache<Value>, GetCurrentCache<Value>];\r\n\r\nexport type CacheContextual<Value> = [UpdateCacheContextual<Value>, GetCurrentCache<Value>];\r\n\r\ntype CreateCache = {\r\n <Value>(options: CacheOptions<Value>): CacheContextual<Value>;\r\n <Value>(options: CacheOptions<Value>, update: CacheUpdater<Value>): Cache<Value>;\r\n <Value>(\r\n options: CacheOptions<Value>,\r\n update?: CacheUpdater<Value>\r\n ): CacheContextual<Value> | Cache<Value>;\r\n};\r\n\r\nexport const createCache: CreateCache = <Value>(\r\n options: CacheOptions<Value>,\r\n update?: CacheUpdater<Value>\r\n): CacheContextual<Value> | Cache<Value> => {\r\n const { _initialValue, _equal, _alwaysUpdateValues } = options;\r\n let _value: Value = _initialValue;\r\n let _previous: Value | undefined;\r\n\r\n const cacheUpdateContextual: UpdateCacheContextual<Value> = (newValue, force?) => {\r\n const curr = _value;\r\n\r\n const newVal = newValue;\r\n const changed = force || (_equal ? !_equal(curr, newVal) : curr !== newVal);\r\n\r\n if (changed || _alwaysUpdateValues) {\r\n _value = newVal;\r\n _previous = curr;\r\n }\r\n\r\n return [_value, changed, _previous];\r\n };\r\n const cacheUpdateIsolated: UpdateCache<Value> = (force?) =>\r\n cacheUpdateContextual(update!(_value, _previous), force);\r\n\r\n const getCurrentCache: GetCurrentCache<Value> = (force?: boolean) => [\r\n _value,\r\n !!force, // changed\r\n _previous,\r\n ];\r\n\r\n return [update ? cacheUpdateIsolated : cacheUpdateContextual, getCurrentCache] as\r\n | CacheContextual<Value>\r\n | Cache<Value>;\r\n};\r\n","export const isBrowser =\r\n // deno has the global `window` defined\r\n typeof window !== 'undefined' &&\r\n // make sure HTML element is available\r\n typeof HTMLElement !== 'undefined' &&\r\n // make sure document is defined\r\n !!window.document;\r\n","import { isBrowser } from '../compatibility/isBrowser';\r\n\r\nexport const wnd = (isBrowser ? window : {}) as typeof window;\r\nexport const mathMax = Math.max;\r\nexport const mathMin = Math.min;\r\nexport const mathRound = Math.round;\r\nexport const mathFloor = Math.floor;\r\nexport const mathCeil = Math.ceil;\r\nexport const mathAbs = Math.abs;\r\nexport const mathSign = Math.sign;\r\nexport const cAF = wnd.cancelAnimationFrame;\r\nexport const rAF = wnd.requestAnimationFrame;\r\nexport const setT = wnd.setTimeout;\r\nexport const clearT = wnd.clearTimeout;\r\n","import { wnd } from '../utils/alias';\r\n\r\nconst getApi = <T>(name: string) =>\r\n (typeof wnd[name as keyof typeof wnd] !== 'undefined'\r\n ? wnd[name as keyof typeof wnd]\r\n : undefined) as T;\r\n\r\nexport const MutationObserverConstructor = getApi<typeof MutationObserver>('MutationObserver');\r\nexport const IntersectionObserverConstructor =\r\n getApi<typeof IntersectionObserver>('IntersectionObserver');\r\nexport const ResizeObserverConstructor = getApi<typeof ResizeObserver>('ResizeObserver');\r\nexport const scrollT = getApi<new (constructor: unknown) => AnimationTimeline>('ScrollTimeline');\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport type { PlainObject } from '../../typings';\r\n\r\nexport const isUndefined = (obj: any): obj is undefined => obj === undefined;\r\n\r\nexport const isNull = (obj: any): obj is null => obj === null;\r\n\r\nexport const type = (obj: any): string =>\r\n isUndefined(obj) || isNull(obj)\r\n ? `${obj}`\r\n : Object.prototype.toString\r\n .call(obj)\r\n .replace(/^\\[object (.+)\\]$/, '$1')\r\n .toLowerCase();\r\n\r\nexport const isNumber = (obj: any): obj is number => typeof obj === 'number';\r\n\r\nexport const isString = (obj: any): obj is string => typeof obj === 'string';\r\n\r\nexport const isBoolean = (obj: any): obj is boolean => typeof obj === 'boolean';\r\n\r\nexport const isFunction = (obj: any): obj is (...args: any[]) => any => typeof obj === 'function';\r\n\r\nexport const isArray = <T = any>(obj: any): obj is Array<T> => Array.isArray(obj);\r\n\r\nexport const isObject = (obj: any): obj is object =>\r\n typeof obj === 'object' && !isArray(obj) && !isNull(obj);\r\n\r\n/**\r\n * Returns true if the given object is array like, false otherwise.\r\n * @param obj The Object\r\n */\r\nexport const isArrayLike = <T extends PlainObject = any>(obj: any): obj is ArrayLike<T> => {\r\n const length = !!obj && obj.length;\r\n const lengthCorrectFormat = isNumber(length) && length > -1 && length % 1 == 0;\r\n\r\n return isArray(obj) || (!isFunction(obj) && lengthCorrectFormat)\r\n ? length > 0 && isObject(obj)\r\n ? length - 1 in obj\r\n : true\r\n : false;\r\n};\r\n\r\n/**\r\n * Returns true if the given object is a \"plain\" (e.g. { key: value }) object, false otherwise.\r\n * @param obj The Object.\r\n */\r\nexport const isPlainObject = <T = any>(obj: any): obj is PlainObject<T> =>\r\n !!obj && obj.constructor === Object;\r\n\r\n/**\r\n * Checks whether the given object is a HTMLElement.\r\n * @param obj The object which shall be checked.\r\n */\r\nexport const isHTMLElement = (obj: any): obj is HTMLElement => obj instanceof HTMLElement;\r\n\r\n/**\r\n * Checks whether the given object is a Element.\r\n * @param obj The object which shall be checked.\r\n */\r\nexport const isElement = (obj: any): obj is Element => obj instanceof Element;\r\n","import { mathMax, rAF, cAF } from './alias';\r\nimport { isFunction } from './types';\r\n\r\n/**\r\n * percent: current percent (0 - 1),\r\n * time: current time (duration * percent),\r\n * min: start value\r\n * max: end value\r\n * duration: duration in ms\r\n */\r\nexport type EasingFn = (\r\n percent: number,\r\n time: number,\r\n min: number,\r\n max: number,\r\n duration: number\r\n) => number;\r\n\r\nconst animationCurrentTime = () => performance.now();\r\n\r\nexport const animateNumber = (\r\n from: number,\r\n to: number,\r\n duration: number,\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n onFrame: (progress: number, percent: number, completed: boolean) => any,\r\n easing?: EasingFn | false\r\n): ((complete?: boolean) => void) => {\r\n let animationFrameId = 0;\r\n const timeStart = animationCurrentTime();\r\n const finalDuration = mathMax(0, duration);\r\n const frame = (complete?: boolean) => {\r\n const timeNow = animationCurrentTime();\r\n const timeElapsed = timeNow - timeStart;\r\n const stopAnimation = timeElapsed >= finalDuration;\r\n const percent = complete\r\n ? 1\r\n : 1 - (mathMax(0, timeStart + finalDuration - timeNow) / finalDuration || 0);\r\n const progress =\r\n (to - from) *\r\n (isFunction(easing)\r\n ? easing(percent, percent * finalDuration, 0, 1, finalDuration)\r\n : percent) +\r\n from;\r\n const animationCompleted = stopAnimation || percent === 1;\r\n\r\n if (onFrame) {\r\n onFrame(progress, percent, animationCompleted);\r\n }\r\n\r\n animationFrameId = animationCompleted ? 0 : rAF!(() => frame());\r\n };\r\n frame();\r\n return (complete) => {\r\n cAF!(animationFrameId);\r\n if (complete) {\r\n frame(complete);\r\n }\r\n };\r\n};\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport type { PlainObject } from '../../typings';\r\nimport { isArray, isArrayLike, isString } from './types';\r\n\r\ntype RunEachItem = ((...args: any) => any | any[]) | false | null | undefined;\r\n\r\nexport function each<T extends Array<unknown> | ReadonlyArray<unknown>>(\r\n array: T,\r\n callback: (\r\n value: T extends Array<infer V> | ReadonlyArray<infer V> ? V : never,\r\n index: number,\r\n source: T\r\n ) => boolean | unknown\r\n): T;\r\nexport function each<T extends ArrayLike<unknown>>(\r\n arrayLikeObject: T,\r\n callback: (\r\n value: T extends ArrayLike<infer V> ? V : never,\r\n index: number,\r\n source: T\r\n ) => boolean | unknown\r\n): T;\r\nexport function each<T extends PlainObject>(\r\n obj: T,\r\n callback: (value: any, key: string, source: T) => boolean | unknown\r\n): T;\r\nexport function each(\r\n source: Array<unknown> | ArrayLike<unknown> | ReadonlyArray<unknown> | PlainObject,\r\n callback: (value: any, indexOrKey: any, source: any) => boolean | unknown\r\n): Array<unknown> | ArrayLike<unknown> | ReadonlyArray<unknown> | Set<unknown> | PlainObject {\r\n if (isArrayLike(source)) {\r\n for (let i = 0; i < source.length; i++) {\r\n if (callback(source[i], i, source) === false) {\r\n break;\r\n }\r\n }\r\n } else if (source) {\r\n // cant use support func keys here due to circular dep\r\n each(Object.keys(source), (key) => callback(source[key], key, source));\r\n }\r\n return source;\r\n}\r\n\r\n/**\r\n * Returns true when the passed item is in the passed array and false otherwise.\r\n * @param arr The array.\r\n * @param item The item.\r\n * @returns Whether the item is in the array.\r\n */\r\nexport const inArray = <T = any>(arr: T[] | readonly T[], item: T): boolean =>\r\n arr.indexOf(item) >= 0;\r\n\r\n/**\r\n * Concats two arrays and returns an new array without modifying any of the passed arrays.\r\n * @param a Array A.\r\n * @param b Array B.\r\n * @returns A new array which has the entries of both arrays.\r\n */\r\nexport const concat = <T>(a: T[] | ReadonlyArray<T>, b: T[] | ReadonlyArray<T>): T[] => a.concat(b);\r\n\r\n/**\r\n * Pushesh all given items into the given array and returns it.\r\n * @param array The array the items shall be pushed into.\r\n * @param items The items which shall be pushed into the array.\r\n */\r\nexport const push = <T>(array: T[], items: T | ArrayLike<T>, arrayIsSingleItem?: boolean): T[] => {\r\n if (!arrayIsSingleItem && !isString(items) && isArrayLike(items)) {\r\n Array.prototype.push.apply(array, items as T[]);\r\n } else {\r\n array.push(items as T);\r\n }\r\n return array;\r\n};\r\n\r\n/**\r\n * Creates a shallow-copied Array instance from an array-like or iterable object.\r\n * @param arr The object from which the array instance shall be created.\r\n */\r\nexport const from = <T = any>(arr?: ArrayLike<T> | Set<T>) => Array.from(arr || []);\r\n\r\n/**\r\n * Creates an array if the passed value is not an array, or returns the value if it is.\r\n * If the passed value is an array like structure and not a string it will be converted into an array.\r\n * @param value The value.\r\n * @returns An array which represents the passed value(s).\r\n */\r\nexport const createOrKeepArray = <T>(value: T | T[] | ArrayLike<T>): T[] => {\r\n if (isArray(value)) {\r\n return value;\r\n }\r\n return !isString(value) && isArrayLike(value) ? from(value) : [value];\r\n};\r\n\r\n/**\r\n * Check whether the passed array is empty.\r\n * @param array The array which shall be checked.\r\n */\r\nexport const isEmptyArray = (array: any[] | null | undefined): boolean => !!array && !array.length;\r\n\r\n/**\r\n * Deduplicates all items of the array.\r\n * @param array The array to be deduplicated.\r\n * @returns The deduplicated array.\r\n */\r\nexport const deduplicateArray = <T extends any[]>(array: T): T => from(new Set(array)) as T;\r\n\r\n/**\r\n * Calls all functions in the passed array/set of functions.\r\n * @param arr The array filled with function which shall be called.\r\n * @param args The args with which each function is called.\r\n * @param keep True when the Set / array should not be cleared afterwards, false otherwise.\r\n */\r\nexport const runEachAndClear = (arr: RunEachItem[], args?: any[], keep?: boolean): void => {\r\n // eslint-disable-next-line prefer-spread\r\n const runFn = (fn: RunEachItem) => (fn ? fn.apply(undefined, args || []) : true); // return true when fn is falsy to not break the loop\r\n each(arr, runFn);\r\n if (!keep) {\r\n (arr as any[]).length = 0;\r\n }\r\n};\r\n","export const strPaddingTop = 'paddingTop';\r\nexport const strPaddingRight = 'paddingRight';\r\nexport const strPaddingLeft = 'paddingLeft';\r\nexport const strPaddingBottom = 'paddingBottom';\r\nexport const strMarginLeft = 'marginLeft';\r\nexport const strMarginRight = 'marginRight';\r\nexport const strMarginBottom = 'marginBottom';\r\nexport const strOverflowX = 'overflowX';\r\nexport const strOverflowY = 'overflowY';\r\nexport const strWidth = 'width';\r\nexport const strHeight = 'height';\r\nexport const strVisible = 'visible';\r\nexport const strHidden = 'hidden';\r\nexport const strScroll = 'scroll';\r\n\r\nexport const capitalizeFirstLetter = (str: string | number | false | null | undefined): string => {\r\n const finalStr = String(str || '');\r\n return finalStr ? finalStr[0].toUpperCase() + finalStr.slice(1) : '';\r\n};\r\n","import type { WH } from '../dom/dimensions';\r\nimport type { XY } from '../dom/offset';\r\nimport type { TRBL } from '../dom/style';\r\nimport type { PlainObject } from '../../typings';\r\nimport { each } from './array';\r\nimport { mathRound } from './alias';\r\nimport { strHeight, strWidth } from './strings';\r\n\r\n/**\r\n * Compares two objects and returns true if all values of the passed prop names are identical, false otherwise or if one of the two object is falsy.\r\n * @param a Object a.\r\n * @param b Object b.\r\n * @param props The props which shall be compared.\r\n */\r\nexport const equal = <T extends PlainObject>(\r\n a: T | undefined,\r\n b: T | undefined,\r\n props: Array<keyof T> | ReadonlyArray<keyof T>,\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n propMutation?: ((value: any) => any) | null | false\r\n): boolean => {\r\n if (a && b) {\r\n let result = true;\r\n each(props, (prop) => {\r\n const compareA = propMutation ? propMutation(a[prop]) : a[prop];\r\n const compareB = propMutation ? propMutation(b[prop]) : b[prop];\r\n if (compareA !== compareB) {\r\n result = false;\r\n }\r\n });\r\n return result;\r\n }\r\n return false;\r\n};\r\n\r\n/**\r\n * Compares object a with object b and returns true if both have the same property values, false otherwise.\r\n * Also returns false if one of the objects is undefined or null.\r\n * @param a Object a.\r\n * @param b Object b.\r\n */\r\nexport const equalWH = <T>(a?: Partial<WH<T>>, b?: Partial<WH<T>>) =>\r\n equal<Partial<WH<T>>>(a, b, ['w', 'h']);\r\n\r\n/**\r\n * Compares object a with object b and returns true if both have the same property values, false otherwise.\r\n * Also returns false if one of the objects is undefined or null.\r\n * @param a Object a.\r\n * @param b Object b.\r\n */\r\nexport const equalXY = <T>(a?: Partial<XY<T>>, b?: Partial<XY<T>>) =>\r\n equal<Partial<XY<T>>>(a, b, ['x', 'y']);\r\n\r\n/**\r\n * Compares object a with object b and returns true if both have the same property values, false otherwise.\r\n * Also returns false if one of the objects is undefined or null.\r\n * @param a Object a.\r\n * @param b Object b.\r\n */\r\nexport const equalTRBL = (a?: TRBL, b?: TRBL) => equal<TRBL>(a, b, ['t', 'r', 'b', 'l']);\r\n\r\n/**\r\n * Compares two DOM Rects for their equality of their width and height properties\r\n * Also returns false if one of the DOM Rects is undefined or null.\r\n * @param a DOM Rect a.\r\n * @param b DOM Rect b.\r\n * @param round Whether the values should be rounded.\r\n */\r\nexport const equalBCRWH = (a?: DOMRect, b?: DOMRect, round?: boolean) =>\r\n equal<DOMRect>(a, b, [strWidth, strHeight], round && ((value) => mathRound(value)));\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { isNumber, isFunction } from './types';\r\nimport { from } from './array';\r\nimport { rAF, cAF, setT, clearT } from './alias';\r\n\r\ntype DebouncerFn = (task: () => void) => () => void;\r\n\r\nexport type DebounceTiming = { _debouncer: DebouncerFn } | number | false | null | undefined;\r\n\r\nexport interface DebounceOptions<FunctionToDebounce extends (...args: any) => any> {\r\n /**\r\n * The timing for debouncing. If false, null or undefined, no debounce is applied.\r\n */\r\n _debounceTiming?: DebounceTiming | (() => DebounceTiming);\r\n /**\r\n * The timing which determines when the debounced will be called even when the debounce timing did not call it yet.\r\n */\r\n _maxDebounceTiming?: DebounceTiming | (() => DebounceTiming);\r\n /**\r\n * Defines the calling on the leading edge of the timeout.\r\n */\r\n _leading?: boolean;\r\n /**\r\n * Function which merges parameters for each canceled debounce.\r\n * If parameters can't be merged the function will return null, otherwise it returns the merged parameters.\r\n */\r\n _mergeParams?: (\r\n prev: Parameters<FunctionToDebounce>,\r\n curr: Parameters<FunctionToDebounce>\r\n ) => Parameters<FunctionToDebounce> | false | null | undefined;\r\n}\r\n\r\nexport interface Debounced<FunctionToDebounce extends (...args: any) => any> {\r\n (...args: Parameters<FunctionToDebounce>): ReturnType<FunctionToDebounce>;\r\n _flush(): void;\r\n}\r\n\r\nexport const bind = <A extends any[], B extends any[], R>(\r\n fn: (...args: [...A, ...B]) => R,\r\n ...args: A\r\n): ((...args: B) => R) => fn.bind(0, ...args);\r\n\r\n/**\r\n * Creates a timeout and cleartimeout tuple. The timeout function always clears the previously created timeout before it runs.\r\n * @param timeout The timeout in ms. If no timeout (or 0) is passed requestAnimationFrame is used instead of setTimeout.\r\n * @returns A tuple with the timeout function as the first value and the clearTimeout function as the second value.\r\n */\r\nexport const selfClearTimeout = (timeout?: number | (() => number)) => {\r\n let id: number;\r\n const setTFn = timeout ? setT : rAF!;\r\n const clearTFn = timeout ? clearT : cAF!;\r\n return [\r\n (callback: () => any) => {\r\n clearTFn(id);\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n id = setTFn(() => callback(), isFunction(timeout) ? timeout() : timeout);\r\n },\r\n () => clearTFn(id),\r\n ] as [timeout: (callback: () => any) => void, clear: () => void];\r\n};\r\n\r\nconst getDebouncer = (\r\n debounceTiming: DebounceTiming | (() => DebounceTiming)\r\n): DebouncerFn | false | null | undefined | void => {\r\n const debounceTimingResult = isFunction(debounceTiming) ? debounceTiming() : debounceTiming;\r\n if (isNumber(debounceTimingResult)) {\r\n const schedule = debounceTimingResult ? setT! : rAF!;\r\n const clear = debounceTimingResult ? clearT : cAF;\r\n return (task) => {\r\n const timeoutId = schedule!(\r\n () => task(),\r\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n // @ts-ignore\r\n debounceTimingResult\r\n );\r\n return () => {\r\n clear!(timeoutId);\r\n };\r\n };\r\n }\r\n\r\n return debounceTimingResult && debounceTimingResult._debouncer;\r\n};\r\n\r\n/**\r\n * Debounces the given function either with a timeout or a animation frame.\r\n * @param functionToDebounce The function which shall be debounced.\r\n * @param options Options for debouncing.\r\n */\r\nexport const debounce = <FunctionToDebounce extends (...args: any) => any>(\r\n functionToDebounce: FunctionToDebounce,\r\n options?: DebounceOptions<FunctionToDebounce>\r\n): Debounced<FunctionToDebounce> => {\r\n const {\r\n _debounceTiming: _timeout,\r\n _maxDebounceTiming: _maxDelay,\r\n _leading,\r\n _mergeParams,\r\n } = options || {};\r\n let cancelMaxTimeoutDebouncer: (() => void) | undefined;\r\n let cancelTimeoutDebounder: (() => void) | undefined;\r\n let prevArguments: Parameters<FunctionToDebounce> | null | undefined;\r\n let latestArguments: Parameters<FunctionToDebounce> | null | undefined;\r\n let leadingInvoked: boolean | undefined;\r\n\r\n const invokeFunctionToDebounce = function (args: Parameters<FunctionToDebounce>) {\r\n if (cancelTimeoutDebounder) {\r\n cancelTimeoutDebounder();\r\n }\r\n if (cancelMaxTimeoutDebouncer) {\r\n cancelMaxTimeoutDebouncer();\r\n }\r\n\r\n leadingInvoked = cancelTimeoutDebounder = cancelMaxTimeoutDebouncer = prevArguments = undefined;\r\n // eslint-disable-next-line\r\n // @ts-ignore\r\n functionToDebounce.apply(this, args);\r\n };\r\n\r\n const mergeParms = (\r\n curr: Parameters<FunctionToDebounce>\r\n ): Parameters<FunctionToDebounce> | false | null | undefined =>\r\n _mergeParams && prevArguments ? _mergeParams(prevArguments, curr) : curr;\r\n\r\n const flush = () => {\r\n /* istanbul ignore next */\r\n if (cancelTimeoutDebounder) {\r\n invokeFunctionToDebounce(mergeParms(latestArguments!) || latestArguments!);\r\n }\r\n };\r\n\r\n const debouncedFn = function () {\r\n // eslint-disable-next-line prefer-rest-params\r\n const args: Parameters<FunctionToDebounce> = from(arguments) as Parameters<FunctionToDebounce>;\r\n const timeoutDebouncer = getDebouncer(_timeout);\r\n\r\n if (timeoutDebouncer) {\r\n const maxDelayDebouncer = getDebouncer(_maxDelay);\r\n const mergeParamsResult = mergeParms(args);\r\n const invokedArgs = mergeParamsResult || args;\r\n const boundInvoke = invokeFunctionToDebounce.bind(0, invokedArgs);\r\n\r\n if (cancelTimeoutDebounder) {\r\n cancelTimeoutDebounder();\r\n }\r\n\r\n if (_leading && !leadingInvoked) {\r\n boundInvoke();\r\n leadingInvoked = true;\r\n cancelTimeoutDebounder = timeoutDebouncer(() => (leadingInvoked = undefined));\r\n } else {\r\n cancelTimeoutDebounder = timeoutDebouncer(boundInvoke);\r\n\r\n if (maxDelayDebouncer && !cancelMaxTimeoutDebouncer) {\r\n cancelMaxTimeoutDebouncer = maxDelayDebouncer(flush);\r\n }\r\n }\r\n\r\n prevArguments = latestArguments = invokedArgs;\r\n } else {\r\n invokeFunctionToDebounce(args);\r\n }\r\n };\r\n debouncedFn._flush = flush;\r\n\r\n return debouncedFn as Debounced<FunctionToDebounce>;\r\n};\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport type { PlainObject } from '../../typings';\r\nimport { isArray, isFunction, isPlainObject, isNull } from './types';\r\nimport { each } from './array';\r\n\r\n/**\r\n * Determines whether the passed object has a property with the passed name.\r\n * @param obj The object.\r\n * @param prop The name of the property.\r\n */\r\nexport const hasOwnProperty = (obj: any, prop: string | number | symbol): boolean =>\r\n Object.prototype.hasOwnProperty.call(obj, prop);\r\n\r\n/**\r\n * Returns the names of the enumerable string properties and methods of an object.\r\n * @param obj The object of which the properties shall be returned.\r\n */\r\nexport const keys = (obj: any): Array<string> => (obj ? Object.keys(obj) : []);\r\n\r\ntype AssignDeep = {\r\n <T, U>(target: T, object1: U): T & U;\r\n <T, U, V>(target: T, object1: U, object2: V): T & U & V;\r\n <T, U, V, W>(target: T, object1: U, object2: V, object3: W): T & U & V & W;\r\n <T, U, V, W, X>(target: T, object1: U, object2: V, object3: W, object4: X): T & U & V & W & X;\r\n <T, U, V, W, X, Y>(\r\n target: T,\r\n object1: U,\r\n object2: V,\r\n object3: W,\r\n object4: X,\r\n object5: Y\r\n ): T & U & V & W & X & Y;\r\n <T, U, V, W, X, Y, Z>(\r\n target: T,\r\n object1?: U,\r\n object2?: V,\r\n object3?: W,\r\n object4?: X,\r\n object5?: Y,\r\n object6?: Z\r\n ): T & U & V & W & X & Y & Z;\r\n};\r\n\r\n// https://github.com/jquery/jquery/blob/master/src/core.js#L116\r\nexport const assignDeep: AssignDeep = <T, U, V, W, X, Y, Z>(\r\n target: T,\r\n object1?: U,\r\n object2?: V,\r\n object3?: W,\r\n object4?: X,\r\n object5?: Y,\r\n object6?: Z\r\n): T & U & V & W & X & Y & Z => {\r\n const sources: Array<any> = [object1, object2, object3, object4, object5, object6];\r\n\r\n // Handle case when target is a string or something (possible in deep copy)\r\n if ((typeof target !== 'object' || isNull(target)) && !isFunction(target)) {\r\n target = {} as T;\r\n }\r\n\r\n each(sources, (source) => {\r\n // Extend the base object\r\n each(source, (_, key) => {\r\n const copy: any = source[key];\r\n\r\n // Prevent Object.prototype pollution\r\n // Prevent never-ending loop\r\n if (target === copy) {\r\n return true;\r\n }\r\n\r\n const copyIsArray = isArray(copy);\r\n\r\n // Recurse if we're merging plain objects or arrays\r\n if (copy && isPlainObject(copy)) {\r\n const src = target[key as keyof T];\r\n let clone: any = src;\r\n\r\n // Ensure proper type for the source value\r\n if (copyIsArray && !isArray(src)) {\r\n clone = [];\r\n } else if (!copyIsArray && !isPlainObject(src)) {\r\n clone = {};\r\n }\r\n\r\n // Never move original objects, clone them\r\n target[key as keyof T] = assignDeep(clone, copy) as any;\r\n } else {\r\n target[key as keyof T] = copyIsArray ? copy.slice() : copy;\r\n }\r\n });\r\n });\r\n\r\n // Return the modified object\r\n return target as any;\r\n};\r\n\r\nexport const removeUndefinedProperties = <T extends PlainObject>(target: T, deep?: boolean): T =>\r\n each(assignDeep({}, target), (value, key, copy) => {\r\n if (value === undefined) {\r\n delete copy[key];\r\n } else if (deep && value && isPlainObject(value)) {\r\n copy[key as keyof typeof copy] = removeUndefinedProperties(value, deep) as any;\r\n }\r\n });\r\n\r\n/**\r\n * Returns true if the given object is empty, false otherwise.\r\n * @param obj The Object.\r\n */\r\nexport const isEmptyObject = (obj: any): boolean => !keys(obj).length;\r\n","export const noop = () => {};\r\n","import { mathMax, mathMin } from './alias';\r\n\r\n/**\r\n * Caps the passed number between the `min` and `max` bounds.\r\n * @param min The min bound.\r\n * @param max The max bound.\r\n * @param number The number to be capped.\r\n * @returns The capped number between min and max.\r\n */\r\nexport const capNumber = (min: number, max: number, number: number) =>\r\n mathMax(min, mathMin(max, number));\r\n","import type { HTMLElementTarget } from './types';\r\nimport { bind, deduplicateArray, each, from, isArray } from '../utils';\r\n\r\nexport type AttributeElementTarget = HTMLElementTarget | Element;\r\n\r\nexport type DomTokens = string | string[] | false | null | undefined | void;\r\n\r\nexport const getDomTokensArray = (tokens: DomTokens) =>\r\n deduplicateArray((isArray(tokens) ? tokens : (tokens || '').split(' ')).filter((token) => token));\r\n\r\n/**\r\n * Gets a attribute with the given attribute of the given element.\r\n * @param elm The element of which the attribute shall be get.\r\n * @param attrName The attribute name which shall be get.\r\n * @returns The attribute value or `null` when the attribute is not set or `false` if the element is undefined.\r\n */\r\nexport const getAttr = (elm: AttributeElementTarget, attrName: string) =>\r\n elm && elm.getAttribute(attrName);\r\n\r\n/**\r\n * Returns whether the given attribute exists on the given element.\r\n * @param elm The element.\r\n * @param attrName The attribute.\r\n * @returns A Truthy value indicates a present attrubte.\r\n */\r\nexport const hasAttr = (elm: AttributeElementTarget, attrName: string) =>\r\n elm && elm.hasAttribute(attrName);\r\n\r\n/**\r\n * Sets the given attributes to the given element.\r\n * @param elm The element of which the attributes shall be removed.\r\n * @param attrName The attribute names separated by a space.\r\n */\r\nexport const setAttrs = (\r\n elm: AttributeElementTarget,\r\n attrNames: string | string[],\r\n value: string | number | false | null | undefined\r\n) => {\r\n each(getDomTokensArray(attrNames), (attrName) => {\r\n if (elm) {\r\n elm.setAttribute(attrName, String(value || ''));\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * Removes the given attributes from the given element.\r\n * @param elm The element of which the attribute shall be removed.\r\n * @param attrName The attribute names separated by a space.\r\n */\r\nexport const removeAttrs = (elm: AttributeElementTarget, attrNames: string | string[]): void => {\r\n each(getDomTokensArray(attrNames), (attrName) => elm && elm.removeAttribute(attrName));\r\n};\r\n\r\nexport const domTokenListAttr = (elm: AttributeElementTarget, attrName: string) => {\r\n const initialArr = getDomTokensArray(getAttr(elm, attrName));\r\n const setElmAttr = bind(setAttrs, elm, attrName);\r\n const domTokenListOperation = (operationTokens: DomTokens, operation: 'add' | 'delete') => {\r\n const initialArrSet = new Set(initialArr);\r\n each(getDomTokensArray(operationTokens), (token) => {\r\n initialArrSet[operation](token);\r\n });\r\n return from(initialArrSet).join(' ');\r\n };\r\n\r\n return {\r\n _remove: (removeTokens: DomTokens) => setElmAttr(domTokenListOperation(removeTokens, 'delete')),\r\n _add: (addTokens: DomTokens) => setElmAttr(domTokenListOperation(addTokens, 'add')),\r\n _has: (hasTokens: DomTokens) => {\r\n const tokenSet = getDomTokensArray(hasTokens);\r\n return tokenSet.reduce(\r\n (boolean, token) => boolean && initialArr.includes(token),\r\n tokenSet.length > 0\r\n );\r\n },\r\n };\r\n};\r\n\r\n/**\r\n * Treats the given attribute like the \"class\" attribute and removes the given value from it.\r\n * @param elm The element.\r\n * @param attrName The attributeName to which the value shall be removed.\r\n * @param value The value which shall be removed.\r\n */\r\nexport const removeAttrClass = (\r\n elm: AttributeElementTarget,\r\n attrName: string,\r\n value: DomTokens\r\n): (() => void) => {\r\n domTokenListAttr(elm, attrName)._remove(value);\r\n return bind(addAttrClass, elm, attrName, value);\r\n};\r\n\r\n/**\r\n * Treats the given attribute like the \"class\" attribute and adds value to it.\r\n * @param elm The element.\r\n * @param attrName The attributeName to which the value shall be added.\r\n * @param value The value which shall be added.\r\n */\r\nexport const addAttrClass = (\r\n elm: AttributeElementTarget,\r\n attrName: string,\r\n value: DomTokens\r\n): (() => void) => {\r\n domTokenListAttr(elm, attrName)._add(value);\r\n return bind(removeAttrClass, elm, attrName, value);\r\n};\r\n\r\nexport const addRemoveAttrClass = (\r\n elm: AttributeElementTarget,\r\n attrName: string,\r\n value: DomTokens,\r\n add?: boolean\r\n) => (add ? addAttrClass : removeAttrClass)(elm, attrName, value);\r\n\r\n/**\r\n * Treats the given attribute like the \"class\" attribute and checks if the given value is in it.\r\n * @param elm The element.\r\n * @param attrName The attributeName from which the content shall be checked.\r\n * @param value The value.\r\n * @returns True if the given attribute has the value in it, false otherwise.\r\n */\r\nexport const hasAttrClass = (\r\n elm: AttributeElementTarget,\r\n attrName: string,\r\n value: DomTokens\r\n): boolean => domTokenListAttr(elm, attrName)._has(value);\r\n","import type { AttributeElementTarget, DomTokens } from './attribute';\r\nimport { each, from } from '../utils/array';\r\nimport { bind } from '../utils/function';\r\nimport { domTokenListAttr } from './attribute';\r\n\r\nconst createDomTokenListClass = (elm: AttributeElementTarget) => domTokenListAttr(elm, 'class');\r\n\r\n/**\r\n * Check whether the given element has the given class name(s).\r\n * @param elm The element.\r\n * @param className The class name(s).\r\n */\r\nexport const hasClass = (elm: AttributeElementTarget, className: DomTokens): boolean =>\r\n createDomTokenListClass(elm)._has(className);\r\n\r\n/**\r\n * Removes the given class name(s) from the given element.\r\n * @param elm The element.\r\n * @param className The class name(s) which shall be removed. (separated by spaces)\r\n */\r\nexport const removeClass = (elm: AttributeElementTarget, className: DomTokens): void => {\r\n createDomTokenListClass(elm)._remove(className);\r\n};\r\n\r\n/**\r\n * Adds the given class name(s) to the given element.\r\n * @param elm The element.\r\n * @param className The class name(s) which shall be added. (separated by spaces)\r\n * @returns A function which removes the added class name(s).\r\n */\r\nexport const addClass = (elm: AttributeElementTarget, className: DomTokens): (() => void) => {\r\n createDomTokenListClass(elm)._add(className);\r\n return bind(removeClass, elm, className);\r\n};\r\n\r\n/**\r\n * Takes two className strings, compares them and returns the difference as array.\r\n * @param classNameA ClassName A.\r\n * @param classNameB ClassName B.\r\n */\r\nexport const diffClass = (\r\n classNameA: string | false | null | undefined,\r\n classNameB: string | false | null | undefined\r\n) => {\r\n const set = new Set<string>(classNameA ? classNameA.split(' ') : []);\r\n\r\n each(classNameB ? classNameB.split(' ') : [], (className) => {\r\n set[set.has(className) ? 'delete' : 'add'](className);\r\n });\r\n\r\n return from(set);\r\n};\r\n","import type { NodeElementTarget } from './types';\r\nimport { isElement } from '../utils/types';\r\nimport { push, from } from '../utils/array';\r\n\r\n/**\r\n * Find all elements with the passed selector, outgoing (and including) the passed element or the document if no element was provided.\r\n * @param selector The selector which has to be searched by.\r\n * @param elm The element from which the search shall be outgoing.\r\n */\r\nexport const find = (selector: string, elm?: NodeElementTarget): Element[] => {\r\n const rootElm = elm ? isElement(elm) && elm : document;\r\n return rootElm ? from(rootElm.querySelectorAll(selector)) : [];\r\n};\r\n\r\n/**\r\n * Find the first element with the passed selector, outgoing (and including) the passed element or the document if no element was provided.\r\n * @param selector The selector which has to be searched by.\r\n * @param elm The element from which the search shall be outgoing.\r\n */\r\nexport const findFirst = (selector: string, elm?: NodeElementTarget): NodeElementTarget => {\r\n const rootElm = elm ? isElement(elm) && elm : document;\r\n return rootElm && rootElm.querySelector(selector);\r\n};\r\n\r\n/**\r\n * Determines whether the passed element is matching with the passed selector.\r\n * @param elm The element which has to be compared with the passed selector.\r\n * @param selector The selector which has to be compared with the passed element. Additional selectors: ':visible' and ':hidden'.\r\n */\r\nexport const is = (elm: NodeElementTarget, selector: string): boolean =>\r\n isElement(elm) && elm.matches(selector);\r\n\r\nexport const isBodyElement = (elm: NodeElementTarget) => is(elm, 'body'); // don't do targetElement === ownerDocument.body in case initialization happens in memory\r\n\r\n/**\r\n * Returns the children (no text-nodes or comments) of the passed element which are matching the passed selector. An empty array is returned if the passed element is null.\r\n * @param elm The element of which the children shall be returned.\r\n * @param selector The selector which must match with the children elements.\r\n */\r\nexport const children = (elm: NodeElementTarget, selector?: string): ReadonlyArray<Element> => {\r\n const childs: Array<Element> = [];\r\n\r\n return isElement(elm)\r\n ? push(\r\n childs,\r\n from(elm.children).filter((child) => (selector ? is(child, selector) : child))\r\n )\r\n : childs;\r\n};\r\n\r\n/**\r\n * Returns the childNodes (incl. text-nodes or comments etc.) of the passed element. An empty array is returned if the passed element is null.\r\n * @param elm The element of which the childNodes shall be returned.\r\n */\r\nexport const contents = (elm: NodeElementTarget): ReadonlyArray<ChildNode> =>\r\n elm ? from(elm.childNodes) : [];\r\n\r\n/**\r\n * Returns the parent element of the passed element, or null if the passed element is null.\r\n * @param elm The element of which the parent element shall be returned.\r\n */\r\nexport const parent = (elm: NodeElementTarget): NodeElementTarget => elm && elm.parentElement;\r\n\r\n/**\r\n * Returns the closest element to the passed element which matches the given selector.\r\n * @param elm The element.\r\n * @param selector The selector.\r\n * @returns The closest element to the passed element which matches the given selector.\r\n */\r\nexport const closest = (elm: NodeElementTarget, selector: string): NodeElementTarget =>\r\n isElement(elm) && elm.closest(selector);\r\n\r\n/**\r\n * Gets the focused element of the passed or default document.\r\n * @returns The focused element of the passed document.\r\n */\r\nexport const getFocusedElement = (doc?: Document) => (doc || document).activeElement;\r\n\r\n/**\r\n * Determines whether the given element lies between two selectors in the DOM.\r\n * @param elm The element.\r\n * @param highBoundarySelector The high boundary selector.\r\n * @param deepBoundarySelector The deep boundary selector.\r\n */\r\nexport const liesBetween = (\r\n elm: NodeElementTarget,\r\n highBoundarySelector: string,\r\n deepBoundarySelector: string\r\n): boolean => {\r\n const closestHighBoundaryElm = closest(elm, highBoundarySelector);\r\n const closestDeepBoundaryElm = elm && findFirst(deepBoundarySelector, closestHighBoundaryElm);\r\n const deepBoundaryIsValid =\r\n closest(closestDeepBoundaryElm, highBoundarySelector) === closestHighBoundaryElm;\r\n\r\n return closestHighBoundaryElm && closestDeepBoundaryElm\r\n ? closestHighBoundaryElm === elm ||\r\n closestDeepBoundaryElm === elm ||\r\n (deepBoundaryIsValid &&\r\n closest(closest(elm, deepBoundarySelector), highBoundarySelector) !==\r\n closestHighBoundaryElm)\r\n : false;\r\n};\r\n","import type { NodeElementTarget, NodeElementTargetCollection } from './types';\r\nimport { createOrKeepArray, each } from '../utils/array';\r\nimport { parent } from './traversal';\r\nimport { bind } from '../utils';\r\n\r\n/**\r\n * Removes the given Nodes from their parent.\r\n * @param nodes The Nodes which shall be removed.\r\n */\r\nexport const removeElements = (nodes: NodeElementTargetCollection): void => {\r\n each(createOrKeepArray(nodes), (node) => {\r\n const parentElm = parent(node);\r\n if (node && parentElm) {\r\n parentElm.removeChild(node);\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * Appends the given children at the end of the given Node.\r\n * @param node The Node to which the children shall be appended.\r\n * @param children The Nodes which shall be appended.\r\n * @returns A function which removes the inserted nodes.\r\n */\r\nexport const appendChildren = (node: NodeElementTarget, children: NodeElementTargetCollection) =>\r\n bind(\r\n removeElements,\r\n node &&\r\n children &&\r\n each(createOrKeepArray(children), (child) => {\r\n if (child) {\r\n node.appendChild(child);\r\n }\r\n })\r\n );\r\n","// at the time of implementation TypeScript doesn't offer any TrustedTypes typescript definitions\r\n// https://github.com/microsoft/TypeScript/issues/30024\r\nlet trustedTypePolicy: unknown | undefined;\r\n\r\nexport const getTrustedTypePolicy = () => trustedTypePolicy;\r\nexport const setTrustedTypePolicy = (newTrustedTypePolicy: unknown | undefined) => {\r\n trustedTypePolicy = newTrustedTypePolicy;\r\n};\r\n","import { each } from '../utils/array';\r\nimport { setAttrs } from './attribute';\r\nimport { contents } from './traversal';\r\nimport { removeElements } from './manipulation';\r\nimport { getTrustedTypePolicy } from '../../trustedTypePolicy';\r\n\r\n/**\r\n * Creates a div DOM node.\r\n */\r\nexport const createDiv = (classNames?: string): HTMLDivElement => {\r\n const div = document.createElement('div');\r\n setAttrs(div, 'class', classNames);\r\n return div;\r\n};\r\n\r\n/**\r\n * Creates DOM nodes modeled after the passed html string and returns the root dom nodes as a array.\r\n * @param html The html string after which the DOM nodes shall be created.\r\n */\r\nexport const createDOM = (html: string): ReadonlyArray<Node> => {\r\n const createdDiv = createDiv();\r\n const trustedTypesPolicy = getTrustedTypePolicy();\r\n const trimmedHtml = html.trim();\r\n createdDiv.innerHTML = trustedTypesPolicy\r\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (trustedTypesPolicy as any).createHTML(trimmedHtml)\r\n : trimmedHtml;\r\n\r\n return each(contents(createdDiv), (elm) => removeElements(elm));\r\n};\r\n","import type { PlainObject, StyleObject, StyleObjectKey, StyleObjectValue } from '../../typings';\r\nimport type { XY } from './offset';\r\nimport type { HTMLElementTarget } from './types';\r\nimport { wnd } from '../utils/alias';\r\nimport { each, from } from '../utils/array';\r\nimport { isString, isNumber, isObject, isNull, isBoolean } from '../utils/types';\r\n\r\nexport interface TRBL {\r\n t: number;\r\n r: number;\r\n b: number;\r\n l: number;\r\n}\r\n\r\nconst getCSSVal = (computedStyle: CSSStyleDeclaration, prop: StyleObjectKey): string =>\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n computedStyle.getPropertyValue(prop) || computedStyle[prop as any] || '';\r\n\r\nconst validFiniteNumber = (number: number) => {\r\n const notNaN = number || 0;\r\n return isFinite(notNaN) ? notNaN : 0;\r\n};\r\n\r\nconst parseToZeroOrNumber = (value?: string): number => validFiniteNumber(parseFloat(value || ''));\r\n\r\nexport const roundCssNumber = (value: number) => Math.round(value * 10000) / 10000;\r\n\r\nexport const ratioToCssPercent = (ratio: number) =>\r\n `${roundCssNumber(validFiniteNumber(ratio) * 100)}%`;\r\n\r\nexport const numberToCssPx = (number: number) => `${roundCssNumber(validFiniteNumber(number))}px`;\r\n\r\nexport function setStyles(\r\n elm: HTMLElementTarget,\r\n styles: StyleObject | false | null | undefined\r\n): void {\r\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\r\n elm &&\r\n styles &&\r\n each(styles, (rawValue: StyleObjectValue, name) => {\r\n try {\r\n const elmStyle = elm.style;\r\n const value =\r\n isNull(rawValue) || isBoolean(rawValue)\r\n ? ''\r\n : isNumber(rawValue)\r\n ? numberToCssPx(rawValue)\r\n : rawValue;\r\n\r\n if (name.indexOf('--') === 0) {\r\n elmStyle.setProperty(name, value);\r\n } else {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n elmStyle[name as any] = value;\r\n }\r\n // eslint-disable-next-line no-empty\r\n } catch {}\r\n });\r\n}\r\n\r\nexport function getStyles(\r\n elm: HTMLElementTarget,\r\n styles: Array<StyleObjectKey> | ReadonlyArray<StyleObjectKey>,\r\n pseudoElm?: string | null | undefined\r\n): Partial<Record<StyleObjectKey, string>>;\r\nexport function getStyles(\r\n elm: HTMLElementTarget,\r\n styles: StyleObjectKey,\r\n pseudoElm?: string | null | undefined\r\n): string;\r\nexport function getStyles(\r\n elm: HTMLElementTarget,\r\n styles: Array<StyleObjectKey> | ReadonlyArray<StyleObjectKey> | StyleObjectKey,\r\n pseudoElm?: string | null | undefined\r\n): Partial<Record<StyleObjectKey, string>> | string {\r\n const getSingleStyle = isString(styles);\r\n let getStylesResult: string | PlainObject = getSingleStyle ? '' : {};\r\n\r\n if (elm) {\r\n const computedStyle = wnd.getComputedStyle(elm, pseudoElm) || elm.style;\r\n getStylesResult = getSingleStyle\r\n ? getCSSVal(computedStyle, styles)\r\n : from(styles).reduce((result, key) => {\r\n result[key] = getCSSVal(computedStyle, key);\r\n return result;\r\n }, getStylesResult as PlainObject);\r\n }\r\n return getStylesResult;\r\n}\r\n\r\n/**\r\n * Returns the top right bottom left values of the passed css property.\r\n * @param elm The element of which the values shall be returned.\r\n * @param propertyPrefix The css property prefix. (e.g. \"border\")\r\n * @param propertySuffix The css property suffix. (e.g. \"width\")\r\n */\r\nexport const topRightBottomLeft = (\r\n elm?: HTMLElementTarget,\r\n propertyPrefix?: string,\r\n propertySuffix?: string\r\n): TRBL => {\r\n const finalPrefix = propertyPrefix ? `${propertyPrefix}-` : '';\r\n const finalSuffix = propertySuffix ? `-${propertySuffix}` : '';\r\n const top = `${finalPrefix}top${finalSuffix}` as StyleObjectKey;\r\n const right = `${finalPrefix}right${finalSuffix}` as StyleObjectKey;\r\n const bottom = `${finalPrefix}bottom${finalSuffix}` as StyleObjectKey;\r\n const left = `${finalPrefix}left${finalSuffix}` as StyleObjectKey;\r\n const result = getStyles(elm, [top, right, bottom, left]);\r\n return {\r\n t: parseToZeroOrNumber(result[top]),\r\n r: parseToZeroOrNumber(result[right]),\r\n b: parseToZeroOrNumber(result[bottom]),\r\n l: parseToZeroOrNumber(result[left]),\r\n };\r\n};\r\n\r\nexport const getTrasformTranslateValue = (\r\n value: string | number | XY<string | number>,\r\n isHorizontal?: boolean\r\n) =>\r\n `translate${\r\n isObject(value) ? `(${value.x},${value.y})` : `${isHorizontal ? 'X' : 'Y'}(${value})`\r\n }`;\r\n","import type { HTMLElementTarget } from './types';\r\nimport { getStyles } from './style';\r\nimport { mathRound, wnd } from '../utils/alias';\r\nimport { bind } from '../utils/function';\r\nimport { strHeight, strWidth } from '../utils/strings';\r\n\r\nexport interface WH<T = number> {\r\n w: T;\r\n h: T;\r\n}\r\n\r\nconst elementHasDimensions = (elm: HTMLElement): boolean =>\r\n !!(elm.offsetWidth || elm.offsetHeight || elm.getClientRects().length);\r\nconst zeroObj: WH = {\r\n w: 0,\r\n h: 0,\r\n};\r\n\r\nconst getElmWidthHeightProperty = <E extends HTMLElement | Window>(\r\n property: E extends HTMLElement ? 'client' | 'offset' | 'scroll' : 'inner',\r\n elm: E | false | null | undefined\r\n): Readonly<WH> =>\r\n elm\r\n ? {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n w: (elm as any)[`${property}Width`],\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n h: (elm as any)[`${property}Height`],\r\n }\r\n : zeroObj;\r\n\r\n/**\r\n * Returns the window inner- width and height.\r\n */\r\nexport const getWindowSize = (customWnd?: Window): Readonly<WH> =>\r\n getElmWidthHeightProperty('inner', customWnd || wnd);\r\n\r\n/**\r\n * Returns the scroll- width and height of the passed element. If the element is null the width and height values are 0.\r\n * @param elm The element of which the scroll- width and height shall be returned.\r\n */\r\nexport const getOffsetSize = bind(getElmWidthHeightProperty<HTMLElement>, 'offset') satisfies (\r\n elm: HTMLElementTar