mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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:
committed by
Lorenzo Sciandra
parent
322f721c4a
commit
62364d00ca
+5
@@ -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"),
|
||||
|
||||
+51
@@ -45,6 +45,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;
|
||||
@@ -71,6 +73,7 @@ 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;
|
||||
import com.facebook.react.views.text.TextLayoutManagerMapBuffer;
|
||||
import com.facebook.react.views.text.TextTransform;
|
||||
import com.facebook.yoga.YogaConstants;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -85,6 +88,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,
|
||||
};
|
||||
@@ -1305,6 +1314,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;
|
||||
@@ -1337,4 +1353,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,15 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
#ifdef ANDROID
|
||||
// constants for Text State serialization
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_ATTRIBUTED_STRING = 0;
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_PARAGRAPH_ATTRIBUTES = 1;
|
||||
// Used for TextInput only
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_HASH = 2;
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_MOST_RECENT_EVENT_COUNT = 3;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* State for <Paragraph> component.
|
||||
* Represents what to render and how to render.
|
||||
|
||||
@@ -26,21 +26,13 @@ inline folly::dynamic toDynamic(ParagraphState const ¶graphState) {
|
||||
return newState;
|
||||
}
|
||||
|
||||
// constants for Text State serialization
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_ATTRIBUTED_STRING = 0;
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_PARAGRAPH_ATTRIBUTES = 1;
|
||||
// Used for TextInput
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_HASH = 2;
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_MOST_RECENT_EVENT_COUNT = 3;
|
||||
|
||||
inline MapBuffer toMapBuffer(ParagraphState const ¶graphState) {
|
||||
auto builder = MapBufferBuilder();
|
||||
auto attStringMapBuffer = toMapBuffer(paragraphState.attributedString);
|
||||
builder.putMapBuffer(TX_STATE_KEY_ATTRIBUTED_STRING, attStringMapBuffer);
|
||||
auto paMapBuffer = toMapBuffer(paragraphState.paragraphAttributes);
|
||||
builder.putMapBuffer(TX_STATE_KEY_PARAGRAPH_ATTRIBUTES, paMapBuffer);
|
||||
// TODO: Used for TextInput
|
||||
builder.putInt(TX_STATE_KEY_HASH, 1234);
|
||||
builder.putInt(TX_STATE_KEY_HASH, attStringMapBuffer.getInt(AS_KEY_HASH));
|
||||
return builder.build();
|
||||
}
|
||||
#endif
|
||||
|
||||
+22
@@ -10,6 +10,11 @@
|
||||
#include <react/renderer/components/text/conversions.h>
|
||||
#include <react/renderer/debug/debugStringConvertibleUtils.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <react/renderer/mapbuffer/MapBuffer.h>
|
||||
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
|
||||
#endif
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace facebook {
|
||||
@@ -89,6 +94,23 @@ folly::dynamic AndroidTextInputState::getDynamic() const {
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
|
||||
MapBuffer AndroidTextInputState::getMapBuffer() const {
|
||||
auto builder = MapBufferBuilder();
|
||||
// See comment in getDynamic block.
|
||||
if (cachedAttributedStringId == 0) {
|
||||
builder.putInt(TX_STATE_KEY_MOST_RECENT_EVENT_COUNT, mostRecentEventCount);
|
||||
|
||||
auto attStringMapBuffer = toMapBuffer(attributedString);
|
||||
builder.putMapBuffer(TX_STATE_KEY_ATTRIBUTED_STRING, attStringMapBuffer);
|
||||
auto paMapBuffer = toMapBuffer(paragraphAttributes);
|
||||
builder.putMapBuffer(TX_STATE_KEY_PARAGRAPH_ATTRIBUTES, paMapBuffer);
|
||||
|
||||
builder.putInt(TX_STATE_KEY_HASH, attStringMapBuffer.getInt(AS_KEY_HASH));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace react
|
||||
|
||||
+1
-3
@@ -94,9 +94,7 @@ class AndroidTextInputState final {
|
||||
AndroidTextInputState const &previousState,
|
||||
folly::dynamic const &data);
|
||||
folly::dynamic getDynamic() const;
|
||||
MapBuffer getMapBuffer() const {
|
||||
return MapBufferBuilder::EMPTY();
|
||||
};
|
||||
MapBuffer getMapBuffer() const;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
Reference in New Issue
Block a user