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

Remove option to paste rich text from Android EditText context menu #38189

Closed
wants to merge 14 commits into from

Conversation

fabOnReact
Copy link
Contributor

@fabOnReact fabOnReact commented Jul 5, 2023

Summary:

Text is copy pasted as rich text on Android TextInput instead of Plain Text.

What is the root cause of that problem?

Android EditText and iOS UITextField/UITextView have different copy/paste behavior.

  • Android TextInput copies/pastes rich text
  • iOS UITextField copies/pastes plain text.
iOS (react-native) Android (react-native)
Simulator.Screen.Recording.-.iPhone.14.Pro.-.2023-06-27.at.21.41.04.mp4
repro_android.mov

What changes do you think we should make in order to solve the problem?

The issue is a bug in react-native #31442:

  1. The JavaScript TextInput and ReactEditText Android state are not in sync
  2. The TextInput Android Native state over-rides the JavaScript state.
  3. onChangeText passes a plain text string to JavaScript, not rich text (text with spans and styles).

More info at Expensify/App#21411 (comment)

The solution consists of:

  1. Over-riding onTextContextMenuItem in ReactEditText to copy/paste plain text instead of rich-text (https://stackoverflow.com/a/45319485/7295772).
  2. Removing the Paste as plaintext option from the insert and selection context menu

fixes #31442

Changelog:

[ANDROID] [FIXED] - Remove option to paste rich text from Android EditText context menu

Test Plan:

Reproducing the issue on Android

2023-06-27.22-28-06.mp4

Fixing the issue on Android

Sourcecode https://github.com/fabriziobertoglio1987/text-input-cursor-flickering-android/blob/fix-copy-paste/app/src/main/java/com/example/myapplication/CustomEditText.java

2023-06-28.21-26-53.mp4

Testing the solution on React Native

2023-06-29.17-49-09.mp4

@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 Jul 5, 2023
@fabOnReact fabOnReact changed the title over-riding onTextContextMenuItem in ReactEditText to copy/paste plain text instead of rich-text Over-riding onTextContextMenuItem in ReactEditText to copy/paste plain text instead of rich-text Jul 5, 2023
@analysis-bot
Copy link

analysis-bot commented Jul 5, 2023

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 8,843,572 -39,854
android hermes armeabi-v7a 8,152,772 +218,558
android hermes x86 9,349,392 +68,907
android hermes x86_64 9,192,090 +8,476
android jsc arm64-v8a 9,456,354 -16,762
android jsc armeabi-v7a 8,637,488 +221,011
android jsc x86 9,539,440 +83,566
android jsc x86_64 9,782,737 +10,654

Base commit: bae63d4
Branch: main

@fabOnReact
Copy link
Contributor Author

fabOnReact commented Jul 14, 2023

Building the main branch with head 06668fc triggers a runtime when opening the RNTester Text examples:

CLICK TO OPEN STACKTRACE

07-22 21:29:39.711 10861 10931 E AndroidRuntime: FATAL EXCEPTION: FrescoIoBoundExecutor-2
07-22 21:29:39.711 10861 10931 E AndroidRuntime: Process: com.facebook.react.uiapp, PID: 10861
07-22 21:29:39.711 10861 10931 E AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "libnative-imagetranscoder.so" not found
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at java.lang.Runtime.loadLibrary0(Runtime.java:1077)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at java.lang.Runtime.loadLibrary0(Runtime.java:998)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at java.lang.System.loadLibrary(System.java:1661)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.soloader.nativeloader.SystemDelegate.loadLibrary(SystemDelegate.java:24)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.soloader.nativeloader.NativeLoader.loadLibrary(NativeLoader.java:52)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.soloader.nativeloader.NativeLoader.loadLibrary(NativeLoader.java:30)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.nativecode.NativeJpegTranscoderSoLoader.ensure(NativeJpegTranscoderSoLoader.java:33)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.nativecode.NativeJpegTranscoder.<init>(NativeJpegTranscoder.java:59)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.nativecode.NativeJpegTranscoderFactory.createImageTranscoder(NativeJpegTranscoderFactory.java:43)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.transcoder.MultiImageTranscoderFactory.getNativeImageTranscoder(MultiImageTranscoderFactory.kt:59)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.transcoder.MultiImageTranscoderFactory.createImageTranscoder(MultiImageTranscoderFactory.kt:40)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.ResizeAndRotateProducer$TransformingConsumer.onNewResultImpl(ResizeAndRotateProducer.java:166)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.ResizeAndRotateProducer$TransformingConsumer.onNewResultImpl(ResizeAndRotateProducer.java:84)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.BaseConsumer.onNewResult(BaseConsumer.java:89)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.AddImageTransformMetaDataProducer$AddImageTransformMetaDataConsumer.onNewResultImpl(AddImageTransformMetaDataProducer.java:49)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.AddImageTransformMetaDataProducer$AddImageTransformMetaDataConsumer.onNewResultImpl(AddImageTransformMetaDataProducer.java:33)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.BaseConsumer.onNewResult(BaseConsumer.java:89)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.MultiplexProducer$Multiplexer.onNextResult(MultiplexProducer.java:510)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.MultiplexProducer$Multiplexer$ForwardingConsumer.onNewResultImpl(MultiplexProducer.java:569)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.MultiplexProducer$Multiplexer$ForwardingConsumer.onNewResultImpl(MultiplexProducer.java:562)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.BaseConsumer.onNewResult(BaseConsumer.java:89)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.EncodedMemoryCacheProducer$EncodedMemoryCacheConsumer.onNewResultImpl(EncodedMemoryCacheProducer.java:181)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.EncodedMemoryCacheProducer$EncodedMemoryCacheConsumer.onNewResultImpl(EncodedMemoryCacheProducer.java:123)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.BaseConsumer.onNewResult(BaseConsumer.java:89)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.DiskCacheReadProducer$1.then(DiskCacheReadProducer.java:113)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.producers.DiskCacheReadProducer$1.then(DiskCacheReadProducer.java:93)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.Task$14.run(Task.java:872)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:105)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.Task.completeImmediately(Task.java:863)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.Task.access$000(Task.java:32)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.Task$10.then(Task.java:654)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.Task$10.then(Task.java:651)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.Task.runContinuations(Task.java:956)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.Task.trySetResult(Task.java:994)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.TaskCompletionSource.trySetResult(TaskCompletionSource.java:39)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.TaskCompletionSource.setResult(TaskCompletionSource.java:62)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at bolts.Task$4.run(Task.java:357)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.core.PriorityThreadFactory.newThread$lambda$0(PriorityThreadFactory.kt:37)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.core.PriorityThreadFactory.$r8$lambda$IPp7Vm9a1KDy8D4770JTjI9qOG4(Unknown Source:0)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at com.facebook.imagepipeline.core.PriorityThreadFactory$$ExternalSyntheticLambda0.run(Unknown Source:4)
07-22 21:29:39.711 10861 10931 E AndroidRuntime: 	at java.lang.Thread.run(Thread.java:1012)

