1 // Copyright 2014 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_platform_delegate_cocoa.h"
10 #include "base/logging.h"
11 #include "chrome/browser/extensions/extension_action.h"
12 #include "chrome/browser/extensions/extension_view_host.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_window.h"
15 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
16 #import "chrome/browser/ui/cocoa/extensions/browser_actions_controller.h"
17 #import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
18 #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
19 #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h"
20 #import "chrome/browser/ui/cocoa/wrench_menu/wrench_menu_controller.h"
21 #include "chrome/browser/ui/toolbar/toolbar_action_view_delegate.h"
22 #include "chrome/common/extensions/api/extension_action/action_info.h"
23 #include "content/public/browser/notification_details.h"
24 #include "content/public/browser/notification_source.h"
25 #include "extensions/browser/notification_types.h"
26 #include "extensions/common/extension.h"
27 #include "extensions/common/feature_switch.h"
31 // Returns the notification to listen to for activation for a particular
32 // |extension_action|.
33 int GetNotificationTypeForAction(const ExtensionAction& extension_action) {
34 if (extension_action.action_type() == extensions::ActionInfo::TYPE_BROWSER)
35 return extensions::NOTIFICATION_EXTENSION_COMMAND_BROWSER_ACTION_MAC;
37 // We should only have page and browser action types.
38 DCHECK_EQ(extensions::ActionInfo::TYPE_PAGE, extension_action.action_type());
39 return extensions::NOTIFICATION_EXTENSION_COMMAND_PAGE_ACTION_MAC;
45 scoped_ptr<ExtensionActionPlatformDelegate>
46 ExtensionActionPlatformDelegate::Create(
47 ExtensionActionViewController* controller) {
48 return make_scoped_ptr(new ExtensionActionPlatformDelegateCocoa(controller));
51 ExtensionActionPlatformDelegateCocoa::ExtensionActionPlatformDelegateCocoa(
52 ExtensionActionViewController* controller)
53 : controller_(controller) {
56 ExtensionActionPlatformDelegateCocoa::~ExtensionActionPlatformDelegateCocoa() {
59 void ExtensionActionPlatformDelegateCocoa::RegisterCommand() {
60 // Commands are handled elsewhere for Cocoa.
63 void ExtensionActionPlatformDelegateCocoa::OnDelegateSet() {
66 GetNotificationTypeForAction(*controller_->extension_action()),
67 content::Source<Profile>(controller_->browser()->profile()));
70 void ExtensionActionPlatformDelegateCocoa::ShowPopup(
71 scoped_ptr<extensions::ExtensionViewHost> host,
72 bool grant_tab_permissions,
73 ExtensionActionViewController::PopupShowAction show_action) {
75 show_action == ExtensionActionViewController::SHOW_POPUP_AND_INSPECT;
76 [ExtensionPopupController host:host.Pass()
77 inBrowser:controller_->browser()
78 anchoredAt:GetPopupPoint()
79 arrowLocation:info_bubble::kTopRight
83 void ExtensionActionPlatformDelegateCocoa::CloseOverflowMenu() {
84 // If this was triggered by an action overflowed to the wrench menu, then
85 // the wrench menu will be open. Close it before opening the popup.
86 WrenchMenuController* wrenchMenuController =
87 [[[BrowserWindowController
88 browserWindowControllerForWindow:
89 controller_->browser()->window()->GetNativeWindow()]
90 toolbarController] wrenchMenuController];
91 if ([wrenchMenuController isMenuOpen])
92 [wrenchMenuController cancel];
95 NSPoint ExtensionActionPlatformDelegateCocoa::GetPopupPoint() const {
96 BrowserWindowController* windowController =
97 [BrowserWindowController browserWindowControllerForWindow:
98 controller_->browser()->window()->GetNativeWindow()];
100 if (controller_->extension_action()->action_type() ==
101 extensions::ActionInfo::TYPE_BROWSER ||
102 extensions::FeatureSwitch::extension_action_redesign()->IsEnabled()) {
103 BrowserActionsController* actionsController =
104 [[windowController toolbarController] browserActionsController];
105 popupPoint = [actionsController popupPointForId:controller_->GetId()];
107 DCHECK_EQ(extensions::ActionInfo::TYPE_PAGE,
108 controller_->extension_action()->action_type());
109 popupPoint = [windowController locationBarBridge]->GetPageActionBubblePoint(
110 controller_->extension_action());
115 void ExtensionActionPlatformDelegateCocoa::Observe(
117 const content::NotificationSource& source,
118 const content::NotificationDetails& details) {
120 case extensions::NOTIFICATION_EXTENSION_COMMAND_BROWSER_ACTION_MAC:
121 case extensions::NOTIFICATION_EXTENSION_COMMAND_PAGE_ACTION_MAC: {
123 GetNotificationTypeForAction(*controller_->extension_action()));
124 std::pair<const std::string, gfx::NativeWindow>* payload =
125 content::Details<std::pair<const std::string, gfx::NativeWindow> >(
127 const std::string& extension_id = payload->first;
128 gfx::NativeWindow window = payload->second;
129 if (window == controller_->browser()->window()->GetNativeWindow() &&
130 extension_id == controller_->extension()->id() &&
131 controller_->IsEnabled(
132 controller_->view_delegate()->GetCurrentWebContents())) {
133 controller_->ExecuteAction(true);
138 NOTREACHED() << L"Unexpected notification";