Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Fix letters duplication when using autoCapitalize #29070

Closed
wants to merge 27 commits into from

Conversation

fabOnReact
Copy link
Contributor

@fabOnReact fabOnReact commented Jun 5, 2020

Summary

This issue fixes #11068 fixes #30393 fixes #27449 fixes #29063 fixes #23578 fixes #30503 fixes #25265.

PROBLEM 1 - TextInput autoCapitalize creates duplicated letters
The issue is caused by textinput/ReactEditText.java#L556 which replaces the text from a starting position 0 to end position length(), but causes letters duplication (more info). The solution proposed in this pr to the above issue is:

  1. store the previous cursor position in variable start/endPosition
  2. use setText() to change the TextInput value
  3. restore the cursor to the previous start/endPosition

PROBLEM 2 - setSpan (6 ... 6) ends beyond length 3
Reported from Joshua in this comment and reported with issue #29063

Exception in native call java.lang.IndexOutOfBoundsException: 
setSpan (6 ... 6) ends beyond length 3

The fix for this issue was merged in master with commit EditText: maintain cursor position when text changes. Relevant discussions are #29070-comment and my commits check for reactTextUpdate.length, revert changes to maybeSetSelection , code review).
Related:

  1. discussing difference between setText() and replace() in the ReactEditText.java API issues/30393#issuecomment-752676908
  2. discussing how JS TextInput keeps internal states and updates it in the ReactEditText.java API issues/29063#issuecomment-658189938
  3. TextInput becomes slow after lots of typing
  4. breaking down why TextInput becomes slow after lots of typing
  5. AOSP method TextView setText
  6. AOSP method TextView getText
  7. AndroidTextInputShadowNode method updateStateIfNeeded
  8. Editable method replace()

Changelog

[Android] [Fixed] - Fix letters duplication when using autoCapitalize

Test Plan

This changes fix the Java API. The Java tests are disabled for this component as explained in commit Disabled unit tests that need yoga libs when running . Detailed tests included in pull/29070#issuecomment-1065799687.

Notes

Pull request #27757 from @safaiyeh fixed letters duplication, but introduced a regression (changing the cursor position). This pull request fixes letters duplication without changing the cursor position and avoid Runtimes caused by moving the cursor to invalid position.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jun 5, 2020
@fabOnReact fabOnReact changed the title fix capitalize characters and position cursor [Android] Fixed letters duplication when using autoCapitalize Jun 5, 2020
@fabOnReact fabOnReact changed the title [Android] Fixed letters duplication when using autoCapitalize [Android] Fix letters duplication when using autoCapitalize Jun 5, 2020
@react-native-bot react-native-bot added Bug Platform: Android Android applications. labels Jun 5, 2020
@safaiyeh

This comment was marked as outdated.

@safaiyeh safaiyeh requested a review from JoshuaGross June 5, 2020 14:36
@analysis-bot

This comment was marked as outdated.

@analysis-bot

This comment was marked as outdated.

@JoshuaGross

This comment was marked as outdated.

facebook-github-bot

This comment was marked as off-topic.

@JoshuaGross
Copy link
Contributor

@fabriziobertoglio1987 I tested this in FB on a few screens and I'm running into this with some controlled TextInputs:

setSpan(5 ... 5) ends beyond length 4

So it looks like there are some out-of-bounds issues, in particular with controlled TextInputs

@fabOnReact

This comment has been minimized.

@fabOnReact

This comment has been minimized.

@fabOnReact

This comment has been minimized.

@safaiyeh

This comment was marked as off-topic.

JavaScript Controller TextInput keep their own state and value for the
TextInput. This means that the value in Java

"This is my word"

can be different from the value in JavaScript, in the case of the
relevant example we delete spaces from sentence like below

"Thisismyword"

The two strings have different length, this causes several problems, an
example is

setSpan(5 ... 5) ends beyond length 4
facebook#29070 (comment)

where we change in JavaScript the TextInput value, but then a
setSelection or other operations are triggered in Java with the old
parameters.

Ideally would be great keeping the same state between Java and
JavaScript, but the current solution is checking and handling this
scenarios
Pull Request facebook#29070 solves
issue facebook#11068 by calling
setText(string)

