Skip to content

Commit 12f5c5e

Browse files
committed
chore: protect against word letter self overflow
1 parent e90e35e commit 12f5c5e

File tree

2 files changed

+19
-12
lines changed

2 files changed

+19
-12
lines changed

frontend/src/ts/input/handlers/before-insert-text.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,16 @@ export function onBeforeInsertText(data: string): boolean {
8888
const pendingWordData = TestUI.pendingWordData.get(
8989
TestState.activeWordIndex,
9090
);
91-
const topAfterAppend = TestUI.getActiveWordTopWithDifferentData(
92-
(pendingWordData ?? TestInput.input.current) + data,
93-
);
94-
const wordJumped = topAfterAppend > TestUI.activeWordTop;
95-
if (wordJumped) {
91+
const { top: topAfterAppend, height: heightAfterAppend } =
92+
TestUI.getActiveWordTopAndHeightWithDifferentData(
93+
(pendingWordData ?? TestInput.input.current) + data,
94+
);
95+
if (topAfterAppend > TestUI.activeWordTop) {
96+
//word jumped to next line
97+
return true;
98+
}
99+
if (heightAfterAppend > TestUI.activeWordHeight) {
100+
// letters wrapped to next line
96101
return true;
97102
}
98103
}

frontend/src/ts/test/test-ui.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,15 +153,11 @@ const wordsWrapperEl = document.querySelector(
153153
) as HTMLElement;
154154

155155
export let activeWordTop = 0;
156+
export let activeWordHeight = 0;
156157
export let lineTransition = false;
157158
export let currentTestLine = 0;
158159
export let resultCalculating = false;
159160

160-
export function setActiveWordTop(): void {
161-
const activeWord = getActiveWordElement();
162-
activeWordTop = activeWord?.offsetTop ?? 0;
163-
}
164-
165161
export function setResultCalculating(val: boolean): void {
166162
resultCalculating = val;
167163
}
@@ -250,6 +246,7 @@ export function updateActiveElement(
250246
newActiveWord.classList.remove("typed");
251247

252248
activeWordTop = newActiveWord.offsetTop;
249+
activeWordHeight = newActiveWord.offsetHeight;
253250
console.log("activewordtopupdated");
254251

255252
updateWordsInputPosition();
@@ -1274,6 +1271,7 @@ export async function lineJump(
12741271
onComplete: () => {
12751272
currentLinesJumping = 0;
12761273
activeWordTop = activeWordEl.offsetTop;
1274+
activeWordHeight = activeWordEl.offsetHeight;
12771275
removeTestElements(lastElementIndexToRemove);
12781276
wordsEl.style.marginTop = "0";
12791277
lineTransition = false;
@@ -1732,7 +1730,10 @@ function updateLiveStatsColor(value: TimerColor): void {
17321730
}
17331731
}
17341732

1735-
export function getActiveWordTopWithDifferentData(data: string): number {
1733+
export function getActiveWordTopAndHeightWithDifferentData(data: string): {
1734+
top: number;
1735+
height: number;
1736+
} {
17361737
const activeWord = getActiveWordElement();
17371738

17381739
if (!activeWord) throw new Error("No active word element found");
@@ -1748,11 +1749,12 @@ export function getActiveWordTopWithDifferentData(data: string): number {
17481749
activeWord.append(...nodes);
17491750

17501751
const top = activeWord.offsetTop;
1752+
const height = activeWord.offsetHeight;
17511753
for (const node of nodes) {
17521754
node.remove();
17531755
}
17541756

1755-
return top;
1757+
return { top, height };
17561758
}
17571759

17581760
// this means input, delete or composition

0 commit comments

Comments
 (0)