Commit 4ec683f
Fix controlled TextInput jumbling characters during autocorrect on Fabric
Summary:
On iOS Fabric, a controlled `<TextInput>` could silently drop characters when iOS autocorrect/IME composition was in flight, regressing the controlled-input "jumbled text" behavior that the `TextInput-dynamicWidth-e2e.js` regression test was designed to catch. The test had been left disabled on iOS Fabric configs because of this, masking the real product regression.
Root cause: `RCTTextInputComponentView` snapshots the backing field's `typingAttributes` once at view init time and uses that snapshot as the "insensitive attributes" set for `RCTIsAttributedStringEffectivelySame` — i.e. the set of UIKit-injected attributes the comparison should ignore so it doesn't trigger a destructive `setAttributedText:` on every keystroke. UIKit, however, injects additional typing attributes lazily after the field becomes first responder. Concretely, the init snapshot has `{NSColor, NSParagraphStyle, NSFont}`, but after focus the live `typingAttributes` also contains `NSBackgroundColor` (used for the marked-text highlight during composition/autocorrect) and the React Native event-emitter wrapping key. When iOS performs a multi-step text replacement (e.g. autocorrect substituting `Thos` -> `This`), characters in the backing string transiently carry these extra attributes. The comparison then incorrectly returns "different", we overwrite the backing field mid-replacement, and the in-flight text mutation is corrupted — exactly the original failure mode this code path was meant to prevent.
Fix: introduce `_insensitiveTypingAttributes`, which unions the init snapshot with the live `typingAttributes` at compare time. The init snapshot is preserved as a floor (in case UIKit later removes attributes it had during normal typing), and any attribute UIKit silently injects after focus is now correctly ignored by the comparison.
The fix is small, scoped to `RCTTextInputComponentView.mm`, and preserves the contract of `RCTIsAttributedStringEffectivelySame`: we only broaden the insensitive set, never narrow it.
Changelog:
[iOS][Fixed] - Fix controlled TextInput jumbling characters during autocorrect/IME composition on Fabric
Differential Revision: D1031236181 parent 32d3eaf commit 4ec683f
1 file changed
Lines changed: 24 additions & 2 deletions
File tree
- packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput
Lines changed: 24 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
879 | 879 | | |
880 | 880 | | |
881 | 881 | | |
882 | | - | |
883 | | - | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
884 | 906 | | |
885 | 907 | | |
886 | 908 | | |
| |||
0 commit comments