https://github.com/fabriziobertoglio1987/react-native/blob/a66718881611eb687035ff458f7f13befd26f0a3/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java#L509-L511

but using setText() causes further problems:

1) After setText we need to call setSelection, to position the cursor at
   the previous state. setText will erase the previous cursor position
https://github.com/fabriziobertoglio1987/react-native/blob/a66718881611eb687035ff458f7f13befd26f0a3/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java#L511

2) calling setSelection after setText causes issues with controlled TextInput. The TextInput is keeping its own internal TextInput value state, which is different from the Java version and has different length.

facebook#29070 (comment)

This causes erors like below, when Java runs operations like
setSelection after setText, as the text in Java is not the JavaScript
version of the Text.

setSpan(5 ... 5) ends beyond length 4

A solution for this is keeping track of the reactTextUpdate.length sent
from JavaScript and saving it as instance variable mMaximumTextLength

3) JavaScript functionality can be included in the library or in
   ReactNative Application to build fully controller TextInputs.

   An example is the one included in this diff, where I use
   onSelectionChange, selection and onChangeText to set from JavaScript
   the position of the cursor, avoiding to set the cursor in a position
   higher then text.length

   The same functionality could be later included in TextInput.js
@fabOnReact fabOnReact reopened this Aug 30, 2020
@fabOnReact fabOnReact marked this pull request as draft March 21, 2022 04:16
@fabOnReact
Copy link
Contributor Author

fabOnReact commented Mar 21, 2022

@fabOnReact
Copy link
Contributor Author

using setText instead of replace changes TextInput height

Expected Result:
The TextInput does not change size while typing on fabric

Actual Result
The TextInput changes size

// The current text gets replaced with the text received from JS. However, the spans on the
// current text need to be adapted to the new text. Since TextView#setText() will remove or
// reset some of these spans even if they are set directly, SpannableStringBuilder#replace() is
// used instead (this is also used by the keyboard implementation underneath the covers).

click to open code used in the test

class RewriteExample extends React.Component<$FlowFixMeProps, any> {
  constructor(props) {
    super(props);
    this.state = {text: ''};
  }
  render() {
    const limit = 20;
    const remainder = limit - this.state.text.length;
    const remainderColor = remainder > 5 ? 'blue' : 'red';
    return (
      <View style={styles.rewriteContainer}>
        <TextInput
          testID="rewrite_sp_underscore_input"
          autoCorrect={false}
          multiline={false}
          maxLength={limit}
          onChangeText={text => {
            text = text.replace(/ /g, '_').toUpperCase();
            this.setState({text});
          }}
          style={styles.default}
          value={this.state.text}
        />
        <Text style={[styles.remainder, {color: remainderColor}]}>
          {remainder}
        </Text>
      </View>
    );
  }
}

click to open recording of test case

2022-03-21.14-06-38.mp4

fabOnReact added a commit to fabOnReact/react-native that referenced this pull request Mar 23, 2022
@MaskedHawk

This comment was marked as duplicate.

@bombillazo

This comment was marked as duplicate.

@fabOnReact

This comment was marked as off-topic.

