Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Side by Side Diff: chrome/browser/tab_contents/render_view_context_menu.cc

Issue 6253017: Pepper/Flapper: First pass at context menu implementation. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: make brettw happier Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/renderer_host/render_view_host.cc ('k') | chrome/common/render_messages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <algorithm> 5 #include <algorithm>
6 #include <set> 6 #include <set>
7 7
8 #include "chrome/browser/tab_contents/render_view_context_menu.h" 8 #include "chrome/browser/tab_contents/render_view_context_menu.h"
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 #include "net/url_request/url_request.h" 53 #include "net/url_request/url_request.h"
54 #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h" 54 #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h"
55 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerAction. h" 55 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerAction. h"
56 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextDirection.h" 56 #include "third_party/WebKit/Source/WebKit/chromium/public/WebTextDirection.h"
57 #include "ui/base/l10n/l10n_util.h" 57 #include "ui/base/l10n/l10n_util.h"
58 #include "webkit/glue/webmenuitem.h" 58 #include "webkit/glue/webmenuitem.h"
59 59
60 using WebKit::WebContextMenuData; 60 using WebKit::WebContextMenuData;
61 using WebKit::WebMediaPlayerAction; 61 using WebKit::WebMediaPlayerAction;
62 62
63 namespace {
64
65 bool IsCustomItemEnabled(const std::vector<WebMenuItem>& items, int id) {
66 DCHECK(id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
67 id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST);
68 for (size_t i = 0; i < items.size(); ++i) {
69 int action_id = IDC_CONTENT_CONTEXT_CUSTOM_FIRST + items[i].action;
70 if (action_id == id)
71 return items[i].enabled;
72 if (items[i].type == WebMenuItem::SUBMENU) {
73 if (IsCustomItemEnabled(items[i].submenu, id))
74 return true;
75 }
76 }
77 return false;
78 }
79
80 bool IsCustomItemChecked(const std::vector<WebMenuItem>& items, int id) {
81 DCHECK(id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
82 id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST);
83 for (size_t i = 0; i < items.size(); ++i) {
84 int action_id = IDC_CONTENT_CONTEXT_CUSTOM_FIRST + items[i].action;
85 if (action_id == id)
86 return items[i].checked;
87 if (items[i].type == WebMenuItem::SUBMENU) {
88 if (IsCustomItemChecked(items[i].submenu, id))
89 return true;
90 }
91 }
92 return false;
93 }
94
95 const size_t kMaxCustomMenuDepth = 5;
96 const size_t kMaxCustomMenuTotalItems = 1000;
97
98 void AddCustomItemsToMenu(const std::vector<WebMenuItem>& items,
99 size_t depth,
100 size_t* total_items,
101 ui::SimpleMenuModel::Delegate* delegate,
102 ui::SimpleMenuModel* menu_model) {
103 if (depth > kMaxCustomMenuDepth) {
104 LOG(ERROR) << "Custom menu too deeply nested.";
105 return;
106 }
107 for (size_t i = 0; i < items.size(); ++i) {
108 if (IDC_CONTENT_CONTEXT_CUSTOM_FIRST + items[i].action >=
109 IDC_CONTENT_CONTEXT_CUSTOM_LAST) {
110 LOG(ERROR) << "Custom menu action value too big.";
111 return;
112 }
113 if (*total_items >= kMaxCustomMenuTotalItems) {
114 LOG(ERROR) << "Custom menu too large (too many items).";
115 return;
116 }
117 (*total_items)++;
118 switch (items[i].type) {
119 case WebMenuItem::OPTION:
120 menu_model->AddItem(
121 items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
122 items[i].label);
123 break;
124 case WebMenuItem::CHECKABLE_OPTION:
125 menu_model->AddCheckItem(
126 items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
127 items[i].label);
128 break;
129 case WebMenuItem::GROUP:
130 // TODO(viettrungluu): I don't know what this is supposed to do.
131 NOTREACHED();
132 break;
133 case WebMenuItem::SEPARATOR:
134 menu_model->AddSeparator();
135 break;
136 case WebMenuItem::SUBMENU: {
137 ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate);
138 AddCustomItemsToMenu(items[i].submenu, depth + 1, total_items, delegate,
139 submenu);
140 menu_model->AddSubMenu(
141 items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
142 items[i].label,
143 submenu);
144 break;
145 }
146 default:
147 NOTREACHED();
148 break;
149 }
150 }
151 }
152
153 } // namespace
154
63 // static 155 // static
64 const size_t RenderViewContextMenu::kMaxExtensionItemTitleLength = 75; 156 const size_t RenderViewContextMenu::kMaxExtensionItemTitleLength = 75;
65 // static 157 // static
66 const size_t RenderViewContextMenu::kMaxSelectionTextLength = 50; 158 const size_t RenderViewContextMenu::kMaxSelectionTextLength = 50;
67 159
68 // static 160 // static
69 bool RenderViewContextMenu::IsDevToolsURL(const GURL& url) { 161 bool RenderViewContextMenu::IsDevToolsURL(const GURL& url) {
70 return url.SchemeIs(chrome::kChromeDevToolsScheme) && 162 return url.SchemeIs(chrome::kChromeDevToolsScheme) &&
71 url.host() == chrome::kChromeUIDevToolsHost; 163 url.host() == chrome::kChromeUIDevToolsHost;
72 } 164 }
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 UMA_HISTOGRAM_TIMES("Extensions.ContextMenus_BuildTime", 443 UMA_HISTOGRAM_TIMES("Extensions.ContextMenus_BuildTime",
352 base::TimeTicks::Now() - begin); 444 base::TimeTicks::Now() - begin);
353 UMA_HISTOGRAM_COUNTS("Extensions.ContextMenus_ItemCount", index); 445 UMA_HISTOGRAM_COUNTS("Extensions.ContextMenus_ItemCount", index);
354 } 446 }
355 447
356 void RenderViewContextMenu::InitMenu() { 448 void RenderViewContextMenu::InitMenu() {
357 bool has_link = !params_.link_url.is_empty(); 449 bool has_link = !params_.link_url.is_empty();
358 bool has_selection = !params_.selection_text.empty(); 450 bool has_selection = !params_.selection_text.empty();
359 451
360 if (AppendCustomItems()) { 452 if (AppendCustomItems()) {
361 AppendDeveloperItems(); 453 // Don't add items for Pepper menu.
454 if (!params_.custom_context.is_pepper_menu)
455 AppendDeveloperItems();
362 return; 456 return;
363 } 457 }
364 458
365 // When no special node or text is selected and selection has no link, 459 // When no special node or text is selected and selection has no link,
366 // show page items. 460 // show page items.
367 bool is_devtools = false; 461 bool is_devtools = false;
368 if (params_.media_type == WebContextMenuData::MediaTypeNone && 462 if (params_.media_type == WebContextMenuData::MediaTypeNone &&
369 !has_link && 463 !has_link &&
370 !params_.is_editable && 464 !params_.is_editable &&
371 !has_selection) { 465 !has_selection) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 511
418 AppendDeveloperItems(); 512 AppendDeveloperItems();
419 } 513 }
420 514
421 void RenderViewContextMenu::LookUpInDictionary() { 515 void RenderViewContextMenu::LookUpInDictionary() {
422 // Used only in the Mac port. 516 // Used only in the Mac port.
423 NOTREACHED(); 517 NOTREACHED();
424 } 518 }
425 519
426 bool RenderViewContextMenu::AppendCustomItems() { 520 bool RenderViewContextMenu::AppendCustomItems() {
427 std::vector<WebMenuItem>& custom_items = params_.custom_items; 521 size_t total_items = 0;
428 for (size_t i = 0; i < custom_items.size(); ++i) { 522 AddCustomItemsToMenu(params_.custom_items, 0, &total_items, this,
429 DCHECK(IDC_CONTENT_CONTEXT_CUSTOM_FIRST + custom_items[i].action < 523 &menu_model_);
430 IDC_CONTENT_CONTEXT_CUSTOM_LAST); 524 return total_items > 0;
431 if (custom_items[i].type == WebMenuItem::SEPARATOR) {
432 menu_model_.AddSeparator();
433 } else if (custom_items[i].type == WebMenuItem::CHECKABLE_OPTION) {
434 menu_model_.AddCheckItem(
435 custom_items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
436 custom_items[i].label);
437 } else {
438 menu_model_.AddItem(
439 custom_items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
440 custom_items[i].label);
441 }
442 }
443 return custom_items.size() > 0;
444 } 525 }
445 526
446 void RenderViewContextMenu::AppendDeveloperItems() { 527 void RenderViewContextMenu::AppendDeveloperItems() {
447 if (g_browser_process->have_inspector_files()) { 528 if (g_browser_process->have_inspector_files()) {
448 // In the DevTools popup menu, "developer items" is normally the only 529 // In the DevTools popup menu, "developer items" is normally the only
449 // section, so omit the separator there. 530 // section, so omit the separator there.
450 if (menu_model_.GetItemCount() > 0) 531 if (menu_model_.GetItemCount() > 0)
451 menu_model_.AddSeparator(); 532 menu_model_.AddSeparator();
452 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_INSPECTELEMENT, 533 menu_model_.AddItemWithStringId(IDC_CONTENT_CONTEXT_INSPECTELEMENT,
453 IDS_CONTENT_CONTEXT_INSPECTELEMENT); 534 IDS_CONTENT_CONTEXT_INSPECTELEMENT);
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after
766 CONTENT_RESTRICTION_SAVE)) { 847 CONTENT_RESTRICTION_SAVE)) {
767 return false; 848 return false;
768 } 849 }
769 850
770 // Allow Spell Check language items on sub menu for text area context menu. 851 // Allow Spell Check language items on sub menu for text area context menu.
771 if ((id >= IDC_SPELLCHECK_LANGUAGES_FIRST) && 852 if ((id >= IDC_SPELLCHECK_LANGUAGES_FIRST) &&
772 (id < IDC_SPELLCHECK_LANGUAGES_LAST)) { 853 (id < IDC_SPELLCHECK_LANGUAGES_LAST)) {
773 return profile_->GetPrefs()->GetBoolean(prefs::kEnableSpellCheck); 854 return profile_->GetPrefs()->GetBoolean(prefs::kEnableSpellCheck);
774 } 855 }
775 856
776 // Process custom actions range. 857 // Custom items.
777 if ((id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST) &&
778 (id < IDC_CONTENT_CONTEXT_CUSTOM_LAST)) {
779 unsigned action = id - IDC_CONTENT_CONTEXT_CUSTOM_FIRST;
780 for (size_t i = 0; i < params_.custom_items.size(); ++i) {
781 if (params_.custom_items[i].action == action)
782 return params_.custom_items[i].enabled;
783 }
784 NOTREACHED();
785 return false;
786 }
787
788 // Custom WebKit items.
789 if (id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST && 858 if (id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
790 id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST) { 859 id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST) {
791 const std::vector<WebMenuItem>& custom_items = params_.custom_items; 860 return IsCustomItemEnabled(params_.custom_items, id);
792 for (size_t i = 0; i < custom_items.size(); ++i) {
793 int action_id = IDC_CONTENT_CONTEXT_CUSTOM_FIRST + custom_items[i].action;
794 if (action_id == id)
795 return custom_items[i].enabled;
796 }
797 return true;
798 } 861 }
799 862
800 // Extension items. 863 // Extension items.
801 if (id >= IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST && 864 if (id >= IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST &&
802 id <= IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST) { 865 id <= IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST) {
803 // In the future we may add APIs for extensions to disable items, but for 866 // In the future we may add APIs for extensions to disable items, but for
804 // now all items are implicitly enabled. 867 // now all items are implicitly enabled.
805 return true; 868 return true;
806 } 869 }
807 870
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 if (id == IDC_CONTENT_CONTEXT_LOOP) { 1076 if (id == IDC_CONTENT_CONTEXT_LOOP) {
1014 return (params_.media_flags & 1077 return (params_.media_flags &
1015 WebContextMenuData::MediaLoop) != 0; 1078 WebContextMenuData::MediaLoop) != 0;
1016 } 1079 }
1017 1080
1018 if (id == IDC_CONTENT_CONTEXT_CONTROLS) { 1081 if (id == IDC_CONTENT_CONTEXT_CONTROLS) {
1019 return (params_.media_flags & 1082 return (params_.media_flags &
1020 WebContextMenuData::MediaControls) != 0; 1083 WebContextMenuData::MediaControls) != 0;
1021 } 1084 }
1022 1085
1023 // Custom WebKit items. 1086 // Custom items.
1024 if (id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST && 1087 if (id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
1025 id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST) { 1088 id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST) {
1026 const std::vector<WebMenuItem>& custom_items = params_.custom_items; 1089 return IsCustomItemChecked(params_.custom_items, id);
1027 for (size_t i = 0; i < custom_items.size(); ++i) {
1028 int action_id = IDC_CONTENT_CONTEXT_CUSTOM_FIRST + custom_items[i].action;
1029 if (action_id == id)
1030 return custom_items[i].checked;
1031 }
1032 return false;
1033 } 1090 }
1034 1091
1035 // Extension items. 1092 // Extension items.
1036 if (id >= IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST && 1093 if (id >= IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST &&
1037 id <= IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST) { 1094 id <= IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST) {
1038 ExtensionMenuItem* item = GetExtensionMenuItem(id); 1095 ExtensionMenuItem* item = GetExtensionMenuItem(id);
1039 if (item) 1096 if (item)
1040 return item->checked(); 1097 return item->checked();
1041 else 1098 else
1042 return false; 1099 return false;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 if (language_number < languages.size()) { 1140 if (language_number < languages.size()) {
1084 StringPrefMember dictionary_language; 1141 StringPrefMember dictionary_language;
1085 dictionary_language.Init(prefs::kSpellCheckDictionary, 1142 dictionary_language.Init(prefs::kSpellCheckDictionary,
1086 profile_->GetPrefs(), NULL); 1143 profile_->GetPrefs(), NULL);
1087 dictionary_language.SetValue(languages[language_number]); 1144 dictionary_language.SetValue(languages[language_number]);
1088 } 1145 }
1089 return; 1146 return;
1090 } 1147 }
1091 1148
1092 // Process custom actions range. 1149 // Process custom actions range.
1093 if ((id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST) && 1150 if (id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
1094 (id < IDC_CONTENT_CONTEXT_CUSTOM_LAST)) { 1151 id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST) {
1095 unsigned action = id - IDC_CONTENT_CONTEXT_CUSTOM_FIRST; 1152 unsigned action = id - IDC_CONTENT_CONTEXT_CUSTOM_FIRST;
1096 source_tab_contents_->render_view_host()-> 1153 source_tab_contents_->render_view_host()->PerformCustomContextMenuAction(
1097 PerformCustomContextMenuAction(action); 1154 params_.custom_context, action);
1098 return; 1155 return;
1099 } 1156 }
1100 1157
1101 // Process extension menu items. 1158 // Process extension menu items.
1102 if (id >= IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST && 1159 if (id >= IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST &&
1103 id <= IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST) { 1160 id <= IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST) {
1104 ExtensionMenuManager* manager = 1161 ExtensionMenuManager* manager =
1105 profile_->GetExtensionService()->menu_manager(); 1162 profile_->GetExtensionService()->menu_manager();
1106 std::map<int, ExtensionMenuItem::Id>::const_iterator i = 1163 std::map<int, ExtensionMenuItem::Id>::const_iterator i =
1107 extension_item_map_.find(id); 1164 extension_item_map_.find(id);
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 break; 1449 break;
1393 #endif // OS_MACOSX 1450 #endif // OS_MACOSX
1394 1451
1395 default: 1452 default:
1396 NOTREACHED(); 1453 NOTREACHED();
1397 break; 1454 break;
1398 } 1455 }
1399 } 1456 }
1400 1457
1401 void RenderViewContextMenu::MenuClosed() { 1458 void RenderViewContextMenu::MenuClosed() {
1402 source_tab_contents_->render_view_host()->ContextMenuClosed(); 1459 source_tab_contents_->render_view_host()->ContextMenuClosed(
1460 params_.custom_context);
1403 } 1461 }
1404 1462
1405 bool RenderViewContextMenu::IsDevCommandEnabled(int id) const { 1463 bool RenderViewContextMenu::IsDevCommandEnabled(int id) const {
1406 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 1464 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1407 if (command_line.HasSwitch(switches::kAlwaysEnableDevTools)) 1465 if (command_line.HasSwitch(switches::kAlwaysEnableDevTools))
1408 return true; 1466 return true;
1409 1467
1410 NavigationEntry *active_entry = 1468 NavigationEntry *active_entry =
1411 source_tab_contents_->controller().GetActiveEntry(); 1469 source_tab_contents_->controller().GetActiveEntry();
1412 if (!active_entry) 1470 if (!active_entry)
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1472 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages), 1530 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages),
1473 g_browser_process->clipboard()); 1531 g_browser_process->clipboard());
1474 } 1532 }
1475 1533
1476 void RenderViewContextMenu::MediaPlayerActionAt( 1534 void RenderViewContextMenu::MediaPlayerActionAt(
1477 const gfx::Point& location, 1535 const gfx::Point& location,
1478 const WebMediaPlayerAction& action) { 1536 const WebMediaPlayerAction& action) {
1479 source_tab_contents_->render_view_host()->MediaPlayerActionAt( 1537 source_tab_contents_->render_view_host()->MediaPlayerActionAt(
1480 location, action); 1538 location, action);
1481 } 1539 }
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/render_view_host.cc ('k') | chrome/common/render_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698