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);
+ }
+}