blob: 5246f8f309dbbd5f24baf878adef280f6a8de264 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/ui/key_commands_provider.h"
#include "base/logging.h"
#include "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/ui/commands/open_new_tab_command.h"
#include "ios/chrome/browser/ui/commands/start_voice_search_command.h"
#import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h"
#include "ios/chrome/browser/ui/rtl_geometry.h"
#include "ios/chrome/grit/ios_strings.h"
#include "ui/base/l10n/l10n_util_mac.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation KeyCommandsProvider
- (NSArray*)
keyCommandsForConsumer:(id<KeyCommandsPlumbing>)consumer
baseViewController:(UIViewController*)baseViewController
dispatcher:
(id<ApplicationCommands, BrowserCommands, OmniboxFocuser>)
dispatcher
editingText:(BOOL)editingText {
__weak id<KeyCommandsPlumbing> weakConsumer = consumer;
__weak UIViewController* weakBaseViewController = baseViewController;
__weak id<ApplicationCommands, BrowserCommands, OmniboxFocuser>
weakDispatcher = dispatcher;
// Block to have the tab model open the tab at |index|, if there is one.
void (^focusTab)(NSUInteger) = ^(NSUInteger index) {
[weakConsumer focusTabAtIndex:index];
};
const BOOL hasTabs = [consumer tabsCount] > 0;
const BOOL useRTLLayout = UseRTLLayout();
// Blocks for navigating forward/back.
void (^browseLeft)();
void (^browseRight)();
if (useRTLLayout) {
browseLeft = ^{
if ([weakConsumer canGoForward])
[weakDispatcher goForward];
};
browseRight = ^{
if ([weakConsumer canGoBack])
[weakDispatcher goBack];
};
} else {
browseLeft = ^{
if ([weakConsumer canGoBack])
[weakDispatcher goBack];
};
browseRight = ^{
if ([weakConsumer canGoForward])
[weakDispatcher goForward];
};
}
// New tab blocks.
void (^newTab)() = ^{
OpenNewTabCommand* newTabCommand = [OpenNewTabCommand command];
newTabCommand.shouldFocusOmnibox = YES;
[weakDispatcher openNewTab:newTabCommand];
};
void (^newIncognitoTab)() = ^{
OpenNewTabCommand* newIncognitoTabCommand =
[OpenNewTabCommand incognitoTabCommand];
newIncognitoTabCommand.shouldFocusOmnibox = YES;
[weakDispatcher openNewTab:newIncognitoTabCommand];
};
const int browseLeftDescriptionID = useRTLLayout
? IDS_IOS_KEYBOARD_HISTORY_FORWARD
: IDS_IOS_KEYBOARD_HISTORY_BACK;
const int browseRightDescriptionID = useRTLLayout
? IDS_IOS_KEYBOARD_HISTORY_BACK
: IDS_IOS_KEYBOARD_HISTORY_FORWARD;
// Initialize the array of commands with an estimated capacity.
NSMutableArray* keyCommands = [NSMutableArray arrayWithCapacity:32];
// List the commands that always appear in the HUD. They appear in the HUD
// since they have titles.
[keyCommands addObjectsFromArray:@[
[UIKeyCommand cr_keyCommandWithInput:@"t"
modifierFlags:UIKeyModifierCommand
title:l10n_util::GetNSStringWithFixup(
IDS_IOS_TOOLS_MENU_NEW_TAB)
action:newTab],
[UIKeyCommand
cr_keyCommandWithInput:@"n"
modifierFlags:UIKeyModifierCommand | UIKeyModifierShift
title:l10n_util::GetNSStringWithFixup(
IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB)
action:newIncognitoTab],
[UIKeyCommand
cr_keyCommandWithInput:@"t"
modifierFlags:UIKeyModifierCommand | UIKeyModifierShift
title:l10n_util::GetNSStringWithFixup(
IDS_IOS_KEYBOARD_REOPEN_CLOSED_TAB)
action:^{
[weakConsumer reopenClosedTab];
}],
]];
// List the commands that only appear when there is at least a tab. When they
// appear, they are in the HUD since they have titles.
if (hasTabs) {
[keyCommands addObjectsFromArray:@[
[UIKeyCommand cr_keyCommandWithInput:@"l"
modifierFlags:UIKeyModifierCommand
title:l10n_util::GetNSStringWithFixup(
IDS_IOS_KEYBOARD_OPEN_LOCATION)
action:^{
[weakDispatcher focusOmnibox];
}],
[UIKeyCommand cr_keyCommandWithInput:@"w"
modifierFlags:UIKeyModifierCommand
title:l10n_util::GetNSStringWithFixup(
IDS_IOS_TOOLS_MENU_CLOSE_TAB)
action:^{
[weakDispatcher closeCurrentTab];
}],
[UIKeyCommand
cr_keyCommandWithInput:@"d"
modifierFlags:UIKeyModifierCommand
title:l10n_util::GetNSStringWithFixup(
IDS_IOS_KEYBOARD_BOOKMARK_THIS_PAGE)
action:^{
[weakDispatcher bookmarkPage];
}],
[UIKeyCommand cr_keyCommandWithInput:@"f"
modifierFlags:UIKeyModifierCommand
title:l10n_util::GetNSStringWithFixup(
IDS_IOS_TOOLS_MENU_FIND_IN_PAGE)
action:^{
[weakDispatcher showFindInPage];
}],
[UIKeyCommand cr_keyCommandWithInput:@"g"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
[weakDispatcher findNextStringInPage];
}],
[UIKeyCommand
cr_keyCommandWithInput:@"g"
modifierFlags:UIKeyModifierCommand | UIKeyModifierShift
title:nil
action:^{
[weakDispatcher findPreviousStringInPage];
}],
[UIKeyCommand cr_keyCommandWithInput:@"r"
modifierFlags:UIKeyModifierCommand
title:l10n_util::GetNSStringWithFixup(
IDS_IOS_ACCNAME_RELOAD)
action:^{
[weakDispatcher reload];
}],
]];
// Since cmd+left and cmd+right are valid system shortcuts when editing
// text, don't register those if text is being edited.
if (!editingText) {
[keyCommands addObjectsFromArray:@[
[UIKeyCommand cr_keyCommandWithInput:UIKeyInputLeftArrow
modifierFlags:UIKeyModifierCommand
title:l10n_util::GetNSStringWithFixup(
browseLeftDescriptionID)
action:browseLeft],
[UIKeyCommand cr_keyCommandWithInput:UIKeyInputRightArrow
modifierFlags:UIKeyModifierCommand
title:l10n_util::GetNSStringWithFixup(
browseRightDescriptionID)
action:browseRight],
]];
}
NSString* voiceSearchTitle = l10n_util::GetNSStringWithFixup(
IDS_IOS_VOICE_SEARCH_KEYBOARD_DISCOVERY_TITLE);
[keyCommands addObjectsFromArray:@[
[UIKeyCommand cr_keyCommandWithInput:@"y"
modifierFlags:UIKeyModifierCommand
title:l10n_util::GetNSStringWithFixup(
IDS_HISTORY_SHOW_HISTORY)
action:^{
[weakDispatcher showHistory];
}],
[UIKeyCommand
cr_keyCommandWithInput:@"."
modifierFlags:UIKeyModifierCommand | UIKeyModifierShift
title:voiceSearchTitle
action:^{
StartVoiceSearchCommand* command =
[[StartVoiceSearchCommand alloc]
initWithOriginView:nil];
[weakDispatcher startVoiceSearch:command];
}],
]];
}
// List the commands that don't appear in the HUD but are always present.
[keyCommands addObjectsFromArray:@[
[UIKeyCommand cr_keyCommandWithInput:UIKeyInputEscape
modifierFlags:Cr_UIKeyModifierNone
title:nil
action:^{
[weakDispatcher dismissModalDialogs];
}],
[UIKeyCommand cr_keyCommandWithInput:@"n"
modifierFlags:UIKeyModifierCommand
title:nil
action:newTab],
[UIKeyCommand cr_keyCommandWithInput:@","
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
[weakDispatcher
showSettingsFromViewController:
weakBaseViewController];
}],
]];
// List the commands that don't appear in the HUD and only appear when there
// is at least a tab.
if (hasTabs) {
[keyCommands addObjectsFromArray:@[
[UIKeyCommand cr_keyCommandWithInput:@"["
modifierFlags:UIKeyModifierCommand
title:nil
action:browseLeft],
[UIKeyCommand cr_keyCommandWithInput:@"]"
modifierFlags:UIKeyModifierCommand
title:nil
action:browseRight],
[UIKeyCommand cr_keyCommandWithInput:@"."
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
[weakDispatcher stopLoading];
}],
[UIKeyCommand cr_keyCommandWithInput:@"?"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
[weakDispatcher showHelpPage];
}],
[UIKeyCommand cr_keyCommandWithInput:@"1"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
focusTab(0);
}],
[UIKeyCommand cr_keyCommandWithInput:@"2"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
focusTab(1);
}],
[UIKeyCommand cr_keyCommandWithInput:@"3"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
focusTab(2);
}],
[UIKeyCommand cr_keyCommandWithInput:@"4"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
focusTab(3);
}],
[UIKeyCommand cr_keyCommandWithInput:@"5"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
focusTab(4);
}],
[UIKeyCommand cr_keyCommandWithInput:@"6"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
focusTab(5);
}],
[UIKeyCommand cr_keyCommandWithInput:@"7"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
focusTab(6);
}],
[UIKeyCommand cr_keyCommandWithInput:@"8"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
focusTab(7);
}],
[UIKeyCommand cr_keyCommandWithInput:@"9"
modifierFlags:UIKeyModifierCommand
title:nil
action:^{
focusTab([weakConsumer tabsCount] - 1);
}],
[UIKeyCommand
cr_keyCommandWithInput:UIKeyInputLeftArrow
modifierFlags:UIKeyModifierCommand | UIKeyModifierAlternate
title:nil
action:^{
[weakConsumer focusPreviousTab];
}],
[UIKeyCommand
cr_keyCommandWithInput:UIKeyInputRightArrow
modifierFlags:UIKeyModifierCommand | UIKeyModifierAlternate
title:nil
action:^{
[weakConsumer focusNextTab];
}],
[UIKeyCommand
cr_keyCommandWithInput:@"\t"
modifierFlags:UIKeyModifierControl | UIKeyModifierShift
title:nil
action:^{
[weakConsumer focusPreviousTab];
}],
[UIKeyCommand
cr_keyCommandWithInput:@"\t"
modifierFlags:UIKeyModifierControl
title:nil
action:^{
[weakConsumer focusNextTab];
}],
]];
}
return keyCommands;
}
@end