diff options
author | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-31 21:41:08 +0000 |
---|---|---|
committer | viettrungluu@chromium.org <viettrungluu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-31 21:41:08 +0000 |
commit | b29aa74b75d57e1dc78bb151f1b7b2153d13ae3f (patch) | |
tree | c06576af8874b736101b045e4e1d75cfed7ba897 /chrome/browser/tab_contents | |
parent | 314e594492cfd5c23225763cb46c5cd190b5551c (diff) | |
download | chromium_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.cc | 160 |
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 { |