Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(567)

Unified Diff: content/renderer/render_frame_impl.cc

Issue 130773004: Start moving context menu code to RenderFrame. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/render_frame_impl.cc
===================================================================
--- content/renderer/render_frame_impl.cc (revision 247964)
+++ content/renderer/render_frame_impl.cc (working copy)
@@ -24,8 +24,11 @@
#include "content/common/view_messages.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
+#include "content/public/common/context_menu_params.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/url_utils.h"
#include "content/public/renderer/content_renderer_client.h"
+#include "content/public/renderer/context_menu_client.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_frame_observer.h"
@@ -33,6 +36,7 @@
#include "content/renderer/browser_plugin/browser_plugin.h"
#include "content/renderer/browser_plugin/browser_plugin_manager.h"
#include "content/renderer/child_frame_compositing_helper.h"
+#include "content/renderer/context_menu_params_builder.h"
#include "content/renderer/internal_document_state_data.h"
#include "content/renderer/npapi/plugin_channel_host.h"
#include "content/renderer/render_thread_impl.h"
@@ -72,6 +76,7 @@
#include "content/renderer/media/rtc_peer_connection_handler.h"
#endif
+using blink::WebContextMenuData;
using blink::WebDataSource;
using blink::WebDocument;
using blink::WebFrame;
@@ -391,6 +396,9 @@
IPC_MESSAGE_HANDLER(FrameMsg_BuffersSwapped, OnBuffersSwapped)
IPC_MESSAGE_HANDLER_GENERIC(FrameMsg_CompositorFrameSwapped,
OnCompositorFrameSwapped(msg))
+ IPC_MESSAGE_HANDLER(FrameMsg_ContextMenuClosed, OnContextMenuClosed)
+ IPC_MESSAGE_HANDLER(FrameMsg_CustomContextMenuAction,
+ OnCustomContextMenuAction)
IPC_END_MESSAGE_MAP_EX()
if (!msg_is_ok) {
@@ -474,6 +482,56 @@
param.a.producing_host_id);
}
+void RenderFrameImpl::OnContextMenuClosed(
+ const CustomContextMenuContext& custom_context) {
+ if (custom_context.request_id) {
+ // External request, should be in our map.
+ ContextMenuClient* client =
+ pending_context_menus_.Lookup(custom_context.request_id);
+ if (client) {
+ client->OnMenuClosed(custom_context.request_id);
+ pending_context_menus_.Remove(custom_context.request_id);
+ }
+ } else {
+ // Internal request, forward to WebKit.
+ render_view_->context_menu_node_.reset();
+ }
+}
+
+void RenderFrameImpl::OnCustomContextMenuAction(
+ const CustomContextMenuContext& custom_context,
+ unsigned action) {
+ if (custom_context.request_id) {
+ // External context menu request, look in our map.
+ ContextMenuClient* client =
+ pending_context_menus_.Lookup(custom_context.request_id);
+ if (client)
+ client->OnMenuAction(custom_context.request_id, action);
+ } else {
+ // Internal request, forward to WebKit.
+ render_view_->webview()->performCustomContextMenuAction(action);
+ }
+}
+
+bool RenderFrameImpl::ShouldUpdateSelectionTextFromContextMenuParams(
+ const base::string16& selection_text,
+ size_t selection_text_offset,
+ const gfx::Range& selection_range,
+ const ContextMenuParams& params) {
+ base::string16 trimmed_selection_text;
+ if (!selection_text.empty() && !selection_range.is_empty()) {
+ const int start = selection_range.GetMin() - selection_text_offset;
+ const size_t length = selection_range.length();
+ if (start >= 0 && start + length <= selection_text.length()) {
+ TrimWhitespace(selection_text.substr(start, length), TRIM_ALL,
+ &trimmed_selection_text);
+ }
+ }
+ base::string16 trimmed_params_text;
+ TrimWhitespace(params.selection_text, TRIM_ALL, &trimmed_params_text);
+ return trimmed_params_text != trimmed_selection_text;
+}
+
void RenderFrameImpl::DidCommitCompositorFrame() {
if (compositing_helper_)
compositing_helper_->DidCommitCompositorFrame();
@@ -498,11 +556,16 @@
int RenderFrameImpl::ShowContextMenu(ContextMenuClient* client,
const ContextMenuParams& params) {
- return render_view_->ShowContextMenu(client, params);
+ DCHECK(client); // A null client means "internal" when we issue callbacks.
+ ContextMenuParams our_params(params);
+ our_params.custom_context.request_id = pending_context_menus_.Add(client);
+ Send(new FrameHostMsg_ContextMenu(routing_id_, our_params));
+ return our_params.custom_context.request_id;
}
void RenderFrameImpl::CancelContextMenu(int request_id) {
- return render_view_->CancelContextMenu(request_id);
+ DCHECK(pending_context_menus_.Lookup(request_id));
+ pending_context_menus_.Remove(request_id);
}
blink::WebPlugin* RenderFrameImpl::CreatePlugin(
@@ -1502,6 +1565,59 @@
arb_robustness_status_code));
}
+void RenderFrameImpl::showContextMenu(const blink::WebContextMenuData& data) {
+ ContextMenuParams params = ContextMenuParamsBuilder::Build(data);
+ params.source_type = GetRenderWidget()->context_menu_source_type();
+ if (params.source_type == ui::MENU_SOURCE_TOUCH_EDIT_MENU) {
+ params.x = GetRenderWidget()->touch_editing_context_menu_location().x();
+ params.y = GetRenderWidget()->touch_editing_context_menu_location().y();
+ }
+ GetRenderWidget()->OnShowHostContextMenu(&params);
+
+ // Plugins, e.g. PDF, don't currently update the render view when their
+ // selected text changes, but the context menu params do contain the updated
+ // selection. If that's the case, update the render view's state just prior
+ // to showing the context menu.
+ // TODO(asvitkine): http://crbug.com/152432
+ if (ShouldUpdateSelectionTextFromContextMenuParams(
+ render_view_->selection_text_,
+ render_view_->selection_text_offset_,
+ render_view_->selection_range_,
+ params)) {
+ render_view_->selection_text_ = params.selection_text;
+ // TODO(asvitkine): Text offset and range is not available in this case.
+ render_view_->selection_text_offset_ = 0;
+ render_view_->selection_range_ =
+ gfx::Range(0, render_view_->selection_text_.length());
+ Send(new ViewHostMsg_SelectionChanged(
+ routing_id_,
+ render_view_->selection_text_,
+ render_view_->selection_text_offset_,
+ render_view_->selection_range_));
+ }
+
+ params.frame_id = frame_->identifier();
+
+ // Serializing a GURL longer than kMaxURLChars will fail, so don't do
+ // it. We replace it with an empty GURL so the appropriate items are disabled
+ // in the context menu.
+ // TODO(jcivelli): http://crbug.com/45160 This prevents us from saving large
+ // data encoded images. We should have a way to save them.
+ if (params.src_url.spec().size() > GetMaxURLChars())
+ params.src_url = GURL();
+ render_view_->context_menu_node_ = data.node;
+
+#if defined(OS_ANDROID)
+ gfx::Rect start_rect;
+ gfx::Rect end_rect;
+ render_view_->GetSelectionBounds(&start_rect, &end_rect);
+ params.selection_start = gfx::Point(start_rect.x(), start_rect.bottom());
+ params.selection_end = gfx::Point(end_rect.right(), end_rect.bottom());
+#endif
+
+ Send(new FrameHostMsg_ContextMenu(routing_id_, params));
+}
+
void RenderFrameImpl::AddObserver(RenderFrameObserver* observer) {
observers_.AddObserver(observer);
}

Powered by Google App Engine
This is Rietveld 408576698