2023-07-14.16-34-10.mp4

Related 823839b

@fabOnReact fabOnReact marked this pull request as ready for review July 17, 2023 08:30
@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Jul 17, 2023
@fabOnReact fabOnReact marked this pull request as draft July 17, 2023 11:50
@fabOnReact fabOnReact marked this pull request as ready for review July 17, 2023 11:57
@fabOnReact fabOnReact marked this pull request as draft July 17, 2023 12:00
@fabOnReact fabOnReact marked this pull request as ready for review July 17, 2023 12:31
@NickGerleman
Copy link
Contributor

Could you explain why you think the current behavior is a bug? At a glance, overriding a context menu command to paste rich text, to instead coerce to plain text, seems at odds with platform expectations.

@fabOnReact
Copy link
Contributor Author

Thanks @NickGerleman

Could you explain why you think the current behavior is a bug?

FIRST REASON: It was reported as a react-native TextInput Issue in different chat applications:

It's already the case that the only data TextInput actually exposes to the app is the plain text -- so the fact that it lets the user paste formatted text, and shows that formatting back, is basically a bug in RN because there's no way the app can end up respecting that formatting.

zulip/zulip-mobile#4660 (comment)

As described on this CZO thread, this issue can lead to a very awkward user experience.

SECOND REASON: React Native Controlled TextInput Component does not support paste with rich text.

  • Native and JavaScript state are not in sync.
  • The rich text pasted in the EditText over-rides the style of a JavaScript Controlled TextInput.

Example of a use case: The user pastes rich text in a JavaScript Controlled TextInput.

Expected behaviour:

  • The JavaScript Controlled TextInput manages the TextInput state and over-rides the Native Android State. The JavaScript TextInput and Text style props set the native text style.
  • onChangeText API is used to update the TextInput internal state and keep it sync with the updates from native.

Actual behaviour:

  • The JavaScript TextInput and Text style props do not change the style of the text.
  • onChangeText passes to JavaScript callback the plain text instead of rich text. It is not possible to keep the two states in sync.
2023-06-28.21-56-29.mp4

more info in comment Expensify/App#21411 (comment)

At a glance, overriding a context menu command to paste rich text, to instead coerce to plain text, seems at odds with platform expectations.

