Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / extensions / extension_action_context_menu_controller.mm
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.
4
5 #import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu_controller.h"
6
7 #include "base/strings/sys_string_conversions.h"
8 #include "chrome/browser/extensions/active_script_controller.h"
9 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
10 #include "chrome/browser/extensions/extension_action_manager.h"
11 #include "chrome/browser/extensions/extension_service.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/browser_window.h"
17 #include "chrome/browser/ui/chrome_pages.h"
18 #include "chrome/browser/ui/cocoa/browser_window_cocoa.h"
19 #include "chrome/browser/ui/cocoa/browser_window_controller.h"
20 #include "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h"
21 #include "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
22 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
23 #include "chrome/browser/ui/cocoa/toolbar/toolbar_controller.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 "chrome/grit/chromium_strings.h"
28 #include "chrome/grit/generated_resources.h"
29 #include "content/public/browser/web_contents.h"
30 #include "extensions/browser/extension_prefs.h"
31 #include "extensions/browser/extension_system.h"
32 #include "extensions/browser/uninstall_reason.h"
33 #include "extensions/common/constants.h"
34 #include "extensions/common/extension.h"
35 #include "extensions/common/extension_urls.h"
36 #include "extensions/common/manifest_handlers/options_page_info.h"
37 #include "ui/base/l10n/l10n_util_mac.h"
38
39 using content::OpenURLParams;
40 using content::Referrer;
41 using content::WebContents;
42 using extensions::Extension;
43
44 // A class that shows a confirmation dialog to uninstall the given extension.
45 // Also acts as the extension's UI delegate in order to display the dialog.
46 class AsyncUninstaller : public extensions::ExtensionUninstallDialog::Delegate {
47  public:
48   AsyncUninstaller(const Extension* extension, Browser* browser)
49       : extension_(extension),
50         profile_(browser->profile()) {
51     extension_uninstall_dialog_.reset(
52         extensions::ExtensionUninstallDialog::Create(
53             profile_, browser->window()->GetNativeWindow(), this));
54     extension_uninstall_dialog_->ConfirmUninstall(extension_);
55   }
56
57   virtual ~AsyncUninstaller() {}
58
59   // ExtensionUninstallDialog::Delegate:
60   virtual void ExtensionUninstallAccepted() OVERRIDE {
61     extensions::ExtensionSystem::Get(profile_)
62         ->extension_service()
63         ->UninstallExtension(extension_->id(),
64                              extensions::UNINSTALL_REASON_USER_INITIATED,
65                              base::Bind(&base::DoNothing),
66                              NULL);
67   }
68   virtual void ExtensionUninstallCanceled() OVERRIDE {}
69
70  private:
71   // The extension that's being uninstalled.
72   const Extension* extension_;
73
74   // The current profile. Weak.
75   Profile* profile_;
76
77   scoped_ptr<extensions::ExtensionUninstallDialog> extension_uninstall_dialog_;
78
79   DISALLOW_COPY_AND_ASSIGN(AsyncUninstaller);
80 };
81
82 @interface ExtensionActionContextMenuController ()
83 - (void)onExtensionName:(id)sender;
84 - (void)onAlwaysRun:(id)sender;
85 - (void)onOptions:(id)sender;
86 - (void)onUninstall:(id)sender;
87 - (void)onHide:(id)sender;
88 - (void)onManage:(id)sender;
89 - (void)onInspect:(id)sender;
90 @end
91
92 @implementation ExtensionActionContextMenuController
93
94 - (id)initWithExtension:(const Extension*)extension
95                 browser:(Browser*)browser
96         extensionAction:(ExtensionAction*)action{
97   if ((self = [super init])) {
98     action_ = action;
99     extension_ = extension;
100     browser_ = browser;
101   }
102   return self;
103 }
104
105 - (void)populateMenu:(NSMenu*)menu {
106   [menu setAutoenablesItems:NO];
107
108   // Extension name.
109   NSMenuItem* item =
110       [menu addItemWithTitle:base::SysUTF8ToNSString(extension_->name())
111                       action:@selector(onExtensionName:)
112                keyEquivalent:@""];
113   [item setTarget:self];
114   [item setEnabled:extensions::ManifestURL::GetHomepageURL(
115       extension_).is_valid()];
116
117   // Separator.
118   [menu addItem:[NSMenuItem separatorItem]];
119
120   // Always Run. Only displayed if there is an active script injection action.
121   content::WebContents* activeTab =
122       browser_->tab_strip_model()->GetActiveWebContents();
123   if (activeTab &&
124       extensions::ActiveScriptController::GetForWebContents(activeTab)
125           ->WantsToRun(extension_)) {
126     item = [menu addItemWithTitle:
127                 l10n_util::GetNSStringWithFixup(IDS_EXTENSIONS_ALWAYS_RUN)
128                            action:@selector(onAlwaysRun:)
129                     keyEquivalent:@""];
130     [item setTarget:self];
131   }
132
133   // Options.
134   item = [menu addItemWithTitle:
135               l10n_util::GetNSStringWithFixup(IDS_EXTENSIONS_OPTIONS_MENU_ITEM)
136                          action:@selector(onOptions:)
137                   keyEquivalent:@""];
138   [item setTarget:self];
139   [item setEnabled:extensions::OptionsPageInfo::GetOptionsPage(
140       extension_).spec().length() > 0];
141
142
143   // Uninstall.
144   item = [menu addItemWithTitle:
145               l10n_util::GetNSStringWithFixup(IDS_EXTENSIONS_UNINSTALL)
146                          action:@selector(onUninstall:)
147                   keyEquivalent:@""];
148   [item setTarget:self];
149
150   // Hide. Only used for browser actions.
151   if (extensions::ExtensionActionManager::Get(
152           browser_->profile())->GetBrowserAction(*extension_)) {
153     item = [menu addItemWithTitle:
154                 l10n_util::GetNSStringWithFixup(IDS_EXTENSIONS_HIDE_BUTTON)
155                            action:@selector(onHide:)
156                     keyEquivalent:@""];
157     [item setTarget:self];
158   }
159
160   // Separator.
161   [menu addItem:[NSMenuItem separatorItem]];
162
163   // Manage.
164   item = [menu addItemWithTitle:
165               l10n_util::GetNSStringWithFixup(IDS_MANAGE_EXTENSION)
166                          action:@selector(onManage:)
167                   keyEquivalent:@""];
168   [item setTarget:self];
169
170   // Inspect.
171   PrefService* service = browser_->profile()->GetPrefs();
172   bool devMode = service->GetBoolean(prefs::kExtensionsUIDeveloperMode);
173   if (devMode) {
174     item = [menu addItemWithTitle:l10n_util::GetNSStringWithFixup(
175                 IDS_EXTENSION_ACTION_INSPECT_POPUP)
176                            action:@selector(onInspect:)
177                     keyEquivalent:@""];
178     [item setTarget:self];
179   }
180 }
181
182 - (void)onExtensionName:(id)sender {
183   GURL url(extension_urls::GetWebstoreItemDetailURLPrefix() + extension_->id());
184   OpenURLParams params(url,
185                        Referrer(),
186                        NEW_FOREGROUND_TAB,
187                        ui::PAGE_TRANSITION_LINK,
188                        false);
189   browser_->OpenURL(params);
190 }
191
192 - (void)onAlwaysRun:(id)sender {
193   content::WebContents* activeTab =
194       browser_->tab_strip_model()->GetActiveWebContents();
195   if (activeTab) {
196     extensions::ActiveScriptController::GetForWebContents(activeTab)
197         ->AlwaysRunOnVisibleOrigin(extension_);
198   }
199 }
200
201 - (void)onOptions:(id)sender {
202   DCHECK(!extensions::OptionsPageInfo::GetOptionsPage(extension_).is_empty());
203   extensions::ExtensionTabUtil::OpenOptionsPage(extension_, browser_);
204 }
205
206 - (void)onUninstall:(id)sender {
207   uninstaller_.reset(new AsyncUninstaller(extension_, browser_));
208 }
209
210 - (void)onHide:(id)sender {
211   extensions::ExtensionActionAPI::SetBrowserActionVisibility(
212       extensions::ExtensionPrefs::Get(browser_->profile()),
213       extension_->id(),
214       false);
215 }
216
217 - (void)onManage:(id)sender {
218   chrome::ShowExtensions(browser_, extension_->id());
219 }
220
221 - (void)onInspect:(id)sender {
222   BrowserWindowCocoa* window =
223       static_cast<BrowserWindowCocoa*>(browser_->window());
224   ToolbarController* toolbarController =
225       [window->cocoa_controller() toolbarController];
226   LocationBarViewMac* locationBarView = [toolbarController locationBarBridge];
227
228   extensions::ExtensionActionManager* actionManager =
229       extensions::ExtensionActionManager::Get(browser_->profile());
230   NSPoint popupPoint = NSZeroPoint;
231   if (actionManager->GetPageAction(*extension_) == action_) {
232     popupPoint = locationBarView->GetPageActionBubblePoint(action_);
233   } else if (actionManager->GetBrowserAction(*extension_) == action_) {
234     BrowserActionsController* controller =
235         [toolbarController browserActionsController];
236     popupPoint = [controller popupPointForBrowserAction:extension_];
237   } else {
238     NOTREACHED() << "action_ is not a page action or browser action?";
239   }
240
241   content::WebContents* activeTab =
242       browser_->tab_strip_model()->GetActiveWebContents();
243   if (!activeTab)
244     return;
245
246   int tabId = extensions::ExtensionTabUtil::GetTabId(activeTab);
247
248   GURL url = action_->GetPopupUrl(tabId);
249   if (!url.is_valid())
250     return;
251
252   [ExtensionPopupController showURL:url
253                           inBrowser:browser_
254                          anchoredAt:popupPoint
255                       arrowLocation:info_bubble::kTopRight
256                             devMode:YES];
257 }
258
259 @end