diff options
| author | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-03-09 14:28:01 +0900 |
|---|---|---|
| committer | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-03-09 14:28:01 +0900 |
| commit | be7e3b9a0cb81b78a744993fef2fa2fd2833fa9c (patch) | |
| tree | c82e18ce93ec0a24c57d7e36eb54a09266b3a25b /packages/frontend/src/scripts/focus-trap.ts | |
| parent | enhnace(frontend): 文字列比較のためのローマナイズを強化(... (diff) | |
| download | sharkey-be7e3b9a0cb81b78a744993fef2fa2fd2833fa9c.tar.gz sharkey-be7e3b9a0cb81b78a744993fef2fa2fd2833fa9c.tar.bz2 sharkey-be7e3b9a0cb81b78a744993fef2fa2fd2833fa9c.zip | |
refactor(frontend): scripts -> utility
Diffstat (limited to 'packages/frontend/src/scripts/focus-trap.ts')
| -rw-r--r-- | packages/frontend/src/scripts/focus-trap.ts | 134 |
1 files changed, 0 insertions, 134 deletions
diff --git a/packages/frontend/src/scripts/focus-trap.ts b/packages/frontend/src/scripts/focus-trap.ts deleted file mode 100644 index fb7caea830..0000000000 --- a/packages/frontend/src/scripts/focus-trap.ts +++ /dev/null @@ -1,134 +0,0 @@ -/* - * SPDX-FileCopyrightText: syuilo and misskey-project - * SPDX-License-Identifier: AGPL-3.0-only - */ -import { getHTMLElementOrNull } from '@/scripts/get-dom-node-or-null.js'; - -const focusTrapElements = new Set<HTMLElement>(); -const ignoreElements = [ - 'script', - 'style', -]; - -function containsFocusTrappedElements(el: HTMLElement): boolean { - return Array.from(focusTrapElements).some((focusTrapElement) => { - return el.contains(focusTrapElement); - }); -} - -function getZIndex(el: HTMLElement): number { - const zIndex = parseInt(window.getComputedStyle(el).zIndex || '0', 10); - if (isNaN(zIndex)) { - return 0; - } - return zIndex; -} - -function getHighestZIndexElement(): { el: HTMLElement; zIndex: number; } | null { - let highestZIndexElement: HTMLElement | null = null; - let highestZIndex = -Infinity; - - focusTrapElements.forEach((el) => { - const zIndex = getZIndex(el); - if (zIndex > highestZIndex) { - highestZIndex = zIndex; - highestZIndexElement = el; - } - }); - - return highestZIndexElement == null ? null : { - el: highestZIndexElement, - zIndex: highestZIndex, - }; -} - -function releaseFocusTrap(el: HTMLElement): void { - focusTrapElements.delete(el); - if (el.inert === true) { - el.inert = false; - } - - const highestZIndexElement = getHighestZIndexElement(); - - if (el.parentElement != null && el !== document.body) { - el.parentElement.childNodes.forEach((siblingNode) => { - const siblingEl = getHTMLElementOrNull(siblingNode); - if (!siblingEl) return; - if ( - siblingEl !== el && - ( - highestZIndexElement == null || - siblingEl === highestZIndexElement.el || - siblingEl.contains(highestZIndexElement.el) - ) - ) { - siblingEl.inert = false; - } else if ( - highestZIndexElement != null && - siblingEl !== highestZIndexElement.el && - !siblingEl.contains(highestZIndexElement.el) && - !ignoreElements.includes(siblingEl.tagName.toLowerCase()) - ) { - siblingEl.inert = true; - } else { - siblingEl.inert = false; - } - }); - releaseFocusTrap(el.parentElement); - } -} - -export function focusTrap(el: HTMLElement, hasInteractionWithOtherFocusTrappedEls: boolean, parent: true): void; -export function focusTrap(el: HTMLElement, hasInteractionWithOtherFocusTrappedEls?: boolean, parent?: false): { release: () => void; }; -export function focusTrap(el: HTMLElement, hasInteractionWithOtherFocusTrappedEls = false, parent = false): { release: () => void; } | void { - const highestZIndexElement = getHighestZIndexElement(); - - const highestZIndex = highestZIndexElement == null ? -Infinity : highestZIndexElement.zIndex; - const zIndex = getZIndex(el); - - // If the element has a lower z-index than the highest z-index element, focus trap the highest z-index element instead - // Focus trapping for this element will be done in the release function - if (!parent && zIndex < highestZIndex) { - focusTrapElements.add(el); - if (highestZIndexElement) { - focusTrap(highestZIndexElement.el, hasInteractionWithOtherFocusTrappedEls); - } - return { - release: () => { - releaseFocusTrap(el); - }, - }; - } - - if (el.inert === true) { - el.inert = false; - } - - if (el.parentElement != null && el !== document.body) { - el.parentElement.childNodes.forEach((siblingNode) => { - const siblingEl = getHTMLElementOrNull(siblingNode); - if (!siblingEl) return; - if ( - siblingEl !== el && - ( - hasInteractionWithOtherFocusTrappedEls === false || - (!focusTrapElements.has(siblingEl) && !containsFocusTrappedElements(siblingEl)) - ) && - !ignoreElements.includes(siblingEl.tagName.toLowerCase()) - ) { - siblingEl.inert = true; - } - }); - focusTrap(el.parentElement, hasInteractionWithOtherFocusTrappedEls, true); - } - - if (!parent) { - focusTrapElements.add(el); - - return { - release: () => { - releaseFocusTrap(el); - }, - }; - } -} |