Support MapBuffer in TextInput State

Summary:
Support MapBuffer in TextInput State.

Changelog: [Internal]

Reviewed By: NickGerleman

Differential Revision: D38546271

fbshipit-source-id: 93e7fd79d9d8473dd646410f3047fcfafa8516f1
This commit is contained in:
Joshua Gross
2022-08-16 12:21:52 -07:00
committed by Facebook GitHub Bot
parent a63204800a
commit 04c75ba988
7 changed files with 93 additions and 13 deletions
@@ -106,6 +106,11 @@ public class TextLayoutManagerMapBuffer {
MapBuffer fragment = fragments.getMapBuffer((short) 0);
MapBuffer textAttributes = fragment.getMapBuffer(FR_KEY_TEXT_ATTRIBUTES);
if (!textAttributes.contains(TextAttributeProps.TA_KEY_LAYOUT_DIRECTION)) {
return false;
}
return TextAttributeProps.getLayoutDirection(
textAttributes.getString(TextAttributeProps.TA_KEY_LAYOUT_DIRECTION))
== LayoutDirection.RTL;
@@ -9,7 +9,8 @@ rn_android_library(
"pfh:ReactNative_CommonInfrastructurePlaceholder",
"supermodule:xplat/default/public.react_native.infra",
],
language = "JAVA",
language = "KOTLIN",
pure_kotlin = False,
required_for_source_only_abi = True,
visibility = [
"PUBLIC",
@@ -29,7 +30,9 @@ rn_android_library(
react_native_target("java/com/facebook/react/views/imagehelper:imagehelper"),
react_native_target("java/com/facebook/react/views/scroll:scroll"),
react_native_target("java/com/facebook/react/views/text:text"),
react_native_target("java/com/facebook/react/common/mapbuffer:mapbuffer"),
react_native_target("java/com/facebook/react/views/view:view"),
react_native_target("java/com/facebook/react/config:config"),
],
exported_deps = [
react_native_dep("third-party/android/androidx:appcompat"),
@@ -44,6 +44,8 @@ import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.mapbuffer.MapBuffer;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.BaseViewManager;
import com.facebook.react.uimanager.FabricViewStateManager;
@@ -69,6 +71,7 @@ import com.facebook.react.views.text.ReactTextViewManagerCallback;
import com.facebook.react.views.text.TextAttributeProps;
import com.facebook.react.views.text.TextInlineImageSpan;
import com.facebook.react.views.text.TextLayoutManager;
import com.facebook.react.views.text.TextLayoutManagerMapBuffer;
import com.facebook.react.views.text.TextTransform;
import com.facebook.yoga.YogaConstants;
import java.lang.reflect.Field;
@@ -83,6 +86,12 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
public static final String TAG = ReactTextInputManager.class.getSimpleName();
public static final String REACT_CLASS = "AndroidTextInput";
// See also ReactTextViewManager
private static final short TX_STATE_KEY_ATTRIBUTED_STRING = 0;
private static final short TX_STATE_KEY_PARAGRAPH_ATTRIBUTES = 1;
private static final short TX_STATE_KEY_HASH = 2;
private static final short TX_STATE_KEY_MOST_RECENT_EVENT_COUNT = 3;
private static final int[] SPACING_TYPES = {
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM,
};
@@ -1286,6 +1295,13 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
stateManager.setStateWrapper(stateWrapper);
if (ReactFeatureFlags.mapBufferSerializationEnabled) {
MapBuffer stateMapBuffer = stateWrapper.getStateDataMapBuffer();
if (stateMapBuffer != null) {
return getReactTextUpdate(view, props, stateMapBuffer);
}
}
ReadableNativeMap state = stateWrapper.getStateData();
if (state == null) {
return null;
@@ -1318,4 +1334,39 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
TextAttributeProps.getJustificationMode(props),
containsMultipleFragments);
}
public Object getReactTextUpdate(ReactEditText view, ReactStylesDiffMap props, MapBuffer state) {
// If native wants to update the state wrapper but the state data hasn't actually
// changed, the MapBuffer may be empty
if (state.getCount() == 0) {
return null;
}
MapBuffer attributedString = state.getMapBuffer(TX_STATE_KEY_ATTRIBUTED_STRING);
MapBuffer paragraphAttributes = state.getMapBuffer(TX_STATE_KEY_PARAGRAPH_ATTRIBUTES);
if (attributedString == null || paragraphAttributes == null) {
throw new IllegalArgumentException(
"Invalid TextInput State (MapBuffer) was received as a parameters");
}
Spannable spanned =
TextLayoutManagerMapBuffer.getOrCreateSpannableForText(
view.getContext(), attributedString, mReactTextViewManagerCallback);
boolean containsMultipleFragments =
attributedString.getMapBuffer(TextLayoutManagerMapBuffer.AS_KEY_FRAGMENTS).getCount() > 1;
int textBreakStrategy =
TextAttributeProps.getTextBreakStrategy(
paragraphAttributes.getString(TextLayoutManagerMapBuffer.PA_KEY_TEXT_BREAK_STRATEGY));
return ReactTextUpdate.buildReactTextUpdateFromState(
spanned,
state.getInt(TX_STATE_KEY_MOST_RECENT_EVENT_COUNT),
TextAttributeProps.getTextAlignment(
props, TextLayoutManagerMapBuffer.isRTL(attributedString)),
textBreakStrategy,
TextAttributeProps.getJustificationMode(props),
containsMultipleFragments);
}
}