Home | History | Annotate | Download | only in extensions
      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_EXTENSIONS_CONTEXT_MENU_MATCHER_H_
      6 #define CHROME_BROWSER_EXTENSIONS_CONTEXT_MENU_MATCHER_H_
      7 
      8 #include <map>
      9 
     10 #include "base/callback.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/memory/scoped_vector.h"
     13 #include "chrome/browser/extensions/menu_manager.h"
     14 #include "ui/base/models/simple_menu_model.h"
     15 
     16 class ExtensionContextMenuBrowserTest;
     17 
     18 namespace content {
     19 class BrowserContext;
     20 }
     21 
     22 namespace extensions {
     23 
     24 // This class contains code that is shared between the various places where
     25 // context menu items added by the extension or app should be shown.
     26 class ContextMenuMatcher {
     27  public:
     28   static const size_t kMaxExtensionItemTitleLength;
     29 
     30   // Convert a command ID so that it fits within the range for
     31   // extension context menu.
     32   static int ConvertToExtensionsCustomCommandId(int id);
     33 
     34   // Returns true if the given id is one generated for extension context menu.
     35   static bool IsExtensionsCustomCommandId(int id);
     36 
     37   // The |filter| will be called on possibly matching menu items, and its
     38   // result is used to determine which items to actually append to the menu.
     39   ContextMenuMatcher(content::BrowserContext* context,
     40                      ui::SimpleMenuModel::Delegate* delegate,
     41                      ui::SimpleMenuModel* menu_model,
     42                      const base::Callback<bool(const MenuItem*)>& filter);
     43 
     44   // This is a helper function to append items for one particular extension.
     45   // The |index| parameter is used for assigning id's, and is incremented for
     46   // each item actually added. |is_action_menu| is used for browser and page
     47   // action context menus, in which menu items are not placed in submenus
     48   // and the extension's icon is not shown.
     49   void AppendExtensionItems(const MenuItem::ExtensionKey& extension_key,
     50                             const base::string16& selection_text,
     51                             int* index,
     52                             bool is_action_menu);
     53 
     54   void Clear();
     55 
     56   // This function returns the top level context menu title of an extension
     57   // based on a printable selection text.
     58   base::string16 GetTopLevelContextMenuTitle(
     59       const MenuItem::ExtensionKey& extension_key,
     60       const base::string16& selection_text);
     61 
     62   bool IsCommandIdChecked(int command_id) const;
     63   bool IsCommandIdEnabled(int command_id) const;
     64   void ExecuteCommand(int command_id,
     65                       content::WebContents* web_contents,
     66                       const content::ContextMenuParams& params);
     67 
     68  private:
     69   friend class ::ExtensionContextMenuBrowserTest;
     70 
     71   bool GetRelevantExtensionTopLevelItems(
     72       const MenuItem::ExtensionKey& extension_key,
     73       const Extension** extension,
     74       bool* can_cross_incognito,
     75       MenuItem::List* items);
     76 
     77   MenuItem::List GetRelevantExtensionItems(
     78       const MenuItem::List& items,
     79       bool can_cross_incognito);
     80 
     81   // Used for recursively adding submenus of extension items.
     82   void RecursivelyAppendExtensionItems(const MenuItem::List& items,
     83                                        bool can_cross_incognito,
     84                                        const base::string16& selection_text,
     85                                        ui::SimpleMenuModel* menu_model,
     86                                        int* index,
     87                                        bool is_action_menu_top_level);
     88 
     89   // Attempts to get an MenuItem given the id of a context menu item.
     90   extensions::MenuItem* GetExtensionMenuItem(int id) const;
     91 
     92   // This will set the icon on the most recently-added item in the menu_model_.
     93   void SetExtensionIcon(const std::string& extension_id);
     94 
     95   content::BrowserContext* browser_context_;
     96   ui::SimpleMenuModel* menu_model_;
     97   ui::SimpleMenuModel::Delegate* delegate_;
     98 
     99   base::Callback<bool(const MenuItem*)> filter_;
    100 
    101   // Maps the id from a context menu item to the MenuItem's internal id.
    102   std::map<int, extensions::MenuItem::Id> extension_item_map_;
    103 
    104   // Keep track of and clean up menu models for submenus.
    105   ScopedVector<ui::SimpleMenuModel> extension_menu_models_;
    106 
    107   DISALLOW_COPY_AND_ASSIGN(ContextMenuMatcher);
    108 };
    109 
    110 }  // namespace extensions
    111 
    112 #endif  // CHROME_BROWSER_EXTENSIONS_CONTEXT_MENU_MATCHER_H_
    113