mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-10-16 18:46:26 +08:00
fix(zen mode): issues when changing tape mode and other caret issues (@NadAlaba) (#5824)
* fix(zen mode): undefined word when changing tape mode during test (@NadAlaba) * fix(zen mode): shrinking full-width-caret when changing tape mode during test (@NadAlaba) * fix(zen mode): messed up caret in RTL languages (@NadAlaba) because of the letter '_' that is added to the beginning of a word in zen mode, the caret is getting positioned on the 2nd letter. Also, since lastWordLetter is always undefined (because wordLen is always 0) offsetHeight and offsetTop are getting the default values regardless of font characteristics. * fix caret staying in position in (blind + word tape + zen) mode * refactor: combine last 2 solutions * rename parameter
This commit is contained in:
parent
55496996de
commit
661c138812
3 changed files with 21 additions and 16 deletions
|
@ -126,7 +126,8 @@ function hide(clearModalChain = false): void {
|
|||
clearModalChain,
|
||||
afterAnimation: async () => {
|
||||
addCommandlineBackground();
|
||||
if (ActivePage.get() === "test") {
|
||||
const isWordsFocused = $("#wordsInput").is(":focus");
|
||||
if (ActivePage.get() === "test" && !isWordsFocused) {
|
||||
focusWords();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -49,6 +49,7 @@ function getTargetPositionLeft(
|
|||
fullWidthCaret: boolean,
|
||||
isLanguageRightToLeft: boolean,
|
||||
activeWordElement: HTMLElement,
|
||||
underscoreAdded: boolean,
|
||||
currentWordNodeList: NodeListOf<Element>,
|
||||
fullWidthCaretWidth: number,
|
||||
wordLen: number,
|
||||
|
@ -98,6 +99,8 @@ function getTargetPositionLeft(
|
|||
}
|
||||
}
|
||||
result = activeWordElement.offsetLeft + positionOffsetToWord;
|
||||
if (underscoreAdded && isLanguageRightToLeft)
|
||||
result += activeWordElement.offsetWidth;
|
||||
} else {
|
||||
const wordsWrapperWidth =
|
||||
$(document.querySelector("#wordsWrapper") as HTMLElement).width() ?? 0;
|
||||
|
@ -129,10 +132,9 @@ export async function updatePosition(noAnim = false): Promise<void> {
|
|||
Config.caretStyle
|
||||
);
|
||||
|
||||
const wordLen = TestWords.words.getCurrent().length;
|
||||
let wordLen = TestWords.words.getCurrent().length;
|
||||
const inputLen = TestInput.input.current.length;
|
||||
const letterIsInvisibleExtra =
|
||||
(Config.blindMode || Config.hideExtraLetters) && inputLen > wordLen;
|
||||
if (Config.mode === "zen") wordLen = inputLen;
|
||||
const activeWordEl = document?.querySelector("#words .active") as HTMLElement;
|
||||
//insert temporary character so the caret will work in zen mode
|
||||
const activeWordEmpty = activeWordEl?.children.length === 0;
|
||||
|
@ -153,28 +155,29 @@ export async function updatePosition(noAnim = false): Promise<void> {
|
|||
| HTMLElement
|
||||
| undefined;
|
||||
|
||||
const spaceWidth = getSpaceWidth(activeWordEl);
|
||||
|
||||
const currentLanguage = await JSONData.getCurrentLanguage(Config.language);
|
||||
const isLanguageRightToLeft = currentLanguage.rightToLeft;
|
||||
|
||||
// in blind mode, and hide extra letters, extra letters have zero offsets
|
||||
// offsetTop and offsetHeight is the same for all visible letters
|
||||
const letterHeight =
|
||||
currentLetter?.offsetHeight ||
|
||||
lastWordLetter?.offsetHeight ||
|
||||
Config.fontSize * Numbers.convertRemToPixels(1);
|
||||
|
||||
const letterPosTop = lastWordLetter?.offsetTop ?? 0;
|
||||
const letterPosTop =
|
||||
currentLetter?.offsetTop || lastWordLetter?.offsetTop || 0;
|
||||
const diff = letterHeight - caret.offsetHeight;
|
||||
let newTop = activeWordEl.offsetTop + letterPosTop + diff / 2;
|
||||
if (Config.caretStyle === "underline") {
|
||||
newTop = activeWordEl.offsetTop + letterPosTop - caret.offsetHeight / 2;
|
||||
}
|
||||
|
||||
let letterWidth = currentLetter?.offsetWidth || spaceWidth;
|
||||
if (currentLetter?.offsetWidth === 0 && !letterIsInvisibleExtra) {
|
||||
// other than in extra letters in blind mode, it could be zero
|
||||
// if current letter is a zero-width character e.g, diacritics)
|
||||
let letterWidth = currentLetter?.offsetWidth;
|
||||
if (letterWidth === undefined || activeWordEmpty) {
|
||||
letterWidth = getSpaceWidth(activeWordEl);
|
||||
} else if (letterWidth === 0) {
|
||||
// current letter is a zero-width character e.g, diacritics)
|
||||
letterWidth = 0;
|
||||
for (let i = inputLen; i >= 0; i--) {
|
||||
letterWidth = (currentWordNodeList[i] as HTMLElement)?.offsetWidth;
|
||||
|
@ -187,6 +190,7 @@ export async function updatePosition(noAnim = false): Promise<void> {
|
|||
fullWidthCaret,
|
||||
isLanguageRightToLeft,
|
||||
activeWordEl,
|
||||
activeWordEmpty,
|
||||
currentWordNodeList,
|
||||
letterWidth,
|
||||
wordLen,
|
||||
|
|
|
@ -422,6 +422,10 @@ export function showWords(): void {
|
|||
}, 125);
|
||||
|
||||
updateWordWrapperClasses();
|
||||
|
||||
if (Config.mode === "zen") {
|
||||
$(document.querySelector(".word") as Element).remove();
|
||||
}
|
||||
}
|
||||
|
||||
const posUpdateLangList = ["japanese", "chinese", "korean"];
|
||||
|
@ -508,7 +512,7 @@ function updateWordsHeight(force = false): void {
|
|||
CustomText.getLimitValue() !== 0
|
||||
) {
|
||||
// overflow-x should not be visible in tape mode, but since showAllLines can't
|
||||
// be enabled simultaneously with tape mode we don' need to check it's off
|
||||
// be enabled simultaneously with tape mode we don't need to check it's off
|
||||
$("#words")
|
||||
.css("height", "auto")
|
||||
.css("overflow", "visible clip")
|
||||
|
@ -587,10 +591,6 @@ function updateWordsHeight(force = false): void {
|
|||
);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
if (Config.mode === "zen") {
|
||||
$(document.querySelector(".word") as Element).remove();
|
||||
}
|
||||
}
|
||||
|
||||
export function addWord(word: string): void {
|
||||
|
|
Loading…
Add table
Reference in a new issue