Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/src/html/pages/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@
</button>
<p id="replayStats">0s</p>
</div>
<div id="wordsWrapper">
<div id="replayWordsWrapper">
<div id="replayWords" class="words"></div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/pages/account-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down Expand Up @@ -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();
Expand Down
13 changes: 8 additions & 5 deletions frontend/src/ts/utils/caret.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
35 changes: 35 additions & 0 deletions frontend/src/ts/utils/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
JSAnimation,
} from "animejs";

// Implementation
/**
* Query Selector
*
Expand All @@ -13,6 +14,7 @@ import {
export function qs<T extends HTMLElement = HTMLElement>(
selector: string,
): ElementWithUtils<T> | null {
checkUniqueSelector(selector);
const el = document.querySelector<T>(selector);
return el ? new ElementWithUtils(el) : null;
}
Expand Down Expand Up @@ -44,6 +46,7 @@ export function qsa<T extends HTMLElement = HTMLElement>(
export function qsr<T extends HTMLElement = HTMLElement>(
selector: string,
): ElementWithUtils<T> {
checkUniqueSelector(selector);
const el = document.querySelector<T>(selector);
if (el === null) {
throw new Error(`Required element not found: ${selector}`);
Expand Down Expand Up @@ -349,6 +352,7 @@ export class ElementWithUtils<T extends HTMLElement = HTMLElement> {
* Query the element for a child element matching the selector
*/
qs<U extends HTMLElement>(selector: string): ElementWithUtils<U> | null {
checkUniqueSelector(selector, this);
const found = this.native.querySelector<U>(selector);
return found ? new ElementWithUtils(found) : null;
}
Expand All @@ -372,6 +376,7 @@ export class ElementWithUtils<T extends HTMLElement = HTMLElement> {
* @throws Error if the element is not found.
*/
qsr<U extends HTMLElement>(selector: string): ElementWithUtils<U> {
checkUniqueSelector(selector, this);
const found = this.native.querySelector<U>(selector);
if (found === null) {
throw new Error(`Required element not found: ${selector}`);
Expand Down Expand Up @@ -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 = `
<div class="container">
<div class="icon lefticon"><i class="fas fa-fw fa-exclamation-triangle"></i></div>
<div class="text">
"Warning: qs/qsr detected selector(s) matching multiple elements, check console for details."
</div>
</div>
</div>`;
bannerCenter?.appendChild(warning);
}
}
Loading