diff options
author | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-28 18:39:02 +0000 |
---|---|---|
committer | pkasting@chromium.org <pkasting@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-28 18:39:02 +0000 |
commit | 124646932219f4cd17a3dc80393485e923deb1ba (patch) | |
tree | 9e20a8428541fb543b21503ce76e7a71251a8722 | |
parent | 96c622f5a85c0a745b5f66856aea419032c934af (diff) | |
download | chromium_src-124646932219f4cd17a3dc80393485e923deb1ba.zip chromium_src-124646932219f4cd17a3dc80393485e923deb1ba.tar.gz chromium_src-124646932219f4cd17a3dc80393485e923deb1ba.tar.bz2 |
Context menus for text selections in editable boxes and links should include the Search menu item. Original patch by Brian Duff (see http://codereview.chromium.org/16510 ), r=me.
BUG=1925
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8815 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu.cc | 50 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu.h | 7 | ||||
-rw-r--r-- | chrome/browser/tab_contents/web_contents_view_win.cc | 2 | ||||
-rw-r--r-- | chrome/common/render_messages.h | 105 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 4 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 2 | ||||
-rw-r--r-- | webkit/glue/context_menu_client_impl.cc | 69 | ||||
-rw-r--r-- | webkit/glue/context_node_types.h | 40 | ||||
-rw-r--r-- | webkit/glue/webview_delegate.h | 4 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_webview_delegate.cc | 4 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_webview_delegate.h | 8 |
11 files changed, 138 insertions, 157 deletions
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc index 4aecf00..9d36be5 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.cc +++ b/chrome/browser/tab_contents/render_view_context_menu.cc @@ -18,7 +18,7 @@ RenderViewContextMenu::RenderViewContextMenu( Menu::Delegate* delegate, HWND owner, - ContextNode::Type type, + ContextNode node, const std::wstring& misspelled_word, const std::vector<std::wstring>& misspelled_word_suggestions, Profile* profile) @@ -26,40 +26,34 @@ RenderViewContextMenu::RenderViewContextMenu( misspelled_word_(misspelled_word), misspelled_word_suggestions_(misspelled_word_suggestions), profile_(profile) { - InitMenu(type); + InitMenu(node); } RenderViewContextMenu::~RenderViewContextMenu() { } -void RenderViewContextMenu::InitMenu(ContextNode::Type type) { - switch (type) { - case ContextNode::PAGE: +void RenderViewContextMenu::InitMenu(ContextNode node) { + if (node.type & ContextNode::PAGE) AppendPageItems(); - break; - case ContextNode::FRAME: + if (node.type & ContextNode::FRAME) AppendFrameItems(); - break; - case ContextNode::LINK: + if (node.type & ContextNode::LINK) AppendLinkItems(); - break; - case ContextNode::IMAGE: - AppendImageItems(); - break; - case ContextNode::IMAGE_LINK: - AppendLinkItems(); - AppendSeparator(); + + if (node.type & ContextNode::IMAGE) { + if (node.type & ContextNode::LINK) + AppendSeparator(); AppendImageItems(); - break; - case ContextNode::SELECTION: - AppendSelectionItems(); - break; - case ContextNode::EDITABLE: - AppendEditableItems(); - break; - default: - NOTREACHED() << "Unknown ContextNode::Type"; } + + if (node.type & ContextNode::EDITABLE) + AppendEditableItems(); + else if (node.type & ContextNode::SELECTION || + node.type & ContextNode::LINK) + AppendCopyItem(); + + if (node.type & ContextNode::SELECTION) + AppendSearchProvider(); AppendSeparator(); AppendDeveloperItems(); } @@ -74,7 +68,6 @@ void RenderViewContextMenu::AppendLinkItems() { AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_OPENLINKOFFTHERECORD); AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SAVELINKAS); AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPYLINKLOCATION); - AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY); } void RenderViewContextMenu::AppendImageItems() { @@ -109,8 +102,11 @@ void RenderViewContextMenu::AppendFrameItems() { AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_VIEWFRAMEINFO); } -void RenderViewContextMenu::AppendSelectionItems() { +void RenderViewContextMenu::AppendCopyItem() { AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_COPY); +} + +void RenderViewContextMenu::AppendSearchProvider() { DCHECK(profile_); if (profile_->GetTemplateURLModel()->GetDefaultSearchProvider() != NULL) AppendDelegateMenuItem(IDS_CONTENT_CONTEXT_SEARCHWEBFOR); diff --git a/chrome/browser/tab_contents/render_view_context_menu.h b/chrome/browser/tab_contents/render_view_context_menu.h index 6c95f57..6d55c03 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.h +++ b/chrome/browser/tab_contents/render_view_context_menu.h @@ -15,7 +15,7 @@ class RenderViewContextMenu : public Menu { RenderViewContextMenu( Menu::Delegate* delegate, HWND owner, - ContextNode::Type type, + ContextNode node, const std::wstring& misspelled_word, const std::vector<std::wstring>& misspelled_word_suggestions, Profile* profile); @@ -23,14 +23,15 @@ class RenderViewContextMenu : public Menu { virtual ~RenderViewContextMenu(); private: - void InitMenu(ContextNode::Type type); + void InitMenu(ContextNode node); void AppendDeveloperItems(); void AppendLinkItems(); void AppendImageItems(); void AppendPageItems(); void AppendFrameItems(); - void AppendSelectionItems(); + void AppendCopyItem(); void AppendEditableItems(); + void AppendSearchProvider(); std::wstring misspelled_word_; std::vector<std::wstring> misspelled_word_suggestions_; diff --git a/chrome/browser/tab_contents/web_contents_view_win.cc b/chrome/browser/tab_contents/web_contents_view_win.cc index 0c7cbef..ee69af7 100644 --- a/chrome/browser/tab_contents/web_contents_view_win.cc +++ b/chrome/browser/tab_contents/web_contents_view_win.cc @@ -319,7 +319,7 @@ void WebContentsViewWin::ShowContextMenu( RenderViewContextMenuController menu_controller(web_contents_, params); RenderViewContextMenu menu(&menu_controller, GetHWND(), - params.type, + params.node, params.misspelled_word, params.dictionary_suggestions, web_contents_->profile()); diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 83dddb1..7d1273f 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -124,7 +124,7 @@ struct ViewHostMsg_FrameNavigate_Params { // could be used for more contextual actions. struct ViewHostMsg_ContextMenu_Params { // This is the type of Context Node that the context menu was invoked on. - ContextNode::Type type; + ContextNode node; // These values represent the coordinates of the mouse when the context menu // was invoked. Coords are relative to the associated RenderView's origin. @@ -543,8 +543,49 @@ struct ParamTraits<FilterPolicy::Type> { }; template <> -struct ParamTraits<ContextNode::Type> { - typedef ContextNode::Type param_type; +struct ParamTraits<ContextNode> { + typedef ContextNode param_type; + static void Write(Message* m, const param_type& p) { + m->WriteInt(p.type); + } + static bool Read(const Message* m, void** iter, param_type* p) { + int type; + if (!m->ReadInt(iter, &type)) + return false; + *p = ContextNode(type); + return true; + } + static void Log(const param_type& p, std::wstring* l) { + std::wstring event = L""; + + if (!p.type) + event.append(L"NONE"); + else { + event.append(L"("); + if (p.type & ContextNode::PAGE) + event.append(L"PAGE|"); + if (p.type & ContextNode::FRAME) + event.append(L"FRAME|"); + if (p.type & ContextNode::LINK) + event.append(L"LINK|"); + if (p.type & ContextNode::IMAGE) + event.append(L"IMAGE|"); + if (p.type & ContextNode::SELECTION) + event.append(L"SELECTION|"); + if (p.type & ContextNode::EDITABLE) + event.append(L"EDITABLE|"); + if (p.type & ContextNode::MISSPELLED_WORD) + event.append(L"MISSPELLED_WORD|"); + event.append(L")"); + } + + LogParam(event, l); + } +}; + +template <> +struct ParamTraits<WebInputEvent::Type> { + typedef WebInputEvent::Type param_type; static void Write(Message* m, const param_type& p) { m->WriteInt(p); } @@ -552,7 +593,7 @@ struct ParamTraits<ContextNode::Type> { int type; if (!m->ReadInt(iter, &type)) return false; - *p = ContextNode::FromInt(type); + *p = static_cast<WebInputEvent::Type>(type); return true; } static void Log(const param_type& p, std::wstring* l) { @@ -591,58 +632,6 @@ struct ParamTraits<ContextNode::Type> { } }; -template <> -struct ParamTraits<WebInputEvent::Type> { - typedef WebInputEvent::Type param_type; - static void Write(Message* m, const param_type& p) { - m->WriteInt(p); - } - static bool Read(const Message* m, void** iter, param_type* p) { - int type; - if (!m->ReadInt(iter, &type)) - return false; - *p = static_cast<WebInputEvent::Type>(type); - return true; - } - static void Log(const param_type& p, std::wstring* l) { - std::wstring event; - switch (p) { - case ContextNode::NONE: - event = L"NONE"; - break; - case ContextNode::PAGE: - event = L"PAGE"; - break; - case ContextNode::FRAME: - event = L"FRAME"; - break; - case ContextNode::LINK: - event = L"LINK"; - break; - case ContextNode::IMAGE: - event = L"IMAGE"; - break; - case ContextNode::IMAGE_LINK: - event = L"IMAGE_LINK"; - break; - case ContextNode::SELECTION: - event = L"SELECTION"; - break; - case ContextNode::EDITABLE: - event = L"EDITABLE"; - break; - case ContextNode::MISPELLED_WORD: - event = L"MISPELLED_WORD"; - break; - default: - event = L"UNKNOWN"; - break; - } - - LogParam(event, l); - } -}; - // Traits for ViewMsg_Accessibility_In_Params structure to pack/unpack. template <> struct ParamTraits<ViewMsg_Accessibility_In_Params> { @@ -943,7 +932,7 @@ template <> struct ParamTraits<ViewHostMsg_ContextMenu_Params> { typedef ViewHostMsg_ContextMenu_Params param_type; static void Write(Message* m, const param_type& p) { - WriteParam(m, p.type); + WriteParam(m, p.node); WriteParam(m, p.x); WriteParam(m, p.y); WriteParam(m, p.link_url); @@ -959,7 +948,7 @@ struct ParamTraits<ViewHostMsg_ContextMenu_Params> { } static bool Read(const Message* m, void** iter, param_type* p) { return - ReadParam(m, iter, &p->type) && + ReadParam(m, iter, &p->node) && ReadParam(m, iter, &p->x) && ReadParam(m, iter, &p->y) && ReadParam(m, iter, &p->link_url) && diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 0eb16ee..b8d321a 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -2027,7 +2027,7 @@ void RenderView::SyncNavigationState() { } void RenderView::ShowContextMenu(WebView* webview, - ContextNode::Type type, + ContextNode node, int x, int y, const GURL& link_url, @@ -2039,7 +2039,7 @@ void RenderView::ShowContextMenu(WebView* webview, int edit_flags, const std::string& security_info) { ViewHostMsg_ContextMenu_Params params; - params.type = type; + params.node = node; params.x = x; params.y = y; params.image_url = image_url; diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 5aff4bd..c7f5384 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -234,7 +234,7 @@ class RenderView : public RenderWidget, ErrorPageType error_type); virtual void ShowContextMenu(WebView* webview, - ContextNode::Type type, + ContextNode node, int x, int y, const GURL& link_url, diff --git a/webkit/glue/context_menu_client_impl.cc b/webkit/glue/context_menu_client_impl.cc index e2fbfcf..30f5e1a 100644 --- a/webkit/glue/context_menu_client_impl.cc +++ b/webkit/glue/context_menu_client_impl.cc @@ -108,23 +108,23 @@ void ContextMenuClientImpl::contextMenuDestroyed() { // Figure out the URL of a page or subframe. Returns |page_type| as the type, // which indicates page or subframe, or ContextNode::NONE if the URL could not // be determined for some reason. -static ContextNode::Type GetTypeAndURLFromFrame(WebCore::Frame* frame, - GURL* url, - ContextNode::Type page_type) { - ContextNode::Type type = ContextNode::NONE; +static ContextNode GetTypeAndURLFromFrame(WebCore::Frame* frame, + GURL* url, + ContextNode page_node) { + ContextNode node; if (frame) { WebCore::DocumentLoader* dl = frame->loader()->documentLoader(); if (dl) { WebDataSource* ds = static_cast<WebDocumentLoaderImpl*>(dl)-> GetDataSource(); if (ds) { - type = page_type; + node = page_node; *url = ds->HasUnreachableURL() ? ds->GetUnreachableURL() : ds->GetRequest().GetURL(); } } } - return type; + return node; } WebCore::PlatformMenuDescription @@ -144,19 +144,17 @@ WebCore::PlatformMenuDescription WebCore::IntPoint menu_point = selected_frame->view()->contentsToWindow(r.point()); - ContextNode::Type type = ContextNode::NONE; + ContextNode node; // Links, Images and Image-Links take preference over all else. WebCore::KURL link_url = r.absoluteLinkURL(); if (!link_url.isEmpty()) { - type = ContextNode::LINK; + node.type |= ContextNode::LINK; } WebCore::KURL image_url = r.absoluteImageURL(); if (!image_url.isEmpty()) { - type = ContextNode::IMAGE; + node.type |= ContextNode::IMAGE; } - if (!image_url.isEmpty() && !link_url.isEmpty()) - type = ContextNode::IMAGE_LINK; // If it's not a link, an image or an image link, show a selection menu or a // more generic page menu. @@ -168,37 +166,40 @@ WebCore::PlatformMenuDescription std::wstring frame_encoding; // Send the frame and page URLs in any case. - ContextNode::Type frame_type = ContextNode::NONE; - ContextNode::Type page_type = + ContextNode frame_node = ContextNode(ContextNode::NONE); + ContextNode page_node = GetTypeAndURLFromFrame(webview_->main_frame()->frame(), &page_url, - ContextNode::PAGE); + ContextNode(ContextNode::PAGE)); if (selected_frame != webview_->main_frame()->frame()) { - frame_type = GetTypeAndURLFromFrame(selected_frame, + frame_node = GetTypeAndURLFromFrame(selected_frame, &frame_url, - ContextNode::FRAME); + ContextNode(ContextNode::FRAME)); frame_encoding = webkit_glue::StringToStdWString( selected_frame->loader()->encoding()); } + + if (r.isSelected()) { + node.type |= ContextNode::SELECTION; + selection_text_string = CollapseWhitespace( + webkit_glue::StringToStdWString(selected_frame->selectedText()), + false); + } + + if (r.isContentEditable()) { + node.type |= ContextNode::EDITABLE; + if (webview_->GetFocusedWebCoreFrame()->editor()-> + isContinuousSpellCheckingEnabled()) { + misspelled_word_string = GetMisspelledWord(default_menu, + selected_frame); + } + } - if (type == ContextNode::NONE) { - if (r.isContentEditable()) { - type = ContextNode::EDITABLE; - if (webview_->GetFocusedWebCoreFrame()->editor()-> - isContinuousSpellCheckingEnabled()) { - misspelled_word_string = GetMisspelledWord(default_menu, - selected_frame); - } - } else if (r.isSelected()) { - type = ContextNode::SELECTION; - selection_text_string = - CollapseWhitespace( - webkit_glue::StringToStdWString(selected_frame->selectedText()), - false); - } else if (selected_frame != webview_->main_frame()->frame()) { - type = frame_type; + if (node.type == ContextNode::NONE) { + if (selected_frame != webview_->main_frame()->frame()) { + node = frame_node; } else { - type = page_type; + node = page_node; } } @@ -232,7 +233,7 @@ WebCore::PlatformMenuDescription WebViewDelegate* d = webview_->delegate(); if (d) { d->ShowContextMenu(webview_, - type, + node, menu_point.x(), menu_point.y(), webkit_glue::KURLToGURL(link_url), diff --git a/webkit/glue/context_node_types.h b/webkit/glue/context_node_types.h index 7bf22a8..b20814a 100644 --- a/webkit/glue/context_node_types.h +++ b/webkit/glue/context_node_types.h @@ -8,45 +8,35 @@ #include "base/basictypes.h" #include "base/logging.h" -// This class is for scoping only. -class ContextNode { - public: - // This enumeration defines the type of node that the user may perform a - // contextual action on in the WebView. - enum Type { - +// The type of node that the user may perform a contextual action on +// in the WebView. +struct ContextNode { + enum TypeBit { // No node is selected - NONE = 0, + NONE = 0x0, // The top page is selected - PAGE = 1, + PAGE = 0x1, // A subframe page is selected - FRAME = 2, + FRAME = 0x2, // A link is selected - LINK = 3, + LINK = 0x4, // An image is selected - IMAGE = 4, - - // An image that is also a link is selected - IMAGE_LINK = 5, + IMAGE = 0x8, // There is a textual or mixed selection that is selected - SELECTION = 6, + SELECTION = 0x10, - // An editiable element is selected - EDITABLE = 7, + // An editable element is selected + EDITABLE = 0x20, // A misspelled word is selected - MISPELLED_WORD = 8 + MISSPELLED_WORD = 0x40, }; - static Type FromInt(int32 type) { - return static_cast<Type>(type); - } - enum Capability { CAN_DO_NONE = 0x0, CAN_UNDO = 0x1, @@ -57,6 +47,10 @@ class ContextNode { CAN_DELETE = 0x20, CAN_SELECT_ALL = 0x40, }; + + int32 type; + ContextNode() : type(NONE) {} + explicit ContextNode(int32 t) : type(t) {} }; #endif // WEBKIT_GLUE_CONTEXT_NODE_TYPES_H__ diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h index 09abc68..982ec49 100644 --- a/webkit/glue/webview_delegate.h +++ b/webkit/glue/webview_delegate.h @@ -549,7 +549,7 @@ class WebViewDelegate : virtual public WebWidgetDelegate { // @abstract Shows a context menu with commands relevant to a specific // element on the current page. // @param webview The WebView sending the delegate method. - // @param type The type of node(s) the context menu is being invoked on + // @param node The node(s) the context menu is being invoked on // @param x The x position of the mouse pointer (relative to the webview) // @param y The y position of the mouse pointer (relative to the webview) // @param link_url The absolute URL of the link that contains the node the @@ -566,7 +566,7 @@ class WebViewDelegate : virtual public WebWidgetDelegate { // @param frame_encoding Which indicates the encoding of current focused // sub frame. virtual void ShowContextMenu(WebView* webview, - ContextNode::Type type, + ContextNode node, int x, int y, const GURL& link_url, diff --git a/webkit/tools/test_shell/test_webview_delegate.cc b/webkit/tools/test_shell/test_webview_delegate.cc index 684b22a..f04eebe 100644 --- a/webkit/tools/test_shell/test_webview_delegate.cc +++ b/webkit/tools/test_shell/test_webview_delegate.cc @@ -471,7 +471,7 @@ void TestWebViewDelegate::StartDragging(WebView* webview, } void TestWebViewDelegate::ShowContextMenu(WebView* webview, - ContextNode::Type type, + ContextNode node, int x, int y, const GURL& link_url, @@ -482,7 +482,7 @@ void TestWebViewDelegate::ShowContextMenu(WebView* webview, const std::wstring& misspelled_word, int edit_flags, const std::string& security_info) { - CapturedContextMenuEvent context(type, x, y); + CapturedContextMenuEvent context(node, x, y); captured_context_menu_events_.push_back(context); } diff --git a/webkit/tools/test_shell/test_webview_delegate.h b/webkit/tools/test_shell/test_webview_delegate.h index 65d0723..bc3836f 100644 --- a/webkit/tools/test_shell/test_webview_delegate.h +++ b/webkit/tools/test_shell/test_webview_delegate.h @@ -40,15 +40,15 @@ class TestWebViewDelegate : public base::RefCounted<TestWebViewDelegate>, public WebViewDelegate { public: struct CapturedContextMenuEvent { - CapturedContextMenuEvent(ContextNode::Type in_type, + CapturedContextMenuEvent(ContextNode in_node, int in_x, int in_y) - : type(in_type), + : node(in_node), x(in_x), y(in_y) { } - ContextNode::Type type; + ContextNode node; int x; int y; }; @@ -102,7 +102,7 @@ class TestWebViewDelegate : public base::RefCounted<TestWebViewDelegate>, virtual void StartDragging(WebView* webview, const WebDropData& drop_data); virtual void ShowContextMenu(WebView* webview, - ContextNode::Type type, + ContextNode node, int x, int y, const GURL& link_url, |