@@ -283,7 +283,7 @@ export function updateActiveElement(
283
283
void updateWordsInputPosition ( ) ;
284
284
}
285
285
if ( ! initial && Config . tapeMode !== "off" ) {
286
- scrollTape ( ) ;
286
+ void scrollTape ( ) ;
287
287
}
288
288
}
289
289
@@ -425,11 +425,10 @@ export function showWords(): void {
425
425
}
426
426
427
427
updateActiveElement ( undefined , true ) ;
428
+ updateWordWrapperClasses ( ) ;
428
429
setTimeout ( ( ) => {
429
430
void Caret . updatePosition ( ) ;
430
431
} , 125 ) ;
431
-
432
- updateWordWrapperClasses ( ) ;
433
432
}
434
433
435
434
export function appendEmptyWordElement ( ) : void {
@@ -577,7 +576,7 @@ export function updateWordsWrapperHeight(force = false): void {
577
576
578
577
function updateWordsMargin ( ) : void {
579
578
if ( Config . tapeMode !== "off" ) {
580
- scrollTape ( true ) ;
579
+ void scrollTape ( true ) ;
581
580
} else {
582
581
setTimeout ( ( ) => {
583
582
$ ( "#words" ) . css ( "margin-left" , "unset" ) ;
@@ -934,7 +933,7 @@ export async function updateActiveWordLetters(
934
933
"<div class='beforeNewline'></div><div class='newline'></div><div class='afterNewline'></div>"
935
934
) ;
936
935
if ( Config . tapeMode !== "off" ) {
937
- scrollTape ( ) ;
936
+ await scrollTape ( ) ;
938
937
}
939
938
}
940
939
@@ -965,15 +964,18 @@ function getNlCharWidthFromPreviousWord(
965
964
}
966
965
967
966
let allowWordRemoval = true ;
968
- export function scrollTape ( noRemove = false ) : void {
967
+ export async function scrollTape ( noRemove = false ) : Promise < void > {
969
968
if ( ActivePage . get ( ) !== "test" || resultVisible ) return ;
970
969
971
970
const waitForLineJumpAnimation = lineTransition && ! allowWordRemoval ;
972
971
if ( waitForLineJumpAnimation ) {
973
- setTimeout ( ( ) => scrollTape ( true ) , 50 ) ;
972
+ setTimeout ( ( ) => void scrollTape ( true ) , 50 ) ;
974
973
return ;
975
974
}
976
975
976
+ const currentLang = await JSONData . getCurrentLanguage ( Config . language ) ;
977
+ const isLanguageRTL = currentLang . rightToLeft ;
978
+
977
979
// index of the active word in the collection of .word elements
978
980
const wordElementIndex = TestState . activeWordIndex - activeWordElementOffset ;
979
981
const wordsWrapperWidth = (
@@ -1051,7 +1053,11 @@ export function scrollTape(noRemove = false): void {
1051
1053
const wordOuterWidth = $ ( child ) . outerWidth ( true ) ?? 0 ;
1052
1054
const forWordLeft = Math . floor ( child . offsetLeft ) ;
1053
1055
const forWordWidth = Math . floor ( child . offsetWidth ) ;
1054
- if ( ! noRemove && forWordLeft < 0 - forWordWidth ) {
1056
+ if (
1057
+ ! noRemove &&
1058
+ ( ( ! isLanguageRTL && forWordLeft < 0 - forWordWidth ) ||
1059
+ ( isLanguageRTL && forWordLeft > wordsWrapperWidth ) )
1060
+ ) {
1055
1061
toRemove . push ( child ) ;
1056
1062
widthRemoved += wordOuterWidth ;
1057
1063
wordsToRemoveCount ++ ;
@@ -1091,30 +1097,43 @@ export function scrollTape(noRemove = false): void {
1091
1097
parseFloat ( afterNewlineEl . style . marginLeft ) || 0 ;
1092
1098
afterNewlineEl . style . marginLeft = `${ currentLineIndent - width } px` ;
1093
1099
} ) ;
1100
+ if ( isLanguageRTL ) widthRemoved *= - 1 ;
1094
1101
const currentWordsMargin = parseFloat ( wordsEl . style . marginLeft ) || 0 ;
1095
1102
wordsEl . style . marginLeft = `${ currentWordsMargin + widthRemoved } px` ;
1096
1103
}
1097
1104
1098
1105
/* calculate current word width to add to #words margin */
1099
1106
let currentWordWidth = 0 ;
1100
- if ( Config . tapeMode === "letter" ) {
1101
- if ( TestInput . input . current . length > 0 ) {
1102
- const letters = activeWordEl . querySelectorAll ( "letter" ) ;
1103
- for ( let i = 0 ; i < TestInput . input . current . length ; i ++ ) {
1104
- const letter = letters [ i ] as HTMLElement ;
1105
- if (
1106
- ( Config . blindMode || Config . hideExtraLetters ) &&
1107
- letter . classList . contains ( "extra" )
1108
- ) {
1109
- continue ;
1110
- }
1111
- currentWordWidth += $ ( letter ) . outerWidth ( true ) ?? 0 ;
1107
+ const inputLength = TestInput . input . current . length ;
1108
+ if ( Config . tapeMode === "letter" && inputLength > 0 ) {
1109
+ const letters = activeWordEl . querySelectorAll ( "letter" ) ;
1110
+ let lastPositiveLetterWidth = 0 ;
1111
+ for ( let i = 0 ; i < inputLength ; i ++ ) {
1112
+ const letter = letters [ i ] as HTMLElement ;
1113
+ if (
1114
+ ( Config . blindMode || Config . hideExtraLetters ) &&
1115
+ letter . classList . contains ( "extra" )
1116
+ ) {
1117
+ continue ;
1112
1118
}
1119
+ const letterOuterWidth = $ ( letter ) . outerWidth ( true ) ?? 0 ;
1120
+ currentWordWidth += letterOuterWidth ;
1121
+ if ( letterOuterWidth > 0 ) lastPositiveLetterWidth = letterOuterWidth ;
1113
1122
}
1123
+ // if current letter has zero width move the tape to previous positive width letter
1124
+ if ( $ ( letters [ inputLength ] as Element ) . outerWidth ( true ) === 0 )
1125
+ currentWordWidth -= lastPositiveLetterWidth ;
1114
1126
}
1127
+
1115
1128
/* change to new #words & .afterNewline margins */
1116
- const tapeMargin = wordsWrapperWidth * ( Config . tapeMargin / 100 ) ;
1117
- const newMargin = tapeMargin - ( wordsWidthBeforeActive + currentWordWidth ) ;
1129
+ let newMargin = wordsWrapperWidth * ( Config . tapeMargin / 100 ) ;
1130
+ if ( isLanguageRTL )
1131
+ newMargin +=
1132
+ wordsWidthBeforeActive +
1133
+ currentWordWidth -
1134
+ wordsEl . offsetWidth +
1135
+ wordRightMargin ;
1136
+ else newMargin -= wordsWidthBeforeActive + currentWordWidth ;
1118
1137
1119
1138
const jqWords = $ ( wordsEl ) ;
1120
1139
if ( Config . smoothLineScroll ) {
@@ -1126,7 +1145,7 @@ export function scrollTape(noRemove = false): void {
1126
1145
duration : SlowTimer . get ( ) ? 0 : 125 ,
1127
1146
queue : "leftMargin" ,
1128
1147
complete : ( ) => {
1129
- if ( noRemove ) scrollTape ( ) ;
1148
+ if ( noRemove ) void scrollTape ( ) ;
1130
1149
} ,
1131
1150
}
1132
1151
) ;
@@ -1146,7 +1165,7 @@ export function scrollTape(noRemove = false): void {
1146
1165
afterNewlinesNewMargins . forEach ( ( margin , index ) => {
1147
1166
( afterNewLineEls [ index ] as HTMLElement ) . style . marginLeft = `${ margin } px` ;
1148
1167
} ) ;
1149
- if ( noRemove ) scrollTape ( ) ;
1168
+ if ( noRemove ) void scrollTape ( ) ;
1150
1169
}
1151
1170
}
1152
1171
0 commit comments