1 // Copyright 2013 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 #import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu_controller.h"
7 #include "base/strings/sys_string_conversions.h"
8 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
9 #include "chrome/browser/extensions/extension_action_manager.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/extensions/extension_system.h"
12 #include "chrome/browser/extensions/extension_tab_util.h"
13 #include "chrome/browser/extensions/extension_uninstall_dialog.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/chrome_pages.h"
17 #include "chrome/browser/ui/cocoa/browser_window_cocoa.h"
18 #include "chrome/browser/ui/cocoa/browser_window_controller.h"
19 #include "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h"
20 #include "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
21 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
22 #include "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
23 #include "chrome/common/extensions/extension_constants.h"
24 #include "chrome/common/extensions/manifest_url_handler.h"
25 #include "chrome/common/pref_names.h"
26 #include "chrome/common/url_constants.h"
27 #include "content/public/browser/web_contents.h"
28 #include "extensions/common/extension.h"
29 #include "grit/chromium_strings.h"
30 #include "grit/generated_resources.h"
31 #include "ui/base/l10n/l10n_util_mac.h"
33 using content::OpenURLParams;
34 using content::Referrer;
35 using content::WebContents;
36 using extensions::Extension;
38 // A class that shows a confirmation dialog to uninstall the given extension.
39 // Also acts as the extension's UI delegate in order to display the dialog.
40 class AsyncUninstaller : public ExtensionUninstallDialog::Delegate {
42 AsyncUninstaller(const Extension* extension, Browser* browser)
43 : extension_(extension),
44 profile_(browser->profile()) {
45 extension_uninstall_dialog_.reset(
46 ExtensionUninstallDialog::Create(profile_, browser, this));
47 extension_uninstall_dialog_->ConfirmUninstall(extension_);
50 virtual ~AsyncUninstaller() {}
52 // ExtensionUninstallDialog::Delegate:
53 virtual void ExtensionUninstallAccepted() OVERRIDE {
54 extensions::ExtensionSystem::Get(profile_)->extension_service()->
55 UninstallExtension(extension_->id(), false, NULL);
57 virtual void ExtensionUninstallCanceled() OVERRIDE {}
60 // The extension that's being uninstalled.
61 const Extension* extension_;
63 // The current profile. Weak.
66 scoped_ptr<ExtensionUninstallDialog> extension_uninstall_dialog_;
68 DISALLOW_COPY_AND_ASSIGN(AsyncUninstaller);
71 @interface ExtensionActionContextMenuController ()
72 - (void)onExtensionName:(id)sender;
73 - (void)onOptions:(id)sender;
74 - (void)onUninstall:(id)sender;
75 - (void)onHide:(id)sender;
76 - (void)onManage:(id)sender;
77 - (void)onInspect:(id)sender;
80 @implementation ExtensionActionContextMenuController
82 - (id)initWithExtension:(const Extension*)extension
83 browser:(Browser*)browser
84 extensionAction:(ExtensionAction*)action{
85 if ((self = [super init])) {
87 extension_ = extension;
93 - (void)populateMenu:(NSMenu*)menu {
94 [menu setAutoenablesItems:NO];
98 [menu addItemWithTitle:base::SysUTF8ToNSString(extension_->name())
99 action:@selector(onExtensionName:)
101 [item setTarget:self];
104 [menu addItem:[NSMenuItem separatorItem]];
107 item = [menu addItemWithTitle:
108 l10n_util::GetNSStringWithFixup(IDS_EXTENSIONS_OPTIONS_MENU_ITEM)
109 action:@selector(onOptions:)
111 [item setTarget:self];
112 [item setEnabled:extensions::ManifestURL::GetOptionsPage(
113 extension_).spec().length() > 0];
117 item = [menu addItemWithTitle:
118 l10n_util::GetNSStringWithFixup(IDS_EXTENSIONS_UNINSTALL)
119 action:@selector(onUninstall:)
121 [item setTarget:self];
123 // Hide. Only used for browser actions.
124 if (extensions::ExtensionActionManager::Get(
125 browser_->profile())->GetBrowserAction(*extension_)) {
126 item = [menu addItemWithTitle:
127 l10n_util::GetNSStringWithFixup(IDS_EXTENSIONS_HIDE_BUTTON)
128 action:@selector(onHide:)
130 [item setTarget:self];
134 [menu addItem:[NSMenuItem separatorItem]];
137 item = [menu addItemWithTitle:
138 l10n_util::GetNSStringWithFixup(IDS_MANAGE_EXTENSION)
139 action:@selector(onManage:)
141 [item setTarget:self];
144 PrefService* service = browser_->profile()->GetPrefs();
145 bool devMode = service->GetBoolean(prefs::kExtensionsUIDeveloperMode);
147 item = [menu addItemWithTitle:l10n_util::GetNSStringWithFixup(
148 IDS_EXTENSION_ACTION_INSPECT_POPUP)
149 action:@selector(onInspect:)
151 [item setTarget:self];
155 - (void)onExtensionName:(id)sender {
156 GURL url(std::string(extension_urls::kGalleryBrowsePrefix) +
157 std::string("/detail/") + extension_->id());
158 OpenURLParams params(url,
161 content::PAGE_TRANSITION_LINK,
163 browser_->OpenURL(params);
166 - (void)onOptions:(id)sender {
167 DCHECK(!extensions::ManifestURL::GetOptionsPage(extension_).is_empty());
168 extensions::ExtensionTabUtil::OpenOptionsPage(extension_, browser_);
171 - (void)onUninstall:(id)sender {
172 uninstaller_.reset(new AsyncUninstaller(extension_, browser_));
175 - (void)onHide:(id)sender {
176 extensions::ExtensionActionAPI::SetBrowserActionVisibility(
177 extensions::ExtensionSystem::Get(
178 browser_->profile())->extension_service()->extension_prefs(),
183 - (void)onManage:(id)sender {
184 chrome::ShowExtensions(browser_, extension_->id());
187 - (void)onInspect:(id)sender {
188 BrowserWindowCocoa* window =
189 static_cast<BrowserWindowCocoa*>(browser_->window());
190 ToolbarController* toolbarController =
191 [window->cocoa_controller() toolbarController];
192 LocationBarViewMac* locationBarView = [toolbarController locationBarBridge];
194 extensions::ExtensionActionManager* actionManager =
195 extensions::ExtensionActionManager::Get(browser_->profile());
196 NSPoint popupPoint = NSZeroPoint;
197 if (actionManager->GetPageAction(*extension_) == action_) {
198 popupPoint = locationBarView->GetPageActionBubblePoint(action_);
199 } else if (actionManager->GetBrowserAction(*extension_) == action_) {
200 BrowserActionsController* controller =
201 [toolbarController browserActionsController];
202 popupPoint = [controller popupPointForBrowserAction:extension_];
204 NOTREACHED() << "action_ is not a page action or browser action?";
207 content::WebContents* activeTab =
208 browser_->tab_strip_model()->GetActiveWebContents();
212 int tabId = extensions::ExtensionTabUtil::GetTabId(activeTab);
214 GURL url = action_->GetPopupUrl(tabId);
218 [ExtensionPopupController showURL:url
220 anchoredAt:popupPoint
221 arrowLocation:info_bubble::kTopRight