The fix is published as two PRs:

  1. The first PR over-rides onTextContextMenuItem in ReactEditText to copy/paste plain text instead of rich-text #38189
  2. The second PR removes the option paste as plain text #38210

The final result is that the option paste as plain text is removed, while paste becomes paste as plain text.

Before/After iOS Before Android
Simulator.Screen.Recording.-.iPhone.14.Pro.-.2023-06-27.at.21.41.04.mp4
repro_android.mov
After Android
2023-06-29.17-49-09.mp4

Copy link
Contributor

@NickGerleman NickGerleman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we combine #38210 into this so that we get both changes at once? Otherwise this makes sense to me, if the application can never have visibility into the rich text.

@fabOnReact fabOnReact marked this pull request as draft July 22, 2023 06:56
@fabOnReact fabOnReact changed the title Over-riding onTextContextMenuItem in ReactEditText to copy/paste plain text instead of rich-text Remove option to paste rich text from Android EditText context menu Jul 22, 2023
@fabOnReact fabOnReact marked this pull request as draft July 26, 2023 13:44
@fabOnReact fabOnReact marked this pull request as ready for review July 27, 2023 03:39
@facebook-github-bot
Copy link
Contributor

@NickGerleman has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@facebook-github-bot facebook-github-bot added the Merged This PR has been merged. label Jul 28, 2023
@facebook-github-bot
Copy link
Contributor

@NickGerleman merged this pull request in b1ceea4.

billnbell pushed a commit to billnbell/react-native that referenced this pull request Jul 29, 2023
…acebook#38189)

Summary:
Text is copy pasted as rich text on Android TextInput instead of Plain Text.

### What is the root cause of that problem?

Android EditText and iOS UITextField/UITextView have different copy/paste behavior.
- Android TextInput copies/pastes rich text
- iOS UITextField copies/pastes plain text.

| iOS (react-native)   | Android (react-native) |
| ----------- | ----------- |
| <video src="https://user-images.githubusercontent.com/24992535/249170968-8fde35f0-a53c-4c5c-bd89-ee822c08eadf.mp4" width="350" />      | <video src="https://user-images.githubusercontent.com/24992535/249171968-bf0915a0-4060-4586-b267-7c2b463d76f6.mov" width="350" />       |

### What changes do you think we should make in order to solve the problem?

The issue is a bug in react-native facebook#31442:

1) The JavaScript TextInput and ReactEditText Android state are not in sync
2) The TextInput Android Native state over-rides the JavaScript state.
3) onChangeText passes a plain text string to JavaScript, not rich text (text with spans and styles).

More info at Expensify/App#21411 (comment)

The solution consists of:

1) **Over-riding onTextContextMenuItem in ReactEditText to copy/paste plain text instead of rich-text** (https://stackoverflow.com/a/45319485/7295772).
2) **Removing the `Paste as plaintext` option from the insert and selection context menu**

fixes facebook#31442

## Changelog:

[ANDROID] [FIXED] - Remove option to paste rich text from Android EditText context menu

Pull Request resolved: facebook#38189

Test Plan:
#### Reproducing the issue on Android

https://user-images.githubusercontent.com/24992535/249185416-76f8a687-1aca-4dc9-9abe-3d73d6e2893c.mp4

#### Fixing the issue on Android
Sourcecode https://github.com/fabriziobertoglio1987/text-input-cursor-flickering-android/blob/fix-copy-paste/app/src/main/java/com/example/myapplication/CustomEditText.java

https://user-images.githubusercontent.com/24992535/249486339-95449bb9-71b6-430c-8207-f5672f034fa9.mp4

#### Testing the solution on React Native

https://github.com/Expensify/App/assets/24992535/b302237b-99e5-44a2-996d-8bc50bbbc95c

Reviewed By: mdvacca

Differential Revision: D47824730

Pulled By: NickGerleman

fbshipit-source-id: 35525e7d52e664b0f78649d23941262ee45a00cd
billnbell pushed a commit to billnbell/react-native that referenced this pull request Jul 29, 2023
…acebook#38189)

Summary:
Text is copy pasted as rich text on Android TextInput instead of Plain Text.

### What is the root cause of that problem?

Android EditText and iOS UITextField/UITextView have different copy/paste behavior.
- Android TextInput copies/pastes rich text
- iOS UITextField copies/pastes plain text.

| iOS (react-native)   | Android (react-native) |
| ----------- | ----------- |
| <video src="https://user-images.githubusercontent.com/24992535/249170968-8fde35f0-a53c-4c5c-bd89-ee822c08eadf.mp4" width="350" />      | <video src="https://user-images.githubusercontent.com/24992535/249171968-bf0915a0-4060-4586-b267-7c2b463d76f6.mov" width="350" />       |

