diff --git a/frontend/src/ts/event-handlers/about.ts b/frontend/src/ts/event-handlers/about.ts index d1c66c86a3ec..0cde61d83e88 100644 --- a/frontend/src/ts/event-handlers/about.ts +++ b/frontend/src/ts/event-handlers/about.ts @@ -1,14 +1,11 @@ import * as SupportPopup from "../modals/support"; import * as ContactModal from "../modals/contact"; +import { qs } from "../utils/dom"; -document - .querySelector("#pageAbout #supportMeAboutButton") - ?.addEventListener("click", () => { - SupportPopup.show(); - }); +qs("#pageAbout #supportMeAboutButton")?.on("click", () => { + SupportPopup.show(); +}); -document - .querySelector("#pageAbout #contactPopupButton2") - ?.addEventListener("click", () => { - ContactModal.show(); - }); +qs("#pageAbout #contactPopupButton2")?.on("click", () => { + ContactModal.show(); +}); diff --git a/frontend/src/ts/event-handlers/account.ts b/frontend/src/ts/event-handlers/account.ts index d852e07144f6..c2f8f97e6a6f 100644 --- a/frontend/src/ts/event-handlers/account.ts +++ b/frontend/src/ts/event-handlers/account.ts @@ -7,18 +7,19 @@ import * as EditResultTagsModal from "../modals/edit-result-tags"; import * as AddFilterPresetModal from "../modals/new-filter-preset"; import { parseWithSchema as parseJsonWithSchema } from "@monkeytype/util/json"; import { z } from "zod"; +import { qs } from "../utils/dom"; -const accountPage = document.querySelector("#pageAccount") as HTMLElement; +const accountPage = qs("#pageAccount"); -$(accountPage).on("click", ".pbsTime .showAllButton", () => { +accountPage?.onChild("click", ".pbsTime .showAllButton", () => { PbTablesModal.show("time"); }); -$(accountPage).on("click", ".pbsWords .showAllButton", () => { +accountPage?.onChild("click", ".pbsWords .showAllButton", () => { PbTablesModal.show("words"); }); -$(accountPage).on("click", ".editProfileButton", () => { +accountPage?.onChild("click", ".editProfileButton", () => { if (!isAuthenticated()) { Notifications.add("You must be logged in to edit your profile", 0); return; @@ -40,9 +41,10 @@ $(accountPage).on("click", ".editProfileButton", () => { const TagsArraySchema = z.array(z.string()); -$(accountPage).on("click", ".group.history .resultEditTagsButton", (e) => { - const resultid = $(e.target).attr("data-result-id"); - const tags = $(e.target).attr("data-tags"); +accountPage?.onChild("click", ".group.history .resultEditTagsButton", (e) => { + const targetButton = e.childTarget as HTMLElement; + const resultid = targetButton?.getAttribute("data-result-id"); + const tags = targetButton?.getAttribute("data-tags"); EditResultTagsModal.show( resultid ?? "", @@ -51,8 +53,6 @@ $(accountPage).on("click", ".group.history .resultEditTagsButton", (e) => { ); }); -$(accountPage) - .find("button.createFilterPresetBtn") - .on("click", () => { - AddFilterPresetModal.show(); - }); +accountPage?.qs("button.createFilterPresetBtn")?.on("click", () => { + AddFilterPresetModal.show(); +}); diff --git a/frontend/src/ts/event-handlers/footer.ts b/frontend/src/ts/event-handlers/footer.ts index 949cca104459..25e8e02856e9 100644 --- a/frontend/src/ts/event-handlers/footer.ts +++ b/frontend/src/ts/event-handlers/footer.ts @@ -9,77 +9,66 @@ import * as VersionHistoryModal from "../modals/version-history"; import { envConfig } from "virtual:env-config"; import { COMPATIBILITY_CHECK } from "@monkeytype/contracts"; import { lastSeenServerCompatibility } from "../ape/adapters/ts-rest-adapter"; +import { qs } from "../utils/dom"; -document - .querySelector("footer #commandLineMobileButton") - ?.addEventListener("click", async () => { - Commandline.show({ - singleListOverride: false, - }); +qs("footer #commandLineMobileButton")?.on("click", async () => { + Commandline.show({ + singleListOverride: false, }); +}); -document - .querySelector("footer #newVersionIndicator") - ?.addEventListener("click", (e) => { - e.stopPropagation(); - document.querySelector("#newVersionIndicator")?.classList.add("hidden"); - }); +qs("footer #newVersionIndicator")?.on("click", (e) => { + e.stopPropagation(); + qs("#newVersionIndicator")?.hide(); +}); -document - .querySelector("footer .currentVersion") - ?.addEventListener("click", (e) => { - const event = e as MouseEvent; - if (event.shiftKey) { - alert( - JSON.stringify( - { - clientVersion: envConfig.clientVersion, - clientCompatibility: COMPATIBILITY_CHECK, - lastSeenServerCompatibility, - }, - null, - 2, - ), - ); - } else { - VersionHistoryModal.show(); - } - }); +qs("footer .currentVersion")?.on("click", (e) => { + const event = e as MouseEvent; + if (event.shiftKey) { + alert( + JSON.stringify( + { + clientVersion: envConfig.clientVersion, + clientCompatibility: COMPATIBILITY_CHECK, + lastSeenServerCompatibility, + }, + null, + 2, + ), + ); + } else { + VersionHistoryModal.show(); + } +}); -document - .querySelector("footer .right .current-theme") - ?.addEventListener("click", async (event) => { - const e = event as MouseEvent; - if (e.shiftKey) { - if (Config.customTheme) { - setConfig("customTheme", false); - return; - } - if ( - isAuthenticated() && - (DB.getSnapshot()?.customThemes?.length ?? 0) < 1 - ) { - Notifications.add("No custom themes!", 0); - setConfig("customTheme", false); - return; - } - setConfig("customTheme", true); - } else { - const subgroup = Config.customTheme ? "customTheme" : "themes"; - Commandline.show({ - subgroupOverride: subgroup, - }); +qs("footer .right .current-theme")?.on("click", async (event) => { + const e = event as MouseEvent; + if (e.shiftKey) { + if (Config.customTheme) { + setConfig("customTheme", false); + return; } - }); + if ( + isAuthenticated() && + (DB.getSnapshot()?.customThemes?.length ?? 0) < 1 + ) { + Notifications.add("No custom themes!", 0); + setConfig("customTheme", false); + return; + } + setConfig("customTheme", true); + } else { + const subgroup = Config.customTheme ? "customTheme" : "themes"; + Commandline.show({ + subgroupOverride: subgroup, + }); + } +}); -document - .querySelector("footer #supportMeButton") - ?.addEventListener("click", () => { - SupportPopup.show(); - }); +qs("footer #supportMeButton")?.on("click", () => { + SupportPopup.show(); +}); -document - .querySelector("footer #contactPopupButton") - ?.addEventListener("click", () => { - ContactModal.show(); - }); +qs("footer #contactPopupButton")?.on("click", () => { + ContactModal.show(); +}); diff --git a/frontend/src/ts/event-handlers/keymap.ts b/frontend/src/ts/event-handlers/keymap.ts index 90eb7e8f46ff..da67f60e37e7 100644 --- a/frontend/src/ts/event-handlers/keymap.ts +++ b/frontend/src/ts/event-handlers/keymap.ts @@ -1,6 +1,7 @@ import * as Commandline from "../commandline/commandline"; +import { qs } from "../utils/dom"; -$("#keymap").on("click", ".r5 .layoutIndicator", async () => { +qs("#keymap")?.onChild("click", ".r5 .layoutIndicator", async () => { Commandline.show({ subgroupOverride: "keymapLayout", }); diff --git a/frontend/src/ts/event-handlers/leaderboards.ts b/frontend/src/ts/event-handlers/leaderboards.ts index 56875b74df9e..61769069e879 100644 --- a/frontend/src/ts/event-handlers/leaderboards.ts +++ b/frontend/src/ts/event-handlers/leaderboards.ts @@ -1,11 +1,8 @@ import { showPopup } from "../modals/simple-modals"; +import { qs } from "../utils/dom"; -const lb = document.getElementById("pageLeaderboards"); +const lb = qs("#pageLeaderboards"); -for (const button of lb?.querySelectorAll( - ".jumpButtons button[data-action='goToPage']", -) ?? []) { - button?.addEventListener("click", () => { - showPopup("lbGoToPage"); - }); -} +lb?.qsa(".jumpButtons button[data-action='goToPage']").on("click", () => { + showPopup("lbGoToPage"); +}); diff --git a/frontend/src/ts/event-handlers/login.ts b/frontend/src/ts/event-handlers/login.ts index 092691a618ba..9931a92b41a0 100644 --- a/frontend/src/ts/event-handlers/login.ts +++ b/frontend/src/ts/event-handlers/login.ts @@ -1,7 +1,8 @@ import * as ForgotPasswordModal from "../modals/forgot-password"; +import { qs } from "../utils/dom"; -const loginPage = document.querySelector("#pageLogin") as HTMLElement; +const loginPage = qs("#pageLogin"); -$(loginPage).on("click", "#forgotPasswordButton", () => { +loginPage?.onChild("click", "#forgotPasswordButton", () => { ForgotPasswordModal.show(); }); diff --git a/frontend/src/ts/event-handlers/settings.ts b/frontend/src/ts/event-handlers/settings.ts index 13137de1b6a5..a8c5610107ae 100644 --- a/frontend/src/ts/event-handlers/settings.ts +++ b/frontend/src/ts/event-handlers/settings.ts @@ -4,67 +4,64 @@ import * as EditPresetPopup from "../modals/edit-preset"; import * as EditTagPopup from "../modals/edit-tag"; import * as Notifications from "../elements/notifications"; +import { qs } from "../utils/dom"; -const settingsPage = document.querySelector("#pageSettings"); +const settingsPage = qs("#pageSettings"); -settingsPage - ?.querySelector("#shareCustomThemeButton") - ?.addEventListener("click", () => { - ShareCustomThemeModal.show(); - }); +settingsPage?.qs("#shareCustomThemeButton")?.on("click", () => { + ShareCustomThemeModal.show(); +}); settingsPage - ?.querySelector(".section.updateCookiePreferences .buttons button") - ?.addEventListener("click", () => { + ?.qs(".section.updateCookiePreferences .buttons button") + ?.on("click", () => { CookiesModal.show(true); }); -settingsPage - ?.querySelector(".section.presets") - ?.addEventListener("click", (e) => { - const target = e.target as HTMLElement; - if (target.classList.contains("addPresetButton")) { - EditPresetPopup.show("add"); - } else if (target.classList.contains("editButton")) { - const presetid = target.parentElement?.getAttribute("data-id"); - const name = target.parentElement?.getAttribute("data-display"); - if ( - presetid === undefined || - name === undefined || - presetid === "" || - name === "" || - presetid === null || - name === null - ) { - Notifications.add( - "Failed to edit preset: Could not find preset id or name", - -1, - ); - return; - } - EditPresetPopup.show("edit", presetid, name); - } else if (target.classList.contains("removeButton")) { - const presetid = target.parentElement?.getAttribute("data-id"); - const name = target.parentElement?.getAttribute("data-display"); - if ( - presetid === undefined || - name === undefined || - presetid === "" || - name === "" || - presetid === null || - name === null - ) { - Notifications.add( - "Failed to remove preset: Could not find preset id or name", - -1, - ); - return; - } - EditPresetPopup.show("remove", presetid, name); +settingsPage?.qs(".section.presets")?.on("click", (e) => { + const target = e.target as HTMLElement; + if (target.classList.contains("addPresetButton")) { + EditPresetPopup.show("add"); + } else if (target.classList.contains("editButton")) { + const presetid = target.parentElement?.getAttribute("data-id"); + const name = target.parentElement?.getAttribute("data-display"); + if ( + presetid === undefined || + name === undefined || + presetid === "" || + name === "" || + presetid === null || + name === null + ) { + Notifications.add( + "Failed to edit preset: Could not find preset id or name", + -1, + ); + return; } - }); + EditPresetPopup.show("edit", presetid, name); + } else if (target.classList.contains("removeButton")) { + const presetid = target.parentElement?.getAttribute("data-id"); + const name = target.parentElement?.getAttribute("data-display"); + if ( + presetid === undefined || + name === undefined || + presetid === "" || + name === "" || + presetid === null || + name === null + ) { + Notifications.add( + "Failed to remove preset: Could not find preset id or name", + -1, + ); + return; + } + EditPresetPopup.show("remove", presetid, name); + } +}); -settingsPage?.querySelector(".section.tags")?.addEventListener("click", (e) => { +settingsPage?.qs(".section.tags")?.on("click", (e) => { const target = e.target as HTMLElement; if (target.classList.contains("addTagButton")) { EditTagPopup.show("add"); diff --git a/frontend/src/ts/event-handlers/test.ts b/frontend/src/ts/event-handlers/test.ts index 072c212cd3dd..f2ee6cf01fd3 100644 --- a/frontend/src/ts/event-handlers/test.ts +++ b/frontend/src/ts/event-handlers/test.ts @@ -17,55 +17,63 @@ import { getMode2 } from "../utils/misc"; import * as ShareTestSettingsPopup from "../modals/share-test-settings"; import { ConfigKey } from "@monkeytype/schemas/configs"; import { ListsObjectKeys } from "../commandline/lists"; +import { qs } from "../utils/dom"; -$(".pageTest").on("click", "#testModesNotice .textButton", async (event) => { - const attr = $(event.currentTarget).attr("commands"); +const testPage = qs(".pageTest"); + +testPage?.onChild("click", "#testModesNotice .textButton", async (event) => { + const target = event.childTarget as HTMLElement; + const attr = target?.getAttribute("commands"); if (attr === undefined) return; Commandline.show({ subgroupOverride: attr as ConfigKey | ListsObjectKeys }); }); -$(".pageTest").on("click", "#testModesNotice .textButton", async (event) => { - const attr = $(event.currentTarget).attr("commandId"); - if (attr === undefined) return; +testPage?.onChild("click", "#testModesNotice .textButton", async (event) => { + const target = event.childTarget as HTMLElement; + const attr = target?.getAttribute("commandId"); + if (attr === null) return; Commandline.show({ commandOverride: attr }); }); -$(".pageTest").on("click", "#testConfig .wordCount .textButton", (e) => { - const wrd = $(e.currentTarget).attr("wordCount"); +testPage?.onChild("click", "#testConfig .wordCount .textButton", (event) => { + const target = event.childTarget as HTMLElement; + const wrd = target?.getAttribute("wordCount"); if (wrd === "custom") { CustomWordAmount.show(); } }); -$(".pageTest").on("click", "#testConfig .time .textButton", (e) => { - const time = $(e.currentTarget).attr("timeconfig"); +testPage?.onChild("click", "#testConfig .time .textButton", (event) => { + const target = event.childTarget as HTMLElement; + const time = target?.getAttribute("timeconfig"); if (time === "custom") { CustomTestDurationModal.show(); } }); -$(".pageTest").on("click", "#testConfig .shareButton", (e) => { +testPage?.onChild("click", "#testConfig .shareButton", () => { ShareTestSettingsPopup.show(); }); -$(".pageTest").on("click", ".tags .editTagsButton", () => { +testPage?.onChild("click", ".tags .editTagsButton", () => { if ((DB.getSnapshot()?.tags?.length ?? 0) > 0) { - const resultid = $(".pageTest .tags .editTagsButton").attr( - "data-result-id", - ) as string; - const activeTagIds = $(".pageTest .tags .editTagsButton").attr( - "data-active-tag-ids", - ) as string; + const resultid = + qs(".pageTest .tags .editTagsButton")?.getAttribute("data-result-id") ?? + ""; + const activeTagIds = + qs(".pageTest .tags .editTagsButton")?.getAttribute( + "data-active-tag-ids", + ) ?? ""; const tags = activeTagIds === "" ? [] : activeTagIds.split(","); EditResultTagsModal.show(resultid, tags, "resultPage"); } }); -$(".pageTest").on("click", "#mobileTestConfigButton", () => { +testPage?.onChild("click", "#mobileTestConfigButton", () => { MobileTestConfigModal.show(); }); -$(".pageTest #rateQuoteButton").on("click", async () => { +qs(".pageTest #rateQuoteButton")?.on("click", async () => { if (TestWords.currentQuote === null) { Notifications.add("Failed to show quote rating popup: no quote", -1); return; @@ -73,7 +81,7 @@ $(".pageTest #rateQuoteButton").on("click", async () => { QuoteRateModal.show(TestWords.currentQuote); }); -$(".pageTest #reportQuoteButton").on("click", async () => { +qs(".pageTest #reportQuoteButton")?.on("click", async () => { if (TestWords.currentQuote === null) { Notifications.add("Failed to show quote report popup: no quote", -1); return; @@ -81,18 +89,19 @@ $(".pageTest #reportQuoteButton").on("click", async () => { void QuoteReportModal.show(TestWords.currentQuote?.id); }); -$(".pageTest").on("click", "#testConfig .quoteLength .textButton", (e) => { - const len = parseInt($(e.currentTarget).attr("quoteLength") ?? "0"); +testPage?.onChild("click", "#testConfig .quoteLength .textButton", (event) => { + const target = event.childTarget as HTMLElement; + const len = parseInt(target?.getAttribute("quoteLength") ?? "0"); if (len === -2) { void QuoteSearchModal.show(); } }); -$(".pageTest").on("click", "#testConfig .customText .textButton", () => { +testPage?.onChild("click", "#testConfig .customText .textButton", () => { CustomTextModal.show(); }); -$(".pageTest").on("click", "#practiseWordsButton", () => { +testPage?.onChild("click", "#practiseWordsButton", () => { if (Config.mode === "zen") { Notifications.add("Practice words is unsupported in zen mode", 0); return; @@ -100,7 +109,7 @@ $(".pageTest").on("click", "#practiseWordsButton", () => { PractiseWordsModal.show(); }); -$(".pageTest #dailyLeaderboardRank").on("click", async () => { +qs(".pageTest #dailyLeaderboardRank")?.on("click", async () => { void navigate( `/leaderboards?type=daily&language=${Config.language}&mode2=${getMode2( Config,