Home | History | Annotate | Download | only in renderer_context_menu
      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.
      4 
      5 #ifndef CHROME_BROWSER_RENDERER_CONTEXT_MENU_RENDER_VIEW_CONTEXT_MENU_H_
      6 #define CHROME_BROWSER_RENDERER_CONTEXT_MENU_RENDER_VIEW_CONTEXT_MENU_H_
      7 
      8 #include <map>
      9 #include <string>
     10 
     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"
     23 
     24 class PrintPreviewContextMenuObserver;
     25 class Profile;
     26 class SpellingMenuObserver;
     27 class SpellCheckerSubMenuObserver;
     28 
     29 namespace content {
     30 class RenderFrameHost;
     31 class RenderViewHost;
     32 class WebContents;
     33 }
     34 
     35 namespace extensions {
     36 class Extension;
     37 class MenuItem;
     38 }
     39 
     40 namespace gfx {
     41 class Point;
     42 }
     43 
     44 namespace blink {
     45 struct WebMediaPlayerAction;
     46 struct WebPluginAction;
     47 }
     48 
     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.
     58 //
     59 //   class MyTask : public net::URLFetcherDelegate {
     60 //    public:
     61 //     MyTask(RenderViewContextMenuProxy* proxy, int id)
     62 //         : proxy_(proxy),
     63 //           id_(id) {
     64 //     }
     65 //     virtual ~MyTask() {
     66 //     }
     67 //     virtual void OnURLFetchComplete(const net::URLFetcher* source,
     68 //                                     const GURL& url,
     69 //                                     const net::URLRequestStatus& status,
     70 //                                     int response,
     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));
     76 //     }
     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(
     81 //           fetcher_.get(),
     82 //           proxy_->GetRenderViewHost()->GetSiteInstance()->GetSite(),
     83 //           proxy_->GetRenderViewHost()->GetProcess()->GetID(),
     84 //           proxy_->GetRenderViewHost()->GetRoutingID());
     85 //       fetcher_->Start();
     86 //     }
     87 //
     88 //    private:
     89 //     URLFetcher fetcher_;
     90 //     RenderViewContextMenuProxy* proxy_;
     91 //     int id_;
     92 //   };
     93 //
     94 //   void RenderViewContextMenu::AppendEditableItems() {
     95 //     // Add a menu item with temporary text shown while we create the final
     96 //     // text.
     97 //     menu_model_.AddItemWithStringId(IDC_MY_ITEM, IDC_MY_TEXT);
     98 //
     99 //     // Start a task that creates the final text.
    100 //     my_task_ = new MyTask(this, IDC_MY_ITEM);
    101 //     my_task_->Start(...);
    102 //   }
    103 //
    104 class RenderViewContextMenuProxy {
    105  public:
    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;
    110 
    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;
    115 
    116   // Update the status and text of the specified context-menu item.
    117   virtual void UpdateMenuItem(int command_id,
    118                               bool enabled,
    119                               bool hidden,
    120                               const base::string16& title) = 0;
    121 
    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;
    126 };
    127 
    128 class RenderViewContextMenu : public ui::SimpleMenuModel::Delegate,
    129                               public RenderViewContextMenuProxy {
    130  public:
    131   static const size_t kMaxSelectionTextLength;
    132 
    133   RenderViewContextMenu(content::RenderFrameHost* render_frame_host,
    134                         const content::ContextMenuParams& params);
    135 
    136   virtual ~RenderViewContextMenu();
    137 
    138   // Initializes the context menu.
    139   void Init();
    140 
    141   // Programmatically closes the context menu.
    142   void Cancel();
    143 
    144   const ui::SimpleMenuModel& menu_model() const { return menu_model_; }
    145   const content::ContextMenuParams& params() const { return params_; }
    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   // 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,
    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(const content::ContextMenuParams& params,
    203                                     const extensions::MenuItem* item);
    204 
    205   // Gets the extension (if any) associated with the WebContents that we're in.
    206   const extensions::Extension* GetExtension() const;
    207   bool AppendCustomItems();
    208 
    209   void AppendDeveloperItems();
    210   void AppendDevtoolsForUnpackedExtensions();
    211   void AppendLinkItems();
    212   void AppendImageItems();
    213   void AppendAudioItems();
    214   void AppendCanvasItems();
    215   void AppendVideoItems();
    216   void AppendMediaItems();
    217   void AppendPluginItems();
    218   void AppendPageItems();
    219   void AppendFrameItems();
    220   void AppendCopyItem();
    221   void AppendPrintItem();
    222   void AppendEditableItems();
    223   void AppendSearchProvider();
    224   void AppendAllExtensionItems();
    225   void AppendCurrentExtensionItems();
    226   void AppendPrintPreviewItems();
    227   void AppendSearchWebForImageItems();
    228   void AppendSpellingSuggestionsSubMenu();
    229   void AppendSpellcheckOptionsSubMenu();
    230   void AppendProtocolHandlerSubMenu();
    231 
    232   // Opens the specified URL string in a new tab.
    233   void OpenURL(const GURL& url, const GURL& referrer,
    234                WindowOpenDisposition disposition,
    235                content::PageTransition transition);
    236 
    237   // Copy to the clipboard an image located at a point in the RenderView
    238   void CopyImageAt(int x, int y);
    239 
    240   // Get an image located at a point in the RenderView for search.
    241   void GetImageThumbnailForSearch();
    242 
    243   // Launch the inspector targeting a point in the RenderView
    244   void Inspect(int x, int y);
    245 
    246   // Writes the specified text/url to the system clipboard
    247   void WriteURLToClipboard(const GURL& url);
    248 
    249   void MediaPlayerActionAt(const gfx::Point& location,
    250                            const blink::WebMediaPlayerAction& action);
    251   void PluginActionAt(const gfx::Point& location,
    252                       const blink::WebPluginAction& action);
    253 
    254   bool IsDevCommandEnabled(int id) const;
    255 
    256   // Returns a list of registered ProtocolHandlers that can handle the clicked
    257   // on URL.
    258   ProtocolHandlerRegistry::ProtocolHandlerList GetHandlersForLinkUrl();
    259 
    260   // Returns a (possibly truncated) version of the current selection text
    261   // suitable or putting in the title of a menu item.
    262   base::string16 PrintableSelectionText();
    263 
    264   // The destination URL to use if the user tries to search for or navigate to
    265   // a text selection.
    266   GURL selection_navigation_url_;
    267 
    268   ui::SimpleMenuModel protocol_handler_submenu_model_;
    269   ProtocolHandlerRegistry* protocol_handler_registry_;
    270 
    271   // An observer that handles spelling-menu items.
    272   scoped_ptr<SpellingMenuObserver> spelling_menu_observer_;
    273 
    274   // An observer that handles a 'spell-checker options' submenu.
    275   scoped_ptr<SpellCheckerSubMenuObserver> spellchecker_submenu_observer_;
    276 
    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_;
    280 #endif
    281 
    282   // Our observers.
    283   mutable ObserverList<RenderViewContextMenuObserver> observers_;
    284 
    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_;
    288 
    289   scoped_ptr<ContextMenuContentType> content_type_;
    290 
    291   DISALLOW_COPY_AND_ASSIGN(RenderViewContextMenu);
    292 };
    293 
    294 #endif  // CHROME_BROWSER_RENDERER_CONTEXT_MENU_RENDER_VIEW_CONTEXT_MENU_H_
    295