### What changes do you think we should make in order to solve the problem?

The issue is a bug in react-native facebook#31442:

1) The JavaScript TextInput and ReactEditText Android state are not in sync
2) The TextInput Android Native state over-rides the JavaScript state.
3) onChangeText passes a plain text string to JavaScript, not rich text (text with spans and styles).

More info at Expensify/App#21411 (comment)

The solution consists of:

1) **Over-riding onTextContextMenuItem in ReactEditText to copy/paste plain text instead of rich-text** (https://stackoverflow.com/a/45319485/7295772).
2) **Removing the `Paste as plaintext` option from the insert and selection context menu**

fixes facebook#31442

## Changelog:

[ANDROID] [FIXED] - Remove option to paste rich text from Android EditText context menu

Pull Request resolved: facebook#38189

Test Plan:
#### Reproducing the issue on Android

https://user-images.githubusercontent.com/24992535/249185416-76f8a687-1aca-4dc9-9abe-3d73d6e2893c.mp4

#### Fixing the issue on Android
Sourcecode https://github.com/fabriziobertoglio1987/text-input-cursor-flickering-android/blob/fix-copy-paste/app/src/main/java/com/example/myapplication/CustomEditText.java

https://user-images.githubusercontent.com/24992535/249486339-95449bb9-71b6-430c-8207-f5672f034fa9.mp4

#### Testing the solution on React Native

https://github.com/Expensify/App/assets/24992535/b302237b-99e5-44a2-996d-8bc50bbbc95c

Reviewed By: mdvacca

Differential Revision: D47824730

Pulled By: NickGerleman

fbshipit-source-id: 35525e7d52e664b0f78649d23941262ee45a00cd
billnbell pushed a commit to billnbell/react-native that referenced this pull request Jul 29, 2023
…acebook#38189)

Summary:
Text is copy pasted as rich text on Android TextInput instead of Plain Text.

### What is the root cause of that problem?

Android EditText and iOS UITextField/UITextView have different copy/paste behavior.
- Android TextInput copies/pastes rich text
- iOS UITextField copies/pastes plain text.

| iOS (react-native)   | Android (react-native) |
| ----------- | ----------- |
| <video src="https://user-images.githubusercontent.com/24992535/249170968-8fde35f0-a53c-4c5c-bd89-ee822c08eadf.mp4" width="350" />      | <video src="https://user-images.githubusercontent.com/24992535/249171968-bf0915a0-4060-4586-b267-7c2b463d76f6.mov" width="350" />       |

### What changes do you think we should make in order to solve the problem?

The issue is a bug in react-native facebook#31442:

1) The JavaScript TextInput and ReactEditText Android state are not in sync
2) The TextInput Android Native state over-rides the JavaScript state.
3) onChangeText passes a plain text string to JavaScript, not rich text (text with spans and styles).

More info at Expensify/App#21411 (comment)

The solution consists of:

1) **Over-riding onTextContextMenuItem in ReactEditText to copy/paste plain text instead of rich-text** (https://stackoverflow.com/a/45319485/7295772).
2) **Removing the `Paste as plaintext` option from the insert and selection context menu**

fixes facebook#31442

## Changelog:

[ANDROID] [FIXED] - Remove option to paste rich text from Android EditText context menu

Pull Request resolved: facebook#38189

Test Plan:
#### Reproducing the issue on Android

https://user-images.githubusercontent.com/24992535/249185416-76f8a687-1aca-4dc9-9abe-3d73d6e2893c.mp4

#### Fixing the issue on Android
Sourcecode https://github.com/fabriziobertoglio1987/text-input-cursor-flickering-android/blob/fix-copy-paste/app/src/main/java/com/example/myapplication/CustomEditText.java

https://user-images.githubusercontent.com/24992535/249486339-95449bb9-71b6-430c-8207-f5672f034fa9.mp4

#### Testing the solution on React Native

https://github.com/Expensify/App/assets/24992535/b302237b-99e5-44a2-996d-8bc50bbbc95c

Reviewed By: mdvacca

Differential Revision: D47824730

Pulled By: NickGerleman

fbshipit-source-id: 35525e7d52e664b0f78649d23941262ee45a00cd
lunaleaps pushed a commit that referenced this pull request Aug 7, 2023
…38189)

Summary:
Text is copy pasted as rich text on Android TextInput instead of Plain Text.

### What is the root cause of that problem?

Android EditText and iOS UITextField/UITextView have different copy/paste behavior.
- Android TextInput copies/pastes rich text
- iOS UITextField copies/pastes plain text.

