diff options
author | aruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-26 00:54:12 +0000 |
---|---|---|
committer | aruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-26 00:54:12 +0000 |
commit | 24d2b17dff7c4044839e1b5abd5baf83f4eb3b1d (patch) | |
tree | 57299b02d66597023406378a45337bbd794aadd9 /content | |
parent | f9d518696118b8f4985a20a18fb2d806af049415 (diff) | |
download | chromium_src-24d2b17dff7c4044839e1b5abd5baf83f4eb3b1d.zip chromium_src-24d2b17dff7c4044839e1b5abd5baf83f4eb3b1d.tar.gz chromium_src-24d2b17dff7c4044839e1b5abd5baf83f4eb3b1d.tar.bz2 |
Multi-select <select> in 'external popup window'
We use an 'external popup window' for both single and multi selection
<select> tag popups. This also supports <optgroup> and disabled <option>
items and multiple selections. On all other chrome platforms a multi-select
<select> tag is rendered in page, so this CL adds a bit of plumbing and IPC
stuff to get the multi-select popups working as well.
WebKit side of this CL is at http://trac.webkit.org/changeset/94600
Review URL: https://chromiumcodereview.appspot.com/10436010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139169 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
24 files changed, 260 insertions, 19 deletions
diff --git a/content/browser/renderer_host/popup_menu_helper_mac.h b/content/browser/renderer_host/popup_menu_helper_mac.h index 1915b1a..bf289e6 100644 --- a/content/browser/renderer_host/popup_menu_helper_mac.h +++ b/content/browser/renderer_host/popup_menu_helper_mac.h @@ -33,7 +33,8 @@ class PopupMenuHelper : public content::NotificationObserver { double item_font_size, int selected_item, const std::vector<WebMenuItem>& items, - bool right_aligned); + bool right_aligned, + bool allow_multiple_selection); private: // content::NotificationObserver implementation: diff --git a/content/browser/renderer_host/popup_menu_helper_mac.mm b/content/browser/renderer_host/popup_menu_helper_mac.mm index 9f37148..5befbe1 100644 --- a/content/browser/renderer_host/popup_menu_helper_mac.mm +++ b/content/browser/renderer_host/popup_menu_helper_mac.mm @@ -33,7 +33,11 @@ void PopupMenuHelper::ShowPopupMenu( double item_font_size, int selected_item, const std::vector<WebMenuItem>& items, - bool right_aligned) { + bool right_aligned, + bool allow_multiple_selection) { + // Only single selection list boxes show a popup on Mac. + DCHECK(!allow_multiple_selection); + // Retain the Cocoa view for the duration of the pop-up so that it can't be // dealloced if my Destroy() method is called while the pop-up's up (which // would in turn delete me, causing a crash once the -runMenuInView diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index b2624fb..93de712 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc @@ -1531,6 +1531,19 @@ void RenderViewHostImpl::DidCancelPopupMenu() { } #endif +#if defined(OS_ANDROID) +void RenderViewHostImpl::DidSelectPopupMenuItems( + const std::vector<int>& selected_indices) { + Send(new ViewMsg_SelectPopupMenuItems(GetRoutingID(), false, + selected_indices)); +} + +void RenderViewHostImpl::DidCancelPopupMenu() { + Send(new ViewMsg_SelectPopupMenuItems(GetRoutingID(), true, + std::vector<int>())); +} +#endif + void RenderViewHostImpl::SendOrientationChangeEvent(int orientation) { Send(new ViewMsg_OrientationChangeEvent(GetRoutingID(), orientation)); } @@ -1786,13 +1799,19 @@ void RenderViewHostImpl::OnCancelDesktopNotification(int notification_id) { GetProcess()->GetID(), GetRoutingID(), notification_id); } -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(OS_ANDROID) void RenderViewHostImpl::OnMsgShowPopup( const ViewHostMsg_ShowPopup_Params& params) { - PopupMenuHelper popup_menu_helper(this); - popup_menu_helper.ShowPopupMenu(params.bounds, params.item_height, - params.item_font_size, params.selected_item, - params.popup_items, params.right_aligned); + RenderViewHostDelegateView* view = delegate_->GetDelegateView(); + if (view) { + view->ShowPopupMenu(params.bounds, + params.item_height, + params.item_font_size, + params.selected_item, + params.popup_items, + params.right_aligned, + params.allow_multiple_selection); + } } #endif diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index 21c3321..f5272a0 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h @@ -393,6 +393,11 @@ class CONTENT_EXPORT RenderViewHostImpl void DidCancelPopupMenu(); #endif +#if defined(OS_ANDROID) + void DidSelectPopupMenuItems(const std::vector<int>& selected_indices); + void DidCancelPopupMenu(); +#endif + // User rotated the screen. Calls the "onorientationchange" Javascript hook. void SendOrientationChangeEvent(int orientation); @@ -543,7 +548,7 @@ class CONTENT_EXPORT RenderViewHostImpl void OnDomOperationResponse(const std::string& json_string, int automation_id); -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(OS_ANDROID) void OnMsgShowPopup(const ViewHostMsg_ShowPopup_Params& params); #endif diff --git a/content/browser/renderer_host/render_view_host_unittest.cc b/content/browser/renderer_host/render_view_host_unittest.cc index d9840d9..e777a51 100644 --- a/content/browser/renderer_host/render_view_host_unittest.cc +++ b/content/browser/renderer_host/render_view_host_unittest.cc @@ -82,17 +82,25 @@ class MockDraggingRenderViewHostDelegateView : public content::RenderViewHostDelegateView { public: virtual ~MockDraggingRenderViewHostDelegateView() {} - virtual void ShowContextMenu(const content::ContextMenuParams& params) {} + virtual void ShowContextMenu( + const content::ContextMenuParams& params) OVERRIDE {} + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) OVERRIDE {} virtual void StartDragging(const WebDropData& drop_data, WebKit::WebDragOperationsMask allowed_ops, const SkBitmap& image, - const gfx::Point& image_offset) { + const gfx::Point& image_offset) OVERRIDE { drag_url_ = drop_data.url; html_base_url_ = drop_data.html_base_url; } - virtual void UpdateDragCursor(WebKit::WebDragOperation operation) {} - virtual void GotFocus() {} - virtual void TakeFocus(bool reverse) {} + virtual void UpdateDragCursor(WebKit::WebDragOperation operation) OVERRIDE {} + virtual void GotFocus() OVERRIDE {} + virtual void TakeFocus(bool reverse) OVERRIDE {} virtual void UpdatePreferredSize(const gfx::Size& pref_size) {} GURL drag_url() { diff --git a/content/browser/web_contents/interstitial_page_impl.cc b/content/browser/web_contents/interstitial_page_impl.cc index e9cdf85..a8d80ed 100644 --- a/content/browser/web_contents/interstitial_page_impl.cc +++ b/content/browser/web_contents/interstitial_page_impl.cc @@ -86,13 +86,20 @@ class InterstitialPageImpl::InterstitialPageRVHDelegateView explicit InterstitialPageRVHDelegateView(InterstitialPageImpl* page); // RenderViewHostDelegateView implementation: + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) OVERRIDE; virtual void StartDragging(const WebDropData& drop_data, WebDragOperationsMask operations_allowed, const SkBitmap& image, - const gfx::Point& image_offset); - virtual void UpdateDragCursor(WebDragOperation operation); - virtual void GotFocus(); - virtual void TakeFocus(bool reverse); + const gfx::Point& image_offset) OVERRIDE; + virtual void UpdateDragCursor(WebDragOperation operation) OVERRIDE; + virtual void GotFocus() OVERRIDE; + virtual void TakeFocus(bool reverse) OVERRIDE; virtual void OnFindReply(int request_id, int number_of_matches, const gfx::Rect& selection_rect, @@ -693,6 +700,17 @@ InterstitialPageImpl::InterstitialPageRVHDelegateView:: : interstitial_page_(page) { } +void InterstitialPageImpl::InterstitialPageRVHDelegateView::ShowPopupMenu( + const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) { + NOTREACHED() << "InterstitialPage does not support showing popup menus."; +} + void InterstitialPageImpl::InterstitialPageRVHDelegateView::StartDragging( const WebDropData& drop_data, WebDragOperationsMask allowed_operations, diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc index 6a74db5..547d189 100644 --- a/content/browser/web_contents/web_contents_view_android.cc +++ b/content/browser/web_contents/web_contents_view_android.cc @@ -121,6 +121,17 @@ void WebContentsViewAndroid::ShowContextMenu( NOTIMPLEMENTED(); } +void WebContentsViewAndroid::ShowPopupMenu( + const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) { + NOTIMPLEMENTED(); +} + void WebContentsViewAndroid::StartDragging( const WebDropData& drop_data, WebKit::WebDragOperationsMask allowed_ops, diff --git a/content/browser/web_contents/web_contents_view_android.h b/content/browser/web_contents/web_contents_view_android.h index 3798d32..5340ffe 100644 --- a/content/browser/web_contents/web_contents_view_android.h +++ b/content/browser/web_contents/web_contents_view_android.h @@ -49,6 +49,13 @@ class WebContentsViewAndroid // Backend implementation of RenderViewHostDelegateView. virtual void ShowContextMenu( const content::ContextMenuParams& params) OVERRIDE; + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) OVERRIDE; virtual void StartDragging(const WebDropData& drop_data, WebKit::WebDragOperationsMask allowed_ops, const SkBitmap& image, diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index 7c81d8e..d643594 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc @@ -405,6 +405,17 @@ void WebContentsViewAura::ShowContextMenu( delegate_->ShowContextMenu(params); } +void WebContentsViewAura::ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) { + // External popup menus are only used on Mac and Android. + NOTIMPLEMENTED(); +} + void WebContentsViewAura::StartDragging( const WebDropData& drop_data, WebKit::WebDragOperationsMask operations, diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h index 1b307af..5c6691828 100644 --- a/content/browser/web_contents/web_contents_view_aura.h +++ b/content/browser/web_contents/web_contents_view_aura.h @@ -67,6 +67,13 @@ class CONTENT_EXPORT WebContentsViewAura // Overridden from RenderViewHostDelegateView: virtual void ShowContextMenu( const content::ContextMenuParams& params) OVERRIDE; + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) OVERRIDE; virtual void StartDragging(const WebDropData& drop_data, WebKit::WebDragOperationsMask operations, const SkBitmap& image, diff --git a/content/browser/web_contents/web_contents_view_gtk.cc b/content/browser/web_contents/web_contents_view_gtk.cc index d118130..4f2b0ce 100644 --- a/content/browser/web_contents/web_contents_view_gtk.cc +++ b/content/browser/web_contents/web_contents_view_gtk.cc @@ -332,6 +332,17 @@ void WebContentsViewGtk::ShowContextMenu( DLOG(ERROR) << "Cannot show context menus without a delegate."; } +void WebContentsViewGtk::ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) { + // External popup menus are only used on Mac and Android. + NOTIMPLEMENTED(); +} + // Render view DnD ------------------------------------------------------------- void WebContentsViewGtk::StartDragging(const WebDropData& drop_data, diff --git a/content/browser/web_contents/web_contents_view_gtk.h b/content/browser/web_contents/web_contents_view_gtk.h index a41053a..0654ab7 100644 --- a/content/browser/web_contents/web_contents_view_gtk.h +++ b/content/browser/web_contents/web_contents_view_gtk.h @@ -73,6 +73,13 @@ class CONTENT_EXPORT WebContentsViewGtk // Backend implementation of RenderViewHostDelegateView. virtual void ShowContextMenu( const content::ContextMenuParams& params) OVERRIDE; + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) OVERRIDE; virtual void StartDragging(const WebDropData& drop_data, WebKit::WebDragOperationsMask allowed_ops, const SkBitmap& image, diff --git a/content/browser/web_contents/web_contents_view_mac.h b/content/browser/web_contents/web_contents_view_mac.h index eb9f049..5e59db3 100644 --- a/content/browser/web_contents/web_contents_view_mac.h +++ b/content/browser/web_contents/web_contents_view_mac.h @@ -86,6 +86,13 @@ class WebContentsViewMac // Backend implementation of RenderViewHostDelegateView. virtual void ShowContextMenu( const content::ContextMenuParams& params) OVERRIDE; + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) OVERRIDE; virtual void StartDragging(const WebDropData& drop_data, WebKit::WebDragOperationsMask allowed_operations, const SkBitmap& image, diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm index b03012f..8ceb079 100644 --- a/content/browser/web_contents/web_contents_view_mac.mm +++ b/content/browser/web_contents/web_contents_view_mac.mm @@ -10,6 +10,7 @@ #import "base/mac/scoped_sending_event.h" #import "base/message_pump_mac.h" +#include "content/browser/renderer_host/popup_menu_helper_mac.h" #include "content/browser/renderer_host/render_view_host_factory.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_mac.h" @@ -287,6 +288,21 @@ void WebContentsViewMac::ShowContextMenu( DLOG(ERROR) << "Cannot show context menus without a delegate."; } +// Display a popup menu for WebKit using Cocoa widgets. +void WebContentsViewMac::ShowPopupMenu( + const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) { + PopupMenuHelper popup_menu_helper(web_contents_->GetRenderViewHost()); + popup_menu_helper.ShowPopupMenu(bounds, item_height, item_font_size, + selected_item, items, right_aligned, + allow_multiple_selection); +} + bool WebContentsViewMac::IsEventTracking() const { return base::MessagePumpMac::IsHandlingSendEvent(); } diff --git a/content/browser/web_contents/web_contents_view_win.cc b/content/browser/web_contents/web_contents_view_win.cc index b24079e..92eff7e 100644 --- a/content/browser/web_contents/web_contents_view_win.cc +++ b/content/browser/web_contents/web_contents_view_win.cc @@ -245,6 +245,17 @@ void WebContentsViewWin::ShowContextMenu( delegate_->ShowContextMenu(params); } +void WebContentsViewWin::ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) { + // External popup menus are only used on Mac and Android. + NOTIMPLEMENTED(); +} + void WebContentsViewWin::StartDragging(const WebDropData& drop_data, WebKit::WebDragOperationsMask operations, const SkBitmap& image, diff --git a/content/browser/web_contents/web_contents_view_win.h b/content/browser/web_contents/web_contents_view_win.h index 0f6f244..87504ac 100644 --- a/content/browser/web_contents/web_contents_view_win.h +++ b/content/browser/web_contents/web_contents_view_win.h @@ -77,6 +77,13 @@ class CONTENT_EXPORT WebContentsViewWin // Implementation of RenderViewHostDelegateView. virtual void ShowContextMenu( const content::ContextMenuParams& params) OVERRIDE; + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) OVERRIDE; virtual void StartDragging(const WebDropData& drop_data, WebKit::WebDragOperationsMask operations, const SkBitmap& image, diff --git a/content/common/view_messages.h b/content/common/view_messages.h index e85bda1..57966c3 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -466,6 +466,9 @@ IPC_STRUCT_BEGIN(ViewHostMsg_ShowPopup_Params) // Whether items should be right-aligned. IPC_STRUCT_MEMBER(bool, right_aligned) + + // Whether this is a multi-select popup. + IPC_STRUCT_MEMBER(bool, allow_multiple_selection) IPC_STRUCT_END() IPC_STRUCT_BEGIN(ViewHostMsg_UpdateRect_Params) @@ -973,8 +976,14 @@ IPC_MESSAGE_ROUTED2(ViewMsg_CSSInsertRequest, std::string /* css string */) // External popup menus. +#if defined(OS_MACOSX) IPC_MESSAGE_ROUTED1(ViewMsg_SelectPopupMenuItem, int /* selected index, -1 means no selection */) +#elif defined(OS_ANDROID) +IPC_MESSAGE_ROUTED2(ViewMsg_SelectPopupMenuItems, + bool /* user canceled the popup */, + std::vector<int> /* selected indices */) +#endif // Change the zoom level for the current main frame. If the level actually // changes, a ViewHostMsg_DidZoomURL message will be sent back to the browser diff --git a/content/port/browser/render_view_host_delegate_view.h b/content/port/browser/render_view_host_delegate_view.h index c04603a..8a646c4 100644 --- a/content/port/browser/render_view_host_delegate_view.h +++ b/content/port/browser/render_view_host_delegate_view.h @@ -6,15 +6,19 @@ #define CONTENT_PORT_BROWSER_RENDER_VIEW_HOST_DELEGATE_VIEW_H_ #pragma once +#include <vector> + #include "base/basictypes.h" #include "content/common/content_export.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDragOperation.h" class SkBitmap; struct WebDropData; +struct WebMenuItem; namespace gfx { class Point; +class Rect; } namespace content { @@ -30,6 +34,17 @@ class CONTENT_EXPORT RenderViewHostDelegateView { // provided in the supplied params. virtual void ShowContextMenu(const ContextMenuParams& params) {} + // Shows a popup menu with the specified items. + // This method should call RenderViewHost::DidSelectPopupMenuItem[s]() or + // RenderViewHost::DidCancelPopupMenu() based on the user action. + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) = 0; + // The user started dragging content of the specified type within the // RenderView. Contextual information about the dragged content is supplied // by WebDropData. diff --git a/content/renderer/external_popup_menu.cc b/content/renderer/external_popup_menu.cc index a8c1ea8..218bb33 100644 --- a/content/renderer/external_popup_menu.cc +++ b/content/renderer/external_popup_menu.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 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. @@ -27,6 +27,8 @@ void ExternalPopupMenu::show(const WebKit::WebRect& bounds) { for (size_t i = 0; i < popup_menu_info_.items.size(); ++i) popup_params.popup_items.push_back(WebMenuItem(popup_menu_info_.items[i])); popup_params.right_aligned = popup_menu_info_.rightAligned; + popup_params.allow_multiple_selection = + popup_menu_info_.allowMultipleSelection; render_view_->Send( new ViewHostMsg_ShowPopup(render_view_->routing_id(), popup_params)); } @@ -36,6 +38,7 @@ void ExternalPopupMenu::close() { render_view_ = NULL; } +#if defined(OS_MACOSX) void ExternalPopupMenu::DidSelectItem(int index) { if (!popup_menu_client_) return; @@ -44,3 +47,17 @@ void ExternalPopupMenu::DidSelectItem(int index) { else popup_menu_client_->didAcceptIndex(index); } +#endif + +#if defined(OS_ANDROID) +void ExternalPopupMenu::DidSelectItems(bool canceled, + const std::vector<int>& indices) { + if (!popup_menu_client_) + return; + if (canceled) + popup_menu_client_->didCancel(); + else + popup_menu_client_->didAcceptIndices(indices); +} +#endif + diff --git a/content/renderer/external_popup_menu.h b/content/renderer/external_popup_menu.h index bdc9aae..f039fcf 100644 --- a/content/renderer/external_popup_menu.h +++ b/content/renderer/external_popup_menu.h @@ -1,10 +1,12 @@ -// 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. #ifndef CONTENT_RENDERER_EXTERNAL_POPUP_MENU_H_ #define CONTENT_RENDERER_EXTERNAL_POPUP_MENU_H_ +#include <vector> + #include "base/basictypes.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebExternalPopupMenu.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenuInfo.h" @@ -22,9 +24,16 @@ class ExternalPopupMenu : public WebKit::WebExternalPopupMenu { virtual ~ExternalPopupMenu() {} +#if defined(OS_MACOSX) // Called when the user has selected an item. |selected_item| is -1 if the // user canceled the popup. void DidSelectItem(int selected_index); +#endif + +#if defined(OS_ANDROID) + // Called when the user has selected items or canceled the popup. + void DidSelectItems(bool canceled, const std::vector<int>& selected_indices); +#endif // WebKit::WebExternalPopupMenu implementation: virtual void show(const WebKit::WebRect& bounds); diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index cbd6617..b133a2c 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -939,6 +939,8 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) { OnGetSerializedHtmlDataForCurrentPageWithLocalLinks) #if defined(OS_MACOSX) IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItem, OnSelectPopupMenuItem) +#elif defined(OS_ANDROID) + IPC_MESSAGE_HANDLER(ViewMsg_SelectPopupMenuItems, OnSelectPopupMenuItems) #endif IPC_MESSAGE_HANDLER(ViewMsg_ContextMenuClosed, OnContextMenuClosed) // TODO(viettrungluu): Move to a separate message filter. @@ -1665,6 +1667,7 @@ WebWidget* RenderViewImpl::createPopupMenu(WebKit::WebPopupType popup_type) { WebExternalPopupMenu* RenderViewImpl::createExternalPopupMenu( const WebPopupMenuInfo& popup_menu_info, WebExternalPopupMenuClient* popup_menu_client) { + // TODO(jcivelli): http:/b/5793321 Implement a better fix, as detailed in bug. DCHECK(!external_popup_menu_.get()); external_popup_menu_.reset( new ExternalPopupMenu(this, popup_menu_info, popup_menu_client)); @@ -5497,6 +5500,22 @@ void RenderViewImpl::OnSelectPopupMenuItem(int selected_index) { } #endif +#if defined(OS_ANDROID) +void RenderViewImpl::OnSelectPopupMenuItems( + bool canceled, + const std::vector<int>& selected_indices) { + // It is possible to receive more than one of these calls if the user presses + // a select faster than it takes for the show-select-popup IPC message to make + // it to the browser UI thread. Ignore the extra-messages. + // TODO(jcivelli): http:/b/5793321 Implement a better fix, as detailed in bug. + if (!external_popup_menu_.get()) + return; + + external_popup_menu_->DidSelectItems(canceled, selected_indices); + external_popup_menu_.reset(); +} +#endif + void RenderViewImpl::OnContextMenuClosed( const content::CustomContextMenuContext& custom_context) { if (custom_context.is_pepper_menu) diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 119ddad..7530fb6 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h @@ -968,6 +968,12 @@ class RenderViewImpl : public RenderWidget, const gfx::Rect& view_frame); CONTENT_EXPORT void OnSelectPopupMenuItem(int selected_index); #endif + +#if defined(OS_ANDROID) + void OnSelectPopupMenuItems(bool canceled, + const std::vector<int>& selected_indices); +#endif + void OnZoom(content::PageZoom zoom); void OnZoomFactor(content::PageZoom zoom, int zoom_center_x, int zoom_center_y); diff --git a/content/test/test_web_contents_view.cc b/content/test/test_web_contents_view.cc index 26411542..d56f1e2 100644 --- a/content/test/test_web_contents_view.cc +++ b/content/test/test_web_contents_view.cc @@ -16,6 +16,15 @@ void TestWebContentsView::ShowContextMenu( const ContextMenuParams& params) { } +void TestWebContentsView::ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) { +} + void TestWebContentsView::StartDragging( const WebDropData& drop_data, WebKit::WebDragOperationsMask allowed_ops, diff --git a/content/test/test_web_contents_view.h b/content/test/test_web_contents_view.h index ad72fe2..01b2a95 100644 --- a/content/test/test_web_contents_view.h +++ b/content/test/test_web_contents_view.h @@ -20,6 +20,13 @@ class TestWebContentsView : public WebContentsView, // RenderViewHostDelegateView: virtual void ShowContextMenu(const ContextMenuParams& params) OVERRIDE; + virtual void ShowPopupMenu(const gfx::Rect& bounds, + int item_height, + double item_font_size, + int selected_item, + const std::vector<WebMenuItem>& items, + bool right_aligned, + bool allow_multiple_selection) OVERRIDE; virtual void StartDragging(const WebDropData& drop_data, WebKit::WebDragOperationsMask allowed_ops, const SkBitmap& image, |