fix(core): track pre-edit selection via beforeinput to stop desync - #60
Open
artnikbrothers wants to merge 1 commit into
Open
fix(core): track pre-edit selection via beforeinput to stop desync#60artnikbrothers wants to merge 1 commit into
artnikbrothers wants to merge 1 commit into
Conversation
The pre-edit selection needed to classify each "input" event (insert vs delete, and the edited range) was cached only by a self-rescheduling setTimeout(0) poll. Browsers throttle nested zero-delay timers to a ~4ms floor, so under fast typing (or extra synchronous work per keystroke, e.g. a form library revalidating on change) the poll falls behind the real cursor position. Separately, a plain `element.value =` write - such as a controlled component re-rendering with a reformatted value - moves the native cursor to the end without firing "input" or updating the cached selection. Either path leaves the cached selection stale relative to the DOM, so the next keystroke's addedValue slice spans the wrong range and splices text back at the wrong position, producing reverted or duplicated characters. Capture the pre-edit selection from the "beforeinput" event instead, which fires synchronously right before the browser applies an edit and always reflects the real DOM selection at that instant - including a cursor already moved by a prior controlled re-render. The existing setTimeout poll is left in place as a fallback for cases beforeinput doesn't cover (autofill, or pure cursor moves with no edit). Fixes GoncharukOrg#59
Author
|
Hi @GoncharukBro, any chance we can review this PR and if all good release it? we have a problem in our applications because of this issue, and would really appreciate if we can fix it |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fast typing (or holding Backspace) can revert or duplicate characters. Root cause:
inputevent (insert vs delete, and the edited range) was cached only by a self-reschedulingsetTimeout(0)poll.element.value =write - e.g. a controlled component re-rendering with a reformatted value - moves the cursor to the end without firinginputor updating the cached selection.addedValueslice spans the wrong range and splices text back at the wrong position - producing the reverted/duplicated characters.Fix: capture the pre-edit selection from the
beforeinputevent instead. It fires synchronously right before the browser applies an edit, so it always reflects the real DOM selection at that instant, including a cursor already moved by a prior controlled re-render. The existingsetTimeoutpoll stays in place as a fallback for casesbeforeinputdoesn't cover (autofill, or a pure cursor move with no edit).Fixes #59