mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Minimize EditText Spans 8/9: CustomStyleSpan (#36577)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/36577 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]( https://github.com/facebook/react-native/issues/35936#issuecomment-1411437789) for greater context on the platform behavior. This change allows us to strip CustomStyleSpan. We already set all but `fontVariant` on the underlying EditText, so we just need to route that through as well. Note that because this span is non-parcelable, it is seemingly not subject to the buggy behavior on Samsung devices of infinitely cloning the spans, but non-parcelable spans have different issues on the devices (they disappear), so moving `fontVariant` to the top-level makes sense here. Changelog: [Android][Fixed] - Minimize EditText Spans 8/N: CustomStyleSpan Reviewed By: javache Differential Revision: D44297384 fbshipit-source-id: ed4c000e961dd456a2a8f4397e27c23a87defb6e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
104cb7f81e
commit
b384bb613b
+4
@@ -71,6 +71,10 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan {
|
||||
return mFontFamily;
|
||||
}
|
||||
|
||||
public @Nullable String getFontFeatureSettings() {
|
||||
return mFeatureSettings;
|
||||
}
|
||||
|
||||
private static void apply(
|
||||
Paint paint,
|
||||
int style,
|
||||
|
||||
+49
@@ -65,6 +65,7 @@ import com.facebook.react.views.text.TextLayoutManager;
|
||||
import com.facebook.react.views.view.ReactViewBackgroundManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A wrapper around the EditText that lets us better control what happens when an EditText gets
|
||||
@@ -518,6 +519,14 @@ public class ReactEditText extends AppCompatEditText
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFontFeatureSettings(String fontFeatureSettings) {
|
||||
if (!Objects.equals(fontFeatureSettings, getFontFeatureSettings())) {
|
||||
super.setFontFeatureSettings(fontFeatureSettings);
|
||||
mTypefaceDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void maybeUpdateTypeface() {
|
||||
if (!mTypefaceDirty) {
|
||||
return;
|
||||
@@ -529,6 +538,17 @@ public class ReactEditText extends AppCompatEditText
|
||||
ReactTypefaceUtils.applyStyles(
|
||||
getTypeface(), mFontStyle, mFontWeight, mFontFamily, getContext().getAssets());
|
||||
setTypeface(newTypeface);
|
||||
|
||||
// Match behavior of CustomStyleSpan and enable SUBPIXEL_TEXT_FLAG when setting anything
|
||||
// nonstandard
|
||||
if (mFontStyle != UNSET
|
||||
|| mFontWeight != UNSET
|
||||
|| mFontFamily != null
|
||||
|| getFontFeatureSettings() != null) {
|
||||
setPaintFlags(getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
|
||||
} else {
|
||||
setPaintFlags(getPaintFlags() & (~Paint.SUBPIXEL_TEXT_FLAG));
|
||||
}
|
||||
}
|
||||
|
||||
// VisibleForTesting from {@link TextInputEventsTestCase}.
|
||||
@@ -738,6 +758,19 @@ public class ReactEditText extends AppCompatEditText
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
stripSpansOfKind(
|
||||
sb,
|
||||
CustomStyleSpan.class,
|
||||
new SpanPredicate<CustomStyleSpan>() {
|
||||
@Override
|
||||
public boolean test(CustomStyleSpan span) {
|
||||
return span.getStyle() == mFontStyle
|
||||
&& Objects.equals(span.getFontFamily(), mFontFamily)
|
||||
&& span.getWeight() == mFontWeight
|
||||
&& Objects.equals(span.getFontFeatureSettings(), getFontFeatureSettings());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private <T> void stripSpansOfKind(
|
||||
@@ -795,6 +828,22 @@ public class ReactEditText extends AppCompatEditText
|
||||
spanFlags);
|
||||
}
|
||||
}
|
||||
|
||||
if (mFontStyle != UNSET
|
||||
|| mFontWeight != UNSET
|
||||
|| mFontFamily != null
|
||||
|| getFontFeatureSettings() != null) {
|
||||
workingText.setSpan(
|
||||
new CustomStyleSpan(
|
||||
mFontStyle,
|
||||
mFontWeight,
|
||||
getFontFeatureSettings(),
|
||||
mFontFamily,
|
||||
getContext().getAssets()),
|
||||
0,
|
||||
workingText.length(),
|
||||
spanFlags);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean sameTextForSpan(
|
||||
|
||||
+6
@@ -69,6 +69,7 @@ import com.facebook.react.views.text.DefaultStyleValuesUtil;
|
||||
import com.facebook.react.views.text.ReactBaseTextShadowNode;
|
||||
import com.facebook.react.views.text.ReactTextUpdate;
|
||||
import com.facebook.react.views.text.ReactTextViewManagerCallback;
|
||||
import com.facebook.react.views.text.ReactTypefaceUtils;
|
||||
import com.facebook.react.views.text.TextAttributeProps;
|
||||
import com.facebook.react.views.text.TextInlineImageSpan;
|
||||
import com.facebook.react.views.text.TextLayoutManager;
|
||||
@@ -413,6 +414,11 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
view.setFontStyle(fontStyle);
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.FONT_VARIANT)
|
||||
public void setFontVariant(ReactEditText view, @Nullable ReadableArray fontVariant) {
|
||||
view.setFontFeatureSettings(ReactTypefaceUtils.parseFontVariant(fontVariant));
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.INCLUDE_FONT_PADDING, defaultBoolean = true)
|
||||
public void setIncludeFontPadding(ReactEditText view, boolean includepad) {
|
||||
view.setIncludeFontPadding(includepad);
|
||||
|
||||
Reference in New Issue
Block a user