1 // Copyright (c) 2012 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_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_H_
6 #define CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_H_
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/observer_list.h"
15 #include "base/strings/string16.h"
16 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
17 #include "chrome/browser/extensions/context_menu_matcher.h"
18 #include "chrome/browser/extensions/menu_manager.h"
19 #include "chrome/browser/tab_contents/render_view_context_menu_observer.h"
20 #include "content/public/common/context_menu_params.h"
21 #include "content/public/common/page_transition_types.h"
22 #include "ui/base/models/simple_menu_model.h"
23 #include "ui/base/window_open_disposition.h"
25 class PrintPreviewContextMenuObserver
;
27 class SpellingMenuObserver
;
28 class SpellCheckerSubMenuObserver
;
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, 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::WebContents
* web_contents
,
134 const content::ContextMenuParams
& params
);
136 virtual ~RenderViewContextMenu();
138 // Initializes the context menu.
141 // Programmatically closes the context menu.
144 // Provide access to the menu model for ExternalTabContainer.
145 const ui::MenuModel
& menu_model() const { return menu_model_
; }
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 // RenderViewContextMenuDelegate 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_
;
186 ui::SimpleMenuModel menu_model_
;
187 extensions::ContextMenuMatcher extension_items_
;
189 // True if we are showing for an external tab contents. The default is false.
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(
203 const content::ContextMenuParams
& params
,
204 const extensions::MenuItem
* item
);
206 // Gets the extension (if any) associated with the WebContents that we're in.
207 const extensions::Extension
* GetExtension() const;
208 void AppendAppModeItems();
209 void AppendPlatformAppItems();
210 void AppendPopupExtensionItems();
211 void AppendPanelItems();
212 bool AppendCustomItems();
213 void AppendDeveloperItems();
214 void AppendLinkItems();
215 void AppendImageItems();
216 void AppendAudioItems();
217 void AppendVideoItems();
218 void AppendMediaItems();
219 void AppendPluginItems();
220 void AppendPageItems();
221 void AppendFrameItems();
222 void AppendCopyItem();
223 void AppendPrintItem();
224 void AppendEditableItems();
225 void AppendSearchProvider();
226 void AppendAllExtensionItems();
227 void AppendSpellingSuggestionsSubMenu();
228 void AppendSpellcheckOptionsSubMenu();
229 void AppendSpeechInputOptionsSubMenu();
230 void AppendProtocolHandlerSubMenu();
232 // Opens the specified URL string in a new tab. The |frame_id| specifies the
233 // frame in which the context menu was displayed, or 0 if the menu action is
234 // independent of that frame (e.g. protocol handler settings).
235 void OpenURL(const GURL
& url
, const GURL
& referrer
, int64 frame_id
,
236 WindowOpenDisposition disposition
,
237 content::PageTransition transition
);
239 // Copy to the clipboard an image located at a point in the RenderView
240 void CopyImageAt(int x
, int y
);
242 // Get an image located at a point in the RenderView for search.
243 void GetImageThumbnailForSearch();
245 // Launch the inspector targeting a point in the RenderView
246 void Inspect(int x
, int y
);
248 // Writes the specified text/url to the system clipboard
249 void WriteURLToClipboard(const GURL
& url
);
251 void MediaPlayerActionAt(const gfx::Point
& location
,
252 const blink::WebMediaPlayerAction
& action
);
253 void PluginActionAt(const gfx::Point
& location
,
254 const blink::WebPluginAction
& action
);
256 bool IsDevCommandEnabled(int id
) const;
258 // Returns a list of registered ProtocolHandlers that can handle the clicked
260 ProtocolHandlerRegistry::ProtocolHandlerList
GetHandlersForLinkUrl();
262 // Returns a (possibly truncated) version of the current selection text
263 // suitable or putting in the title of a menu item.
264 base::string16
PrintableSelectionText();
266 // The destination URL to use if the user tries to search for or navigate to
268 GURL selection_navigation_url_
;
270 ui::SimpleMenuModel speech_input_submenu_model_
;
271 ui::SimpleMenuModel protocol_handler_submenu_model_
;
272 ScopedVector
<ui::SimpleMenuModel
> extension_menu_models_
;
273 ProtocolHandlerRegistry
* protocol_handler_registry_
;
275 // An observer that handles spelling-menu items.
276 scoped_ptr
<SpellingMenuObserver
> spelling_menu_observer_
;
278 // An observer that handles a 'spell-checker options' submenu.
279 scoped_ptr
<SpellCheckerSubMenuObserver
> spellchecker_submenu_observer_
;
281 #if defined(ENABLE_FULL_PRINTING)
282 // An observer that disables menu items when print preview is active.
283 scoped_ptr
<PrintPreviewContextMenuObserver
> print_preview_menu_observer_
;
287 mutable ObserverList
<RenderViewContextMenuObserver
> observers_
;
289 // Whether a command has been executed. Used to track whether menu observers
290 // should be notified of menu closing without execution.
291 bool command_executed_
;
293 // Whether or not the menu was triggered for a browser plugin guest.
294 // Guests are rendered inside chrome apps, but have most of the actions
295 // that a regular web page has.
296 // Currently actions/items that are suppressed from guests are: searching,
297 // printing, speech and instant.
300 DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenu
);
303 #endif // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_H_