@fabOnReact fabOnReact closed this Jan 10, 2023
facebook-github-bot pushed a commit that referenced this pull request Mar 1, 2023
Summary:
**Android**: The functionality consists of calling the [AccessibilityNodeInfo#setError][10] and [#setContentInvalid][13] method to display the error message in the TextInput.

**Fixes [#30848] - Adding an accessibilityErrorMessage prop to the TextInput Component**:
**Android**: The prop accessibilityErrorMessage triggers the AccessibilityNodeInfo method [setError][10] which automatically sets the correct properties on the AccessibilityNodeInfo that will inform screen readers of this state. The method calls setContentInvalid(true) and setError(youErrorString) on the AccessibilityNodeInfo.

**Fixes [#30859] -  Detecting changes in the Error state (text inputs)**
**Fabric - Android** - Adding accessibilityErrorMessage to field AndroidTextInputState.
ReactTextInputManager and ReactEditText receive state updates both from [Javascript][32] and [cpp (fabric)][34].
- accessibilityErrorMessage is added to the fabric AndroidTextInputState field
- The updates are received in the ReactAndroid API with method updateState from ReactTextInputManager
- After updating the TextInput text with onChangeText, the update of the accessibilityErrorMessage is triggered with method maybeSetAccessibilityError which triggers [setError][10].

More info:
- An explanation of [state updates between fabric and ReactAndroid for the TextInput component][34]
- [ReactNative renderer state updates][35]

**Paper - Android** - Adding accessibilityErrorMessage to ReactTextInputShadowNode to trigger updates in Paper renderer when accessibilityErrorMessage is changed within the onChange callback.

Related Links (Android):
- [In this diff I'm shipping and deleting mapBufferSerialization for Text measurement][101]
- [This diff implement and integrates Mapbuffer into Fabric text measure system][39]
- [Refactor ViewPropsMapBuffer -> general MapBuffer props mechanism][100]
- [TextInput: support modifying TextInputs with multiple Fragments (Cxx side)][24]
- [TextInput: keep C++ state in-sync with updated AttributedStrings in Java][23]
- [AccessibilityNodeInfo#setError][11]
- [Explanation on how TextInput calls SET_TEXT_AND_SELECTION in Java API][32]
- [Fabric: convertRawProp was extended to accept an optional default value][27]
- [understanding onChangeText callback][31]
- [Editable method replace()][12]
- [Change of error state from onChangeText show/hides a TextInput error][30]
- [AndroidTextInput: support using commands instead of setNativeProps (native change)][25]
- [TextInput: support editing completely empty TextInputs][26]
- [[Android] Fix letters duplication when using autoCapitalize #29070]
- [Support optional types for C++ TurboModules][28]
- [discussion on using announceForAccessibility in ReactEditText][36]
- [ fix annoucement delayed to next character][61]
- [Announce accessibility state changes happening in the background][29]
- [Refactor MountingManager into MountingManager + SurfaceMountingManager][37]

iOS Functionalities are included in separate PR #35908
Documentation PR facebook/react-native-website#3010

Next PR [2/2 TextInput accessibilityErrorMessage (VoiceOver, iOS) #35908
Related facebook/react-native-deprecated-modules#18

## Changelog

[Android] [Added] - Adding TextInput prop accessibilityErrorMessage to announce with TalkBack screenreaders

Pull Request resolved: #33468

Test Plan:
**Android - 20 Jan 2023**
#33468 (comment)

**iOS - 20 Jan 2023**
#33468 (comment)

<details><summary>CLICK TO OPEN OLD VIDEO TEST CASES</summary>
<p>

**PR Branch - Android and iOS 24th June**
[88]: Android - accessibilityValue announces correctly with/out errorMessage set with onChangeText or with outside event (Fabric) ([link][88])

**PR Branch - Android**
[1]. Test Cases of the functionality (Fabric) ([link][1])
[2]. Test Cases of the functionality (Paper) ([link][2])

**Main Branch**
[6]. Android - Runtime Error in main branch when passing value of 1 to TextInput  placeholder prop ([link][6])

**Issues Solved**
[7]. TalkBack error does not clear error on the next typed character when using onChangeText ([link][7])
**Other Tests**
[8]. Setting the TextInput errorMessage state with setTextAndSelection Java API from JavaScript ([link][8])
[9]. Setting the TextInput errorMessage state from fabric TextInput internal state to Java ReactTextUpdate API ([link][9])

</p>
</details>

[1]: fabOnReact/react-native-notes#12 (comment) "Test Cases of the functionality (Android - Fabric)"
[2]: fabOnReact/react-native-notes#12 (comment) "Test Cases of the functionality (Android - Paper)"
[3]: fabOnReact/react-native-notes#12 (comment) "Test Cases of the functionality (iOS - Fabric)"
[6]: fabOnReact/react-native-notes#12 (comment) "Runtime Error in main branch when passing value of 1 to TextInput  placeholder prop"
[7]: fabOnReact/react-native-notes#12 (comment) "TalkBack error announcement done on next typed character with onChangeText"
[8]: fabOnReact/react-native-notes#12 (comment) "setting the TextInput errorMessage state with setTextAndSelection Java API from JavaScript"
[9]: fabOnReact/react-native-notes#12 (comment) "Setting the TextInput errorMessage state from fabric TextInput internal state to Java ReactTextUpdate API"

[10]: https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setError(java.lang.CharSequence) "AOSP setError"
[11]: https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setError(java.lang.CharSequence) "AccessibilityNodeInfo#setError"
[12]: https://github.com/aosp-mirror/platform_frameworks_base/blob/1ac46f932ef88a8f96d652580d8105e361ffc842/core/java/android/text/Editable.java#L28-L52 "Editable method replace"
[13]: https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setContentInvalid(boolean) "setContentInvalid"

[20]: 60b6c9b "draft implementation of android_errorMessage "
[21]: 012d92d "add errorMessage to ReactTextUpdate and maybeSetAccessibilityError"
[22]: fabOnReact@cad239b "rename android_errorMessage to errorMessageAndroid"
[23]: fabOnReact@0bae474 "TextInput: keep C++ state in-sync with updated AttributedStrings in Java"
[24]: fabOnReact@0556e86 "TextInput: support modifying TextInputs with multiple Fragments (Cxx side)"
[25]: fabOnReact@7ab5eb4 "AndroidTextInput: support using commands instead of setNativeProps (native change)"
[26]: fabOnReact@b9491b7 "TextInput: support editing completely empty TextInputs"
[27]: fabOnReact@7f1ed68 "Fabric: convertRawProp was extended to accept an optional default value"
[28]: 6e0fa5f "Support optional types for C++ TurboModules"
[29]: fabOnReact@baa66f6 "Announce accessibility state changes happening in the background"

[30]: fabOnReact/react-native-notes#12 (comment) "Change of error state from onChangeText show/hides a TextInput error"
[31]: fabOnReact/react-native-notes#12 (comment) "understanding onChangeText callback"
[32]: #29063 (comment) "Explanation on how TextInput calls SET_TEXT_AND_SELECTION in Java API"
[33]: #33468 (comment) "Explanation of TextInput state management with fabric C++ and JAVA API"
[34]: #33468 (comment) "state updates between fabric and ReactAndroid for the TextInput component"
[35]: https://reactnative.dev/architecture/render-pipeline#react-native-renderer-state-updates "ReactNative renderer state updates"
[35]: fabOnReact/react-native-notes#12 (comment) "Analysis on how AndroidTextInputState.cpp sends updates to ReactTextInputManager"
[36]: #33468 (comment) "discussion on using announceForAccessibility in ReactEditText"
[37]: fabOnReact@29eb632 "Refactor MountingManager into MountingManager + SurfaceMountingManager"
[38]: fabOnReact@733f228 "Diff C++ props for Android consumption"
[39]: fabOnReact@91b3f5d "This diff implement and integrates Mapbuffer into Fabric text measure system"

[40]: #29070 "[Android] Fix letters duplication when using autoCapitalize #29070"

[50]: fabOnReact/react-native-notes#12  "Notes from work on iOS/Android: Text input error for screenreaders #12"
[51]: #30848 "iOS/Android: Text input error for screenreaders #30848"
[52]: #30859 "Android: Error state change (text inputs) #30859"

[61]: eb33c93 "fix annoucement delayed to next character"

[70]: fabOnReact/react-native-notes#12 (comment) "iOS - Paper renderer does not update the accessibilityValue"
[71]: fabOnReact/react-native-notes#12 (comment) "Test Cases of the functionality (Fabric) after removing changes to .cpp libs"
[72]: fabOnReact/react-native-notes#12 (comment) "Test Cases of the functionality (Paper) after removing changes to .cpp libs"
[73]: fabOnReact/react-native-notes#12 (comment) "iOS - announcing error onChangeText and screenreader focus"
[74]: fabOnReact/react-native-notes#12 (comment) "iOS - The screenreader announces the TextInput value after the errorMessage is cleared"
[75]: fabOnReact/react-native-notes#12 (comment) "iOS - Exception thrown while executing UI block: - [RCTTextView setOnAccessibiltyAction:]: unrecognized selector sent to instance (Paper) (main branch)"
[76]: #30859 (comment) "iOS - announce lastChar (not entire text) onChangeText and avoid multiple announcements (Fabric)"
[77]: #30859 (comment) "iOS - announces or does not announce the accessibilityError through Button onPress (not onChangeText) (Fabric)"
[78]: #30859 (comment) "iOS - the error is announced with accessibilityInvalid true and does not clear after typing text (onChangeText) (Fabric)"
[79]: #30848 (comment) "iOS - Exception thrown while executing UI block: - RCTUITextView setAccessibilityErrorMessage:]: unrecognized selector sent to instance (iOS - Paper on main branch)"

[80]: fabOnReact@e13b9c6 "RCTTextField was spliited into two classes"
[81]: fabOnReact@ee9697e "Introducing RCTBackedTextInputDelegate"
[82]: fabOnReact@2dd2529 "Add option to hide context menu for TextInput"
[83]: https://github.com/fabriziobertoglio1987/react-native/blob/343eea1e3150cf54d6f7727cd01d13eb7247c7f7/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm#L48-L72 "RCTParagraphComponentAccessibilityProvider accessibilityElements"
[84]: https://github.com/fabriziobertoglio1987/react-native/blob/c8790a114f6f21774c43f0e9b9210e7b35d1c243/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm#L613 "RCTTextInputComponentView method _setAttributedString"
[85]: https://github.com/fabriziobertoglio1987/react-native/blob/c8790a114f6f21774c43f0e9b9210e7b35d1c243/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm#L146 "RCTTextInputComponentView method updateProps"
[86]: https://github.com/fabriziobertoglio1987/react-native/blob/c8790a114f6f21774c43f0e9b9210e7b35d1c243/Libraries/Text/TextInput/RCTBaseTextInputView.m#L150 "RCTBaseTextInputView setAttributedText"
[87]: #30859 (comment) "iOS - accessibilityValue announces correctly with/out errorMessage set with onChangeText or with outside event"
[88]: #30859 (comment) "Android - accessibilityValue announces correctly with/out errorMessage set with onChangeText or with outside event"
[89]: #30859 (comment) "iOS - accessibilityValue announces correctly with/out errorMessage set with onChangeText or with outside event (Fabric)"

[100]: fabOnReact@110b191 "Refactor ViewPropsMapBuffer -> general MapBuffer props mechanism"
[101]: fabOnReact@22b6e1c "In this diff I'm shipping and deleting mapBufferSerialization for Text measurement"

Reviewed By: blavalla

Differential Revision: D38410635

Pulled By: lunaleaps

fbshipit-source-id: cd80e9a1be8f5ca017c979d7907974cf72ca4777
OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this pull request May 22, 2023
…#33468)

Summary:
**Android**: The functionality consists of calling the [AccessibilityNodeInfo#setError][10] and [#setContentInvalid][13] method to display the error message in the TextInput.

**Fixes [facebook#30848] - Adding an accessibilityErrorMessage prop to the TextInput Component**:
**Android**: The prop accessibilityErrorMessage triggers the AccessibilityNodeInfo method [setError][10] which automatically sets the correct properties on the AccessibilityNodeInfo that will inform screen readers of this state. The method calls setContentInvalid(true) and setError(youErrorString) on the AccessibilityNodeInfo.

**Fixes [facebook#30859] -  Detecting changes in the Error state (text inputs)**
**Fabric - Android** - Adding accessibilityErrorMessage to field AndroidTextInputState.
ReactTextInputManager and ReactEditText receive state updates both from [Javascript][32] and [cpp (fabric)][34].
- accessibilityErrorMessage is added to the fabric AndroidTextInputState field
- The updates are received in the ReactAndroid API with method updateState from ReactTextInputManager
- After updating the TextInput text with onChangeText, the update of the accessibilityErrorMessage is triggered with method maybeSetAccessibilityError which triggers [setError][10].

More info:
- An explanation of [state updates between fabric and ReactAndroid for the TextInput component][34]
- [ReactNative renderer state updates][35]

**Paper - Android** - Adding accessibilityErrorMessage to ReactTextInputShadowNode to trigger updates in Paper renderer when accessibilityErrorMessage is changed within the onChange callback.

Related Links (Android):
- [In this diff I'm shipping and deleting mapBufferSerialization for Text measurement][101]
- [This diff implement and integrates Mapbuffer into Fabric text measure system][39]
- [Refactor ViewPropsMapBuffer -> general MapBuffer props mechanism][100]
- [TextInput: support modifying TextInputs with multiple Fragments (Cxx side)][24]
- [TextInput: keep C++ state in-sync with updated AttributedStrings in Java][23]
- [AccessibilityNodeInfo#setError][11]
- [Explanation on how TextInput calls SET_TEXT_AND_SELECTION in Java API][32]
- [Fabric: convertRawProp was extended to accept an optional default value][27]
- [understanding onChangeText callback][31]
- [Editable method replace()][12]
- [Change of error state from onChangeText show/hides a TextInput error][30]
- [AndroidTextInput: support using commands instead of setNativeProps (native change)][25]
- [TextInput: support editing completely empty TextInputs][26]
- [[Android] Fix letters duplication when using autoCapitalize facebook#29070]
- [Support optional types for C++ TurboModules][28]
- [discussion on using announceForAccessibility in ReactEditText][36]
- [ fix annoucement delayed to next character][61]
- [Announce accessibility state changes happening in the background][29]
- [Refactor MountingManager into MountingManager + SurfaceMountingManager][37]

iOS Functionalities are included in separate PR facebook#35908
Documentation PR facebook/react-native-website#3010

Next PR [2/2 TextInput accessibilityErrorMessage (VoiceOver, iOS) facebook#35908
Related facebook/react-native-deprecated-modules#18

## Changelog

[Android] [Added] - Adding TextInput prop accessibilityErrorMessage to announce with TalkBack screenreaders

Pull Request resolved: facebook#33468

Test Plan:
**Android - 20 Jan 2023**
facebook#33468 (comment)

**iOS - 20 Jan 2023**
facebook#33468 (comment)

<details><summary>CLICK TO OPEN OLD VIDEO TEST CASES</summary>
<p>

**PR Branch - Android and iOS 24th June**
[88]: Android - accessibilityValue announces correctly with/out errorMessage set with onChangeText or with outside event (Fabric) ([link][88])

**PR Branch - Android**
[1]. Test Cases of the functionality (Fabric) ([link][1])
[2]. Test Cases of the functionality (Paper) ([link][2])

**Main Branch**
[6]. Android - Runtime Error in main branch when passing value of 1 to TextInput  placeholder prop ([link][6])

**Issues Solved**
[7]. TalkBack error does not clear error on the next typed character when using onChangeText ([link][7])
**Other Tests**
[8]. Setting the TextInput errorMessage state with setTextAndSelection Java API from JavaScript ([link][8])
[9]. Setting the TextInput errorMessage state from fabric TextInput internal state to Java ReactTextUpdate API ([link][9])

</p>
</details>

[1]: fabOnReact/react-native-notes#12 (comment) "Test Cases of the functionality (Android - Fabric)"
[2]: fabOnReact/react-native-notes#12 (comment) "Test Cases of the functionality (Android - Paper)"
[3]: fabOnReact/react-native-notes#12 (comment) "Test Cases of the functionality (iOS - Fabric)"
[6]: fabOnReact/react-native-notes#12 (comment) "Runtime Error in main branch when passing value of 1 to TextInput  placeholder prop"
[7]: fabOnReact/react-native-notes#12 (comment) "TalkBack error announcement done on next typed character with onChangeText"
[8]: fabOnReact/react-native-notes#12 (comment) "setting the TextInput errorMessage state with setTextAndSelection Java API from JavaScript"
[9]: fabOnReact/react-native-notes#12 (comment) "Setting the TextInput errorMessage state from fabric TextInput internal state to Java ReactTextUpdate API"

[10]: https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setError(java.lang.CharSequence) "AOSP setError"
[11]: https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setError(java.lang.CharSequence) "AccessibilityNodeInfo#setError"
[12]: https://github.com/aosp-mirror/platform_frameworks_base/blob/1ac46f932ef88a8f96d652580d8105e361ffc842/core/java/android/text/Editable.java#L28-L52 "Editable method replace"
[13]: https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setContentInvalid(boolean) "setContentInvalid"

[20]: facebook@60b6c9b "draft implementation of android_errorMessage "
[21]: facebook@012d92d "add errorMessage to ReactTextUpdate and maybeSetAccessibilityError"
[22]: fabOnReact@cad239b "rename android_errorMessage to errorMessageAndroid"
[23]: fabOnReact@0bae474 "TextInput: keep C++ state in-sync with updated AttributedStrings in Java"
[24]: fabOnReact@0556e86 "TextInput: support modifying TextInputs with multiple Fragments (Cxx side)"
[25]: fabOnReact@7ab5eb4 "AndroidTextInput: support using commands instead of setNativeProps (native change)"
[26]: fabOnReact@b9491b7 "TextInput: support editing completely empty TextInputs"
[27]: fabOnReact@7f1ed68 "Fabric: convertRawProp was extended to accept an optional default value"
[28]: facebook@6e0fa5f "Support optional types for C++ TurboModules"
[29]: fabOnReact@baa66f6 "Announce accessibility state changes happening in the background"

[30]: fabOnReact/react-native-notes#12 (comment) "Change of error state from onChangeText show/hides a TextInput error"
[31]: fabOnReact/react-native-notes#12 (comment) "understanding onChangeText callback"
[32]: facebook#29063 (comment) "Explanation on how TextInput calls SET_TEXT_AND_SELECTION in Java API"
[33]: facebook#33468 (comment) "Explanation of TextInput state management with fabric C++ and JAVA API"
[34]: facebook#33468 (comment) "state updates between fabric and ReactAndroid for the TextInput component"
[35]: https://reactnative.dev/architecture/render-pipeline#react-native-renderer-state-updates "ReactNative renderer state updates"
[35]: fabOnReact/react-native-notes#12 (comment) "Analysis on how AndroidTextInputState.cpp sends updates to ReactTextInputManager"
[36]: facebook#33468 (comment) "discussion on using announceForAccessibility in ReactEditText"
[37]: fabOnReact@29eb632 "Refactor MountingManager into MountingManager + SurfaceMountingManager"
[38]: fabOnReact@733f228 "Diff C++ props for Android consumption"
[39]: fabOnReact@91b3f5d "This diff implement and integrates Mapbuffer into Fabric text measure system"

[40]: facebook#29070 "[Android] Fix letters duplication when using autoCapitalize facebook#29070"

[50]: fabOnReact/react-native-notes#12  "Notes from work on iOS/Android: Text input error for screenreaders facebook#12"
[51]: facebook#30848 "iOS/Android: Text input error for screenreaders facebook#30848"
[52]: facebook#30859 "Android: Error state change (text inputs) facebook#30859"

[61]: facebook@eb33c93 "fix annoucement delayed to next character"

[70]: fabOnReact/react-native-notes#12 (comment) "iOS - Paper renderer does not update the accessibilityValue"
[71]: fabOnReact/react-native-notes#12 (comment) "Test Cases of the functionality (Fabric) after removing changes to .cpp libs"
[72]: fabOnReact/react-native-notes#12 (comment) "Test Cases of the functionality (Paper) after removing changes to .cpp libs"
[73]: fabOnReact/react-native-notes#12 (comment) "iOS - announcing error onChangeText and screenreader focus"
[74]: fabOnReact/react-native-notes#12 (comment) "iOS - The screenreader announces the TextInput value after the errorMessage is cleared"
[75]: fabOnReact/react-native-notes#12 (comment) "iOS - Exception thrown while executing UI block: - [RCTTextView setOnAccessibiltyAction:]: unrecognized selector sent to instance (Paper) (main branch)"
[76]: facebook#30859 (comment) "iOS - announce lastChar (not entire text) onChangeText and avoid multiple announcements (Fabric)"
[77]: facebook#30859 (comment) "iOS - announces or does not announce the accessibilityError through Button onPress (not onChangeText) (Fabric)"
[78]: facebook#30859 (comment) "iOS - the error is announced with accessibilityInvalid true and does not clear after typing text (onChangeText) (Fabric)"
[79]: facebook#30848 (comment) "iOS - Exception thrown while executing UI block: - RCTUITextView setAccessibilityErrorMessage:]: unrecognized selector sent to instance (iOS - Paper on main branch)"

[80]: fabOnReact@e13b9c6 "RCTTextField was spliited into two classes"
[81]: fabOnReact@ee9697e "Introducing RCTBackedTextInputDelegate"
[82]: fabOnReact@2dd2529 "Add option to hide context menu for TextInput"
[83]: https://github.com/fabriziobertoglio1987/react-native/blob/343eea1e3150cf54d6f7727cd01d13eb7247c7f7/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.mm#L48-L72 "RCTParagraphComponentAccessibilityProvider accessibilityElements"
[84]: https://github.com/fabriziobertoglio1987/react-native/blob/c8790a114f6f21774c43f0e9b9210e7b35d1c243/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm#L613 "RCTTextInputComponentView method _setAttributedString"
[85]: https://github.com/fabriziobertoglio1987/react-native/blob/c8790a114f6f21774c43f0e9b9210e7b35d1c243/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm#L146 "RCTTextInputComponentView method updateProps"
[86]: https://github.com/fabriziobertoglio1987/react-native/blob/c8790a114f6f21774c43f0e9b9210e7b35d1c243/Libraries/Text/TextInput/RCTBaseTextInputView.m#L150 "RCTBaseTextInputView setAttributedText"
[87]: facebook#30859 (comment) "iOS - accessibilityValue announces correctly with/out errorMessage set with onChangeText or with outside event"
[88]: facebook#30859 (comment) "Android - accessibilityValue announces correctly with/out errorMessage set with onChangeText or with outside event"
[89]: facebook#30859 (comment) "iOS - accessibilityValue announces correctly with/out errorMessage set with onChangeText or with outside event (Fabric)"

[100]: fabOnReact@110b191 "Refactor ViewPropsMapBuffer -> general MapBuffer props mechanism"
[101]: fabOnReact@22b6e1c "In this diff I'm shipping and deleting mapBufferSerialization for Text measurement"

Reviewed By: blavalla

Differential Revision: D38410635

Pulled By: lunaleaps

fbshipit-source-id: cd80e9a1be8f5ca017c979d7907974cf72ca4777
@t-fritsch
Copy link

hi @fabriziobertoglio1987

thanks for the efforts you put into this issue.

I wonder why you closed this PR ? This bug is so annoying.. I teach React Native since a long time now and having such "stupid" bug isn't really giving confidence to newcomers. This may not have been a problem in the past, but now RN has rising competitors that give the impression to be much more stable.

@fabOnReact
Copy link
Contributor Author

Thanks @t-fritsch.

My knowledge of the react-native ReactEditText API improved a lot in the last 3 years.
I wanted to publish an improved solution but never had the time.

I can prioritize this task if you want.

@fabOnReact fabOnReact reopened this Jan 17, 2024
@fabOnReact fabOnReact closed this Jan 17, 2024
Copy link

github-actions bot commented Jan 17, 2024

Fails
🚫

📋 Missing Changelog - Please add a Changelog to your PR description. See Changelog format

Generated by 🚫 dangerJS against 6e6ab1b

@fabOnReact fabOnReact reopened this Jan 18, 2024
fabOnReact added a commit to fabOnReact/react-native-improved that referenced this pull request Jan 24, 2024
fabOnReact added a commit to fabOnReact/react-native-improved that referenced this pull request Jan 24, 2024
* apply [Android] Fix letters duplication when using autoCapitalize #29070

facebook/react-native#29070

* adding autocapitalize to example

* update readme

* update readme
@fabOnReact
Copy link
Contributor Author

This PR is included in the react-native-improved library:

react-native-improved

  • Supports ONLY react-native 0.73.
  • Supports only old architechture (new architechture is WIP)

Set-up

In package.json

 "scripts": {
+  "postinstall": "yarn run react-native-patch"
 }

Then

npm

npm install react-native-improved --save-dev

yarn v1

yarn add react-native-improved --dev

@fabOnReact fabOnReact closed this Feb 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment