// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include <cmath>
-
#import "chrome/browser/ui/cocoa/location_bar/page_action_decoration.h"
#include "base/strings/sys_string_conversions.h"
-#include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
#include "chrome/browser/extensions/extension_action.h"
-#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_window.h"
#import "chrome/browser/ui/cocoa/extensions/extension_action_context_menu_controller.h"
-#import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
-#include "chrome/browser/ui/cocoa/last_active_browser_cocoa.h"
#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h"
-#include "chrome/browser/ui/webui/extensions/extension_info_ui.h"
-#include "components/sessions/session_id.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
+#include "chrome/browser/ui/extensions/extension_action_view_controller.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_registry.h"
-#include "extensions/common/manifest_handlers/icons_handler.h"
-#include "skia/ext/skia_utils_mac.h"
-#include "ui/gfx/canvas_skia_paint.h"
#include "ui/gfx/image/image.h"
using content::WebContents;
Browser* browser,
ExtensionAction* page_action)
: owner_(NULL),
- browser_(browser),
- page_action_(page_action),
- current_tab_id_(-1),
+ contextMenuController_(nil),
preview_enabled_(false) {
const Extension* extension = extensions::ExtensionRegistry::Get(
browser->profile())->enabled_extensions().GetByID(
page_action->extension_id());
DCHECK(extension);
- icon_factory_.reset(new ExtensionActionIconFactory(
- browser_->profile(), extension, page_action, this));
-
- registrar_.Add(this,
- extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
- content::Source<Profile>(browser_->profile()));
- registrar_.Add(this,
- extensions::NOTIFICATION_EXTENSION_COMMAND_PAGE_ACTION_MAC,
- content::Source<Profile>(browser_->profile()));
+ viewController_.reset(
+ new ExtensionActionViewController(extension, browser, page_action));
+ viewController_->SetDelegate(this);
// We set the owner last of all so that we can determine whether we are in
// the process of initializing this class or not.
// Either notify listeners or show a popup depending on the Page
// Action.
bool PageActionDecoration::OnMousePressed(NSRect frame, NSPoint location) {
- ActivatePageAction(frame, true);
+ ActivatePageAction(true);
// We don't want other code to try and handle this click. Returning true
// prevents this by indicating that we handled it.
return true;
}
bool PageActionDecoration::ActivatePageAction(bool grant_active_tab) {
- return ActivatePageAction(
- owner_->GetPageActionFrame(page_action_), grant_active_tab);
-}
-
-bool PageActionDecoration::ActivatePageAction(
- NSRect frame, bool grant_active_tab) {
WebContents* web_contents = owner_->GetWebContents();
if (!web_contents)
return false;
- switch (extensions::ExtensionActionAPI::Get(browser_->profile())->
- ExecuteExtensionAction(
- GetExtension(), browser_, grant_active_tab)) {
- case ExtensionAction::ACTION_NONE:
- break;
-
- case ExtensionAction::ACTION_SHOW_POPUP:
- ShowPopup(frame, page_action_->GetPopupUrl(current_tab_id_));
- break;
- }
-
+ viewController_->ExecuteAction(grant_active_tab);
return true;
}
-void PageActionDecoration::OnIconUpdated() {
- // If we have no owner, that means this class is still being constructed.
- WebContents* web_contents = owner_ ? owner_->GetWebContents() : NULL;
- if (web_contents) {
- UpdateVisibility(web_contents, current_url_);
- owner_->RedrawDecoration(this);
- }
+const extensions::Extension* PageActionDecoration::GetExtension() {
+ return viewController_->extension();
}
-void PageActionDecoration::UpdateVisibility(WebContents* contents,
- const GURL& url) {
- // Save this off so we can pass it back to the extension when the action gets
- // executed. See PageActionDecoration::OnMousePressed.
- current_tab_id_ =
- contents ? extensions::ExtensionTabUtil::GetTabId(contents) : -1;
- current_url_ = url;
+ExtensionAction* PageActionDecoration::GetPageAction() {
+ return viewController_->extension_action();
+}
- bool visible = contents &&
- (preview_enabled_ || page_action_->GetIsVisible(current_tab_id_));
+void PageActionDecoration::UpdateVisibility(WebContents* contents) {
+ bool visible =
+ contents && (preview_enabled_ || viewController_->IsEnabled(contents));
if (visible) {
- SetToolTip(page_action_->GetTitle(current_tab_id_));
+ SetToolTip(viewController_->GetTooltip(contents));
// Set the image.
- gfx::Image icon = icon_factory_->GetIcon(current_tab_id_);
+ gfx::Image icon = viewController_->GetIcon(contents);
if (!icon.IsEmpty()) {
SetImage(icon.ToNSImage());
} else if (!GetImage()) {
SetVisible(visible);
}
-void PageActionDecoration::SetToolTip(NSString* tooltip) {
- tooltip_.reset([tooltip retain]);
-}
-
-void PageActionDecoration::SetToolTip(std::string tooltip) {
- SetToolTip(tooltip.empty() ? nil : base::SysUTF8ToNSString(tooltip));
-}
-
NSString* PageActionDecoration::GetToolTip() {
return tooltip_.get();
}
}
NSMenu* PageActionDecoration::GetMenu() {
- const Extension* extension = GetExtension();
- if (!extension->ShowConfigureContextMenus())
- return nil;
-
- contextMenuController_.reset([[ExtensionActionContextMenuController alloc]
- initWithExtension:extension
- browser:browser_
- extensionAction:page_action_]);
-
- base::scoped_nsobject<NSMenu> contextMenu([[NSMenu alloc] initWithTitle:@""]);
- [contextMenuController_ populateMenu:contextMenu];
- return contextMenu.autorelease();
+ // |contextMenuController| can be nil if we don't show menus for this
+ // extension.
+ if (contextMenuController_) {
+ base::scoped_nsobject<NSMenu> contextMenu(
+ [[NSMenu alloc] initWithTitle:@""]);
+ [contextMenuController_ populateMenu:contextMenu];
+ return contextMenu.autorelease();
+ }
+ return nil;
}
-void PageActionDecoration::ShowPopup(const NSRect& frame,
- const GURL& popup_url) {
- // Anchor popup at the bottom center of the page action icon.
- AutocompleteTextField* field = owner_->GetAutocompleteTextField();
- NSPoint anchor = GetBubblePointInFrame(frame);
- anchor = [field convertPoint:anchor toView:nil];
+void PageActionDecoration::SetToolTip(const base::string16& tooltip) {
+ NSString* nsTooltip =
+ tooltip.empty() ? nil : base::SysUTF16ToNSString(tooltip);
+ tooltip_.reset([nsTooltip retain]);
+}
- [ExtensionPopupController showURL:popup_url
- inBrowser:chrome::GetLastActiveBrowser()
- anchoredAt:anchor
- arrowLocation:info_bubble::kTopRight
- devMode:NO];
+ToolbarActionViewController*
+PageActionDecoration::GetPreferredPopupViewController() {
+ return viewController_.get();
}
-const Extension* PageActionDecoration::GetExtension() {
- const Extension* extension = extensions::ExtensionRegistry::Get(
- browser_->profile())->enabled_extensions().GetByID(
- page_action_->extension_id());
- DCHECK(extension);
- return extension;
+content::WebContents* PageActionDecoration::GetCurrentWebContents() const {
+ return owner_ ? owner_->GetWebContents() : nullptr;
}
-void PageActionDecoration::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- switch (type) {
- case extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE: {
- ExtensionPopupController* popup = [ExtensionPopupController popup];
- if (popup && ![popup isClosing])
- [popup close];
+void PageActionDecoration::UpdateState() {
+ // If we have no owner, that means this class is still being constructed.
+ WebContents* web_contents = owner_ ? owner_->GetWebContents() : NULL;
+ if (web_contents) {
+ UpdateVisibility(web_contents);
+ owner_->RedrawDecoration(this);
+ }
+}
- break;
- }
- case extensions::NOTIFICATION_EXTENSION_COMMAND_PAGE_ACTION_MAC: {
- std::pair<const std::string, gfx::NativeWindow>* payload =
- content::Details<std::pair<const std::string, gfx::NativeWindow> >(
- details).ptr();
- std::string extension_id = payload->first;
- gfx::NativeWindow window = payload->second;
- if (window != browser_->window()->GetNativeWindow())
- break;
- if (extension_id != page_action_->extension_id())
- break;
- if (IsVisible())
- ActivatePageAction(true);
- break;
- }
+NSPoint PageActionDecoration::GetPopupPoint() {
+ // Anchor popup at the bottom center of the page action icon.
+ AutocompleteTextField* field = owner_->GetAutocompleteTextField();
+ NSPoint anchor = GetBubblePointInFrame(
+ owner_->GetPageActionFrame(viewController_->extension_action()));
+ anchor = [field convertPoint:anchor toView:nil];
+ return anchor;
+}
- default:
- NOTREACHED() << "Unexpected notification";
- break;
- }
+void PageActionDecoration::SetContextMenuController(
+ ExtensionActionContextMenuController* menuController) {
+ contextMenuController_ = menuController;
}