Skip to content

Commit

Permalink
[RN][macos] Remove irrelevant context menu items for single/multiline…
Browse files Browse the repository at this point in the history
… text input

Summary:
**Context**

Strip out irrelevant menu items from TextInput context menu for single & multi line inputs.

**Change**
- Expose public static method on RCTTextView.h for determining submenu
- Add delegate methods for single/multi line inputs
- Filter the menu items with block


Test Plan:
## Singleline input
|before|after|
|{F743226674}|{F743226745}|

## Multiline input
|before|after|
|{F743226792}|{F743226809}|

Reviewers: lyahdav, ericroz, #seller_expansion

Reviewed By: lyahdav

Subscribers: alexhenry

Differential Revision: https://phabricator.intern.facebook.com/D37199687

Tasks: T114066390

Tags: marketplace, oncall, oncallteam-react-native-desktop, marketplace_seller_expansion
  • Loading branch information
Shawn Dempsey authored and christophpurrer committed Aug 9, 2022
1 parent 193922b commit 54fa917
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 22 deletions.
29 changes: 7 additions & 22 deletions Libraries/Text/Text/RCTTextView.m
Original file line number Diff line number Diff line change
Expand Up @@ -479,38 +479,23 @@ - (void)handleLongPress:(UILongPressGestureRecognizer *)gesture

- (NSMenu *)textView:(NSTextView *)view menu:(NSMenu *)menu forEvent:(NSEvent *)event atIndex:(NSUInteger)charIndex
{
// Remove items not applicable for readonly text.
for (NSMenuItem *item in menu.itemArray) {
if (item.action == @selector(cut:) || item.action == @selector(paste:) || [RCTTextView item:item hasSubmenuItemWithAction:@selector(checkSpelling:)] || [RCTTextView item:item hasSubmenuItemWithAction:@selector(orderFrontSubstitutionsPanel:)]) {
item.hidden = YES;
}
}
[[RCTTouchHandler touchHandlerForView:self] willShowMenuWithEvent:event];

RCTHideMenuItemsWithFilterPredicate(menu, ^bool(NSMenuItem *item) {
// Remove items not applicable for readonly text.
return (item.action == @selector(cut:) || item.action == @selector(paste:) || RCTMenuItemHasSubmenuItemWithAction(item, @selector(checkSpelling:)) || RCTMenuItemHasSubmenuItemWithAction(item, @selector(orderFrontSubstitutionsPanel:)));
});

if (_additionalMenuItems.count > 0) {
[menu insertItem:[NSMenuItem separatorItem] atIndex:0];
for (NSMenuItem* item in [_additionalMenuItems reverseObjectEnumerator]) {
[menu insertItem:item atIndex:0];
}
}

[[RCTTouchHandler touchHandlerForView:self] willShowMenuWithEvent:event];


return menu;
}

+ (BOOL)item:(NSMenuItem *)item hasSubmenuItemWithAction:(SEL)action
{
if (!item.hasSubmenu) {
return NO;
}
for (NSMenuItem *submenuItem in item.submenu.itemArray) {
if (submenuItem.action == action) {
return YES;
}
}
return NO;
}

- (void)textDidEndEditing:(NSNotification *)notification
{
_textView.selectedRange = NSMakeRange(NSNotFound, 0);
Expand Down
6 changes: 6 additions & 0 deletions Libraries/Text/TextInput/Multiline/RCTUITextView.m
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,12 @@ - (NSMenu *)menuForEvent:(NSEvent *)event
if (menu) {
[[RCTTouchHandler touchHandlerForView:self] willShowMenuWithEvent:event];
}

RCTHideMenuItemsWithFilterPredicate(menu, ^bool(NSMenuItem *item) {
// hide font & layout orientation menu options
return (RCTMenuItemHasSubmenuItemWithAction(item, @selector(orderFrontFontPanel:)) || RCTMenuItemHasSubmenuItemWithAction(item, @selector(changeLayoutOrientation:)));
});

return menu;
}
#endif // ]TODO(macOS ISS#2323203)
Expand Down
6 changes: 6 additions & 0 deletions Libraries/Text/TextInput/Singleline/RCTUITextField.m
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,12 @@ - (NSMenu *)textView:(NSTextView *)view menu:(NSMenu *)menu forEvent:(NSEvent *)
if (menu) {
[[RCTTouchHandler touchHandlerForView:self] willShowMenuWithEvent:event];
}

RCTHideMenuItemsWithFilterPredicate(menu, ^bool(NSMenuItem *item) {
// hide font menu option
return RCTMenuItemHasSubmenuItemWithAction(item, @selector(orderFrontFontPanel:));
});

return menu;
}

Expand Down
6 changes: 6 additions & 0 deletions React/Base/RCTUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,10 @@ RCT_EXTERN BOOL RCTValidateTypeOfViewCommandArgument(
NSString const *commandName,
NSString const *argPos);

#if TARGET_OS_OSX
typedef bool (^RCTMenuItemFilterPredicate)(NSMenuItem *_Nonnull item);
RCT_EXTERN void RCTHideMenuItemsWithFilterPredicate(NSMenu *_Nonnull menu, RCTMenuItemFilterPredicate shouldFilter);
RCT_EXTERN BOOL RCTMenuItemHasSubmenuItemWithAction(NSMenuItem *_Nonnull item, SEL action);
#endif

NS_ASSUME_NONNULL_END
24 changes: 24 additions & 0 deletions React/Base/RCTUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -1159,3 +1159,27 @@ RCT_EXTERN BOOL RCTValidateTypeOfViewCommandArgument(

return true;
}

#if TARGET_OS_OSX
void RCTHideMenuItemsWithFilterPredicate(NSMenu *menu, RCTMenuItemFilterPredicate shouldFilter)
{
for (NSMenuItem *item in menu.itemArray) {
if (shouldFilter(item)) {
item.hidden = YES;
}
}
}

BOOL RCTMenuItemHasSubmenuItemWithAction(NSMenuItem *item, SEL action)
{
if (!item.hasSubmenu) {
return NO;
}
for (NSMenuItem *submenuItem in item.submenu.itemArray) {
if (submenuItem.action == action) {
return YES;
}
}
return NO;
}
#endif

0 comments on commit 54fa917

Please sign in to comment.