Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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: 2 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

### Checks

- [ ] Adding/modifying Typescript code?
- [ ] I have used `qs`,`qsa` or `qsr` instead of JQuery selectors.
- [ ] Adding quotes?
- [ ] Make sure to include translations for the quotes in the description (or another comment) so we can verify their content.
- [ ] Adding a language?
Expand Down
2 changes: 2 additions & 0 deletions docs/CONTRIBUTING_ADVANCED.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ If you are on a UNIX system and you get a spawn error, run npm with `sudo`.

Code formatting is enforced by [Prettier](https://prettier.io/docs/en/install.html), which automatically runs every time you make a commit.

We are currently in the process of converting from JQuery to vanilla JS. When submitting new code, please use the `qs`, `qsa` and `qsr` helper functions. These return a class with a lot of JQuery-like methods. You can read how they work and import them from `frontend/src/ts/utils/dom.ts`.

For guidelines on commit messages, adding themes, languages, or quotes, please refer to [CONTRIBUTING.md](./CONTRIBUTING.md). Following these guidelines will increase the chances of getting your change accepted.

## Questions
Expand Down
44 changes: 41 additions & 3 deletions frontend/__tests__/setup-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,44 @@ vi.mock("../src/ts/firebase", () => ({
isAuthenticated: () => false,
}));

const input = document.createElement("input");
input.id = "wordsInput";
document.body.appendChild(input);
vi.mock("../src/ts/utils/dom", () => {
const createMockElement = (): any => {
const mock = {
qsr: vi.fn(),
qs: vi.fn().mockReturnValue(null),
find: vi.fn(),
addClass: vi.fn(),
removeClass: vi.fn(),
hide: vi.fn(),
show: vi.fn(),
setText: vi.fn(),
prependHtml: vi.fn(),
empty: vi.fn(),
appendHtml: vi.fn(),
native: document.createElement("div"),
};

// Make chainable methods return the mock itself
mock.qsr.mockImplementation(() => createMockElement());
mock.addClass.mockReturnValue(mock);
mock.removeClass.mockReturnValue(mock);
mock.hide.mockReturnValue(mock);
mock.show.mockReturnValue(mock);
mock.setText.mockReturnValue(mock);
mock.prependHtml.mockReturnValue(mock);
mock.empty.mockReturnValue(mock);

return mock;
};

return {
qsr: vi.fn().mockImplementation(() => createMockElement()),
qs: vi.fn().mockImplementation(() => createMockElement()),
qsa: vi.fn().mockReturnValue([]),
};
});

// Mock document.querySelector to return a div
global.document.querySelector = vi
.fn()
.mockReturnValue(document.createElement("div"));
2 changes: 1 addition & 1 deletion frontend/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<div id="backgroundLoader" class="hidden"></div>
<div id="bannerCenter" class="focus"></div>
<div id="notificationCenter">
<div class="clearAll button invisible" style="display: none">
<div class="clearAll button hidden">
<i class="fas fa-times"></i>
Clear all
</div>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/styles/notifications.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
.clearAll.button {
font-size: 0.75em;
margin-bottom: 1rem;
overflow: hidden;
}
&.focus .clearAll {
visibility: hidden;
Expand Down
40 changes: 21 additions & 19 deletions frontend/src/ts/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { getActiveFunboxesWithFunction } from "./test/funbox/list";
import * as Sentry from "./sentry";
import { tryCatch } from "@monkeytype/util/trycatch";
import * as AuthEvent from "./observables/auth-event";
import { qs, qsa } from "./utils/dom";

export const gmailProvider = new GoogleAuthProvider();
export const githubProvider = new GithubAuthProvider();
Expand All @@ -43,9 +44,9 @@ async function sendVerificationEmail(): Promise<void> {
}

Loader.show();
$(".sendVerificationEmail").prop("disabled", true);
qs(".sendVerificationEmail")?.disable();
const result = await Ape.users.verificationEmail();
$(".sendVerificationEmail").prop("disabled", false);
qs(".sendVerificationEmail")?.enable();
if (result.status !== 200) {
Loader.hide();
Notifications.add(
Expand Down Expand Up @@ -100,7 +101,7 @@ async function getDataAndInit(): Promise<boolean> {
} catch (error) {
console.error(error);
LoginPage.enableInputs();
$("header nav .view-account").css("opacity", 1);
qs("header nav .view-account")?.setStyle({ opacity: "1" });
if (error instanceof DB.SnapshotInitError) {
if (error.responseCode === 429) {
Notifications.add(
Expand Down Expand Up @@ -215,9 +216,9 @@ export async function signIn(email: string, password: string): Promise<void> {
return;
}

const rememberMe = $(".pageLogin .login #rememberMe input").prop(
"checked",
) as boolean;
const rememberMe =
qs<HTMLInputElement>(".pageLogin .login #rememberMe input")?.isChecked() ??
false;

const { error } = await tryCatch(
signInWithEmailAndPassword(email, password, rememberMe),
Expand Down Expand Up @@ -249,9 +250,9 @@ async function signInWithProvider(provider: AuthProvider): Promise<void> {
LoginPage.showPreloader();
LoginPage.disableInputs();
LoginPage.disableSignUpButton();
const rememberMe = $(".pageLogin .login #rememberMe input").prop(
"checked",
) as boolean;
const rememberMe =
qs<HTMLInputElement>(".pageLogin .login #rememberMe input")?.isChecked() ??
false;

const { error } = await tryCatch(signInWithPopup(provider, rememberMe));

Expand Down Expand Up @@ -406,24 +407,24 @@ async function signUp(): Promise<void> {
}
}

$(".pageLogin .login form").on("submit", (e) => {
qs(".pageLogin .login form")?.on("submit", (e) => {
e.preventDefault();
const email =
($(".pageLogin .login input")[0] as HTMLInputElement).value ?? "";
qsa<HTMLInputElement>(".pageLogin .login input")?.[0]?.getValue() ?? "";
const password =
($(".pageLogin .login input")[1] as HTMLInputElement).value ?? "";
qsa<HTMLInputElement>(".pageLogin .login input")?.[1]?.getValue() ?? "";
void signIn(email, password);
});

$(".pageLogin .login button.signInWithGoogle").on("click", () => {
qs(".pageLogin .login button.signInWithGoogle")?.on("click", () => {
void signInWithGoogle();
});

$(".pageLogin .login button.signInWithGitHub").on("click", () => {
qs(".pageLogin .login button.signInWithGitHub")?.on("click", () => {
void signInWithGitHub();
});

$("nav .accountButtonAndMenu .menu button.signOut").on("click", () => {
qs("nav .accountButtonAndMenu .menu button.signOut")?.on("click", () => {
if (!isAuthAvailable()) {
Notifications.add("Authentication uninitialized", -1, {
duration: 3,
Expand All @@ -433,19 +434,20 @@ $("nav .accountButtonAndMenu .menu button.signOut").on("click", () => {
signOut();
});

$(".pageLogin .register form").on("submit", (e) => {
qs(".pageLogin .register form")?.on("submit", (e) => {
e.preventDefault();
void signUp();
});

$(".pageAccountSettings").on("click", "#addGoogleAuth", () => {
qs(".pageAccountSettings")?.onChild("click", "#addGoogleAuth", () => {
void addGoogleAuth();
});
$(".pageAccountSettings").on("click", "#addGithubAuth", () => {

qs(".pageAccountSettings")?.onChild("click", "#addGithubAuth", () => {
void addGithubAuth();
});

$(".pageAccount").on("click", ".sendVerificationEmail", () => {
qs(".pageAccount")?.onChild("click", ".sendVerificationEmail", () => {
if (!ConnectionState.get()) {
Notifications.add("You are offline", 0, {
duration: 2,
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/ts/commandline/commandline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
ValidationResult,
} from "../elements/input-validation";
import { isInputElementFocused } from "../input/input-element";
import { qs } from "../utils/dom";

type CommandlineMode = "search" | "input";
type InputModeParams = {
Expand Down Expand Up @@ -55,14 +56,14 @@ let lastState:
| undefined;

function removeCommandlineBackground(): void {
$("#commandLine").addClass("noBackground");
qs("#commandLine")?.addClass("noBackground");
if (Config.showOutOfFocusWarning) {
OutOfFocus.hide();
}
}

function addCommandlineBackground(): void {
$("#commandLine").removeClass("noBackground");
qs("#commandLine")?.removeClass("noBackground");
if (Config.showOutOfFocusWarning && !isInputElementFocused()) {
OutOfFocus.show();
}
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/ts/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,13 @@ export function setIndicateTypos(
return genericSet("indicateTypos", value, nosave);
}

export function setCompositionDisplay(
value: ConfigSchemas.CompositionDisplay,
nosave?: boolean,
): boolean {
return genericSet("compositionDisplay", value, nosave);
}

export function setAutoSwitchTheme(
boolean: boolean,
nosave?: boolean,
Expand Down
67 changes: 34 additions & 33 deletions frontend/src/ts/controllers/ad-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Config from "../config";
import * as TestState from "../test/test-state";
import * as EG from "./eg-ad-controller";
import * as PW from "./pw-ad-controller";
import { onDocumentReady, qs } from "../utils/dom";

const breakpoint = 900;
let widerThanBreakpoint = true;
Expand Down Expand Up @@ -61,32 +62,32 @@ function removeAll(): void {
}

function removeSellout(): void {
$("#ad-footer-wrapper").remove();
$("#ad-footer-small-wrapper").remove();
$("#ad-about-1-wrapper").remove();
$("#ad-about-1-small-wrapper").remove();
$("#ad-about-2-wrapper").remove();
$("#ad-about-2-small-wrapper").remove();
$("#ad-settings-1-wrapper").remove();
$("#ad-settings-1-small-wrapper").remove();
$("#ad-settings-2-wrapper").remove();
$("#ad-settings-2-small-wrapper").remove();
$("#ad-settings-3-wrapper").remove();
$("#ad-settings-3-small-wrapper").remove();
$("#ad-account-1-wrapper").remove();
$("#ad-account-1-small-wrapper").remove();
$("#ad-account-2-wrapper").remove();
$("#ad-account-2-small-wrapper").remove();
qs("#ad-footer-wrapper")?.remove();
qs("#ad-footer-small-wrapper")?.remove();
qs("#ad-about-1-wrapper")?.remove();
qs("#ad-about-1-small-wrapper")?.remove();
qs("#ad-about-2-wrapper")?.remove();
qs("#ad-about-2-small-wrapper")?.remove();
qs("#ad-settings-1-wrapper")?.remove();
qs("#ad-settings-1-small-wrapper")?.remove();
qs("#ad-settings-2-wrapper")?.remove();
qs("#ad-settings-2-small-wrapper")?.remove();
qs("#ad-settings-3-wrapper")?.remove();
qs("#ad-settings-3-small-wrapper")?.remove();
qs("#ad-account-1-wrapper")?.remove();
qs("#ad-account-1-small-wrapper")?.remove();
qs("#ad-account-2-wrapper")?.remove();
qs("#ad-account-2-small-wrapper")?.remove();
}

function removeOn(): void {
$("#ad-vertical-right-wrapper").remove();
$("#ad-vertical-left-wrapper").remove();
qs("#ad-vertical-right-wrapper")?.remove();
qs("#ad-vertical-left-wrapper")?.remove();
}

function removeResult(): void {
$("#ad-result-wrapper").remove();
$("#ad-result-small-wrapper").remove();
qs("#ad-result-wrapper")?.remove();
qs("#ad-result-small-wrapper")?.remove();
}

function updateVerticalMargin(): void {
Expand Down Expand Up @@ -219,7 +220,7 @@ export async function renderResult(): Promise<void> {
await checkCookieblocker();

if (adBlock) {
$("#ad-result-wrapper .iconAndText .text").html(`
qs("#ad-result-wrapper .iconAndText .text")?.setHtml(`
Using an ad blocker? No worries
<div class="smalltext">
We understand ads can be annoying
Expand All @@ -233,7 +234,7 @@ export async function renderResult(): Promise<void> {
}

if (cookieBlocker) {
$("#ad-result-wrapper .iconAndText .text").html(`
qs("#ad-result-wrapper .iconAndText .text")?.setHtml(`
Ads not working? Ooops
<div class="smalltext">
You may have a cookie popup blocker enabled - ads will not show without your consent
Expand All @@ -255,15 +256,15 @@ export async function renderResult(): Promise<void> {

export function updateFooterAndVerticalAds(visible: boolean): void {
if (visible) {
$("#ad-vertical-left-wrapper").removeClass("testPage");
$("#ad-vertical-right-wrapper").removeClass("testPage");
$("#ad-footer-wrapper").removeClass("testPage");
$("#ad-footer-small-wrapper").removeClass("testPage");
qs("#ad-vertical-left-wrapper")?.removeClass("testPage");
qs("#ad-vertical-right-wrapper")?.removeClass("testPage");
qs("#ad-footer-wrapper")?.removeClass("testPage");
qs("#ad-footer-small-wrapper")?.removeClass("testPage");
} else {
$("#ad-vertical-left-wrapper").addClass("testPage");
$("#ad-vertical-right-wrapper").addClass("testPage");
$("#ad-footer-wrapper").addClass("testPage");
$("#ad-footer-small-wrapper").addClass("testPage");
qs("#ad-vertical-left-wrapper")?.addClass("testPage");
qs("#ad-vertical-right-wrapper")?.addClass("testPage");
qs("#ad-footer-wrapper")?.addClass("testPage");
qs("#ad-footer-small-wrapper")?.addClass("testPage");
}
}

Expand Down Expand Up @@ -293,7 +294,7 @@ const debouncedMarginUpdate = debounce(500, updateVerticalMargin);
const debouncedBreakpointUpdate = debounce(500, updateBreakpoint);
const debouncedBreakpoint2Update = debounce(500, updateBreakpoint2);

$(window).on("resize", () => {
window.addEventListener("resize", () => {
debouncedMarginUpdate();
debouncedBreakpointUpdate();
debouncedBreakpoint2Update();
Expand All @@ -316,7 +317,7 @@ BannerEvent.subscribe(() => {
updateVerticalMargin();
});

$(() => {
onDocumentReady(() => {
updateBreakpoint(true);
updateBreakpoint2();
});
Expand All @@ -325,7 +326,7 @@ window.onerror = function (error): void {
//@ts-expect-error ---
if (choice === "eg") {
if (typeof error === "string" && error.startsWith("EG APS")) {
$("#ad-result-wrapper .iconAndText").addClass("withLeft");
qs("#ad-result-wrapper .iconAndText")?.addClass("withLeft");
}
}
};
3 changes: 2 additions & 1 deletion frontend/src/ts/controllers/analytics-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
} from "firebase/analytics";
import { getAnalytics } from "../firebase";
import { createErrorMessage } from "../utils/misc";
import { qs } from "../utils/dom";

let analytics: AnalyticsType;

Expand All @@ -28,7 +29,7 @@ export function activateAnalytics(): void {
try {
analytics = getAnalytics();
setAnalyticsCollectionEnabled(analytics, true);
$("body").append(`
qs("body")?.appendHtml(`
<script
async
src="https://www.googletagmanager.com/gtag/js?id=UA-165993088-1"
Expand Down
Loading
Loading