Skip to content

Commit 36b59ae

Browse files
fehmerMiodec
andauthored
impr: add multiple elements found warning in dom utils (@fehmer) (monkeytypegame#7242)
Co-authored-by: Miodec <[email protected]>
1 parent 65aadb7 commit 36b59ae

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

frontend/src/html/pages/test.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@
417417
</button>
418418
<p id="replayStats">0s</p>
419419
</div>
420-
<div id="wordsWrapper">
420+
<div id="replayWordsWrapper">
421421
<div id="replayWords" class="words"></div>
422422
</div>
423423
</div>

frontend/src/ts/pages/account-settings.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import * as BlockedUserTable from "../elements/account-settings/blocked-user-tab
1212
import * as Notifications from "../elements/notifications";
1313
import { z } from "zod";
1414
import * as AuthEvent from "../observables/auth-event";
15-
import { qs, qsr, onWindowLoad } from "../utils/dom";
15+
import { qs, qsa, qsr, onWindowLoad } from "../utils/dom";
1616

1717
const pageElement = qsr(".page.pageAccountSettings");
1818

@@ -165,7 +165,7 @@ qs(".page.pageAccountSettings")?.onChild("click", ".tabs button", (event) => {
165165
page.setUrlParams(state);
166166
});
167167

168-
qs(
168+
qsa(
169169
".page.pageAccountSettings .section.discordIntegration .getLinkAndGoToOauth",
170170
)?.on("click", () => {
171171
Loader.show();

frontend/src/ts/utils/dom.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
JSAnimation,
55
} from "animejs";
66

7+
// Implementation
78
/**
89
* Query Selector
910
*
@@ -13,6 +14,7 @@ import {
1314
export function qs<T extends HTMLElement = HTMLElement>(
1415
selector: string,
1516
): ElementWithUtils<T> | null {
17+
checkUniqueSelector(selector);
1618
const el = document.querySelector<T>(selector);
1719
return el ? new ElementWithUtils(el) : null;
1820
}
@@ -44,6 +46,7 @@ export function qsa<T extends HTMLElement = HTMLElement>(
4446
export function qsr<T extends HTMLElement = HTMLElement>(
4547
selector: string,
4648
): ElementWithUtils<T> {
49+
checkUniqueSelector(selector);
4750
const el = document.querySelector<T>(selector);
4851
if (el === null) {
4952
throw new Error(`Required element not found: ${selector}`);
@@ -349,6 +352,7 @@ export class ElementWithUtils<T extends HTMLElement = HTMLElement> {
349352
* Query the element for a child element matching the selector
350353
*/
351354
qs<U extends HTMLElement>(selector: string): ElementWithUtils<U> | null {
355+
checkUniqueSelector(selector, this);
352356
const found = this.native.querySelector<U>(selector);
353357
return found ? new ElementWithUtils(found) : null;
354358
}
@@ -372,6 +376,7 @@ export class ElementWithUtils<T extends HTMLElement = HTMLElement> {
372376
* @throws Error if the element is not found.
373377
*/
374378
qsr<U extends HTMLElement>(selector: string): ElementWithUtils<U> {
379+
checkUniqueSelector(selector, this);
375380
const found = this.native.querySelector<U>(selector);
376381
if (found === null) {
377382
throw new Error(`Required element not found: ${selector}`);
@@ -691,3 +696,33 @@ export class ElementsWithUtils<
691696
return this;
692697
}
693698
}
699+
700+
function checkUniqueSelector(
701+
selector: string,
702+
parent?: ElementWithUtils,
703+
): void {
704+
if (!import.meta.env.DEV) return;
705+
const elements = parent ? parent.qsa(selector) : qsa(selector);
706+
if (elements.length > 1) {
707+
console.warn(
708+
`Multiple elements found for selector "${selector}". Did you mean to use QSA? If not, try making the query more specific.`,
709+
elements.native,
710+
);
711+
console.trace("Stack trace for qs/qsr call:");
712+
if (document.querySelector("#domUtilsQsWarning") !== null) return;
713+
714+
const bannerCenter = document.querySelector("#bannerCenter");
715+
const warning = document.createElement("div");
716+
warning.classList.add("psa", "bad", "content-grid");
717+
warning.id = "domUtilsQsWarning";
718+
warning.innerHTML = `
719+
<div class="container">
720+
<div class="icon lefticon"><i class="fas fa-fw fa-exclamation-triangle"></i></div>
721+
<div class="text">
722+
"Warning: qs/qsr detected selector(s) matching multiple elements, check console for details."
723+
</div>
724+
</div>
725+
</div>`;
726+
bannerCenter?.appendChild(warning);
727+
}
728+
}

0 commit comments

Comments
 (0)