Skip to content

Commit bd22d8f

Browse files
authored
refactor: split updateWordsHeight() and move some style changes to .scss files (@nadalaba) (monkeytypegame#5920)
1 parent f7be839 commit bd22d8f

File tree

3 files changed

+87
-131
lines changed

3 files changed

+87
-131
lines changed

frontend/src/styles/test.scss

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,12 @@
261261
}
262262
}
263263

264-
&.tape .word {
265-
margin: 0.25em 0.6em 0.75em 0;
266-
white-space: nowrap;
264+
&.tape {
265+
width: 200vw;
266+
.word {
267+
margin: 0.25em 0.6em 0.75em 0;
268+
white-space: nowrap;
269+
}
267270
}
268271

269272
/* a little hack for right-to-left languages */
@@ -462,14 +465,6 @@
462465
display: inline-block;
463466
}
464467

465-
&.lastbeforenewline::after {
466-
font-family: "Font Awesome";
467-
font-weight: 600;
468-
content: "\f107";
469-
margin-left: 0.5rem;
470-
opacity: 0.25;
471-
}
472-
473468
.wordInputHighlight {
474469
opacity: 1;
475470
white-space: nowrap;
@@ -564,10 +559,6 @@
564559
pointer-events: none;
565560
top: -2.5rem;
566561

567-
&.focus {
568-
// top: 0rem;
569-
}
570-
571562
i {
572563
margin-right: 0.5rem;
573564
}
@@ -1181,7 +1172,9 @@
11811172
.pageTest {
11821173
#wordsWrapper {
11831174
position: relative;
1175+
overflow: visible clip;
11841176
&.tape {
1177+
overflow: hidden;
11851178
-webkit-mask-image: linear-gradient(
11861179
90deg,
11871180
rgba(0, 0, 0, 0) 1%,
@@ -1220,7 +1213,8 @@
12201213
}
12211214
.outOfFocusWarning {
12221215
text-align: center;
1223-
height: 0;
1216+
height: 100%;
1217+
align-content: center;
12241218
font-size: 1rem;
12251219
z-index: 999;
12261220
position: absolute;

frontend/src/ts/controllers/input-controller.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -340,12 +340,12 @@ async function handleSpace(): Promise<void> {
340340
TestUI.updateActiveElement();
341341
void Caret.updatePosition();
342342

343-
if (
344-
!Config.showAllLines ||
343+
const shouldLimitToThreeLines =
345344
Config.mode === "time" ||
346-
(Config.mode === "custom" && CustomText.getLimitValue() === 0) ||
347-
(Config.mode === "custom" && CustomText.getLimitMode() === "time")
348-
) {
345+
(Config.mode === "custom" && CustomText.getLimitMode() === "time") ||
346+
(Config.mode === "custom" && CustomText.getLimitValue() === 0);
347+
348+
if (!Config.showAllLines || shouldLimitToThreeLines) {
349349
const currentTop: number = Math.floor(
350350
document.querySelectorAll<HTMLElement>("#words .word")[
351351
TestState.activeWordIndex - TestUI.activeWordElementOffset - 1
@@ -364,8 +364,8 @@ async function handleSpace(): Promise<void> {
364364

365365
if (nextTop > currentTop) {
366366
TestUI.lineJump(currentTop);
367-
}
368-
} //end of line wrap
367+
} //end of line wrap
368+
}
369369

370370
// enable if i decide that auto tab should also work after a space
371371
// if (

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

Lines changed: 70 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ ConfigEvent.subscribe((eventKey, eventValue, nosave) => {
152152
}
153153
if (eventKey === "fontSize" && !nosave) {
154154
OutOfFocus.hide();
155-
updateWordsHeight(true);
156-
void updateWordsInputPosition(true);
155+
updateWordWrapperClasses();
157156
}
158157
if (
159158
["fontSize", "fontFamily", "blindMode", "hideExtraLetters"].includes(
@@ -184,16 +183,7 @@ ConfigEvent.subscribe((eventKey, eventValue, nosave) => {
184183
updateWordWrapperClasses();
185184
}
186185

187-
if (eventKey === "tapeMode" && !nosave) {
188-
if (eventValue === "off") {
189-
$("#words").css("margin-left", "unset");
190-
} else {
191-
scrollTape();
192-
}
193-
updateLiveStatsMargin();
194-
}
195-
196-
if (eventKey === "tapeMargin") {
186+
if (["tapeMode", "tapeMargin"].includes(eventKey)) {
197187
updateLiveStatsMargin();
198188
}
199189

@@ -404,7 +394,8 @@ function updateWordWrapperClasses(): void {
404394
$("#words").attr("class", existing.join(" "));
405395

406396
updateWordsWidth();
407-
updateWordsHeight(true);
397+
updateWordsWrapperHeight(true);
398+
updateWordsMargin();
408399
setTimeout(() => {
409400
void updateWordsInputPosition(true);
410401
}, 250);
@@ -419,8 +410,7 @@ export function showWords(): void {
419410
wordsHTML += getWordHTML(TestWords.words.get(i));
420411
}
421412
} else {
422-
wordsHTML =
423-
'<div class="word">word height</div><div class="word active"></div>';
413+
wordsHTML = '<div class="word active"></div>';
424414
}
425415

426416
$("#words").html(wordsHTML);
@@ -431,10 +421,6 @@ export function showWords(): void {
431421
}, 125);
432422

433423
updateWordWrapperClasses();
434-
435-
if (Config.mode === "zen") {
436-
$(document.querySelector(".word") as Element).remove();
437-
}
438424
}
439425

440426
const posUpdateLangList = ["japanese", "chinese", "korean"];
@@ -495,107 +481,83 @@ export async function updateWordsInputPosition(initial = false): Promise<void> {
495481
}
496482
}
497483

498-
function updateWordsHeight(force = false): void {
484+
export function updateWordsWrapperHeight(force = false): void {
499485
if (ActivePage.get() !== "test" || resultVisible) return;
500486
if (!force && Config.mode !== "custom") return;
501-
$("#wordsWrapper").removeClass("hidden");
502-
const wordHeight = $(document.querySelector(".word") as Element).outerHeight(
503-
true
504-
) as number;
505-
const wordsHeight = $(
506-
document.querySelector("#words") as Element
507-
).outerHeight(true) as number;
487+
const wrapperEl = document.getElementById("wordsWrapper") as HTMLElement;
488+
const wordElements = wrapperEl.querySelectorAll<HTMLElement>("#words .word");
489+
const activeWordEl =
490+
wordElements[TestState.activeWordIndex - activeWordElementOffset];
491+
if (!activeWordEl) return;
492+
493+
wrapperEl.classList.remove("hidden");
494+
495+
//insert temporary character for zen mode
496+
const activeWordEmpty = activeWordEl?.children.length === 0;
497+
if (activeWordEmpty) {
498+
activeWordEl.insertAdjacentHTML(
499+
"beforeend",
500+
'<letter style="opacity: 0;">_</letter>'
501+
);
502+
}
503+
const wordComputedStyle = window.getComputedStyle(activeWordEl);
504+
const wordMargin =
505+
parseInt(wordComputedStyle.marginTop) +
506+
parseInt(wordComputedStyle.marginBottom);
507+
const wordHeight = activeWordEl.offsetHeight + wordMargin;
508+
509+
let wrapperHeightStr: string;
510+
let outOfFocusMargin: string | undefined = undefined;
508511

509512
const shouldLimitToThreeLines =
510513
Config.mode === "time" ||
511514
(Config.mode === "custom" && CustomText.getLimitMode() === "time") ||
512-
(Config.mode === "custom" &&
513-
CustomText.getLimitMode() === "word" &&
514-
CustomText.getLimitValue() === 0) ||
515-
(Config.mode === "custom" &&
516-
CustomText.getLimitMode() === "section" &&
517-
CustomText.getLimitValue() === 0);
515+
(Config.mode === "custom" && CustomText.getLimitValue() === 0);
518516

519517
if (Config.showAllLines && !shouldLimitToThreeLines) {
520-
// overflow-x should not be visible in tape mode, but since showAllLines can't
521-
// be enabled simultaneously with tape mode we don't need to check it's off
522-
$("#words")
523-
.css("height", "auto")
524-
.css("overflow", "visible clip")
525-
.css("width", "100%")
526-
.css("margin-left", "unset");
527-
$("#wordsWrapper").css("height", "auto").css("overflow", "visible clip");
528-
529-
let nh = wordHeight * 3;
530-
531-
if (nh > wordsHeight) {
532-
nh = wordsHeight;
533-
}
534-
$(".outOfFocusWarning").css(
535-
"margin-top",
536-
wordHeight + convertRemToPixels(1) / 2 + "px"
537-
);
518+
wrapperHeightStr = "auto";
519+
outOfFocusMargin = wordHeight + convertRemToPixels(1) / 2 + "px";
520+
} else if (Config.tapeMode !== "off") {
521+
wrapperHeightStr = TestWords.hasNewline
522+
? wordHeight * 3 + "px"
523+
: wordHeight * 1 + "px";
538524
} else {
539-
let finalWordsHeight: number, finalWrapperHeight: number;
540-
541-
if (Config.tapeMode !== "off") {
542-
finalWordsHeight = wordHeight * 2;
543-
finalWrapperHeight = wordHeight;
544-
} else {
545-
let lines = 0;
546-
let lastHeight = 0;
547-
let wordIndex = 0;
548-
const words = document.querySelectorAll("#words .word");
549-
let wrapperHeight = 0;
550-
551-
const wordComputedStyle = window.getComputedStyle(words[0] as Element);
552-
const wordTopMargin = parseInt(wordComputedStyle.marginTop);
553-
const wordBottomMargin = parseInt(wordComputedStyle.marginBottom);
554-
555-
while (lines < 3) {
556-
const word = words[wordIndex] as HTMLElement | null;
557-
if (!word) break;
558-
const height = word.offsetTop;
559-
if (height > lastHeight) {
560-
lines++;
561-
wrapperHeight += word.offsetHeight + wordTopMargin + wordBottomMargin;
562-
lastHeight = height;
563-
}
564-
wordIndex++;
525+
let lines = 0;
526+
let lastTop = 0;
527+
let wordIndex = 0;
528+
let wrapperHeight = 0;
529+
530+
while (lines < 3) {
531+
const word = wordElements[wordIndex] as HTMLElement | null;
532+
if (!word) break;
533+
const top = word.offsetTop;
534+
if (top > lastTop) {
535+
lines++;
536+
wrapperHeight += word.offsetHeight + wordMargin;
537+
lastTop = top;
565538
}
566-
567-
if (lines < 3) wrapperHeight = wrapperHeight * (3 / lines);
568-
569-
const wordsHeight = (wrapperHeight / 3) * 4;
570-
571-
finalWordsHeight = wordsHeight;
572-
finalWrapperHeight = wrapperHeight;
539+
wordIndex++;
573540
}
541+
if (lines < 3) wrapperHeight = wrapperHeight * (3 / lines);
574542

575-
// $("#words").css("height", "0px");
576-
// not sure why this was here, wonder if removing it will break anything
543+
wrapperHeightStr = wrapperHeight + "px";
544+
}
577545

578-
if (Config.tapeMode !== "off") {
579-
$("#words").css({ overflow: "hidden", width: "200vw" });
580-
$("#wordsWrapper").css({ overflow: "hidden" });
581-
scrollTape();
582-
} else {
583-
$("#words").css({
584-
overflow: "visible clip",
585-
marginLeft: "unset",
586-
width: "",
587-
});
588-
$("#wordsWrapper").css({ overflow: "visible clip" });
589-
}
546+
wrapperEl.style.height = wrapperHeightStr;
547+
if (outOfFocusMargin !== undefined) {
548+
$(".outOfFocusWarning").css({ height: 0, "margin-top": outOfFocusMargin });
549+
}
590550

591-
setTimeout(() => {
592-
$("#words").css("height", finalWordsHeight + "px");
593-
$("#wordsWrapper").css("height", finalWrapperHeight + "px");
594-
$(".outOfFocusWarning").css(
595-
"margin-top",
596-
finalWrapperHeight / 2 - convertRemToPixels(1) / 2 + "px"
597-
);
598-
}, 0);
551+
if (activeWordEmpty) {
552+
activeWordEl?.replaceChildren();
553+
}
554+
}
555+
556+
function updateWordsMargin(): void {
557+
if (Config.tapeMode !== "off") {
558+
scrollTape();
559+
} else {
560+
setTimeout(() => $("#words").css("margin-left", "unset"), 0);
599561
}
600562
}
601563

@@ -1106,7 +1068,7 @@ export function lineJump(currentTop: number): void {
11061068
const wordsWrapperWidth = (
11071069
document.querySelector("#wordsWrapper") as HTMLElement
11081070
).offsetWidth;
1109-
const newMargin = wordsWrapperWidth / 2;
1071+
const newMargin = wordsWrapperWidth * (Config.tapeMargin / 100);
11101072
newCss["marginLeft"] = `${newMargin}px`;
11111073
}
11121074
currentLinesAnimating++;
@@ -1136,7 +1098,7 @@ export function lineJump(currentTop: number): void {
11361098
}
11371099
}
11381100
currentTestLine++;
1139-
updateWordsHeight();
1101+
updateWordsWrapperHeight();
11401102
}
11411103

11421104
export function setRightToLeft(isEnabled: boolean): void {

0 commit comments

Comments
 (0)