1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_RENDERER_CONTEXT_MENU_RENDER_VIEW_CONTEXT_MENU_H_
6 #define CHROME_BROWSER_RENDERER_CONTEXT_MENU_RENDER_VIEW_CONTEXT_MENU_H_
11 #include "base/memory/scoped_ptr.h"
12 #include "base/observer_list.h"
13 #include "base/strings/string16.h"
14 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
15 #include "chrome/browser/extensions/context_menu_matcher.h"
16 #include "chrome/browser/extensions/menu_manager.h"
17 #include "chrome/browser/renderer_context_menu/context_menu_content_type.h"
18 #include "chrome/browser/renderer_context_menu/render_view_context_menu_observer.h"
19 #include "content/public/common/context_menu_params.h"
20 #include "content/public/common/page_transition_types.h"
21 #include "ui/base/models/simple_menu_model.h"
22 #include "ui/base/window_open_disposition.h"
24 class PrintPreviewContextMenuObserver
;
26 class SpellingMenuObserver
;
27 class SpellCheckerSubMenuObserver
;
30 class RenderFrameHost
;
35 namespace extensions
{
45 struct WebMediaPlayerAction
;
46 struct WebPluginAction
;
49 // An interface that controls a RenderViewContextMenu instance from observers.
50 // This interface is designed mainly for controlling the instance while showing
51 // so we can add a context-menu item that takes long time to create its text,
52 // such as retrieving the item text from a server. The simplest usage is:
53 // 1. Adding an item with temporary text;
54 // 2. Posting a background task that creates the item text, and;
55 // 3. Calling UpdateMenuItem() in the callback function.
56 // The following snippet describes the simple usage that updates a context-menu
57 // item with this interface.
59 // class MyTask : public net::URLFetcherDelegate {
61 // MyTask(RenderViewContextMenuProxy* proxy, int id)
65 // virtual ~MyTask() {
67 // virtual void OnURLFetchComplete(const net::URLFetcher* source,
69 // const net::URLRequestStatus& status,
71 // const net::ResponseCookies& cookies,
72 // const std::string& data) {
73 // bool enabled = response == 200;
74 // const char* text = enabled ? "OK" : "ERROR";
75 // proxy_->UpdateMenuItem(id_, enabled, base::ASCIIToUTF16(text));
77 // void Start(const GURL* url, net::URLRequestContextGetter* context) {
78 // fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this));
79 // fetcher_->SetRequestContext(context);
80 // content::AssociateURLFetcherWithRenderView(
82 // proxy_->GetRenderViewHost()->GetSiteInstance()->GetSite(),
83 // proxy_->GetRenderViewHost()->GetProcess()->GetID(),
84 // proxy_->GetRenderViewHost()->GetRoutingID());
89 // URLFetcher fetcher_;
90 // RenderViewContextMenuProxy* proxy_;
94 // void RenderViewContextMenu::AppendEditableItems() {
95 // // Add a menu item with temporary text shown while we create the final
97 // menu_model_.AddItemWithStringId(IDC_MY_ITEM, IDC_MY_TEXT);
99 // // Start a task that creates the final text.
100 // my_task_ = new MyTask(this, IDC_MY_ITEM);
101 // my_task_->Start(...);
104 class RenderViewContextMenuProxy
{
106 // Add a menu item to a context menu.
107 virtual void AddMenuItem(int command_id
, const base::string16
& title
) = 0;
108 virtual void AddCheckItem(int command_id
, const base::string16
& title
) = 0;
109 virtual void AddSeparator() = 0;
111 // Add a submenu item to a context menu.
112 virtual void AddSubMenu(int command_id
,
113 const base::string16
& label
,
114 ui::MenuModel
* model
) = 0;
116 // Update the status and text of the specified context-menu item.
117 virtual void UpdateMenuItem(int command_id
,
120 const base::string16
& title
) = 0;
122 // Retrieve the given associated objects with a context menu.
123 virtual content::RenderViewHost
* GetRenderViewHost() const = 0;
124 virtual content::WebContents
* GetWebContents() const = 0;
125 virtual Profile
* GetProfile() const = 0;
128 class RenderViewContextMenu
: public ui::SimpleMenuModel::Delegate
,
129 public RenderViewContextMenuProxy
{
131 static const size_t kMaxSelectionTextLength
;
133 RenderViewContextMenu(content::RenderFrameHost
* render_frame_host
,
134 const content::ContextMenuParams
& params
);
136 virtual ~RenderViewContextMenu();
138 // Initializes the context menu.
141 // Programmatically closes the context menu.
144 const ui::SimpleMenuModel
& menu_model() const { return menu_model_
; }
145 const content::ContextMenuParams
& params() const { return params_
; }
147 // SimpleMenuModel::Delegate implementation.
148 virtual bool IsCommandIdChecked(int command_id
) const OVERRIDE
;
149 virtual bool IsCommandIdEnabled(int command_id
) const OVERRIDE
;
150 virtual void ExecuteCommand(int command_id
, int event_flags
) OVERRIDE
;
151 virtual void MenuWillShow(ui::SimpleMenuModel
* source
) OVERRIDE
;
152 virtual void MenuClosed(ui::SimpleMenuModel
* source
) OVERRIDE
;
154 // RenderViewContextMenuProxy implementation.
155 virtual void AddMenuItem(int command_id
,
156 const base::string16
& title
) OVERRIDE
;
157 virtual void AddCheckItem(int command_id
,
158 const base::string16
& title
) OVERRIDE
;
159 virtual void AddSeparator() OVERRIDE
;
160 virtual void AddSubMenu(int command_id
,
161 const base::string16
& label
,
162 ui::MenuModel
* model
) OVERRIDE
;
163 virtual void UpdateMenuItem(int command_id
,
166 const base::string16
& title
) OVERRIDE
;
167 virtual content::RenderViewHost
* GetRenderViewHost() const OVERRIDE
;
168 virtual content::WebContents
* GetWebContents() const OVERRIDE
;
169 virtual Profile
* GetProfile() const OVERRIDE
;
174 // Platform specific functions.
175 virtual void PlatformInit() = 0;
176 virtual void PlatformCancel() = 0;
177 virtual bool GetAcceleratorForCommandId(
179 ui::Accelerator
* accelerator
) = 0;
180 virtual void AppendPlatformEditableItems();
182 content::ContextMenuParams params_
;
183 content::WebContents
* source_web_contents_
;
184 // The RenderFrameHost's IDs.
185 int render_process_id_
;
186 int render_frame_id_
;
189 ui::SimpleMenuModel menu_model_
;
190 extensions::ContextMenuMatcher extension_items_
;
193 friend class RenderViewContextMenuTest
;
194 friend class RenderViewContextMenuPrefsTest
;
196 static bool IsDevToolsURL(const GURL
& url
);
197 static bool IsInternalResourcesURL(const GURL
& url
);
198 static bool ExtensionContextAndPatternMatch(
199 const content::ContextMenuParams
& params
,
200 extensions::MenuItem::ContextList contexts
,
201 const extensions::URLPatternSet
& target_url_patterns
);
202 static bool MenuItemMatchesParams(const content::ContextMenuParams
& params
,
203 const extensions::MenuItem
* item
);
205 // Gets the extension (if any) associated with the WebContents that we're in.
206 const extensions::Extension
* GetExtension() const;
207 bool AppendCustomItems();
209 void AppendDeveloperItems();
210 void AppendDevtoolsForUnpackedExtensions();
211 void AppendLinkItems();
212 void AppendImageItems();
213 void AppendAudioItems();
214 void AppendVideoItems();
215 void AppendMediaItems();
216 void AppendPluginItems();
217 void AppendPageItems();
218 void AppendFrameItems();
219 void AppendCopyItem();
220 void AppendPrintItem();
221 void AppendEditableItems();
222 void AppendSearchProvider();
223 void AppendAllExtensionItems();
224 void AppendCurrentExtensionItems();
225 void AppendPrintPreviewItems();
226 void AppendSearchWebForImageItems();
227 void AppendSpellingSuggestionsSubMenu();
228 void AppendSpellcheckOptionsSubMenu();
229 void AppendProtocolHandlerSubMenu();
231 // Opens the specified URL string in a new tab.
232 void OpenURL(const GURL
& url
, const GURL
& referrer
,
233 WindowOpenDisposition disposition
,
234 content::PageTransition transition
);
236 // Copy to the clipboard an image located at a point in the RenderView
237 void CopyImageAt(int x
, int y
);
239 // Get an image located at a point in the RenderView for search.
240 void GetImageThumbnailForSearch();
242 // Launch the inspector targeting a point in the RenderView
243 void Inspect(int x
, int y
);
245 // Writes the specified text/url to the system clipboard
246 void WriteURLToClipboard(const GURL
& url
);
248 void MediaPlayerActionAt(const gfx::Point
& location
,
249 const blink::WebMediaPlayerAction
& action
);
250 void PluginActionAt(const gfx::Point
& location
,
251 const blink::WebPluginAction
& action
);
253 bool IsDevCommandEnabled(int id
) const;
255 // Returns a list of registered ProtocolHandlers that can handle the clicked
257 ProtocolHandlerRegistry::ProtocolHandlerList
GetHandlersForLinkUrl();
259 // Returns a (possibly truncated) version of the current selection text
260 // suitable or putting in the title of a menu item.
261 base::string16
PrintableSelectionText();
263 // The destination URL to use if the user tries to search for or navigate to
265 GURL selection_navigation_url_
;
267 ui::SimpleMenuModel protocol_handler_submenu_model_
;
268 ProtocolHandlerRegistry
* protocol_handler_registry_
;
270 // An observer that handles spelling-menu items.
271 scoped_ptr
<SpellingMenuObserver
> spelling_menu_observer_
;
273 // An observer that handles a 'spell-checker options' submenu.
274 scoped_ptr
<SpellCheckerSubMenuObserver
> spellchecker_submenu_observer_
;
276 #if defined(ENABLE_FULL_PRINTING)
277 // An observer that disables menu items when print preview is active.
278 scoped_ptr
<PrintPreviewContextMenuObserver
> print_preview_menu_observer_
;
282 mutable ObserverList
<RenderViewContextMenuObserver
> observers_
;
284 // Whether a command has been executed. Used to track whether menu observers
285 // should be notified of menu closing without execution.
286 bool command_executed_
;
288 scoped_ptr
<ContextMenuContentType
> content_type_
;
290 DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenu
);
293 #endif // CHROME_BROWSER_RENDERER_CONTEXT_MENU_RENDER_VIEW_CONTEXT_MENU_H_