diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2024-08-30 17:21:18 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2024-08-30 17:21:18 +0800 |
| commit | efbc2ffe6a1ee5ec38a4396305561d6515d0943e (patch) | |
| tree | 2b4c94f18f2c792dfda813050755d5c0273fae22 /node_modules/swup/src/utils | |
| parent | 43acceb75957c880a5ba5a31aae221394a36d5f6 (diff) | |
node fixes, updates
Diffstat (limited to 'node_modules/swup/src/utils')
| -rw-r--r-- | node_modules/swup/src/utils/index.ts | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/node_modules/swup/src/utils/index.ts b/node_modules/swup/src/utils/index.ts new file mode 100644 index 00000000..2d0e77a2 --- /dev/null +++ b/node_modules/swup/src/utils/index.ts @@ -0,0 +1,68 @@ +/** Find an element by selector. */ +export const query = (selector: string, context: Document | Element = document) => { + return context.querySelector<HTMLElement>(selector); +}; + +/** Find a set of elements by selector. */ +export const queryAll = ( + selector: string, + context: Document | Element = document +): HTMLElement[] => { + return Array.from(context.querySelectorAll(selector)); +}; + +/** Return a Promise that resolves after the next event loop. */ +export const nextTick = (): Promise<void> => { + return new Promise((resolve) => { + requestAnimationFrame(() => { + requestAnimationFrame(() => { + resolve(); + }); + }); + }); +}; + +/** Check if an object is a Promise or a Thenable */ +export function isPromise<T>(obj: unknown): obj is PromiseLike<T> { + return ( + !!obj && + (typeof obj === 'object' || typeof obj === 'function') && + typeof (obj as Record<string, unknown>).then === 'function' + ); +} + +/** Call a function as a Promise. Resolves with the returned Promsise or immediately. */ +// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any +export function runAsPromise(func: Function, args: unknown[] = []): Promise<unknown> { + return new Promise((resolve, reject) => { + const result: unknown = func(...args); + if (isPromise(result)) { + result.then(resolve, reject); + } else { + resolve(result); + } + }); +} + +/** + * Force a layout reflow, e.g. after adding classnames + * @see https://stackoverflow.com/a/21665117/3759615 + */ +export function forceReflow(element?: HTMLElement): void { + element = element || document.body; + element?.getBoundingClientRect(); +} + +/** + * Read data attribute from closest element with that attribute. + * + * Returns `undefined` if no element is found or attribute is missing. + * Returns `true` if attribute is present without a value. + */ +export function getContextualAttr( + el: Element | undefined, + attr: string +): string | boolean | undefined { + const target = el?.closest(`[${attr}]`); + return target?.hasAttribute(attr) ? target?.getAttribute(attr) || true : undefined; +} |
