[iOS] Add Tab Grid context menu actions
Bug: 1196953
Change-Id: Ib80ebf889af6cf1c84e0b3b9ac7deb433226ad0c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2841164
Commit-Queue: Mike Dougherty <michaeldo@chromium.org>
Auto-Submit: Mike Dougherty <michaeldo@chromium.org>
Reviewed-by: Robert Kaplow <rkaplow@chromium.org>
Reviewed-by: Gauthier Ambard <gambard@chromium.org>
Reviewed-by: Sebastien Lalancette <seblalancette@chromium.org>
Cr-Commit-Position: refs/heads/master@{#874990}
GitOrigin-RevId: f32268180be17731109719dccab8b57488b5b07f
diff --git a/chrome/app/strings/ios_strings.grd b/chrome/app/strings/ios_strings.grd
index d7db9dd..4bf3982 100644
--- a/chrome/app/strings/ios_strings.grd
+++ b/chrome/app/strings/ios_strings.grd
@@ -606,6 +606,12 @@
<message name="IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST" desc="The iOS menu item for adding a link to the reading list.">
Add to Reading List
</message>
+ <message name="IDS_IOS_CONTENT_CONTEXT_ADDTOBOOKMARKS" desc="The iOS context menu item for adding the url of a tab to the bookmarks. [iOS only]">
+ Add to Bookmarks
+ </message>
+ <message name="IDS_IOS_CONTENT_CONTEXT_CLOSETAB" desc="The iOS context menu item for closing a tab. [iOS only]">
+ Close tab
+ </message>
<message name="IDS_IOS_CONTENT_CONTEXT_COPY" desc="The iOS menu item for copying a link's URL into the pasteboard. Shorter than the desktop version [iOS only]">
Copy Link URL
</message>
diff --git a/chrome/app/strings/ios_strings_grd/IDS_IOS_CONTENT_CONTEXT_ADDTOBOOKMARKS.png.sha1 b/chrome/app/strings/ios_strings_grd/IDS_IOS_CONTENT_CONTEXT_ADDTOBOOKMARKS.png.sha1
new file mode 100644
index 0000000..b084a92
--- /dev/null
+++ b/chrome/app/strings/ios_strings_grd/IDS_IOS_CONTENT_CONTEXT_ADDTOBOOKMARKS.png.sha1
@@ -0,0 +1 @@
+359688ea1a4a8748e36fddeef3866be608ba33b0
\ No newline at end of file
diff --git a/chrome/app/strings/ios_strings_grd/IDS_IOS_CONTENT_CONTEXT_CLOSETAB.png.sha1 b/chrome/app/strings/ios_strings_grd/IDS_IOS_CONTENT_CONTEXT_CLOSETAB.png.sha1
new file mode 100644
index 0000000..b084a92
--- /dev/null
+++ b/chrome/app/strings/ios_strings_grd/IDS_IOS_CONTENT_CONTEXT_CLOSETAB.png.sha1
@@ -0,0 +1 @@
+359688ea1a4a8748e36fddeef3866be608ba33b0
\ No newline at end of file
diff --git a/chrome/browser/ui/menu/BUILD.gn b/chrome/browser/ui/menu/BUILD.gn
index c4b87f2..8b88757 100644
--- a/chrome/browser/ui/menu/BUILD.gn
+++ b/chrome/browser/ui/menu/BUILD.gn
@@ -12,6 +12,8 @@
]
configs += [ "//build/config/compiler:enable_arc" ]
deps = [
+ "resources:bookmark",
+ "resources:close",
"resources:copy_link_url",
"resources:delete",
"resources:edit",
@@ -22,6 +24,7 @@
"resources:open_in_incognito",
"resources:open_in_new_tab",
"resources:open_new_window",
+ "resources:read_later",
"resources:remove",
"resources:share",
"//base",
@@ -51,6 +54,8 @@
sources = [ "action_factory_unittest.mm" ]
deps = [
":menu",
+ "resources:bookmark",
+ "resources:close",
"resources:copy_link_url",
"resources:delete",
"resources:edit",
@@ -61,6 +66,7 @@
"resources:open_in_incognito",
"resources:open_in_new_tab",
"resources:open_new_window",
+ "resources:read_later",
"resources:remove",
"resources:share",
"//base",
diff --git a/chrome/browser/ui/menu/action_factory.h b/chrome/browser/ui/menu/action_factory.h
index 7ae3d32..8f5e31e 100644
--- a/chrome/browser/ui/menu/action_factory.h
+++ b/chrome/browser/ui/menu/action_factory.h
@@ -110,6 +110,15 @@
// The action will invoke the |block| when executed.
- (UIAction*)actionToOpenJavascriptWithBlock:(ProceduralBlock)block;
+// Creates a UIAction instance for adding to the reading list.
+- (UIAction*)actionToAddToReadingListWithBlock:(ProceduralBlock)block;
+
+// Creates a UIAction instance for adding to bookmarks.
+- (UIAction*)actionToBookmarkWithBlock:(ProceduralBlock)block;
+
+// Creates a UIAction instance for closing a tab.
+- (UIAction*)actionToCloseTabWithBlock:(ProceduralBlock)block;
+
@end
#endif // IOS_CHROME_BROWSER_UI_MENU_ACTION_FACTORY_H_
diff --git a/chrome/browser/ui/menu/action_factory.mm b/chrome/browser/ui/menu/action_factory.mm
index d9dcedf..107f310 100644
--- a/chrome/browser/ui/menu/action_factory.mm
+++ b/chrome/browser/ui/menu/action_factory.mm
@@ -241,4 +241,30 @@
block:block];
}
+- (UIAction*)actionToAddToReadingListWithBlock:(ProceduralBlock)block {
+ return [self actionWithTitle:l10n_util::GetNSString(
+ IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST)
+ image:[UIImage imageNamed:@"read_later"]
+ type:MenuActionType::AddToReadingList
+ block:block];
+}
+
+- (UIAction*)actionToBookmarkWithBlock:(ProceduralBlock)block {
+ return [self actionWithTitle:l10n_util::GetNSString(
+ IDS_IOS_CONTENT_CONTEXT_ADDTOBOOKMARKS)
+ image:[UIImage imageNamed:@"bookmark"]
+ type:MenuActionType::AddToBookmarks
+ block:block];
+}
+
+- (UIAction*)actionToCloseTabWithBlock:(ProceduralBlock)block {
+ UIAction* action = [self
+ actionWithTitle:l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_CLOSETAB)
+ image:[UIImage imageNamed:@"close"]
+ type:MenuActionType::CloseTab
+ block:block];
+ action.attributes = UIMenuElementAttributesDestructive;
+ return action;
+}
+
@end
diff --git a/chrome/browser/ui/menu/action_factory_unittest.mm b/chrome/browser/ui/menu/action_factory_unittest.mm
index a8e6793..d8e2fa9 100644
--- a/chrome/browser/ui/menu/action_factory_unittest.mm
+++ b/chrome/browser/ui/menu/action_factory_unittest.mm
@@ -87,6 +87,44 @@
}
}
+// Tests that the bookmark action has the right title and image.
+TEST_F(ActionFactoryTest, BookmarkAction) {
+ if (@available(iOS 13.0, *)) {
+ ActionFactory* factory =
+ [[ActionFactory alloc] initWithBrowser:test_browser_.get()
+ scenario:kTestMenuScenario];
+
+ UIImage* expectedImage = [UIImage imageNamed:@"bookmark"];
+ NSString* expectedTitle =
+ l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_ADDTOBOOKMARKS);
+
+ UIAction* action = [factory actionToBookmarkWithBlock:^{
+ }];
+
+ EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
+ EXPECT_EQ(expectedImage, action.image);
+ }
+}
+
+// Tests that the close action has the right title and image.
+TEST_F(ActionFactoryTest, CloseAction) {
+ if (@available(iOS 13.0, *)) {
+ ActionFactory* factory =
+ [[ActionFactory alloc] initWithBrowser:test_browser_.get()
+ scenario:kTestMenuScenario];
+
+ UIImage* expectedImage = [UIImage imageNamed:@"close"];
+ NSString* expectedTitle =
+ l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_CLOSETAB);
+
+ UIAction* action = [factory actionToCloseTabWithBlock:^{
+ }];
+
+ EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
+ EXPECT_EQ(expectedImage, action.image);
+ }
+}
+
// Tests that the copy action has the right title and image.
TEST_F(ActionFactoryTest, CopyAction) {
if (@available(iOS 13.0, *)) {
@@ -218,6 +256,25 @@
}
}
+// Tests that the read later action has the right title and image.
+TEST_F(ActionFactoryTest, ReadLaterAction) {
+ if (@available(iOS 13.0, *)) {
+ ActionFactory* factory =
+ [[ActionFactory alloc] initWithBrowser:test_browser_.get()
+ scenario:kTestMenuScenario];
+
+ UIImage* expectedImage = [UIImage imageNamed:@"read_later"];
+ NSString* expectedTitle =
+ l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST);
+
+ UIAction* action = [factory actionToAddToReadingListWithBlock:^{
+ }];
+
+ EXPECT_TRUE([expectedTitle isEqualToString:action.title]);
+ EXPECT_EQ(expectedImage, action.image);
+ }
+}
+
// Tests that the remove action has the right title and image.
TEST_F(ActionFactoryTest, RemoveAction) {
if (@available(iOS 13.0, *)) {
diff --git a/chrome/browser/ui/menu/menu_action_type.h b/chrome/browser/ui/menu/menu_action_type.h
index 4554fcf..60fa598 100644
--- a/chrome/browser/ui/menu/menu_action_type.h
+++ b/chrome/browser/ui/menu/menu_action_type.h
@@ -24,7 +24,10 @@
Unread = 12,
ViewOffline = 13,
OpenJavascript = 14,
- kMaxValue = OpenJavascript
+ AddToReadingList = 15,
+ AddToBookmarks = 16,
+ CloseTab = 17,
+ kMaxValue = CloseTab
};
#endif // IOS_CHROME_BROWSER_UI_MENU_MENU_ACTION_TYPE_H_
diff --git a/chrome/browser/ui/menu/menu_histograms.h b/chrome/browser/ui/menu/menu_histograms.h
index 9da9bc3..8bf62e9 100644
--- a/chrome/browser/ui/menu/menu_histograms.h
+++ b/chrome/browser/ui/menu/menu_histograms.h
@@ -19,7 +19,8 @@
kContextMenuImage = 7,
kContextMenuImageLink = 8,
kContextMenuLink = 9,
- kMaxValue = kContextMenuLink,
+ kTabGridEntry = 10,
+ kMaxValue = kTabGridEntry,
};
// Records a menu shown histogram metric for the |scenario|.
diff --git a/chrome/browser/ui/menu/menu_histograms.mm b/chrome/browser/ui/menu/menu_histograms.mm
index fc3a7c5..d6cbccd 100644
--- a/chrome/browser/ui/menu/menu_histograms.mm
+++ b/chrome/browser/ui/menu/menu_histograms.mm
@@ -29,6 +29,7 @@
"Mobile.ContextMenu.HistoryEntry.Actions";
const char kMostVisitedEntryActionsHistogram[] =
"Mobile.ContextMenu.MostVisitedEntry.Actions";
+const char kTabGridActionsHistogram[] = "Mobile.ContextMenu.TabGrid.Actions";
const char KContextMenuImageActionsHistogram[] =
"Mobile.ContextMenu.WebImage.Actions";
const char KContextMenuImageLinkActionsHistogram[] =
@@ -63,5 +64,7 @@
return KContextMenuImageLinkActionsHistogram;
case MenuScenario::kContextMenuLink:
return KContextMenuLinkActionsHistogram;
+ case MenuScenario::kTabGridEntry:
+ return kTabGridActionsHistogram;
}
}
diff --git a/chrome/browser/ui/menu/resources/BUILD.gn b/chrome/browser/ui/menu/resources/BUILD.gn
index 4c8e025..f13283b 100644
--- a/chrome/browser/ui/menu/resources/BUILD.gn
+++ b/chrome/browser/ui/menu/resources/BUILD.gn
@@ -4,6 +4,22 @@
import("//build/config/ios/asset_catalog.gni")
+imageset("bookmark") {
+ sources = [
+ "bookmark.imageset/Contents.json",
+ "bookmark.imageset/bookmark@2x.png",
+ "bookmark.imageset/bookmark@3x.png",
+ ]
+}
+
+imageset("close") {
+ sources = [
+ "close.imageset/Contents.json",
+ "close.imageset/close@2x.png",
+ "close.imageset/close@3x.png",
+ ]
+}
+
imageset("copy_link_url") {
sources = [
"copy_link_url.imageset/Contents.json",
@@ -52,6 +68,14 @@
]
}
+imageset("read_later") {
+ sources = [
+ "read_later.imageset/Contents.json",
+ "read_later.imageset/read_later@2x.png",
+ "read_later.imageset/read_later@3x.png",
+ ]
+}
+
imageset("remove") {
sources = [
"remove.imageset/Contents.json",
diff --git a/chrome/browser/ui/menu/resources/bookmark.imageset/Contents.json b/chrome/browser/ui/menu/resources/bookmark.imageset/Contents.json
new file mode 100644
index 0000000..8c7ee47
--- /dev/null
+++ b/chrome/browser/ui/menu/resources/bookmark.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images": [
+ {
+ "idiom": "universal",
+ "filename": "bookmark@2x.png",
+ "scale": "2x"
+ },
+ {
+ "idiom": "universal",
+ "filename": "bookmark@3x.png",
+ "scale": "3x"
+ }
+ ],
+ "info": {
+ "author": "xcode",
+ "version": 1
+ },
+ "properties": {
+ "template-rendering-intent": "template"
+ }
+}
diff --git a/chrome/browser/ui/menu/resources/bookmark.imageset/bookmark@2x.png b/chrome/browser/ui/menu/resources/bookmark.imageset/bookmark@2x.png
new file mode 100644
index 0000000..3b3a248
--- /dev/null
+++ b/chrome/browser/ui/menu/resources/bookmark.imageset/bookmark@2x.png
Binary files differ
diff --git a/chrome/browser/ui/menu/resources/bookmark.imageset/bookmark@3x.png b/chrome/browser/ui/menu/resources/bookmark.imageset/bookmark@3x.png
new file mode 100644
index 0000000..4284bac
--- /dev/null
+++ b/chrome/browser/ui/menu/resources/bookmark.imageset/bookmark@3x.png
Binary files differ
diff --git a/chrome/browser/ui/menu/resources/close.imageset/Contents.json b/chrome/browser/ui/menu/resources/close.imageset/Contents.json
new file mode 100644
index 0000000..2a18c8b
--- /dev/null
+++ b/chrome/browser/ui/menu/resources/close.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images": [
+ {
+ "idiom": "universal",
+ "filename": "close@2x.png",
+ "scale": "2x"
+ },
+ {
+ "idiom": "universal",
+ "filename": "close@3x.png",
+ "scale": "3x"
+ }
+ ],
+ "info": {
+ "author": "xcode",
+ "version": 1
+ },
+ "properties": {
+ "template-rendering-intent": "template"
+ }
+}
diff --git a/chrome/browser/ui/menu/resources/close.imageset/close@2x.png b/chrome/browser/ui/menu/resources/close.imageset/close@2x.png
new file mode 100644
index 0000000..a9790d9
--- /dev/null
+++ b/chrome/browser/ui/menu/resources/close.imageset/close@2x.png
Binary files differ
diff --git a/chrome/browser/ui/menu/resources/close.imageset/close@3x.png b/chrome/browser/ui/menu/resources/close.imageset/close@3x.png
new file mode 100644
index 0000000..ab4acb6
--- /dev/null
+++ b/chrome/browser/ui/menu/resources/close.imageset/close@3x.png
Binary files differ
diff --git a/chrome/browser/ui/menu/resources/read_later.imageset/Contents.json b/chrome/browser/ui/menu/resources/read_later.imageset/Contents.json
new file mode 100644
index 0000000..a54f5f1
--- /dev/null
+++ b/chrome/browser/ui/menu/resources/read_later.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images": [
+ {
+ "idiom": "universal",
+ "filename": "read_later@2x.png",
+ "scale": "2x"
+ },
+ {
+ "idiom": "universal",
+ "filename": "read_later@3x.png",
+ "scale": "3x"
+ }
+ ],
+ "info": {
+ "author": "xcode",
+ "version": 1
+ },
+ "properties": {
+ "template-rendering-intent": "template"
+ }
+}
diff --git a/chrome/browser/ui/menu/resources/read_later.imageset/read_later@2x.png b/chrome/browser/ui/menu/resources/read_later.imageset/read_later@2x.png
new file mode 100644
index 0000000..2cbd943
--- /dev/null
+++ b/chrome/browser/ui/menu/resources/read_later.imageset/read_later@2x.png
Binary files differ
diff --git a/chrome/browser/ui/menu/resources/read_later.imageset/read_later@3x.png b/chrome/browser/ui/menu/resources/read_later.imageset/read_later@3x.png
new file mode 100644
index 0000000..bba2a7e
--- /dev/null
+++ b/chrome/browser/ui/menu/resources/read_later.imageset/read_later@3x.png
Binary files differ