• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 #include "chrome/browser/extensions/extension_context_menu_model.h"
6 
7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/extension_tabs_module.h"
10 #include "chrome/browser/prefs/pref_service.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/common/extensions/extension.h"
14 #include "chrome/common/extensions/extension_action.h"
15 #include "chrome/common/extensions/extension_constants.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/common/url_constants.h"
18 #include "grit/generated_resources.h"
19 
20 enum MenuEntries {
21   NAME = 0,
22   CONFIGURE,
23   HIDE,
24   DISABLE,
25   UNINSTALL,
26   MANAGE,
27   INSPECT_POPUP
28 };
29 
ExtensionContextMenuModel(const Extension * extension,Browser * browser,PopupDelegate * delegate)30 ExtensionContextMenuModel::ExtensionContextMenuModel(
31     const Extension* extension,
32     Browser* browser,
33     PopupDelegate* delegate)
34     : ALLOW_THIS_IN_INITIALIZER_LIST(SimpleMenuModel(this)),
35       extension_id_(extension->id()),
36       browser_(browser),
37       profile_(browser->profile()),
38       delegate_(delegate) {
39   extension_action_ = extension->browser_action();
40   if (!extension_action_)
41     extension_action_ = extension->page_action();
42 
43   InitCommonCommands();
44 
45   if (profile_->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode) &&
46       delegate_) {
47     AddSeparator();
48     AddItemWithStringId(INSPECT_POPUP, IDS_EXTENSION_ACTION_INSPECT_POPUP);
49   }
50 }
51 
~ExtensionContextMenuModel()52 ExtensionContextMenuModel::~ExtensionContextMenuModel() {
53 }
54 
InitCommonCommands()55 void ExtensionContextMenuModel::InitCommonCommands() {
56   const Extension* extension = GetExtension();
57 
58   // The extension pointer should only be null if the extension was uninstalled,
59   // and since the menu just opened, it should still be installed.
60   DCHECK(extension);
61 
62   AddItem(NAME, UTF8ToUTF16(extension->name()));
63   AddSeparator();
64   AddItemWithStringId(CONFIGURE, IDS_EXTENSIONS_OPTIONS);
65   AddItemWithStringId(DISABLE, IDS_EXTENSIONS_DISABLE);
66   AddItemWithStringId(UNINSTALL, IDS_EXTENSIONS_UNINSTALL);
67   if (extension->browser_action())
68     AddItemWithStringId(HIDE, IDS_EXTENSIONS_HIDE_BUTTON);
69   AddSeparator();
70   AddItemWithStringId(MANAGE, IDS_MANAGE_EXTENSIONS);
71 }
72 
IsCommandIdChecked(int command_id) const73 bool ExtensionContextMenuModel::IsCommandIdChecked(int command_id) const {
74   return false;
75 }
76 
IsCommandIdEnabled(int command_id) const77 bool ExtensionContextMenuModel::IsCommandIdEnabled(int command_id) const {
78   const Extension* extension = this->GetExtension();
79   if (!extension)
80     return false;
81 
82   if (command_id == CONFIGURE) {
83     return extension->options_url().spec().length() > 0;
84   } else if (command_id == NAME) {
85     // The NAME links to the Homepage URL. If the extension doesn't have a
86     // homepage, we just disable this menu item.
87     return extension->GetHomepageURL().is_valid();
88   } else if (command_id == INSPECT_POPUP) {
89     TabContents* contents = browser_->GetSelectedTabContents();
90     if (!contents)
91       return false;
92 
93     return extension_action_->HasPopup(ExtensionTabUtil::GetTabId(contents));
94   } else if (command_id == DISABLE || command_id == UNINSTALL) {
95     // Some extension types can not be disabled or uninstalled.
96     return Extension::UserMayDisable(extension->location());
97   }
98   return true;
99 }
100 
GetAcceleratorForCommandId(int command_id,ui::Accelerator * accelerator)101 bool ExtensionContextMenuModel::GetAcceleratorForCommandId(
102     int command_id, ui::Accelerator* accelerator) {
103   return false;
104 }
105 
ExecuteCommand(int command_id)106 void ExtensionContextMenuModel::ExecuteCommand(int command_id) {
107   const Extension* extension = GetExtension();
108   if (!extension)
109     return;
110 
111   switch (command_id) {
112     case NAME: {
113       browser_->OpenURL(extension->GetHomepageURL(), GURL(),
114                         NEW_FOREGROUND_TAB, PageTransition::LINK);
115       break;
116     }
117     case CONFIGURE:
118       DCHECK(!extension->options_url().is_empty());
119       profile_->GetExtensionProcessManager()->OpenOptionsPage(extension,
120                                                               browser_);
121       break;
122     case HIDE: {
123       ExtensionService* extension_service = profile_->GetExtensionService();
124       extension_service->SetBrowserActionVisibility(extension, false);
125       break;
126     }
127     case DISABLE: {
128       ExtensionService* extension_service = profile_->GetExtensionService();
129       extension_service->DisableExtension(extension_id_);
130       break;
131     }
132     case UNINSTALL: {
133       AddRef();  // Balanced in Accepted() and Canceled()
134       extension_uninstall_dialog_.reset(new ExtensionUninstallDialog(profile_));
135       extension_uninstall_dialog_->ConfirmUninstall(this, extension);
136       break;
137     }
138     case MANAGE: {
139       browser_->OpenURL(GURL(chrome::kChromeUIExtensionsURL), GURL(),
140                         SINGLETON_TAB, PageTransition::LINK);
141       break;
142     }
143     case INSPECT_POPUP: {
144       delegate_->InspectPopup(extension_action_);
145       break;
146     }
147     default:
148      NOTREACHED() << "Unknown option";
149      break;
150   }
151 }
152 
ExtensionDialogAccepted()153 void ExtensionContextMenuModel::ExtensionDialogAccepted() {
154   if (GetExtension())
155     profile_->GetExtensionService()->UninstallExtension(extension_id_, false,
156                                                         NULL);
157 
158   Release();
159 }
160 
ExtensionDialogCanceled()161 void ExtensionContextMenuModel::ExtensionDialogCanceled() {
162   Release();
163 }
164 
GetExtension() const165 const Extension* ExtensionContextMenuModel::GetExtension() const {
166   ExtensionService* extension_service = profile_->GetExtensionService();
167   return extension_service->GetExtensionById(extension_id_, false);
168 }
169