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, 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::WebContents
* web_contents
,
134 const content::ContextMenuParams
& params
);
136 virtual ~RenderViewContextMenu();
138 // Initializes the context menu.
141 // Programmatically closes the context menu.
144 const ui::MenuModel
& menu_model() const { return menu_model_
; }
146 // SimpleMenuModel::Delegate implementation.
147 virtual bool IsCommandIdChecked(int command_id
) const OVERRIDE
;
148 virtual bool IsCommandIdEnabled(int command_id
) const OVERRIDE
;
149 virtual void ExecuteCommand(int command_id
, int event_flags
) OVERRIDE
;
150 virtual void MenuWillShow(ui::SimpleMenuModel
* source
) OVERRIDE
;
151 virtual void MenuClosed(ui::SimpleMenuModel
* source
) OVERRIDE
;
153 // RenderViewContextMenuDelegate implementation.
154 virtual void AddMenuItem(int command_id
,
155 const base::string16
& title
) OVERRIDE
;
156 virtual void AddCheckItem(int command_id
,
157 const base::string16
& title
) OVERRIDE
;
158 virtual void AddSeparator() OVERRIDE
;
159 virtual void AddSubMenu(int command_id
,
160 const base::string16
& label
,
161 ui::MenuModel
* model
) OVERRIDE
;
162 virtual void UpdateMenuItem(int command_id
,
165 const base::string16
& title
) OVERRIDE
;
166 virtual content::RenderViewHost
* GetRenderViewHost() const OVERRIDE
;
167 virtual content::WebContents
* GetWebContents() const OVERRIDE
;
168 virtual Profile
* GetProfile() const OVERRIDE
;
173 // Platform specific functions.
174 virtual void PlatformInit() = 0;
175 virtual void PlatformCancel() = 0;
176 virtual bool GetAcceleratorForCommandId(
178 ui::Accelerator
* accelerator
) = 0;
179 virtual void AppendPlatformEditableItems();
181 content::ContextMenuParams params_
;
182 content::WebContents
* source_web_contents_
;
185 ui::SimpleMenuModel menu_model_
;
186 extensions::ContextMenuMatcher extension_items_
;
189 friend class RenderViewContextMenuTest
;
190 friend class RenderViewContextMenuPrefsTest
;
192 static bool IsDevToolsURL(const GURL
& url
);
193 static bool IsInternalResourcesURL(const GURL
& url
);
194 static bool ExtensionContextAndPatternMatch(
195 const content::ContextMenuParams
& params
,
196 extensions::MenuItem::ContextList contexts
,
197 const extensions::URLPatternSet
& target_url_patterns
);
198 static bool MenuItemMatchesParams(
199 const content::ContextMenuParams
& params
,
200 const extensions::MenuItem
* item
);
202 // Gets the extension (if any) associated with the WebContents that we're in.
203 const extensions::Extension
* GetExtension() const;
204 void AppendAppModeItems();
205 void AppendPlatformAppItems();
206 void AppendPopupExtensionItems();
207 void AppendPanelItems();
208 bool AppendCustomItems();
209 void AppendDeveloperItems();
210 void AppendLinkItems();
211 void AppendImageItems();
212 void AppendAudioItems();
213 void AppendVideoItems();
214 void AppendMediaItems();
215 void AppendPluginItems();
216 void AppendPageItems();
217 void AppendFrameItems();
218 void AppendCopyItem();
219 void AppendPrintItem();
220 void AppendEditableItems();
221 void AppendSearchProvider();
222 void AppendAllExtensionItems();
223 void AppendSpellingSuggestionsSubMenu();
224 void AppendSpellcheckOptionsSubMenu();
225 void AppendSpeechInputOptionsSubMenu();
226 void AppendProtocolHandlerSubMenu();
228 // Opens the specified URL string in a new tab. The |frame_id| specifies the
229 // frame in which the context menu was displayed, or 0 if the menu action is
230 // independent of that frame (e.g. protocol handler settings).
231 void OpenURL(const GURL
& url
, const GURL
& referrer
, int64 frame_id
,
232 WindowOpenDisposition disposition
,
233 content::PageTransition transition
);
235 // Copy to the clipboard an image located at a point in the RenderView
236 void CopyImageAt(int x
, int y
);
238 // Get an image located at a point in the RenderView for search.
239 void GetImageThumbnailForSearch();
241 // Launch the inspector targeting a point in the RenderView
242 void Inspect(int x
, int y
);
244 // Writes the specified text/url to the system clipboard
245 void WriteURLToClipboard(const GURL
& url
);
247 void MediaPlayerActionAt(const gfx::Point
& location
,
248 const blink::WebMediaPlayerAction
& action
);
249 void PluginActionAt(const gfx::Point
& location
,
250 const blink::WebPluginAction
& action
);
252 bool IsDevCommandEnabled(int id
) const;
254 // Returns a list of registered ProtocolHandlers that can handle the clicked
256 ProtocolHandlerRegistry::ProtocolHandlerList
GetHandlersForLinkUrl();
258 // Returns a (possibly truncated) version of the current selection text
259 // suitable or putting in the title of a menu item.
260 base::string16
PrintableSelectionText();
262 // The destination URL to use if the user tries to search for or navigate to
264 GURL selection_navigation_url_
;
266 ui::SimpleMenuModel speech_input_submenu_model_
;
267 ui::SimpleMenuModel protocol_handler_submenu_model_
;
268 ScopedVector
<ui::SimpleMenuModel
> extension_menu_models_
;
269 ProtocolHandlerRegistry
* protocol_handler_registry_
;
271 // An observer that handles spelling-menu items.
272 scoped_ptr
<SpellingMenuObserver
> spelling_menu_observer_
;
274 // An observer that handles a 'spell-checker options' submenu.
275 scoped_ptr
<SpellCheckerSubMenuObserver
> spellchecker_submenu_observer_
;
277 #if defined(ENABLE_FULL_PRINTING)
278 // An observer that disables menu items when print preview is active.
279 scoped_ptr
<PrintPreviewContextMenuObserver
> print_preview_menu_observer_
;
283 mutable ObserverList
<RenderViewContextMenuObserver
> observers_
;
285 // Whether a command has been executed. Used to track whether menu observers
286 // should be notified of menu closing without execution.
287 bool command_executed_
;
289 // Whether or not the menu was triggered for a browser plugin guest.
290 // Guests are rendered inside chrome apps, but have most of the actions
291 // that a regular web page has.
292 // Currently actions/items that are suppressed from guests are: searching,
293 // printing, speech and instant.
296 DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenu
);
299 #endif // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_H_