From a96ad8ad4a8f5e6eb0ab7b2907fa298ba4f1d2bb Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Fri, 11 Nov 2022 18:33:55 +0100 Subject: [PATCH] DRAFT CPP solution to pass static string as accessibilityUnit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getOrCreateSpannableForText is not called. The method is called on the parent Text, but not on the Span Text. Review implementation of accessibilityRole in [BaseViewManager](https://github.com/fabriziobertoglio1987/react-native/blob/ec4bc8eb5905f81cebbb4b623acda8245ee5683c/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java#L247) and [ReactMapBufferPropSetter.kt](http://www.apple.com/)
Probably the method setAccessibilityRole is called directly from kotlin MapBufferPropSetter
Add required changes and debug the functionality accessibilityRole link is called, but time is not
they have the same cpp configuration, but one of them is not invoked in BaseViewManager. 
This suggest missing configs from the [accessibility link PR](https://github.com/facebook/react-native/commit/7b5b114d578142d18bf4a7a5279b179a9ac8d958), maybe accessibilityRole Link is triggered with resetAccessibilityDelegate Find logic in accessibility link PR that resets the Delegate
Before resetting the Delegate, TextLayoutManager adds the Span to the Text. The field is TextAttributes mIsAccessibilityLink. This field is set to true if accessibilityRole = link
mIsAccessibilityLink is set to true in the ReactBaseTextShadowNode #setIsAccessibilityLink sets the value Debug the value of ReactBaseTextShadowNode #setAccessibilityUnit
Verify if accessibilityUnit is retrieve in that method, because this manager is also for nested text Check if setIsAccessibiltyLink also is triggered for role time, if not understand why text does not trigger. Yes, it is triggered. We set there the accessibilityRole
- We could follow the same implementation, we add the span based on mIsAccessibilityTtsSpan
- We retrieve get spans of class ReactTtsSpan 
- We follow same implementation from accessibilityLinks Implement same logic for accessibilityRole time Verify accessibilityRole time is invoked Use resetAccessibilityDelegate to add accessibilityUnit info to child Text Copy missing changes from another prop (for ex. accessibilityRole). setAccessibilityRole is triggered, while setAccessibilityUnit is not triggered. Review missing diff with [#2](https://github.com/fabriziobertoglio1987/react-native/pull/2/files) Review the current diff with main branch Add breakpoint in cpp SOLUTION: adding the value in [attributedstring/conversion.h](https://github.com/fabriziobertoglio1987/react-native/blob/ec4bc8eb5905f81cebbb4b623acda8245ee5683c/ReactCommon/react/renderer/attributedstring/conversions.h#L1087) will then pass it to [TextAttributesProps as key 24](https://www.icloud.com/iclouddrive/0b8-oKB396zP7Astpyc3puGqQ#ACC_UNIT_passed_as_key_24) --- .../react/uimanager/BaseViewManagerDelegate.java | 3 +++ .../react/views/text/ReactBaseTextShadowNode.java | 5 +++++ .../facebook/react/views/text/TextAttributeProps.java | 11 +++++++++++ .../facebook/react/views/text/TextLayoutManager.java | 2 ++ .../react/views/view/ReactMapBufferPropSetter.kt | 9 +++------ .../react/renderer/attributedstring/conversions.h | 5 +++++ .../js/examples/Accessibility/AccessibilityExample.js | 9 +++++++++ 7 files changed, 38 insertions(+), 6 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java index bb809381494e5e..9aa83a6af69f92 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManagerDelegate.java @@ -7,6 +7,7 @@ package com.facebook.react.uimanager; +import android.util.Log; import android.view.View; import androidx.annotation.Nullable; import com.facebook.react.bridge.ColorPropConverter; @@ -30,6 +31,8 @@ public BaseViewManagerDelegate(U viewManager) { @Override public void setProperty(T view, String propName, @Nullable Object value) { + Log.w("TESTING::BaseViewManagerDelegate", "propName: " + (propName)); + Log.w("TESTING::BaseViewManagerDelegate", "value: " + (value)); switch (propName) { case ViewProps.ACCESSIBILITY_ACTIONS: mViewManager.setAccessibilityActions(view, (ReadableArray) value); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java index 738b8ced4ac277..e03ae115366c1e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactBaseTextShadowNode.java @@ -15,6 +15,7 @@ import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.TextUtils; +import android.util.Log; import android.view.Gravity; import androidx.annotation.Nullable; import com.facebook.infer.annotation.Assertions; @@ -507,6 +508,8 @@ public void setBackgroundColor(@Nullable Integer color) { @ReactProp(name = ViewProps.ACCESSIBILITY_ROLE) public void setIsAccessibilityLink(@Nullable String accessibilityRole) { + Log.w("TESTING::ReactBaseTextShadowNode", "setIsAccessibilityLink"); + Log.w("TESTING::ReactBaseTextShadowNode", "accessibilityRole: " + (accessibilityRole)); if (isVirtual()) { String roleClassName = AccessibilityRole.getValue(AccessibilityRole.fromValue(accessibilityRole)); @@ -519,6 +522,8 @@ public void setIsAccessibilityLink(@Nullable String accessibilityRole) { @ReactProp(name = "accessibilityUnit") public void setAccessibilityUnit(@Nullable String accessibilityUnit) { + Log.w("TESTING::ReactBaseTextShadowNode", "setAccessibilityUnit"); + Log.w("TESTING::ReactBaseTextShadowNode", "accessibilityUnit: " + (accessibilityUnit)); if (isVirtual()) { markUpdated(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java index 6ac85573a31337..0c0406b90e69c7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java @@ -11,6 +11,7 @@ import android.text.Layout; import android.text.TextUtils; import android.util.LayoutDirection; +import android.util.Log; import android.view.Gravity; import androidx.annotation.Nullable; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; @@ -53,6 +54,7 @@ public class TextAttributeProps { public static final short TA_KEY_IS_HIGHLIGHTED = 20; public static final short TA_KEY_LAYOUT_DIRECTION = 21; public static final short TA_KEY_ACCESSIBILITY_ROLE = 22; + public static final short TA_KEY_ACCESSIBILITY_UNIT = 47; public static final int UNSET = -1; @@ -144,6 +146,8 @@ public static TextAttributeProps fromMapBuffer(MapBuffer props) { // TODO T83483191: Review constants that are not being set! Iterator iterator = props.iterator(); + Log.w("TESTING::TextAttributeProps", "fromMapBuffer"); + Log.w("TESTING::TextAttributeProps", "props: " + (props)); while (iterator.hasNext()) { MapBuffer.Entry entry = iterator.next(); switch (entry.getKey()) { @@ -206,6 +210,9 @@ public static TextAttributeProps fromMapBuffer(MapBuffer props) { case TA_KEY_ACCESSIBILITY_ROLE: result.setAccessibilityRole(entry.getStringValue()); break; + case TA_KEY_ACCESSIBILITY_UNIT: + result.setAccessibilityUnit(entry.getStringValue()); + break; } } @@ -602,6 +609,8 @@ private void setTextTransform(@Nullable String textTransform) { private void setAccessibilityRole(@Nullable String accessibilityRole) { if (accessibilityRole != null) { + Log.w("TESTING::TextAttributeProps", "setAccessibilityRole"); + Log.w("TESTING::TextAttributeProps", "accessibilityRole: " + (accessibilityRole)); mIsAccessibilityRoleSet = true; mAccessibilityRole = AccessibilityRole.fromValue(accessibilityRole); mIsAccessibilityLink = mAccessibilityRole.equals(AccessibilityRole.LINK); @@ -613,6 +622,8 @@ private void setAccessibilityRole(@Nullable String accessibilityRole) { } private void setAccessibilityUnit(@Nullable String accessibilityUnit) { + Log.w("TESTING::TextAttributeProps", "setAccessibilityUnit"); + Log.w("TESTING::TextAttributeProps", "accessibilityUnit: " + (accessibilityUnit)); // not yet implemented } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java index 1f3bf935ab80ae..761e16dbd0eb65 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java @@ -19,6 +19,7 @@ import android.text.StaticLayout; import android.text.TextPaint; import android.util.LayoutDirection; +import android.util.Log; import android.util.LruCache; import android.view.View; import androidx.annotation.NonNull; @@ -196,6 +197,7 @@ public static Spannable getOrCreateSpannableForText( Context context, ReadableMap attributedString, @Nullable ReactTextViewManagerCallback reactTextViewManagerCallback) { + Log.w("TESTING::TextLayoutManager", "getOrCreateSpannableForText"); return createSpannableFromAttributedString( context, attributedString, reactTextViewManagerCallback); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt index b75d0692785302..4abc9cae783669 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt @@ -133,7 +133,7 @@ object ReactMapBufferPropSetter { viewManager.accessibilityState(view, entry.mapBufferValue) } VP_ACCESSIBILITY_UNIT -> { - viewManager.accessibilityUnit(view, entry.stringValue) + viewManager.setAccessibilityUnit(view, entry.stringValue.takeIf { it.isNotEmpty() }) } VP_ACCESSIBILITY_VALUE -> { viewManager.accessibilityValue(view, entry.stringValue) @@ -285,11 +285,8 @@ object ReactMapBufferPropSetter { private fun ReactViewManager.accessibilityUnit(view: ReactViewGroup, value: String) { Log.w("TESTING::ReactMapBufferPropSetter", "accessibilityUnit"); - /* - val accessibilityUnit = JavaOnlyMap() - accessibilityUnit.putString("hours", "10") - setAccessibilityUnit(view, accessibilityUnit) - */ + Log.w("TESTING::ReactMapBufferPropSetter", "value: " + ( value )); + setAccessibilityUnit(view,"random string") } private fun ReactViewManager.accessibilityState(view: ReactViewGroup, value: MapBuffer) { diff --git a/ReactCommon/react/renderer/attributedstring/conversions.h b/ReactCommon/react/renderer/attributedstring/conversions.h index 857b37a673eb28..8a74dbd1a03423 100644 --- a/ReactCommon/react/renderer/attributedstring/conversions.h +++ b/ReactCommon/react/renderer/attributedstring/conversions.h @@ -1083,6 +1083,7 @@ constexpr static MapBuffer::Key TA_KEY_IS_HIGHLIGHTED = 20; constexpr static MapBuffer::Key TA_KEY_LAYOUT_DIRECTION = 21; constexpr static MapBuffer::Key TA_KEY_ACCESSIBILITY_ROLE = 22; constexpr static MapBuffer::Key TA_KEY_LINE_BREAK_STRATEGY = 23; +constexpr static MapBuffer::Key TA_KEY_ACCESSIBILITY_UNIT = 47; // constants for ParagraphAttributes serialization constexpr static MapBuffer::Key PA_KEY_MAX_NUMBER_OF_LINES = 0; @@ -1226,8 +1227,12 @@ inline MapBuffer toMapBuffer(const TextAttributes &textAttributes) { TA_KEY_LAYOUT_DIRECTION, toString(*textAttributes.layoutDirection)); } if (textAttributes.accessibilityRole.has_value()) { + + LOG(ERROR) << "TESTING:: attributedString conversions.h accessibilityRole: " << toString(*textAttributes.accessibilityRole); builder.putString( TA_KEY_ACCESSIBILITY_ROLE, toString(*textAttributes.accessibilityRole)); + builder.putString( + TA_KEY_ACCESSIBILITY_UNIT, "random unit"); } return builder.build(); } diff --git a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js index 3b5b8c6d8bb601..039496f5f682b7 100644 --- a/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js +++ b/packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js @@ -178,6 +178,15 @@ class AccessibilityExample extends React.Component<{}> { 17:00 + + This is a + + link + +