diff --git a/frontend/src/html/pages/test.html b/frontend/src/html/pages/test.html index 95ad7beed8a8..f2d8f33c8140 100644 --- a/frontend/src/html/pages/test.html +++ b/frontend/src/html/pages/test.html @@ -417,7 +417,7 @@

0s

-
+
diff --git a/frontend/src/ts/pages/account-settings.ts b/frontend/src/ts/pages/account-settings.ts index ab7ea2378da8..66de98e1a522 100644 --- a/frontend/src/ts/pages/account-settings.ts +++ b/frontend/src/ts/pages/account-settings.ts @@ -12,7 +12,7 @@ import * as BlockedUserTable from "../elements/account-settings/blocked-user-tab import * as Notifications from "../elements/notifications"; import { z } from "zod"; import * as AuthEvent from "../observables/auth-event"; -import { qs, qsr, onWindowLoad } from "../utils/dom"; +import { qs, qsa, qsr, onWindowLoad } from "../utils/dom"; const pageElement = qsr(".page.pageAccountSettings"); @@ -165,7 +165,7 @@ qs(".page.pageAccountSettings")?.onChild("click", ".tabs button", (event) => { page.setUrlParams(state); }); -qs( +qsa( ".page.pageAccountSettings .section.discordIntegration .getLinkAndGoToOauth", )?.on("click", () => { Loader.show(); diff --git a/frontend/src/ts/utils/caret.ts b/frontend/src/ts/utils/caret.ts index d782ebf28c7b..60c603c482ba 100644 --- a/frontend/src/ts/utils/caret.ts +++ b/frontend/src/ts/utils/caret.ts @@ -297,13 +297,16 @@ export class Caret { // we also clamp the letterIndex to be within the range of actual letters // anything beyond just goes to the edge of the word let side: "beforeLetter" | "afterLetter" = "beforeLetter"; - if ( - options.letterIndex >= letters.length || - (Config.blindMode && options.letterIndex >= wordText.length) - ) { + if (options.letterIndex >= letters.length) { side = "afterLetter"; - options.letterIndex = letters.length - 1; + + if (Config.blindMode) { + options.letterIndex = wordText?.length - 1; + } else { + options.letterIndex = letters.length - 1; + } } + if (options.letterIndex < 0) { options.letterIndex = 0; } diff --git a/frontend/src/ts/utils/dom.ts b/frontend/src/ts/utils/dom.ts index 7c5d808ffb2e..025b7b0496c7 100644 --- a/frontend/src/ts/utils/dom.ts +++ b/frontend/src/ts/utils/dom.ts @@ -4,6 +4,7 @@ import { JSAnimation, } from "animejs"; +// Implementation /** * Query Selector * @@ -13,6 +14,7 @@ import { export function qs( selector: string, ): ElementWithUtils | null { + checkUniqueSelector(selector); const el = document.querySelector(selector); return el ? new ElementWithUtils(el) : null; } @@ -44,6 +46,7 @@ export function qsa( export function qsr( selector: string, ): ElementWithUtils { + checkUniqueSelector(selector); const el = document.querySelector(selector); if (el === null) { throw new Error(`Required element not found: ${selector}`); @@ -349,6 +352,7 @@ export class ElementWithUtils { * Query the element for a child element matching the selector */ qs(selector: string): ElementWithUtils | null { + checkUniqueSelector(selector, this); const found = this.native.querySelector(selector); return found ? new ElementWithUtils(found) : null; } @@ -372,6 +376,7 @@ export class ElementWithUtils { * @throws Error if the element is not found. */ qsr(selector: string): ElementWithUtils { + checkUniqueSelector(selector, this); const found = this.native.querySelector(selector); if (found === null) { throw new Error(`Required element not found: ${selector}`); @@ -691,3 +696,33 @@ export class ElementsWithUtils< return this; } } + +function checkUniqueSelector( + selector: string, + parent?: ElementWithUtils, +): void { + if (!import.meta.env.DEV) return; + const elements = parent ? parent.qsa(selector) : qsa(selector); + if (elements.length > 1) { + console.warn( + `Multiple elements found for selector "${selector}". Did you mean to use QSA? If not, try making the query more specific.`, + elements.native, + ); + console.trace("Stack trace for qs/qsr call:"); + if (document.querySelector("#domUtilsQsWarning") !== null) return; + + const bannerCenter = document.querySelector("#bannerCenter"); + const warning = document.createElement("div"); + warning.classList.add("psa", "bad", "content-grid"); + warning.id = "domUtilsQsWarning"; + warning.innerHTML = ` +
+
+
+ "Warning: qs/qsr detected selector(s) matching multiple elements, check console for details." +
+
+ `; + bannerCenter?.appendChild(warning); + } +}