Skip to content

Commit

Permalink
Back out "Fix issue#11068 of duplicating characters when replacing le…
Browse files Browse the repository at this point in the history
…tters to lowercase or uppercase in TextInput"

Summary:
Changelog: [Internal] - Back out #35929 due to #35929 (comment)

Original Phabricator Diff: D47243817

Reviewed By: sunzhaoyuan

Differential Revision: D47785787

fbshipit-source-id: 81598be3f0b4e0e753dfbee4cee781673f900827
  • Loading branch information
lunaleaps authored and facebook-github-bot committed Jul 26, 2023
1 parent bae0016 commit c1eec4c
Showing 1 changed file with 7 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -632,13 +632,10 @@ public void maybeSetText(ReactTextUpdate reactTextUpdate) {
if (reactTextUpdate.getText().length() == 0) {
setText(null);
} else {
boolean shouldRestoreComposingSpans = length() == spannableStringBuilder.length();

// When we update text, we trigger onChangeText code that will
// try to update state if the wrapper is available. Temporarily disable
// to prevent an infinite loop.
getText().replace(0, length(), spannableStringBuilder);

if (shouldRestoreComposingSpans) {
restoreComposingSpansToTextFrom(spannableStringBuilder);
}
}
mDisableTextDiffing = false;

Expand All @@ -653,13 +650,10 @@ public void maybeSetText(ReactTextUpdate reactTextUpdate) {
}

/**
* Remove and/or add {@link Spanned#SPAN_EXCLUSIVE_EXCLUSIVE} spans, since they should only exist
* as long as the text they cover is the same unless they are {@link Spanned#SPAN_COMPOSING}. All
* other spans will remain the same, since they will adapt to the new text, hence why {@link
* SpannableStringBuilder#replace} never removes them. Keep copy of {@link Spanned#SPAN_COMPOSING}
* Spans in {@param spannableStringBuilder}, because they are important for keyboard suggestions.
* Without keeping these Spans, suggestions default to be put after the current selection
* position, possibly resulting in letter duplication.
* Remove and/or add {@link Spanned.SPAN_EXCLUSIVE_EXCLUSIVE} spans, since they should only exist
* as long as the text they cover is the same. All other spans will remain the same, since they
* will adapt to the new text, hence why {@link SpannableStringBuilder#replace} never removes
* them.
*/
private void manageSpans(SpannableStringBuilder spannableStringBuilder) {
Object[] spans = getText().getSpans(0, length(), Object.class);
Expand All @@ -668,7 +662,6 @@ private void manageSpans(SpannableStringBuilder spannableStringBuilder) {
int spanFlags = getText().getSpanFlags(span);
boolean isExclusiveExclusive =
(spanFlags & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) == Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
boolean isComposing = (spanFlags & Spanned.SPAN_COMPOSING) == Spanned.SPAN_COMPOSING;

// Remove all styling spans we might have previously set
if (span instanceof ReactSpan) {
Expand All @@ -683,12 +676,6 @@ private void manageSpans(SpannableStringBuilder spannableStringBuilder) {
final int spanStart = getText().getSpanStart(span);
final int spanEnd = getText().getSpanEnd(span);

// We keep a copy of Composing spans
if (isComposing) {
spannableStringBuilder.setSpan(span, spanStart, spanEnd, spanFlags);
continue;
}

// Make sure the span is removed from existing text, otherwise the spans we set will be
// ignored or it will cover text that has changed.
getText().removeSpan(span);
Expand Down Expand Up @@ -816,34 +803,6 @@ private void addSpansFromStyleAttributes(SpannableStringBuilder workingText) {
}
}

/**
* Attaches the {@link Spanned#SPAN_COMPOSING} from {@param spannableStringBuilder} to {@link
* ReactEditText#getText}
*
* <p>See {@link ReactEditText#manageSpans} for more details. Also
* https://github.com/facebook/react-native/issues/11068
*/
private void restoreComposingSpansToTextFrom(SpannableStringBuilder spannableStringBuilder) {
Editable text = getText();
if (text == null) {
return;
}
Object[] spans = spannableStringBuilder.getSpans(0, length(), Object.class);
for (Object span : spans) {
int spanFlags = spannableStringBuilder.getSpanFlags(span);
boolean isComposing = (spanFlags & Spanned.SPAN_COMPOSING) == Spanned.SPAN_COMPOSING;

if (!isComposing) {
continue;
}

final int spanStart = spannableStringBuilder.getSpanStart(span);
final int spanEnd = spannableStringBuilder.getSpanEnd(span);

text.setSpan(span, spanStart, spanEnd, spanFlags);
}
}

private static boolean sameTextForSpan(
final Editable oldText,
final SpannableStringBuilder newText,
Expand Down

0 comments on commit c1eec4c

Please sign in to comment.