-
Notifications
You must be signed in to change notification settings - Fork 145
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
Support arbitrary selectable text in Text component #1346
Conversation
Summary: RN Mac's implementation of the `selectable` prop on `Text` only allows selecting the entire Text component and right click to copy. This diff makes the `Text.selectable` prop on Mac allow arbitrary selection. To do this we used `NSTextView` to render the `Text` component instead of RN Mac's custom text rendering, because it has a `selectable` property which gives us the behavior we want. We also allow adding custom menu items in the context menu. Note the change to RNTesterPage.js was required to fix microsoft#754. Test Plan: See test plan of D27250072 for integration to Zeratul. Confirmed text selection works in RNTester Text example: {F588619781} --- Also I went to RNTester Text examples and did an image diff comparison before and after these changes (differences are in pink): {F588602710} - The font smoothing isn't something we need --- {F588602715} - The examples with images are different because they load random images - The pink background on "With size and background color" isn't a difference, the background color is pink in code --- {F588602706} - The <TextInput multiline/> example has an off by 1 pixel difference that wasn't trivial to fix and doesn't seem significant enough to investigate Reviewers: skyle, ericroz Reviewed By: skyle Subscribers: eliwhite Differential Revision: https://phabricator.intern.facebook.com/D27484533 Tasks: T83817888 Signature: 27484533:1617928003:6c1c60a15db8ef3551aafe22229fafc9fea0053e # Conflicts: # Libraries/Text/Text/RCTTextView.m # React/Base/RCTTouchHandler.h # React/Base/RCTTouchHandler.m
Summary: This fixes a regression introduced by D29340382 since the `contentView` of the window was changed to the `RCTRootView` instance. The problem isn't there though, but is due to now the `contentView` having flipped geometry. The `hitTest:` method expects coordinates in the superview's coordinate space: > A point that is in the coordinate system of the view’s superview, not of the view itself. Also see how `RCTTouchHandler` also calls `convertPoint:` on the `superview` before passing to `hitTest:` for the same reason: https://fburl.com/diffusion/krx4lxao Test Plan: {F628902534} Reviewers: lyahdav Reviewed By: lyahdav Subscribers: eliwhite Differential Revision: https://phabricator.intern.facebook.com/D29469639 Tasks: T94420821 Signature: 29469639:1625001662:97028699aee404282c83e35cd66f6308bc793a2a
We probably want to do a lot more testing for this specific change, as it's a fundamental difference for how we render text. Curious, have y'all done any performance impact testing with this changee? |
We did not do any performance impact testing. Does this repo (internally to MSFT or in OSS) have any performance testing setup? |
Not that I'm aware of. I guess the more generic question: What kind of testing was done with making sure that Text still rendered the same everywhere? I can imagine just running RN-Tester before and after this change is a good start (we'll probably do that too). Also curious if you all heard back from RN Core about why they didn't use UITextView with iOS? |
We went through all the Text examples in RN Tester and confirmed the before/after were identical.
I'll let @shwanton answer this, he has an internal thread on this. |
Another data point -> we shipped Messenger Desktop (macOS) with that change end of 2021 and so far haven't been aware of any text rendering issues. |
This Textview refactor happened in late 2017 so not many folks have full context on why we removed UITextView. However, it does look like the performance reasons should be now mitigated. One main callout was that "it does not instantiate UIView for virtual components which reduces memory utilization", which should be solved with Fabric. RN Core recommended we run an experiment before switching out UITextView on iOS. This work is planned but has not been started yet. We have been using this on Messenger Desktop all year & haven't seen any regressions or issues w/ NSTextView. |
@Saadnajmi was there any other data you needed to help this PR get merged? |
@shwanton Sorry, I totally missed the screenshots you sent. Thanks! @mischreiber FYI |
I have some concerns with this PR as-is:
|
@shwanton another example of a change we might want to make this to PR: D28557126 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotta fix the failing checks first, of course.
@mischreiber Fixed! |
nice work! |
* Support arbitrary selectable text in Text component Summary: RN Mac's implementation of the `selectable` prop on `Text` only allows selecting the entire Text component and right click to copy. This diff makes the `Text.selectable` prop on Mac allow arbitrary selection. To do this we used `NSTextView` to render the `Text` component instead of RN Mac's custom text rendering, because it has a `selectable` property which gives us the behavior we want. We also allow adding custom menu items in the context menu. Note the change to RNTesterPage.js was required to fix microsoft#754. Test Plan: See test plan of D27250072 for integration to Zeratul. Confirmed text selection works in RNTester Text example: {F588619781} --- Also I went to RNTester Text examples and did an image diff comparison before and after these changes (differences are in pink): {F588602710} - The font smoothing isn't something we need --- {F588602715} - The examples with images are different because they load random images - The pink background on "With size and background color" isn't a difference, the background color is pink in code --- {F588602706} - The <TextInput multiline/> example has an off by 1 pixel difference that wasn't trivial to fix and doesn't seem significant enough to investigate Reviewers: skyle, ericroz Reviewed By: skyle Subscribers: eliwhite Differential Revision: https://phabricator.intern.facebook.com/D27484533 Tasks: T83817888 Signature: 27484533:1617928003:6c1c60a15db8ef3551aafe22229fafc9fea0053e # Conflicts: # Libraries/Text/Text/RCTTextView.m # React/Base/RCTTouchHandler.h # React/Base/RCTTouchHandler.m * Fix GH tags * Revert RNTesterPage style change * Fix hit-testing in RCTTextView for selection Summary: This fixes a regression introduced by D29340382 since the `contentView` of the window was changed to the `RCTRootView` instance. The problem isn't there though, but is due to now the `contentView` having flipped geometry. The `hitTest:` method expects coordinates in the superview's coordinate space: > A point that is in the coordinate system of the view’s superview, not of the view itself. Also see how `RCTTouchHandler` also calls `convertPoint:` on the `superview` before passing to `hitTest:` for the same reason: https://fburl.com/diffusion/krx4lxao Test Plan: {F628902534} Reviewers: lyahdav Reviewed By: lyahdav Subscribers: eliwhite Differential Revision: https://phabricator.intern.facebook.com/D29469639 Tasks: T94420821 Signature: 29469639:1625001662:97028699aee404282c83e35cd66f6308bc793a2a * Revert changes to touch handler * Only keep NSTextView changes * Remove unused property * Re-add focus ring for selected text * Fix typos * Ensure that RCTTextView manages the key loop view * move focusable property lower in list * Fix macos tags * Remove iOS only highlighted prop that was causing re-render issues on macOS * yarn lint Co-authored-by: Liron Yahdav <[email protected]> Co-authored-by: Shawn Dempsey <[email protected]> Co-authored-by: Scott Kyle <[email protected]>
Summary: isHighlighted is only used for iOS. Even macOS disables it (see microsoft#1346). This change ensures that the isHighlighted prop is only updated for iOS. [General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS Reviewed By: lenaic, sammy-SC Differential Revision: D47800845 fbshipit-source-id: cadfe0cd64de8d98a10e3f24b3ae17b9bada8b3a
Summary: Pull Request resolved: facebook#38642 isHighlighted is only used for iOS. Even macOS disables it (see microsoft#1346). This change ensures that the isHighlighted prop is only updated for iOS. ## Changelog: [General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS Reviewed By: lenaic, sammy-SC Differential Revision: D47800845 fbshipit-source-id: 9888db039f5b955da0c3dfa43dd304f3f4d01f19
Summary: Pull Request resolved: #38642 isHighlighted is only used for iOS. Even macOS disables it (see microsoft#1346). This change ensures that the isHighlighted prop is only updated for iOS. ## Changelog: [General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS Reviewed By: lenaic, sammy-SC Differential Revision: D47800845 fbshipit-source-id: af109be17027b2fbc9408e2ec9e1b841c709fe35
Summary: Pull Request resolved: facebook#38642 isHighlighted is only used for iOS. Even macOS disables it (see microsoft#1346). This change ensures that the isHighlighted prop is only updated for iOS. ## Changelog: [General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS Reviewed By: lenaic, sammy-SC Differential Revision: D47800845 fbshipit-source-id: af109be17027b2fbc9408e2ec9e1b841c709fe35
Summary: Pull Request resolved: facebook#38642 isHighlighted is only used for iOS. Even macOS disables it (see microsoft#1346). This change ensures that the isHighlighted prop is only updated for iOS. ## Changelog: [General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS Reviewed By: lenaic, sammy-SC Differential Revision: D47800845 fbshipit-source-id: af109be17027b2fbc9408e2ec9e1b841c709fe35
Summary: Pull Request resolved: facebook#38642 isHighlighted is only used for iOS. Even macOS disables it (see #1346). This change ensures that the isHighlighted prop is only updated for iOS. ## Changelog: [General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS Reviewed By: lenaic, sammy-SC Differential Revision: D47800845 fbshipit-source-id: af109be17027b2fbc9408e2ec9e1b841c709fe35 Co-authored-by: Eric Rozell <[email protected]>
Summary: Pull Request resolved: facebook#38642 isHighlighted is only used for iOS. Even macOS disables it (see #1346). This change ensures that the isHighlighted prop is only updated for iOS. ## Changelog: [General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS Reviewed By: lenaic, sammy-SC Differential Revision: D47800845 fbshipit-source-id: af109be17027b2fbc9408e2ec9e1b841c709fe35 Co-authored-by: Eric Rozell <[email protected]>
Summary: Pull Request resolved: facebook#38642 isHighlighted is only used for iOS. Even macOS disables it (see microsoft#1346). This change ensures that the isHighlighted prop is only updated for iOS. ## Changelog: [General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS Reviewed By: lenaic, sammy-SC Differential Revision: D47800845 fbshipit-source-id: af109be17027b2fbc9408e2ec9e1b841c709fe35
Summary: Pull Request resolved: facebook#38642 isHighlighted is only used for iOS. Even macOS disables it (see microsoft#1346). This change ensures that the isHighlighted prop is only updated for iOS. ## Changelog: [General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS Reviewed By: lenaic, sammy-SC Differential Revision: D47800845 fbshipit-source-id: af109be17027b2fbc9408e2ec9e1b841c709fe35
Summary: Pull Request resolved: facebook#38642 isHighlighted is only used for iOS. Even macOS disables it (see microsoft#1346). This change ensures that the isHighlighted prop is only updated for iOS. ## Changelog: [General] [Fixed] - Avoids re-renders during text selection on desktop platforms by limiting native-only `isHighlighted` prop to iOS Reviewed By: lenaic, sammy-SC Differential Revision: D47800845 fbshipit-source-id: af109be17027b2fbc9408e2ec9e1b841c709fe35
Please select one of the following
Summary
Summary:
RN Mac's implementation of the
selectable
prop onText
only allows selecting the entire Text component and right click to copy. This diff makes theText.selectable
prop on Mac allow arbitrary selection. To do this we usedNSTextView
to render theText
component instead of RN Mac's custom text rendering, because it has aselectable
property which gives us the behavior we want.Differential Revision: https://phabricator.intern.facebook.com/D27484533
Tasks: T83817888
Changelog
[macOS] [Fixed] - Support arbitrary selectable text in Text component
[macOS] [Fixed] - Add
focusable
andenableFocusRing
props to Text to control focus behaviorTest Plan
before (RN iOS behavior)

after
CleanShot.2022-09-28.at.16.04.59.mp4