Skip to content

Commit 54cc78a

Browse files
NickGerlemankelset
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 b164055 commit 54cc78a

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

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

Lines changed: 31 additions & 0 deletions
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;
@@ -667,6 +670,26 @@ public boolean test(ReactForegroundColorSpan span) {
667670
return span.getForegroundColor() == getCurrentTextColor();
668671
}
669672
});
673+
674+
stripSpansOfKind(
675+
sb,
676+
ReactStrikethroughSpan.class,
677+
new SpanPredicate<ReactStrikethroughSpan>() {
678+
@Override
679+
public boolean test(ReactStrikethroughSpan span) {
680+
return (getPaintFlags() & Paint.STRIKE_THRU_TEXT_FLAG) != 0;
681+
}
682+
});
683+
684+
stripSpansOfKind(
685+
sb,
686+
ReactUnderlineSpan.class,
687+
new SpanPredicate<ReactUnderlineSpan>() {
688+
@Override
689+
public boolean test(ReactUnderlineSpan span) {
690+
return (getPaintFlags() & Paint.UNDERLINE_TEXT_FLAG) != 0;
691+
}
692+
});
670693
}
671694

672695
private <T> void stripSpansOfKind(
@@ -700,6 +723,14 @@ private void restoreStyleEquivalentSpans(SpannableStringBuilder workingText) {
700723
spans.add(new ReactBackgroundColorSpan(backgroundColor));
701724
}
702725

726+
if ((getPaintFlags() & Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
727+
spans.add(new ReactStrikethroughSpan());
728+
}
729+
730+
if ((getPaintFlags() & Paint.UNDERLINE_TEXT_FLAG) != 0) {
731+
spans.add(new ReactUnderlineSpan());
732+
}
733+
703734
for (Object span : spans) {
704735
workingText.setSpan(span, 0, workingText.length(), spanFlags);
705736
}

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

Lines changed: 15 additions & 0 deletions
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;
@@ -903,6 +904,20 @@ public void setAutoFocus(ReactEditText view, boolean autoFocus) {
903904
view.setAutoFocus(autoFocus);
904905
}
905906

907+
@ReactProp(name = ViewProps.TEXT_DECORATION_LINE)
908+
public void setTextDecorationLine(ReactEditText view, @Nullable String textDecorationLineString) {
909+
view.setPaintFlags(
910+
view.getPaintFlags() & ~(Paint.STRIKE_THRU_TEXT_FLAG | Paint.UNDERLINE_TEXT_FLAG));
911+
912+
for (String token : textDecorationLineString.split(" ")) {
913+
if (token.equals("underline")) {
914+
view.setPaintFlags(view.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
915+
} else if (token.equals("line-through")) {
916+
view.setPaintFlags(view.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
917+
}
918+
}
919+
}
920+
906921
@ReactPropGroup(
907922
names = {
908923
ViewProps.BORDER_WIDTH,

0 commit comments

Comments
 (0)