summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authoraruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-26 00:54:12 +0000
committeraruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-26 00:54:12 +0000
commit24d2b17dff7c4044839e1b5abd5baf83f4eb3b1d (patch)
tree57299b02d66597023406378a45337bbd794aadd9 /content
parentf9d518696118b8f4985a20a18fb2d806af049415 (diff)
downloadchromium_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')
-rw-r--r--content/browser/renderer_host/popup_menu_helper_mac.h3
-rw-r--r--content/browser/renderer_host/popup_menu_helper_mac.mm6
-rw-r--r--content/browser/renderer_host/render_view_host_impl.cc29
-rw-r--r--content/browser/renderer_host/render_view_host_impl.h7
-rw-r--r--content/browser/renderer_host/render_view_host_unittest.cc18
-rw-r--r--content/browser/web_contents/interstitial_page_impl.cc26
-rw-r--r--content/browser/web_contents/web_contents_view_android.cc11
-rw-r--r--content/browser/web_contents/web_contents_view_android.h7
-rw-r--r--content/browser/web_contents/web_contents_view_aura.cc11
-rw-r--r--content/browser/web_contents/web_contents_view_aura.h7
-rw-r--r--content/browser/web_contents/web_contents_view_gtk.cc11
-rw-r--r--content/browser/web_contents/web_contents_view_gtk.h7
-rw-r--r--content/browser/web_contents/web_contents_view_mac.h7
-rw-r--r--content/browser/web_contents/web_contents_view_mac.mm16
-rw-r--r--content/browser/web_contents/web_contents_view_win.cc11
-rw-r--r--content/browser/web_contents/web_contents_view_win.h7
-rw-r--r--content/common/view_messages.h9
-rw-r--r--content/port/browser/render_view_host_delegate_view.h15
-rw-r--r--content/renderer/external_popup_menu.cc19
-rw-r--r--content/renderer/external_popup_menu.h11
-rw-r--r--content/renderer/render_view_impl.cc19
-rw-r--r--content/renderer/render_view_impl.h6
-rw-r--r--content/test/test_web_contents_view.cc9
-rw-r--r--content/test/test_web_contents_view.h7
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,