Add Partial translate edit menu in WKWebView.
The entry should replace the "translate" entry and be displayed in the same conditions. If the translate entry cannot be found, place the entry before the lookup menu. If the edit menu new api is not enabled, add the entry at the end of the menu using legacy API. Bug: 1416451 Change-Id: Ibb3c6145b2ec03fa3b637c86cb8559bac87b8660 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4272005 Reviewed-by: Sylvain Defresne <sdefresne@chromium.org> Commit-Queue: Olivier Robin <olivierrobin@chromium.org> Cr-Commit-Position: refs/heads/main@{#1107802}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
bf3e7fb6e9
commit
e75b414226
ios/chrome
app
strings
browser
@@ -1777,6 +1777,9 @@ While in Incognito, sites can't use cookies to see your browsing activity across
|
||||
<message name="IDS_IOS_PARTIAL_TRANSLATE_ACTION_TRANSLATE_FULL_PAGE" desc="The action button to translate the full page (Title Case).">
|
||||
Translate Full Page
|
||||
</message>
|
||||
<message name="IDS_IOS_PARTIAL_TRANSLATE_EDIT_MENU_ENTRY" desc="Action displayed in Edit Menu to trigger Partial Translate. As an action, it should be an infinitive verb, but should also respect the 'Google Translate' branding. Possible variations are 'Google Translate' or 'Translate with Google' are acceptable to meet those criteria [MAX_LENGTH=25em].">
|
||||
Google Translate
|
||||
</message>
|
||||
<message name="IDS_IOS_PARTIAL_TRANSLATE_ERROR_GENERIC" desc="Error message when when the process failed (unknown reason).">
|
||||
Partial translation failed.
|
||||
</message>
|
||||
|
1
ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PARTIAL_TRANSLATE_EDIT_MENU_ENTRY.png.sha1
Normal file
1
ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PARTIAL_TRANSLATE_EDIT_MENU_ENTRY.png.sha1
Normal file
@@ -0,0 +1 @@
|
||||
71ce1af2b892c6c849ff7d0236616d7acd959458
|
@@ -63,6 +63,7 @@ source_set("ui") {
|
||||
"//ios/chrome/app/strings",
|
||||
"//ios/chrome/browser/ui:feature_flags",
|
||||
"//ios/chrome/browser/ui/link_to_text",
|
||||
"//ios/chrome/browser/ui/partial_translate",
|
||||
"//ios/chrome/browser/ui/util",
|
||||
"//ios/chrome/common/ui/util",
|
||||
"//ui/base",
|
||||
|
@@ -106,6 +106,8 @@
|
||||
id<BrowserCoordinatorCommands> handler =
|
||||
HandlerForProtocol(dispatcher, BrowserCoordinatorCommands);
|
||||
self.partialTranslateMediator.browserHandler = handler;
|
||||
self.browserEditMenuHandler.partialTranslateDelegate =
|
||||
self.partialTranslateMediator;
|
||||
}
|
||||
|
||||
[self.webContentAreaOverlayContainerCoordinator start];
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@protocol LinkToTextDelegate;
|
||||
@protocol PartialTranslateDelegate;
|
||||
|
||||
// A handler for the Browser edit menu.
|
||||
// This class is in charge of customising the menu and executing the commands.
|
||||
@@ -15,6 +16,10 @@
|
||||
// The delegate to handle link to text button selection.
|
||||
@property(nonatomic, weak) id<LinkToTextDelegate> linkToTextDelegate;
|
||||
|
||||
// The delegate to handle Partial Translate button selection.
|
||||
@property(nonatomic, weak) id<PartialTranslateDelegate>
|
||||
partialTranslateDelegate;
|
||||
|
||||
// Will be called by `BrowserContainerViewController buildMenuWithBuilder:`
|
||||
// to customize its edit menu.
|
||||
- (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder;
|
||||
|
@@ -5,7 +5,9 @@
|
||||
#import "ios/chrome/browser/ui/browser_container/browser_edit_menu_handler.h"
|
||||
|
||||
#import "base/feature_list.h"
|
||||
#import "ios/chrome/browser/ui/link_to_text/link_to_text_mediator.h"
|
||||
#import "base/mac/foundation_util.h"
|
||||
#import "ios/chrome/browser/ui/link_to_text/link_to_text_delegate.h"
|
||||
#import "ios/chrome/browser/ui/partial_translate/partial_translate_delegate.h"
|
||||
#import "ios/chrome/browser/ui/ui_feature_flags.h"
|
||||
#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
|
||||
#import "ios/chrome/grit/ios_strings.h"
|
||||
@@ -16,11 +18,24 @@
|
||||
#endif
|
||||
|
||||
@interface BrowserEditMenuHandler ()
|
||||
|
||||
// A cache for the first responder that is reset on the next runloop.
|
||||
@property(nonatomic, weak) UIResponder* firstResponder;
|
||||
|
||||
@end
|
||||
|
||||
@implementation BrowserEditMenuHandler
|
||||
@implementation BrowserEditMenuHandler {
|
||||
// Keep the original translate command to display partial translate in the
|
||||
// same conditions.
|
||||
UICommand* _originalTranslateCommand;
|
||||
}
|
||||
|
||||
- (void)buildMenuWithBuilder:(id<UIMenuBuilder>)builder {
|
||||
[self addLinkToText:builder];
|
||||
[self addPartialTranslate:builder];
|
||||
}
|
||||
|
||||
- (void)addLinkToText:(id<UIMenuBuilder>)builder {
|
||||
if (!base::FeatureList::IsEnabled(kIOSCustomBrowserEditMenu)) {
|
||||
return;
|
||||
}
|
||||
@@ -39,30 +54,132 @@
|
||||
[builder insertChildMenu:linkToTextMenu atEndOfMenuForIdentifier:UIMenuRoot];
|
||||
}
|
||||
|
||||
- (void)addPartialTranslate:(id<UIMenuBuilder>)builder {
|
||||
if (!base::FeatureList::IsEnabled(kIOSEditMenuPartialTranslate)) {
|
||||
return;
|
||||
}
|
||||
NSString* title =
|
||||
l10n_util::GetNSString(IDS_IOS_PARTIAL_TRANSLATE_EDIT_MENU_ENTRY);
|
||||
NSString* partialTranslateId = @"chromecommand.partialTranslate";
|
||||
UICommand* partialTranslateCommand =
|
||||
[UICommand commandWithTitle:title
|
||||
image:nil
|
||||
action:@selector(chromePartialTranslate:)
|
||||
propertyList:partialTranslateId];
|
||||
|
||||
// Translate command is in the lookup menu.
|
||||
// Retrieve the menu so it can be replaced with partial translate.
|
||||
UIMenu* lookupMenu = [builder menuForIdentifier:UIMenuLookup];
|
||||
NSArray* children = lookupMenu.children;
|
||||
NSInteger translateIndex = -1;
|
||||
for (NSUInteger index = 0; index < children.count; index++) {
|
||||
UIMenuElement* element = children[index];
|
||||
// Translate is a command.
|
||||
if (![element isKindOfClass:[UICommand class]]) {
|
||||
continue;
|
||||
}
|
||||
UICommand* command = base::mac::ObjCCast<UICommand>(element);
|
||||
if (command.action != NSSelectorFromString(@"_translate:")) {
|
||||
continue;
|
||||
}
|
||||
_originalTranslateCommand = command;
|
||||
translateIndex = index;
|
||||
break;
|
||||
}
|
||||
|
||||
if (translateIndex == -1) {
|
||||
// Translate command not found. Fallback adding the partial translate before
|
||||
// the lookup menu.
|
||||
// TODO(crbug.com/1417639): Catch this so it can be fixed.
|
||||
UIMenu* partialTranslateMenu =
|
||||
[UIMenu menuWithTitle:title
|
||||
image:nil
|
||||
identifier:partialTranslateId
|
||||
options:UIMenuOptionsDisplayInline
|
||||
children:@[ partialTranslateCommand ]];
|
||||
[builder insertSiblingMenu:partialTranslateMenu
|
||||
beforeMenuForIdentifier:UIMenuLookup];
|
||||
return;
|
||||
}
|
||||
|
||||
// Rebuild the lookup menu with partial translate
|
||||
NSMutableArray* newChildren = [NSMutableArray arrayWithArray:children];
|
||||
newChildren[translateIndex] = partialTranslateCommand;
|
||||
UIMenu* newPartialTranslate = [UIMenu menuWithTitle:lookupMenu.title
|
||||
image:lookupMenu.image
|
||||
identifier:lookupMenu.identifier
|
||||
options:lookupMenu.options
|
||||
children:newChildren];
|
||||
|
||||
[builder replaceMenuForIdentifier:UIMenuLookup withMenu:newPartialTranslate];
|
||||
}
|
||||
|
||||
- (void)addEditMenuEntries {
|
||||
if (base::FeatureList::IsEnabled(kIOSCustomBrowserEditMenu)) {
|
||||
return;
|
||||
}
|
||||
if (!base::FeatureList::IsEnabled(kSharedHighlightingIOS)) {
|
||||
return;
|
||||
if (base::FeatureList::IsEnabled(kSharedHighlightingIOS)) {
|
||||
NSString* title = l10n_util::GetNSString(IDS_IOS_SHARE_LINK_TO_TEXT);
|
||||
UIMenuItem* menuItem =
|
||||
[[UIMenuItem alloc] initWithTitle:title action:@selector(linkToText:)];
|
||||
RegisterEditMenuItem(menuItem);
|
||||
}
|
||||
if (base::FeatureList::IsEnabled(kIOSEditMenuPartialTranslate)) {
|
||||
NSString* title =
|
||||
l10n_util::GetNSString(IDS_IOS_PARTIAL_TRANSLATE_EDIT_MENU_ENTRY);
|
||||
UIMenuItem* menuItem =
|
||||
[[UIMenuItem alloc] initWithTitle:title
|
||||
action:@selector(chromePartialTranslate:)];
|
||||
RegisterEditMenuItem(menuItem);
|
||||
}
|
||||
NSString* title = l10n_util::GetNSString(IDS_IOS_SHARE_LINK_TO_TEXT);
|
||||
UIMenuItem* menuItem =
|
||||
[[UIMenuItem alloc] initWithTitle:title action:@selector(linkToText:)];
|
||||
RegisterEditMenuItem(menuItem);
|
||||
}
|
||||
|
||||
- (BOOL)canPerformChromeAction:(SEL)action withSender:(id)sender {
|
||||
if (action == @selector(linkToText:)) {
|
||||
return [self.linkToTextDelegate shouldOfferLinkToText];
|
||||
}
|
||||
if (action == @selector(chromePartialTranslate:)) {
|
||||
BOOL canHandlePartialTranslate =
|
||||
[self.partialTranslateDelegate canHandlePartialTranslateSelection];
|
||||
if (canHandlePartialTranslate && [self firstResponder] &&
|
||||
_originalTranslateCommand) {
|
||||
return [[self firstResponder]
|
||||
canPerformAction:_originalTranslateCommand.action
|
||||
withSender:_originalTranslateCommand];
|
||||
}
|
||||
return canHandlePartialTranslate;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - LinkToTextDelegate methods
|
||||
|
||||
- (void)linkToText:(UIMenuItem*)item {
|
||||
DCHECK(base::FeatureList::IsEnabled(kSharedHighlightingIOS));
|
||||
DCHECK(self.linkToTextDelegate);
|
||||
[self.linkToTextDelegate handleLinkToTextSelection];
|
||||
}
|
||||
|
||||
#pragma mark - PartialTranslateDelegate methods
|
||||
|
||||
- (void)chromePartialTranslate:(UIMenuItem*)item {
|
||||
DCHECK(base::FeatureList::IsEnabled(kIOSEditMenuPartialTranslate));
|
||||
DCHECK(self.partialTranslateDelegate);
|
||||
[self.partialTranslateDelegate handlePartialTranslateSelection];
|
||||
}
|
||||
|
||||
#pragma mark - private methods
|
||||
|
||||
- (UIResponder*)firstResponder {
|
||||
if (_firstResponder) {
|
||||
return _firstResponder;
|
||||
}
|
||||
_firstResponder = GetFirstResponder();
|
||||
__weak BrowserEditMenuHandler* weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
weakSelf.firstResponder = nil;
|
||||
});
|
||||
return _firstResponder;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@@ -11,6 +11,9 @@
|
||||
// Handles the link to text menu item selection.
|
||||
- (void)handlePartialTranslateSelection;
|
||||
|
||||
// Returns whether a partial translate can be handled.
|
||||
- (BOOL)canHandlePartialTranslateSelection;
|
||||
|
||||
@end
|
||||
|
||||
#endif // IOS_CHROME_BROWSER_UI_PARTIAL_TRANSLATE_PARTIAL_TRANSLATE_DELEGATE_H_
|
||||
|
@@ -71,6 +71,17 @@
|
||||
}));
|
||||
}
|
||||
|
||||
- (BOOL)canHandlePartialTranslateSelection {
|
||||
DCHECK(base::FeatureList::IsEnabled(kSharedHighlightingIOS));
|
||||
// TODO(crbug.com/1417238): add metrics
|
||||
WebSelectionTabHelper* tabHelper = [self webSelectionTabHelper];
|
||||
if (!tabHelper) {
|
||||
return NO;
|
||||
}
|
||||
return tabHelper->CanRetrieveSelectedText() &&
|
||||
PartialTranslateLimitMaxCharacters() > 0u;
|
||||
}
|
||||
|
||||
- (void)switchToFullTranslateWithMessage:(NSString*)message {
|
||||
// TODO(crbug.com/1417238): add metrics
|
||||
if (!self.alertDelegate) {
|
||||
|
Reference in New Issue
Block a user