| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h" | 5 #import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu.h" |
| 6 | 6 |
| 7 #include "base/sys_string_conversions.h" | 7 #include "base/sys_string_conversions.h" |
| 8 #include "chrome/browser/extensions/extension_service.h" | 8 #include "chrome/browser/extensions/extension_service.h" |
| 9 #include "chrome/browser/extensions/extension_tab_util.h" | 9 #include "chrome/browser/extensions/extension_tab_util.h" |
| 10 #include "chrome/browser/extensions/extension_uninstall_dialog.h" | 10 #include "chrome/browser/extensions/extension_uninstall_dialog.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 const Extension* extension_; | 65 const Extension* extension_; |
| 66 | 66 |
| 67 // The current profile. Weak. | 67 // The current profile. Weak. |
| 68 Profile* profile_; | 68 Profile* profile_; |
| 69 | 69 |
| 70 scoped_ptr<ExtensionUninstallDialog> extension_uninstall_dialog_; | 70 scoped_ptr<ExtensionUninstallDialog> extension_uninstall_dialog_; |
| 71 | 71 |
| 72 DISALLOW_COPY_AND_ASSIGN(AsyncUninstaller); | 72 DISALLOW_COPY_AND_ASSIGN(AsyncUninstaller); |
| 73 }; | 73 }; |
| 74 | 74 |
| 75 namespace extension_action_context_menu { | |
| 76 | |
| 77 class DevmodeObserver : public content::NotificationObserver { | |
| 78 public: | |
| 79 DevmodeObserver(ExtensionActionContextMenu* menu, | |
| 80 PrefService* service) | |
| 81 : menu_(menu), pref_service_(service) { | |
| 82 registrar_.Init(pref_service_); | |
| 83 registrar_.Add(prefs::kExtensionsUIDeveloperMode, this); | |
| 84 } | |
| 85 virtual ~DevmodeObserver() {} | |
| 86 | |
| 87 void Observe(int type, | |
| 88 const content::NotificationSource& source, | |
| 89 const content::NotificationDetails& details) { | |
| 90 if (type == chrome::NOTIFICATION_PREF_CHANGED) | |
| 91 [menu_ updateInspectorItem]; | |
| 92 else | |
| 93 NOTREACHED(); | |
| 94 } | |
| 95 | |
| 96 private: | |
| 97 ExtensionActionContextMenu* menu_; | |
| 98 PrefService* pref_service_; | |
| 99 PrefChangeRegistrar registrar_; | |
| 100 }; | |
| 101 | |
| 102 class ProfileObserverBridge : public content::NotificationObserver { | |
| 103 public: | |
| 104 ProfileObserverBridge(ExtensionActionContextMenu* owner, | |
| 105 const Profile* profile) | |
| 106 : owner_(owner), | |
| 107 profile_(profile) { | |
| 108 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, | |
| 109 content::Source<Profile>(profile)); | |
| 110 } | |
| 111 | |
| 112 ~ProfileObserverBridge() {} | |
| 113 | |
| 114 // Overridden from content::NotificationObserver | |
| 115 void Observe(int type, | |
| 116 const content::NotificationSource& source, | |
| 117 const content::NotificationDetails& details) { | |
| 118 if (type == chrome::NOTIFICATION_PROFILE_DESTROYED && | |
| 119 source == content::Source<Profile>(profile_)) { | |
| 120 [owner_ invalidateProfile]; | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 private: | |
| 125 ExtensionActionContextMenu* owner_; | |
| 126 const Profile* profile_; | |
| 127 content::NotificationRegistrar registrar_; | |
| 128 }; | |
| 129 | |
| 130 } // namespace extension_action_context_menu | |
| 131 | |
| 132 @interface ExtensionActionContextMenu(Private) | 75 @interface ExtensionActionContextMenu(Private) |
| 133 // Callback for the context menu items. | 76 // Callback for the context menu items. |
| 134 - (void)dispatch:(id)menuItem; | 77 - (void)dispatch:(id)menuItem; |
| 135 @end | 78 @end |
| 136 | 79 |
| 137 @implementation ExtensionActionContextMenu | 80 @implementation ExtensionActionContextMenu |
| 138 | 81 |
| 139 namespace { | 82 namespace { |
| 140 // Enum of menu item choices to their respective indices. | 83 // Enum of menu item choices to their respective indices. |
| 141 // NOTE: You MUST keep this in sync with the |menuItems| NSArray below. | 84 // NOTE: You MUST keep this in sync with the |menuItems| NSArray below. |
| 142 enum { | 85 enum { |
| 143 kExtensionContextName = 0, | 86 kExtensionContextName = 0, |
| 144 kExtensionContextOptions = 2, | 87 kExtensionContextOptions = 2, |
| 145 kExtensionContextDisable = 3, | 88 kExtensionContextDisable = 3, |
| 146 kExtensionContextUninstall = 4, | 89 kExtensionContextUninstall = 4, |
| 147 kExtensionContextHide = 5, | 90 kExtensionContextHide = 5, |
| 148 kExtensionContextManage = 7, | 91 kExtensionContextManage = 7, |
| 149 kExtensionContextInspect = 8 | |
| 150 }; | 92 }; |
| 151 | 93 |
| 152 int CurrentTabId() { | 94 int CurrentTabId() { |
| 153 Browser* browser = BrowserList::GetLastActive(); | 95 Browser* browser = BrowserList::GetLastActive(); |
| 154 if(!browser) | 96 if(!browser) |
| 155 return -1; | 97 return -1; |
| 156 WebContents* contents = browser->GetSelectedWebContents(); | 98 WebContents* contents = browser->GetSelectedWebContents(); |
| 157 if (!contents) | 99 if (!contents) |
| 158 return -1; | 100 return -1; |
| 159 return ExtensionTabUtil::GetTabId(contents); | 101 return ExtensionTabUtil::GetTabId(contents); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 if ([itemObj tag] == kExtensionContextHide && | 138 if ([itemObj tag] == kExtensionContextHide && |
| 197 !extension->browser_action()) { | 139 !extension->browser_action()) { |
| 198 [itemObj setTarget:nil]; // Item is disabled. | 140 [itemObj setTarget:nil]; // Item is disabled. |
| 199 [itemObj setHidden:YES]; // Item is hidden. | 141 [itemObj setHidden:YES]; // Item is hidden. |
| 200 } else { | 142 } else { |
| 201 [itemObj setTarget:self]; | 143 [itemObj setTarget:self]; |
| 202 } | 144 } |
| 203 } | 145 } |
| 204 } | 146 } |
| 205 | 147 |
| 206 NSString* inspectorTitle = | |
| 207 l10n_util::GetNSStringWithFixup(IDS_EXTENSION_ACTION_INSPECT_POPUP); | |
| 208 inspectorItem_.reset([[NSMenuItem alloc] initWithTitle:inspectorTitle | |
| 209 action:@selector(dispatch:) | |
| 210 keyEquivalent:@""]); | |
| 211 [inspectorItem_.get() setTarget:self]; | |
| 212 [inspectorItem_.get() setTag:kExtensionContextInspect]; | |
| 213 | |
| 214 PrefService* service = profile_->GetPrefs(); | |
| 215 observer_.reset( | |
| 216 new extension_action_context_menu::DevmodeObserver(self, service)); | |
| 217 profile_observer_.reset( | |
| 218 new extension_action_context_menu::ProfileObserverBridge(self, | |
| 219 profile)); | |
| 220 | |
| 221 [self updateInspectorItem]; | |
| 222 return self; | 148 return self; |
| 223 } | 149 } |
| 224 return nil; | 150 return nil; |
| 225 } | 151 } |
| 226 | 152 |
| 227 - (void)updateInspectorItem { | |
| 228 PrefService* service = profile_->GetPrefs(); | |
| 229 bool devmode = service->GetBoolean(prefs::kExtensionsUIDeveloperMode); | |
| 230 if (devmode) { | |
| 231 if ([self indexOfItem:inspectorItem_.get()] == -1) | |
| 232 [self addItem:inspectorItem_.get()]; | |
| 233 } else { | |
| 234 if ([self indexOfItem:inspectorItem_.get()] != -1) | |
| 235 [self removeItem:inspectorItem_.get()]; | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 - (void)dispatch:(id)menuItem { | 153 - (void)dispatch:(id)menuItem { |
| 240 Browser* browser = BrowserList::FindBrowserWithProfile(profile_); | 154 Browser* browser = BrowserList::FindBrowserWithProfile(profile_); |
| 241 if (!browser) | 155 if (!browser) |
| 242 return; | 156 return; |
| 243 | 157 |
| 244 NSMenuItem* item = (NSMenuItem*)menuItem; | 158 NSMenuItem* item = (NSMenuItem*)menuItem; |
| 245 switch ([item tag]) { | 159 switch ([item tag]) { |
| 246 case kExtensionContextName: { | 160 case kExtensionContextName: { |
| 247 GURL url(std::string(extension_urls::kGalleryBrowsePrefix) + | 161 GURL url(std::string(extension_urls::kGalleryBrowsePrefix) + |
| 248 std::string("/detail/") + extension_->id()); | 162 std::string("/detail/") + extension_->id()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 272 } | 186 } |
| 273 case kExtensionContextHide: { | 187 case kExtensionContextHide: { |
| 274 ExtensionService* extension_service = profile_->GetExtensionService(); | 188 ExtensionService* extension_service = profile_->GetExtensionService(); |
| 275 extension_service->SetBrowserActionVisibility(extension_, false); | 189 extension_service->SetBrowserActionVisibility(extension_, false); |
| 276 break; | 190 break; |
| 277 } | 191 } |
| 278 case kExtensionContextManage: { | 192 case kExtensionContextManage: { |
| 279 browser->ShowExtensionsTab(); | 193 browser->ShowExtensionsTab(); |
| 280 break; | 194 break; |
| 281 } | 195 } |
| 282 case kExtensionContextInspect: { | |
| 283 BrowserWindowCocoa* window = | |
| 284 static_cast<BrowserWindowCocoa*>(browser->window()); | |
| 285 ToolbarController* toolbarController = | |
| 286 [window->cocoa_controller() toolbarController]; | |
| 287 LocationBarViewMac* locationBarView = | |
| 288 [toolbarController locationBarBridge]; | |
| 289 | |
| 290 NSPoint popupPoint = NSZeroPoint; | |
| 291 if (extension_->page_action() == action_) { | |
| 292 popupPoint = locationBarView->GetPageActionBubblePoint(action_); | |
| 293 | |
| 294 } else if (extension_->browser_action() == action_) { | |
| 295 BrowserActionsController* controller = | |
| 296 [toolbarController browserActionsController]; | |
| 297 popupPoint = [controller popupPointForBrowserAction:extension_]; | |
| 298 | |
| 299 } else { | |
| 300 NOTREACHED() << "action_ is not a page action or browser action?"; | |
| 301 } | |
| 302 | |
| 303 int tabId = CurrentTabId(); | |
| 304 GURL url = action_->GetPopupUrl(tabId); | |
| 305 DCHECK(url.is_valid()); | |
| 306 [ExtensionPopupController showURL:url | |
| 307 inBrowser:BrowserList::GetLastActive() | |
| 308 anchoredAt:popupPoint | |
| 309 arrowLocation:info_bubble::kTopRight | |
| 310 devMode:YES]; | |
| 311 break; | |
| 312 } | |
| 313 default: | 196 default: |
| 314 NOTREACHED(); | 197 NOTREACHED(); |
| 315 break; | 198 break; |
| 316 } | 199 } |
| 317 } | 200 } |
| 318 | 201 |
| 319 - (BOOL)validateMenuItem:(NSMenuItem*)menuItem { | 202 - (BOOL)validateMenuItem:(NSMenuItem*)menuItem { |
| 320 if ([menuItem tag] == kExtensionContextInspect) { | 203 if ([menuItem tag] == kExtensionContextOptions) { |
| 321 // Disable 'Inspect popup' if there is no popup. | |
| 322 return action_ && action_->HasPopup(CurrentTabId()); | |
| 323 } else if ([menuItem tag] == kExtensionContextOptions) { | |
| 324 // Disable 'Options' if there are no options to set. | 204 // Disable 'Options' if there are no options to set. |
| 325 return extension_->options_url().spec().length() > 0; | 205 return extension_->options_url().spec().length() > 0; |
| 326 } | 206 } |
| 327 return YES; | 207 return YES; |
| 328 } | 208 } |
| 329 | 209 |
| 330 - (void)invalidateProfile { | |
| 331 observer_.reset(); | |
| 332 profile_ = NULL; | |
| 333 } | |
| 334 | |
| 335 @end | 210 @end |
| OLD | NEW |