Skip to content

[lexical] Bug Fix: Handle iOS 10-key Korean IME deleteContentBackward with targetRange#8475

Merged
etrepum merged 3 commits into
facebook:mainfrom
kotom320:fix/ios-10key-korean-input-corruption
May 11, 2026
Merged

[lexical] Bug Fix: Handle iOS 10-key Korean IME deleteContentBackward with targetRange#8475
etrepum merged 3 commits into
facebook:mainfrom
kotom320:fix/ios-10key-korean-input-corruption

Conversation

@kotom320

@kotom320 kotom320 commented May 7, 2026

Copy link
Copy Markdown
Contributor

Description

The iOS 10-key (천지인/Chunjiin) Korean keyboard does not fire compositionstart/compositionend events. Instead, each syllable composition step sends:

  1. beforeinput deleteContentBackward with a non-collapsed targetRange — to erase the current in-progress syllable
  2. beforeinput insertText — to insert the updated syllable

Because editor.isComposing() is always false for this keyboard type, Lexical falls through to DELETE_CHARACTER_COMMAND, which ignores targetRange entirely and deletes one character before the cursor. The wrong character is deleted, and orphaned jamo accumulate in the editor state with each composition step.

This PR adds a guard in the deleteContentBackward handler: when on iOS with a non-collapsed targetRange, call
selection.applyDOMRange(targetRange) and removeText() to delete exactly the range the IME requested, then return early.
If applyDOMRange cannot resolve the range (collapsed result), the code falls through to the existing path unchanged.

targetRange and IS_IOS are already in scope at the call site — no new imports or dependencies needed.

Test plan

Before

Typing 안녕하세요 on iOS 10-key (천지인) keyboard produces corrupted output: 안녕하ᄉ세 ᄋᄋ요 (orphaned jamo appear equal to the number of dot presses per vowel)

ScreenRecording_05-07-2026.17-38-05_1.MOV

After

Typing 안녕하세요 on iOS 10-key (천지인) keyboard produces correct output: 안녕하세요

@meta-cla

meta-cla Bot commented May 7, 2026

Copy link
Copy Markdown

Hi @kotom320!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@vercel

vercel Bot commented May 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lexical Ready Ready Preview, Comment May 11, 2026 5:49am
lexical-playground Ready Ready Preview, Comment May 11, 2026 5:49am

Request Review

@etrepum etrepum left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if this also added some kind of test to confirm that the behavior is more correct. Note that we can't do anything with this until the CLA is signed (there is some delay for the bot to confirm it)

@mayrang

mayrang commented May 7, 2026

Copy link
Copy Markdown
Contributor

Test suggestion from a Korean user — the case worth nailing is the text-node boundary, when the IME range straddles two text nodes mid-composition. That's where IME bugs tend to hide in this area.

@etrepum

etrepum commented May 10, 2026

Copy link
Copy Markdown
Collaborator

If the CLA isn't signed we will have to close this eventually but I would be happy to review another attempt at this fix by a contributor who can sign the CLA especially if it includes tests.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 11, 2026
@kotom320

Copy link
Copy Markdown
Contributor Author

@etrepum
Sorry for the delay! I've signed the CLA and added test cases covering the fix. Please take another look when you get a chance.

@etrepum etrepum added the extended-tests Run extended e2e tests on a PR label May 11, 2026
@etrepum

etrepum commented May 11, 2026

Copy link
Copy Markdown
Collaborator

@mayrang since it sounds like you are familiar with this Korean IME do you have any opinions on this solution and how it behaves in the playground? https://lexical-playground-git-fork-kotom320-fix-io-590d2a-fbopensource.vercel.app/

It's tricky for me to validate that it behaves as expected as I have no fluency in Korean

@etrepum etrepum left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks reasonable to me, the behavior certainly seems like an improvement over the current playground, but I am unsure if it exactly matches the expectations of someone familiar with this language and IME. Will hold off on merging for a bit for a second opinion but approving in the meantime.

@mayrang

mayrang commented May 11, 2026

Copy link
Copy Markdown
Contributor

@etrepum — checked on iOS Safari with the built-in 10키 (천지인) Korean keyboard.

  • Main playground reproduces the bug: typing 안녕하세요 yields "안녕하ᄉ세ᄋᄋ요" with orphan jamo, matching the Before video.
  • Fork preview with this fix produces clean "안녕하세요".

Third-party Korean keyboard apps (Naver SmartBoard, etc.) don't go through this code path — they use a different IME route — so they're unaffected either way. The fix is targeting the iOS built-in 10키 case, which is the only option for users who don't install a third-party keyboard.

Side note: iOS 10-key diverges from Android 10-key and from other Korean IMEs at both the browser event layer (no compositionstart/end) and now in Lexical's handling, which puts it on a less-trodden path than the standard composition flow. The fix lands the most visible symptom; other quirks in this path could surface later as it gets more real-world iOS exposure. Will take a closer look when I have some time.

@etrepum

etrepum commented May 11, 2026

Copy link
Copy Markdown
Collaborator

@mayrang thank you, I will merge this as-is as it's a clear improvement! Please feel free assist or offer PRs on any other IME issue since you have a lot more domain knowledge than most of the active maintainers

@etrepum etrepum added this pull request to the merge queue May 11, 2026
Merged via the queue into facebook:main with commit 210c629 May 11, 2026
69 of 71 checks passed
@mayrang

mayrang commented May 11, 2026

Copy link
Copy Markdown
Contributor

Thanks @etrepum. Will keep an eye on the IME-tagged issues and chime in when there's something concrete to add.

@kotom320

Copy link
Copy Markdown
Contributor Author

Thank you for merging this! @mayrang, I really appreciate your support and insights. It was a great help and I learned a lot from your explanation. @etrepum, thanks for the review and for your patience. I'm just glad that this fix could be of help to the project!

@etrepum etrepum mentioned this pull request May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. extended-tests Run extended e2e tests on a PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants