From 62364d00ca6c178dc073f4d31ac8645ac8165ff7 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Tue, 16 Aug 2022 12:21:52 -0700 Subject: [PATCH] Support MapBuffer in TextInput State Summary: Support MapBuffer in TextInput State. Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D38546271 fbshipit-source-id: 93e7fd79d9d8473dd646410f3047fcfafa8516f1 --- .../text/TextLayoutManagerMapBuffer.java | 5 ++ .../com/facebook/react/views/textinput/BUCK | 5 +- .../textinput/ReactTextInputManager.java | 51 +++++++++++++++++++ .../renderer/components/text/ParagraphState.h | 9 ++++ .../renderer/components/text/conversions.h | 10 +--- .../AndroidTextInputState.cpp | 22 ++++++++ .../androidtextinput/AndroidTextInputState.h | 4 +- 7 files changed, 93 insertions(+), 13 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java index ecbf0d45489..d86cf9a095a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java @@ -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; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/BUCK index c3930446837..ef99a74bf37 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/BUCK @@ -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"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index d62251bc319..99025ee3ccc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -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 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); + } } diff --git a/ReactCommon/react/renderer/components/text/ParagraphState.h b/ReactCommon/react/renderer/components/text/ParagraphState.h index 76dcbcf1cee..24a8e1258e8 100644 --- a/ReactCommon/react/renderer/components/text/ParagraphState.h +++ b/ReactCommon/react/renderer/components/text/ParagraphState.h @@ -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 component. * Represents what to render and how to render. diff --git a/ReactCommon/react/renderer/components/text/conversions.h b/ReactCommon/react/renderer/components/text/conversions.h index 712b8f2fde2..a4a90aa37c9 100644 --- a/ReactCommon/react/renderer/components/text/conversions.h +++ b/ReactCommon/react/renderer/components/text/conversions.h @@ -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 diff --git a/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.cpp b/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.cpp index a2deb59db33..c57e8b7970f 100644 --- a/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.cpp +++ b/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.cpp @@ -10,6 +10,11 @@ #include #include +#ifdef ANDROID +#include +#include +#endif + #include 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 diff --git a/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.h b/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.h index 4dc50ac9410..f46d6829e1a 100644 --- a/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.h +++ b/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.h @@ -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