| iOS (react-native)   | Android (react-native) |
| ----------- | ----------- |
| <video src="https://user-images.githubusercontent.com/24992535/249170968-8fde35f0-a53c-4c5c-bd89-ee822c08eadf.mp4" width="350" />      | <video src="https://user-images.githubusercontent.com/24992535/249171968-bf0915a0-4060-4586-b267-7c2b463d76f6.mov" width="350" />       |

### What changes do you think we should make in order to solve the problem?

The issue is a bug in react-native #31442:

1) The JavaScript TextInput and ReactEditText Android state are not in sync
2) The TextInput Android Native state over-rides the JavaScript state.
3) onChangeText passes a plain text string to JavaScript, not rich text (text with spans and styles).

More info at Expensify/App#21411 (comment)

The solution consists of:

1) **Over-riding onTextContextMenuItem in ReactEditText to copy/paste plain text instead of rich-text** (https://stackoverflow.com/a/45319485/7295772).
2) **Removing the `Paste as plaintext` option from the insert and selection context menu**

fixes #31442

## Changelog:

[ANDROID] [FIXED] - Remove option to paste rich text from Android EditText context menu

Pull Request resolved: #38189

Test Plan:
#### Reproducing the issue on Android

https://user-images.githubusercontent.com/24992535/249185416-76f8a687-1aca-4dc9-9abe-3d73d6e2893c.mp4

#### Fixing the issue on Android
Sourcecode https://github.com/fabriziobertoglio1987/text-input-cursor-flickering-android/blob/fix-copy-paste/app/src/main/java/com/example/myapplication/CustomEditText.java

https://user-images.githubusercontent.com/24992535/249486339-95449bb9-71b6-430c-8207-f5672f034fa9.mp4

#### Testing the solution on React Native

https://github.com/Expensify/App/assets/24992535/b302237b-99e5-44a2-996d-8bc50bbbc95c

Reviewed By: mdvacca

Differential Revision: D47824730

Pulled By: NickGerleman

fbshipit-source-id: 35525e7d52e664b0f78649d23941262ee45a00cd
Kudo pushed a commit to expo/react-native that referenced this pull request Aug 21, 2023
…acebook#38189)

Summary:
Text is copy pasted as rich text on Android TextInput instead of Plain Text.

### What is the root cause of that problem?

Android EditText and iOS UITextField/UITextView have different copy/paste behavior.
- Android TextInput copies/pastes rich text
- iOS UITextField copies/pastes plain text.

| iOS (react-native)   | Android (react-native) |
| ----------- | ----------- |
| <video src="https://user-images.githubusercontent.com/24992535/249170968-8fde35f0-a53c-4c5c-bd89-ee822c08eadf.mp4" width="350" />      | <video src="https://user-images.githubusercontent.com/24992535/249171968-bf0915a0-4060-4586-b267-7c2b463d76f6.mov" width="350" />       |

### What changes do you think we should make in order to solve the problem?

The issue is a bug in react-native facebook#31442:

1) The JavaScript TextInput and ReactEditText Android state are not in sync
2) The TextInput Android Native state over-rides the JavaScript state.
3) onChangeText passes a plain text string to JavaScript, not rich text (text with spans and styles).

More info at Expensify/App#21411 (comment)

The solution consists of:

1) **Over-riding onTextContextMenuItem in ReactEditText to copy/paste plain text instead of rich-text** (https://stackoverflow.com/a/45319485/7295772).
2) **Removing the `Paste as plaintext` option from the insert and selection context menu**

fixes facebook#31442

## Changelog:

[ANDROID] [FIXED] - Remove option to paste rich text from Android EditText context menu

Pull Request resolved: facebook#38189

Test Plan:
#### Reproducing the issue on Android

https://user-images.githubusercontent.com/24992535/249185416-76f8a687-1aca-4dc9-9abe-3d73d6e2893c.mp4

#### Fixing the issue on Android
Sourcecode https://github.com/fabriziobertoglio1987/text-input-cursor-flickering-android/blob/fix-copy-paste/app/src/main/java/com/example/myapplication/CustomEditText.java

https://user-images.githubusercontent.com/24992535/249486339-95449bb9-71b6-430c-8207-f5672f034fa9.mp4

#### Testing the solution on React Native

https://github.com/Expensify/App/assets/24992535/b302237b-99e5-44a2-996d-8bc50bbbc95c

Reviewed By: mdvacca

Differential Revision: D47824730

Pulled By: NickGerleman

fbshipit-source-id: 35525e7d52e664b0f78649d23941262ee45a00cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.
Projects
None yet
4 participants