From 296d41874f5e2fe9ddd518f8d2fbc2fa563929a0 Mon Sep 17 00:00:00 2001 From: Dustin Brett Date: Fri, 23 May 2025 10:24:16 -0700 Subject: [PATCH] Safer query selectors --- .../FileManager/useFileKeyboardShortcuts.ts | 15 ++++++++++----- .../Files/FileManager/useFocusableEntries.ts | 18 +++++++++++------- hooks/useGlobalKeyboardShortcuts.ts | 15 +++++++++++---- utils/functions.ts | 16 +++++++++++----- 4 files changed, 43 insertions(+), 21 deletions(-) diff --git a/components/system/Files/FileManager/useFileKeyboardShortcuts.ts b/components/system/Files/FileManager/useFileKeyboardShortcuts.ts index bcb5f8c6..798ed9ed 100644 --- a/components/system/Files/FileManager/useFileKeyboardShortcuts.ts +++ b/components/system/Files/FileManager/useFileKeyboardShortcuts.ts @@ -276,11 +276,16 @@ const useFileKeyboardShortcuts = ( if (focusOnEntry) { blurEntry(); focusEntry(focusOnEntry); - fileManagerRef.current - ?.querySelector( - `button[aria-label='${focusOnEntry.replace(SHORTCUT_EXTENSION, "")}']` - ) - ?.scrollIntoView(); + + try { + fileManagerRef.current + ?.querySelector( + `button[aria-label='${CSS.escape(focusOnEntry.replace(SHORTCUT_EXTENSION, ""))}']` + ) + ?.scrollIntoView(); + } catch { + // Ignore error getting/scrolling element + } } } } diff --git a/components/system/Files/FileManager/useFocusableEntries.ts b/components/system/Files/FileManager/useFocusableEntries.ts index af698924..63dd3dc2 100644 --- a/components/system/Files/FileManager/useFocusableEntries.ts +++ b/components/system/Files/FileManager/useFocusableEntries.ts @@ -134,14 +134,18 @@ const useFocusableEntries = ( ); if (lines.length > 1) { - const element = fileManagerRef.current?.querySelector( - `[aria-label='${textLabel}'] figcaption` - ); + try { + const element = fileManagerRef.current?.querySelector( + `[aria-label='${CSS.escape(textLabel)}'] figcaption` + ); - if (element) { - $labelHeightOffset = - (lines.length - 1) * - Number.parseFloat(window.getComputedStyle(element).lineHeight); + if (element) { + $labelHeightOffset = + (lines.length - 1) * + Number.parseFloat(window.getComputedStyle(element).lineHeight); + } + } catch { + // Ignore error getting element } } } diff --git a/hooks/useGlobalKeyboardShortcuts.ts b/hooks/useGlobalKeyboardShortcuts.ts index 4f6e1153..11e13771 100644 --- a/hooks/useGlobalKeyboardShortcuts.ts +++ b/hooks/useGlobalKeyboardShortcuts.ts @@ -22,10 +22,17 @@ declare global { } } -export const getNavButtonByTitle = (title: string): HTMLButtonElement | null => - document.querySelector( - `main > nav > div[title='${title}']` - ) as HTMLButtonElement; +export const getNavButtonByTitle = ( + title: string +): HTMLButtonElement | undefined => { + try { + return document.querySelector( + `main > nav > div[title='${CSS.escape(title)}']` + ) as HTMLButtonElement; + } catch { + return undefined; + } +}; let metaDown = false; let metaComboUsed = false; diff --git a/utils/functions.ts b/utils/functions.ts index a0a81226..270858f8 100644 --- a/utils/functions.ts +++ b/utils/functions.ts @@ -510,11 +510,17 @@ export const updateIconPositionsIfEmpty = ( const entryUrl = join(url, entry); if (!iconPositions[entryUrl]) { - const gridEntry = [...gridElement.children].find((element) => - element.querySelector( - `button[aria-label="${entry.replace(SHORTCUT_EXTENSION, "")}"]` - ) - ); + let gridEntry: Element | undefined; + + try { + gridEntry = [...gridElement.children].find((element) => + element.querySelector( + `button[aria-label="${CSS.escape(entry.replace(SHORTCUT_EXTENSION, ""))}"]` + ) + ); + } catch { + // Ignore error getting element + } if (gridEntry instanceof HTMLElement) { const { x, y, height, width } = gridEntry.getBoundingClientRect();