mirror of
				https://github.com/monkeytypegame/monkeytype.git
				synced 2025-10-31 19:26:22 +08:00 
			
		
		
		
	fix(caret): caret not resetting position on quick restart (@nadalaba) (#7038)
- quick restarting immediately after some input makes the caret fail to reset its position sometimes. https://github.com/user-attachments/assets/d9e1def5-d8f6-4af2-845c-778c89279849 this happens because the reset of caret's position that should happen on the callback inside `requestAnimationFrame` in `caret.goTo()` (triggered in `TestUI.updateWordsWrapperClasses()`) is cancelled by a later call to `caret.goTo()` (triggered by `TestUI.focusWords()`). However the second call sets the position directly without stopping previous animation `$('#caret').stop().animate()`. As a result, the earlier animation (caused by last input) continues after the reset, if the restart was done fast enough. - update some previous comments.
This commit is contained in:
		
							parent
							
								
									42227666a8
								
							
						
					
					
						commit
						a0c9decc3f
					
				
					 2 changed files with 11 additions and 5 deletions
				
			
		|  | @ -286,6 +286,7 @@ export function restart(options = {} as RestartOptions): void { | |||
|   TimerProgress.hide(); | ||||
|   Replay.pauseReplay(); | ||||
|   TestState.setBailedOut(false); | ||||
|   Caret.resetPosition(); | ||||
|   PaceCaret.reset(); | ||||
|   Monkey.hide(); | ||||
|   TestInput.input.setKoreanStatus(false); | ||||
|  |  | |||
|  | @ -102,6 +102,7 @@ export class Caret { | |||
|     top: number; | ||||
|     width?: number; | ||||
|   }): void { | ||||
|     $(this.element).stop("pos", true, false); | ||||
|     this.element.style.left = `${options.left}px`; | ||||
|     this.element.style.top = `${options.top}px`; | ||||
|     if (options.width !== undefined) { | ||||
|  | @ -143,6 +144,8 @@ export class Caret { | |||
|   } | ||||
| 
 | ||||
|   public handleTapeWordsRemoved(widthRemoved: number): void { | ||||
|     // Removing tape words reduces the absolute value of options.newValue passed to handleTapeScroll().
 | ||||
|     // To keep the target marginLeft accurate, we reduce the absolute value of cumulative correction by the same amount.
 | ||||
|     this.cumulativeTapeMarginCorrection += widthRemoved; | ||||
|   } | ||||
| 
 | ||||
|  | @ -154,12 +157,14 @@ export class Caret { | |||
|     this.readyToResetMarginLeft = false; | ||||
| 
 | ||||
|     /** | ||||
|      * If we didn't reset marginLeft, then options.newValue gives the correct caret | ||||
|      * position by adding up the widths of all typed characters. But since we reset | ||||
|      * caret.style.marginLeft during the test, the caret ends up too far left. | ||||
|      * options.newValue is the total width of all previously typed characters, and assuming we didn't | ||||
|      * reset marginLeft or remove any tape words, then it would be the correct marginLeft to go to. | ||||
|      * | ||||
|      * To fix this, we track how much marginLeft we've reset so far (cumulativeTapeMarginCorrection), | ||||
|      * and subtract it from options.newValue to get the correct newMarginLeft. | ||||
|      * Each time marginLeft is reset, the distance between options.newValue and the current | ||||
|      * marginLeft-after-reset increases, making the caret shift too much left (in LTR). | ||||
|      * | ||||
|      * To correct this, we decrease the new target marginLeft by how much we've | ||||
|      * reset the margin so far (cumulativeTapeMarginCorrection). | ||||
|      */ | ||||
|     const newMarginLeft = | ||||
|       options.newValue - this.cumulativeTapeMarginCorrection; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue