summaryrefslogtreecommitdiffstats
path: root/chrome/browser/tab_contents
diff options
context:
space:
mode:
authorviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-31 21:41:08 +0000
committerviettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-31 21:41:08 +0000
commitb29aa74b75d57e1dc78bb151f1b7b2153d13ae3f (patch)
treec06576af8874b736101b045e4e1d75cfed7ba897 /chrome/browser/tab_contents
parent314e594492cfd5c23225763cb46c5cd190b5551c (diff)
downloadchromium_src-b29aa74b75d57e1dc78bb151f1b7b2153d13ae3f.zip
chromium_src-b29aa74b75d57e1dc78bb151f1b7b2153d13ae3f.tar.gz
chromium_src-b29aa74b75d57e1dc78bb151f1b7b2153d13ae3f.tar.bz2
Pepper/Flapper: First pass at context menu implementation.
This meets the needs of Flapper. We may want to generalize/restrict/modify the API for inclusion into PPAPI, but hopefully this lays a foundation. BUG=none TEST=Flapper context menus work (with the right version of Flapper) Review URL: http://codereview.chromium.org/6253017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73193 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/tab_contents')
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.cc160
1 files changed, 109 insertions, 51 deletions
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc
index 0339888..2bd6ff1 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu.cc
@@ -60,6 +60,98 @@
using WebKit::WebContextMenuData;
using WebKit::WebMediaPlayerAction;
+namespace {
+
+bool IsCustomItemEnabled(const std::vector<WebMenuItem>& items, int id) {
+ DCHECK(id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
+ id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST);
+ for (size_t i = 0; i < items.size(); ++i) {
+ int action_id = IDC_CONTENT_CONTEXT_CUSTOM_FIRST + items[i].action;
+ if (action_id == id)
+ return items[i].enabled;
+ if (items[i].type == WebMenuItem::SUBMENU) {
+ if (IsCustomItemEnabled(items[i].submenu, id))
+ return true;
+ }
+ }
+ return false;
+}
+
+bool IsCustomItemChecked(const std::vector<WebMenuItem>& items, int id) {
+ DCHECK(id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
+ id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST);
+ for (size_t i = 0; i < items.size(); ++i) {
+ int action_id = IDC_CONTENT_CONTEXT_CUSTOM_FIRST + items[i].action;
+ if (action_id == id)
+ return items[i].checked;
+ if (items[i].type == WebMenuItem::SUBMENU) {
+ if (IsCustomItemChecked(items[i].submenu, id))
+ return true;
+ }
+ }
+ return false;
+}
+
+const size_t kMaxCustomMenuDepth = 5;
+const size_t kMaxCustomMenuTotalItems = 1000;
+
+void AddCustomItemsToMenu(const std::vector<WebMenuItem>& items,
+ size_t depth,
+ size_t* total_items,
+ ui::SimpleMenuModel::Delegate* delegate,
+ ui::SimpleMenuModel* menu_model) {
+ if (depth > kMaxCustomMenuDepth) {
+ LOG(ERROR) << "Custom menu too deeply nested.";
+ return;
+ }
+ for (size_t i = 0; i < items.size(); ++i) {
+ if (IDC_CONTENT_CONTEXT_CUSTOM_FIRST + items[i].action >=
+ IDC_CONTENT_CONTEXT_CUSTOM_LAST) {
+ LOG(ERROR) << "Custom menu action value too big.";
+ return;
+ }
+ if (*total_items >= kMaxCustomMenuTotalItems) {
+ LOG(ERROR) << "Custom menu too large (too many items).";
+ return;
+ }
+ (*total_items)++;
+ switch (items[i].type) {
+ case WebMenuItem::OPTION:
+ menu_model->AddItem(
+ items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
+ items[i].label);
+ break;
+ case WebMenuItem::CHECKABLE_OPTION:
+ menu_model->AddCheckItem(
+ items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
+ items[i].label);
+ break;
+ case WebMenuItem::GROUP:
+ // TODO(viettrungluu): I don't know what this is supposed to do.
+ NOTREACHED();
+ break;
+ case WebMenuItem::SEPARATOR:
+ menu_model->AddSeparator();
+ break;
+ case WebMenuItem::SUBMENU: {
+ ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate);
+ AddCustomItemsToMenu(items[i].submenu, depth + 1, total_items, delegate,
+ submenu);
+ menu_model->AddSubMenu(
+ items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
+ items[i].label,
+ submenu);
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
+ }
+ }
+}
+
+} // namespace
+
// static
const size_t RenderViewContextMenu::kMaxExtensionItemTitleLength = 75;
// static
@@ -358,7 +450,9 @@ void RenderViewContextMenu::InitMenu() {
bool has_selection = !params_.selection_text.empty();
if (AppendCustomItems()) {
- AppendDeveloperItems();
+ // Don't add items for Pepper menu.
+ if (!params_.custom_context.is_pepper_menu)
+ AppendDeveloperItems();
return;
}
@@ -424,23 +518,10 @@ void RenderViewContextMenu::LookUpInDictionary() {
}
bool RenderViewContextMenu::AppendCustomItems() {
- std::vector<WebMenuItem>& custom_items = params_.custom_items;
- for (size_t i = 0; i < custom_items.size(); ++i) {
- DCHECK(IDC_CONTENT_CONTEXT_CUSTOM_FIRST + custom_items[i].action <
- IDC_CONTENT_CONTEXT_CUSTOM_LAST);
- if (custom_items[i].type == WebMenuItem::SEPARATOR) {
- menu_model_.AddSeparator();
- } else if (custom_items[i].type == WebMenuItem::CHECKABLE_OPTION) {
- menu_model_.AddCheckItem(
- custom_items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
- custom_items[i].label);
- } else {
- menu_model_.AddItem(
- custom_items[i].action + IDC_CONTENT_CONTEXT_CUSTOM_FIRST,
- custom_items[i].label);
- }
- }
- return custom_items.size() > 0;
+ size_t total_items = 0;
+ AddCustomItemsToMenu(params_.custom_items, 0, &total_items, this,
+ &menu_model_);
+ return total_items > 0;
}
void RenderViewContextMenu::AppendDeveloperItems() {
@@ -773,28 +854,10 @@ bool RenderViewContextMenu::IsCommandIdEnabled(int id) const {
return profile_->GetPrefs()->GetBoolean(prefs::kEnableSpellCheck);
}
- // Process custom actions range.
- if ((id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST) &&
- (id < IDC_CONTENT_CONTEXT_CUSTOM_LAST)) {
- unsigned action = id - IDC_CONTENT_CONTEXT_CUSTOM_FIRST;
- for (size_t i = 0; i < params_.custom_items.size(); ++i) {
- if (params_.custom_items[i].action == action)
- return params_.custom_items[i].enabled;
- }
- NOTREACHED();
- return false;
- }
-
- // Custom WebKit items.
+ // Custom items.
if (id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST) {
- const std::vector<WebMenuItem>& custom_items = params_.custom_items;
- for (size_t i = 0; i < custom_items.size(); ++i) {
- int action_id = IDC_CONTENT_CONTEXT_CUSTOM_FIRST + custom_items[i].action;
- if (action_id == id)
- return custom_items[i].enabled;
- }
- return true;
+ return IsCustomItemEnabled(params_.custom_items, id);
}
// Extension items.
@@ -1020,16 +1083,10 @@ bool RenderViewContextMenu::IsCommandIdChecked(int id) const {
WebContextMenuData::MediaControls) != 0;
}
- // Custom WebKit items.
+ // Custom items.
if (id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST) {
- const std::vector<WebMenuItem>& custom_items = params_.custom_items;
- for (size_t i = 0; i < custom_items.size(); ++i) {
- int action_id = IDC_CONTENT_CONTEXT_CUSTOM_FIRST + custom_items[i].action;
- if (action_id == id)
- return custom_items[i].checked;
- }
- return false;
+ return IsCustomItemChecked(params_.custom_items, id);
}
// Extension items.
@@ -1090,11 +1147,11 @@ void RenderViewContextMenu::ExecuteCommand(int id) {
}
// Process custom actions range.
- if ((id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST) &&
- (id < IDC_CONTENT_CONTEXT_CUSTOM_LAST)) {
+ if (id >= IDC_CONTENT_CONTEXT_CUSTOM_FIRST &&
+ id <= IDC_CONTENT_CONTEXT_CUSTOM_LAST) {
unsigned action = id - IDC_CONTENT_CONTEXT_CUSTOM_FIRST;
- source_tab_contents_->render_view_host()->
- PerformCustomContextMenuAction(action);
+ source_tab_contents_->render_view_host()->PerformCustomContextMenuAction(
+ params_.custom_context, action);
return;
}
@@ -1399,7 +1456,8 @@ void RenderViewContextMenu::ExecuteCommand(int id) {
}
void RenderViewContextMenu::MenuClosed() {
- source_tab_contents_->render_view_host()->ContextMenuClosed();
+ source_tab_contents_->render_view_host()->ContextMenuClosed(
+ params_.custom_context);
}
bool RenderViewContextMenu::IsDevCommandEnabled(int id) const {