diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-04 13:59:30 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-04 13:59:30 +0000 |
commit | f5d5cd0d6f5848de7824dcb0f3951bb287798861 (patch) | |
tree | 6392dbaae231ca25d66c363021b2bdf0f7edf402 /chrome/browser/tab_contents | |
parent | d6f7b10731967732d970c4e7a768402ff37b4e78 (diff) | |
download | chromium_src-f5d5cd0d6f5848de7824dcb0f3951bb287798861.zip chromium_src-f5d5cd0d6f5848de7824dcb0f3951bb287798861.tar.gz chromium_src-f5d5cd0d6f5848de7824dcb0f3951bb287798861.tar.bz2 |
Reland 135113 - Add a way to programmatically close context menus.
This allows for writing browser tests that test navigations via context menus
BUG=124750
TEST=ContextMenuBrowserTest.RealMenu
TBR=pkasting
Original review: https://chromiumcodereview.appspot.com/10317005/
Review URL: http://codereview.chromium.org/10355009
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@135328 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/tab_contents')
7 files changed, 104 insertions, 1 deletions
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc index 77fe06f..9bf97a0 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.cc +++ b/chrome/browser/tab_contents/render_view_context_menu.cc @@ -260,6 +260,10 @@ void RenderViewContextMenu::Init() { PlatformInit(); } +void RenderViewContextMenu::Cancel() { + PlatformCancel(); +} + static bool ExtensionPatternMatch(const URLPatternSet& patterns, const GURL& url) { // No patterns means no restriction, so that implicitly matches. @@ -1882,6 +1886,11 @@ void RenderViewContextMenu::MenuWillShow(ui::SimpleMenuModel* source) { source_web_contents_->GetRenderWidgetHostView(); if (view) view->SetShowingContextMenu(true); + + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_CONTEXT_MENU_SHOWN, + content::Source<RenderViewContextMenu>(this), + content::NotificationService::NoDetails()); } void RenderViewContextMenu::MenuClosed(ui::SimpleMenuModel* source) { diff --git a/chrome/browser/tab_contents/render_view_context_menu.h b/chrome/browser/tab_contents/render_view_context_menu.h index 01ea703..8eb10d7 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.h +++ b/chrome/browser/tab_contents/render_view_context_menu.h @@ -134,6 +134,9 @@ class RenderViewContextMenu : public ui::SimpleMenuModel::Delegate, // Initializes the context menu. void Init(); + // Programmatically closes the context menu. + void Cancel(); + // Provide access to the menu model for ExternalTabContainer. const ui::MenuModel& menu_model() const { return menu_model_; } @@ -164,6 +167,7 @@ class RenderViewContextMenu : public ui::SimpleMenuModel::Delegate, // Platform specific functions. virtual void PlatformInit() = 0; + virtual void PlatformCancel() = 0; virtual bool GetAcceleratorForCommandId( int command_id, ui::Accelerator* accelerator) = 0; diff --git a/chrome/browser/tab_contents/render_view_context_menu_browsertest.cc b/chrome/browser/tab_contents/render_view_context_menu_browsertest.cc index 03cc2b6..a7619c0 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_browsertest.cc +++ b/chrome/browser/tab_contents/render_view_context_menu_browsertest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -10,12 +10,17 @@ #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/tab_contents/render_view_context_menu.h" #include "chrome/browser/ui/browser.h" +#include "chrome/common/chrome_notification_types.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_view.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" using content::WebContents; @@ -28,6 +33,7 @@ class TestRenderViewContextMenu : public RenderViewContextMenu { : RenderViewContextMenu(web_contents, params) { } virtual void PlatformInit() { } + virtual void PlatformCancel() { } virtual bool GetAcceleratorForCommandId( int command_id, ui::Accelerator* accelerator) { @@ -39,6 +45,36 @@ class TestRenderViewContextMenu : public RenderViewContextMenu { } }; +// Wait for a context menu to be shown, and then execute a command with the +// given command id in this menu, and close the menu again. +class ContextMenuNotificationObserver : public content::NotificationObserver { + public: + explicit ContextMenuNotificationObserver(int command_to_execute) + : command_to_execute_(command_to_execute) { + registrar_.Add(this, + chrome::NOTIFICATION_CONTEXT_MENU_SHOWN, + content::NotificationService::AllSources()); + } + + virtual ~ContextMenuNotificationObserver() {} + + private: + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE { + DCHECK_EQ(chrome::NOTIFICATION_CONTEXT_MENU_SHOWN, type); + RenderViewContextMenu* context_menu = + content::Source<RenderViewContextMenu>(source).ptr(); + context_menu->ExecuteCommand(command_to_execute_); + context_menu->Cancel(); + } + + content::NotificationRegistrar registrar_; + int command_to_execute_; + + DISALLOW_COPY_AND_ASSIGN(ContextMenuNotificationObserver); +}; + class ContextMenuBrowserTest : public InProcessBrowserTest { public: ContextMenuBrowserTest() { } @@ -84,4 +120,48 @@ IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, ASSERT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_COPYLINKLOCATION)); } +// GTK requires a X11-level mouse event to open a context menu correctly. +#if defined(TOOLKIT_GTK) +#define MAYBE_RealMenu DISABLED_RealMenu +#else +#define MAYBE_RealMenu RealMenu +#endif +// Opens a link in a new tab via a "real" context menu. +IN_PROC_BROWSER_TEST_F(ContextMenuBrowserTest, + MAYBE_RealMenu) { + ContextMenuNotificationObserver menu_observer( + IDC_CONTENT_CONTEXT_OPENLINKNEWTAB); + ui_test_utils::WindowedTabAddedNotificationObserver tab_observer( + content::NotificationService::AllSources()); + + // Go to a page with a link + ui_test_utils::NavigateToURL( + browser(), GURL("data:text/html,<a href='about:blank'>link</a>")); + + // Open a context menu. + WebKit::WebMouseEvent mouse_event; + mouse_event.type = WebKit::WebInputEvent::MouseDown; + mouse_event.button = WebKit::WebMouseEvent::ButtonRight; + mouse_event.x = 15; + mouse_event.y = 15; + gfx::Rect offset; + content::WebContents* tab = browser()->GetSelectedWebContents(); + tab->GetView()->GetContainerBounds(&offset); + mouse_event.globalX = 15 + offset.x(); + mouse_event.globalY = 15 + offset.y(); + mouse_event.clickCount = 1; + tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event); + mouse_event.type = WebKit::WebInputEvent::MouseUp; + tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event); + + // The menu_observer will select "Open in new tab", wait for the new tab to + // be added. + tab_observer.Wait(); + tab = tab_observer.GetTab(); + ui_test_utils::WaitForLoadStop(tab); + + // Verify that it's the correct tab. + EXPECT_EQ(GURL("about:blank"), tab->GetURL()); +} + } // namespace diff --git a/chrome/browser/tab_contents/render_view_context_menu_gtk.cc b/chrome/browser/tab_contents/render_view_context_menu_gtk.cc index 03587b3..c699a2c 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_gtk.cc +++ b/chrome/browser/tab_contents/render_view_context_menu_gtk.cc @@ -112,6 +112,10 @@ void RenderViewContextMenuGtk::PlatformInit() { } } +void RenderViewContextMenuGtk::PlatformCancel() { + menu_gtk_->Cancel(); +} + bool RenderViewContextMenuGtk::GetAcceleratorForCommandId( int command_id, ui::Accelerator* accelerator) { diff --git a/chrome/browser/tab_contents/render_view_context_menu_gtk.h b/chrome/browser/tab_contents/render_view_context_menu_gtk.h index 6b08da1..ec62d56 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_gtk.h +++ b/chrome/browser/tab_contents/render_view_context_menu_gtk.h @@ -41,6 +41,7 @@ class RenderViewContextMenuGtk : public RenderViewContextMenu, protected: // RenderViewContextMenu implementation -------------------------------------- virtual void PlatformInit() OVERRIDE; + virtual void PlatformCancel() OVERRIDE; // TODO(port): implement. virtual bool GetAcceleratorForCommandId( int command_id, diff --git a/chrome/browser/tab_contents/render_view_context_menu_mac.h b/chrome/browser/tab_contents/render_view_context_menu_mac.h index c5d0efe8..a524ffc 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_mac.h +++ b/chrome/browser/tab_contents/render_view_context_menu_mac.h @@ -37,6 +37,7 @@ class RenderViewContextMenuMac : public RenderViewContextMenu { protected: // RenderViewContextMenu implementation. virtual void PlatformInit() OVERRIDE; + virtual void PlatformCancel() OVERRIDE; virtual bool GetAcceleratorForCommandId( int command_id, ui::Accelerator* accelerator) OVERRIDE; diff --git a/chrome/browser/tab_contents/render_view_context_menu_mac.mm b/chrome/browser/tab_contents/render_view_context_menu_mac.mm index 9e0f067..e1fc8ee 100644 --- a/chrome/browser/tab_contents/render_view_context_menu_mac.mm +++ b/chrome/browser/tab_contents/render_view_context_menu_mac.mm @@ -108,6 +108,10 @@ void RenderViewContextMenuMac::PlatformInit() { } } +void RenderViewContextMenuMac::PlatformCancel() { + [menu_controller_ cancel]; +} + void RenderViewContextMenuMac::ExecuteCommand(int id) { // Auxiliary windows that do not have address bars (Panels for example) // may not have Instant support. |