Skip to content

Commit 0869ea2

Browse files
NickGerlemanfacebook-github-bot
authored andcommitted
Minimize EditText Spans 5/9: Strikethrough and Underline (#36544)
Summary: Pull Request resolved: #36544 This is part of a series of changes to minimize the number of spans committed to EditText, as a mitigation for platform issues on Samsung devices. See this [GitHub thread]( #35936 (comment)) for greater context on the platform behavior. This change makes us apply strikethrough and underline as paint flags to the underlying EditText, instead of just the spans. We then opt ReactUnderlineSpan and ReactStrikethroughSpan into being strippable. This does actually create visual behavior changes, where child text will inherit any underline or strikethrough of the root EditText (including if the child specifies `textDecorationLine: "none"`. The new behavior is consistent with both iOS and web though, so it seems like more of a bugfix than a regression. Changelog: [Android][Fixed] - Minimize Spans 5/N: Strikethrough and Underline Reviewed By: rshest Differential Revision: D44240778 fbshipit-source-id: d564dfc0121057a5e3b09bb71b8f5662e28be17e
1 parent 155591b commit 0869ea2

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java

+31
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
import android.content.Context;
1414
import android.graphics.Color;
15+
import android.graphics.Paint;
1516
import android.graphics.Rect;
1617
import android.graphics.Typeface;
1718
import android.graphics.drawable.Drawable;
@@ -54,8 +55,10 @@
5455
import com.facebook.react.views.text.ReactBackgroundColorSpan;
5556
import com.facebook.react.views.text.ReactForegroundColorSpan;
5657
import com.facebook.react.views.text.ReactSpan;
58+
import com.facebook.react.views.text.ReactStrikethroughSpan;
5759
import com.facebook.react.views.text.ReactTextUpdate;
5860
import com.facebook.react.views.text.ReactTypefaceUtils;
61+
import com.facebook.react.views.text.ReactUnderlineSpan;
5962
import com.facebook.react.views.text.TextAttributes;
6063
import com.facebook.react.views.text.TextInlineImageSpan;
6164
import com.facebook.react.views.text.TextLayoutManager;
@@ -703,6 +706,26 @@ public boolean test(ReactForegroundColorSpan span) {
703706
return span.getForegroundColor() == getCurrentTextColor();
704707
}
705708
});
709+
710+
stripSpansOfKind(
711+
sb,
712+
ReactStrikethroughSpan.class,
713+
new SpanPredicate<ReactStrikethroughSpan>() {
714+
@Override
715+
public boolean test(ReactStrikethroughSpan span) {
716+
return (getPaintFlags() & Paint.STRIKE_THRU_TEXT_FLAG) != 0;
717+
}
718+
});
719+
720+
stripSpansOfKind(
721+
sb,
722+
ReactUnderlineSpan.class,
723+
new SpanPredicate<ReactUnderlineSpan>() {
724+
@Override
725+
public boolean test(ReactUnderlineSpan span) {
726+
return (getPaintFlags() & Paint.UNDERLINE_TEXT_FLAG) != 0;
727+
}
728+
});
706729
}
707730

708731
private <T> void stripSpansOfKind(
@@ -736,6 +759,14 @@ private void restoreStyleEquivalentSpans(SpannableStringBuilder workingText) {
736759
spans.add(new ReactBackgroundColorSpan(backgroundColor));
737760
}
738761

762+
if ((getPaintFlags() & Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
763+
spans.add(new ReactStrikethroughSpan());
764+
}
765+
766+
if ((getPaintFlags() & Paint.UNDERLINE_TEXT_FLAG) != 0) {
767+
spans.add(new ReactUnderlineSpan());
768+
}
769+
739770
for (Object span : spans) {
740771
workingText.setSpan(span, 0, workingText.length(), spanFlags);
741772
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java

+15
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import android.content.res.ColorStateList;
1414
import android.graphics.BlendMode;
1515
import android.graphics.BlendModeColorFilter;
16+
import android.graphics.Paint;
1617
import android.graphics.PorterDuff;
1718
import android.graphics.drawable.Drawable;
1819
import android.os.Build;
@@ -935,6 +936,20 @@ public void setAutoFocus(ReactEditText view, boolean autoFocus) {
935936
view.setAutoFocus(autoFocus);
936937
}
937938

939+
@ReactProp(name = ViewProps.TEXT_DECORATION_LINE)
940+
public void setTextDecorationLine(ReactEditText view, @Nullable String textDecorationLineString) {
941+
view.setPaintFlags(
942+
view.getPaintFlags() & ~(Paint.STRIKE_THRU_TEXT_FLAG | Paint.UNDERLINE_TEXT_FLAG));
943+
944+
for (String token : textDecorationLineString.split(" ")) {
945+
if (token.equals("underline")) {
946+
view.setPaintFlags(view.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
947+
} else if (token.equals("line-through")) {
948+
view.setPaintFlags(view.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
949+
}
950+
}
951+
}
952+
938953
@ReactPropGroup(
939954
names = {
940955
ViewProps.BORDER_WIDTH,

0 commit comments

Comments
 (0)