Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / tab_contents / render_view_context_menu.h
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.
4
5 #ifndef CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_H_
6 #define CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_H_
7
8 #include <map>
9 #include <string>
10 #include <vector>
11
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"
24
25 class PrintPreviewContextMenuObserver;
26 class Profile;
27 class SpellingMenuObserver;
28 class SpellCheckerSubMenuObserver;
29
30 namespace content {
31 class RenderFrameHost;
32 class RenderViewHost;
33 class WebContents;
34 }
35
36 namespace extensions {
37 class Extension;
38 class MenuItem;
39 }
40
41 namespace gfx {
42 class Point;
43 }
44
45 namespace blink {
46 struct WebMediaPlayerAction;
47 struct WebPluginAction;
48 }
49
50 // An interface that controls a RenderViewContextMenu instance from observers.
51 // This interface is designed mainly for controlling the instance while showing
52 // so we can add a context-menu item that takes long time to create its text,
53 // such as retrieving the item text from a server. The simplest usage is:
54 // 1. Adding an item with temporary text;
55 // 2. Posting a background task that creates the item text, and;
56 // 3. Calling UpdateMenuItem() in the callback function.
57 // The following snippet describes the simple usage that updates a context-menu
58 // item with this interface.
59 //
60 //   class MyTask : public net::URLFetcherDelegate {
61 //    public:
62 //     MyTask(RenderViewContextMenuProxy* proxy, int id)
63 //         : proxy_(proxy),
64 //           id_(id) {
65 //     }
66 //     virtual ~MyTask() {
67 //     }
68 //     virtual void OnURLFetchComplete(const net::URLFetcher* source,
69 //                                     const GURL& url,
70 //                                     const net::URLRequestStatus& status,
71 //                                     int response,
72 //                                     const net::ResponseCookies& cookies,
73 //                                     const std::string& data) {
74 //       bool enabled = response == 200;
75 //       const char* text = enabled ? "OK" : "ERROR";
76 //       proxy_->UpdateMenuItem(id_, enabled, base::ASCIIToUTF16(text));
77 //     }
78 //     void Start(const GURL* url, net::URLRequestContextGetter* context) {
79 //       fetcher_.reset(new URLFetcher(url, URLFetcher::GET, this));
80 //       fetcher_->SetRequestContext(context);
81 //       content::AssociateURLFetcherWithRenderView(
82 //           fetcher_.get(),
83 //           proxy_->GetRenderViewHost()->GetSiteInstance()->GetSite(),
84 //           proxy_->GetRenderViewHost()->GetProcess()->GetID(),
85 //           proxy_->GetRenderViewHost()->GetRoutingID());
86 //       fetcher_->Start();
87 //     }
88 //
89 //    private:
90 //     URLFetcher fetcher_;
91 //     RenderViewContextMenuProxy* proxy_;
92 //     int id_;
93 //   };
94 //
95 //   void RenderViewContextMenu::AppendEditableItems() {
96 //     // Add a menu item with temporary text shown while we create the final
97 //     // text.
98 //     menu_model_.AddItemWithStringId(IDC_MY_ITEM, IDC_MY_TEXT);
99 //
100 //     // Start a task that creates the final text.
101 //     my_task_ = new MyTask(this, IDC_MY_ITEM);
102 //     my_task_->Start(...);
103 //   }
104 //
105 class RenderViewContextMenuProxy {
106  public:
107   // Add a menu item to a context menu.
108   virtual void AddMenuItem(int command_id, const base::string16& title) = 0;
109   virtual void AddCheckItem(int command_id, const base::string16& title) = 0;
110   virtual void AddSeparator() = 0;
111
112   // Add a submenu item to a context menu.
113   virtual void AddSubMenu(int command_id,
114                           const base::string16& label,
115                           ui::MenuModel* model) = 0;
116
117   // Update the status and text of the specified context-menu item.
118   virtual void UpdateMenuItem(int command_id,
119                               bool enabled,
120                               bool hidden,
121                               const base::string16& title) = 0;
122
123   // Retrieve the given associated objects with a context menu.
124   virtual content::RenderViewHost* GetRenderViewHost() const = 0;
125   virtual content::WebContents* GetWebContents() const = 0;
126   virtual Profile* GetProfile() const = 0;
127 };
128
129 class RenderViewContextMenu : public ui::SimpleMenuModel::Delegate,
130                               public RenderViewContextMenuProxy {
131  public:
132   static const size_t kMaxSelectionTextLength;
133
134   RenderViewContextMenu(content::RenderFrameHost* render_frame_host,
135                         const content::ContextMenuParams& params);
136
137   virtual ~RenderViewContextMenu();
138
139   // Initializes the context menu.
140   void Init();
141
142   // Programmatically closes the context menu.
143   void Cancel();
144
145   const ui::MenuModel& menu_model() const { return menu_model_; }
146
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;
153
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,
164                               bool enabled,
165                               bool hidden,
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;
170
171  protected:
172   void InitMenu();
173
174   // Platform specific functions.
175   virtual void PlatformInit() = 0;
176   virtual void PlatformCancel() = 0;
177   virtual bool GetAcceleratorForCommandId(
178       int command_id,
179       ui::Accelerator* accelerator) = 0;
180   virtual void AppendPlatformEditableItems();
181
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_;
187   Profile* profile_;
188
189   ui::SimpleMenuModel menu_model_;
190   extensions::ContextMenuMatcher extension_items_;
191
192  private:
193   friend class RenderViewContextMenuTest;
194   friend class RenderViewContextMenuPrefsTest;
195
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);
205
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();
231
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);
238
239   // Copy to the clipboard an image located at a point in the RenderView
240   void CopyImageAt(int x, int y);
241
242   // Get an image located at a point in the RenderView for search.
243   void GetImageThumbnailForSearch();
244
245   // Launch the inspector targeting a point in the RenderView
246   void Inspect(int x, int y);
247
248   // Writes the specified text/url to the system clipboard
249   void WriteURLToClipboard(const GURL& url);
250
251   void MediaPlayerActionAt(const gfx::Point& location,
252                            const blink::WebMediaPlayerAction& action);
253   void PluginActionAt(const gfx::Point& location,
254                       const blink::WebPluginAction& action);
255
256   bool IsDevCommandEnabled(int id) const;
257
258   // Returns a list of registered ProtocolHandlers that can handle the clicked
259   // on URL.
260   ProtocolHandlerRegistry::ProtocolHandlerList GetHandlersForLinkUrl();
261
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();
265
266   // The destination URL to use if the user tries to search for or navigate to
267   // a text selection.
268   GURL selection_navigation_url_;
269
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_;
274
275   // An observer that handles spelling-menu items.
276   scoped_ptr<SpellingMenuObserver> spelling_menu_observer_;
277
278   // An observer that handles a 'spell-checker options' submenu.
279   scoped_ptr<SpellCheckerSubMenuObserver> spellchecker_submenu_observer_;
280
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_;
284 #endif
285
286   // Our observers.
287   mutable ObserverList<RenderViewContextMenuObserver> observers_;
288
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_;
292
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.
298   bool is_guest_;
299
300   DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenu);
301 };
302
303 #endif  // CHROME_BROWSER_TAB_CONTENTS_RENDER_VIEW_CONTEXT_MENU_H_