Fix IME composition Enter key handling on Windows#20
Merged
Conversation
The composition guard kept a flag true from compositionstart through one macrotask after compositionend and preventDefault()'d every Enter in that span. On Windows Zhuyin, the Enter that commits bopomofo into Han is part of the active composition, so swallowing it stopped the IME from finalizing and the raw phonetic buffer got inserted instead. Scope the guard to a short window after compositionend and bail when the event is still composing (isComposing / keyCode 229), so only the stray post-composition Enter that ProseMirror would mis-handle as a block split is suppressed. Decision logic extracted to imeGuard.js with unit tests. https://claude.ai/code/session_01KT7qFP6oQ5GdiotRi7X5De
A 0 sentinel for "no compositionend yet" collides with performance.now() (ms since page load): within the first POST_COMPOSITION_ENTER_MS after the time origin, now - 0 falls inside the window and a plain Enter would be swallowed. Use a negative-infinity sentinel so the window never matches until a real compositionend has occurred. https://claude.ai/code/session_01KT7qFP6oQ5GdiotRi7X5De
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.
Summary
Fixes a bug where pressing Enter to confirm an IME selection on Windows would trigger a spurious block split in the editor, causing the "line shifts down" symptom. The issue occurs because Windows fires a stray
keydownevent for Enter right aftercompositionend, which ProseMirror's default handler interprets as a deliberate newline.Changes
New module
imeGuard.js: ImplementsisStrayPostCompositionEnter()to detect and suppress only the stray Enter that arrives within 50ms ofcompositionend. The logic carefully preserves Enters that are still part of an active composition (e.g., Zhuyin pressing Enter to commit phonetic input) and those delivered to the IME itself (keyCode 229).New test file
imeGuard.test.js: Comprehensive test suite covering:Updated
Editor.jsx: Replaced the previous composition guard logic with a cleaner implementation:compositionstarthandler (no longer needed)compositionendto record a timestamp (lastCompositionEndAt) instead of setting a boolean flagisStrayPostCompositionEnter()that uses the timestamp windowsetTimeout(0)workaround in favor of a time-based windowImplementation Details
performance.now()for precise timing, consistent with the timestamp recorded atcompositionendNO_COMPOSITIONsentinel isNumber.NEGATIVE_INFINITYto prevent false positives during the first 50ms after page load (whenperformance.now()is small)isComposing: trueorkeyCode: 229, as these are part of the IME's input flowhttps://claude.ai/code/session_01KT7qFP6oQ5GdiotRi7X5De