diff options
Diffstat (limited to 'chrome/browser/cocoa/extensions')
4 files changed, 146 insertions, 11 deletions
diff --git a/chrome/browser/cocoa/extensions/extension_infobar_controller.h b/chrome/browser/cocoa/extensions/extension_infobar_controller.h new file mode 100644 index 0000000..93b7e57 --- /dev/null +++ b/chrome/browser/cocoa/extensions/extension_infobar_controller.h @@ -0,0 +1,22 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_COCOA_EXTENSIONS_EXTENSION_INFOBAR_CONTROLLER_H_ +#define CHROME_BROWSER_COCOA_EXTENSIONS_EXTENSION_INFOBAR_CONTROLLER_H_ + +#import "chrome/browser/cocoa/infobar_controller.h" + +#import <Cocoa/Cocoa.h> + +@interface ExtensionInfoBarController : InfoBarController { + // The native extension view retrieved from the extension host. Weak. + NSView* extensionView_; + + // The window containing this InfoBar. Weak. + NSWindow* window_; +} + +@end + +#endif // CHROME_BROWSER_COCOA_EXTENSIONS_EXTENSION_INFOBAR_CONTROLLER_H_ diff --git a/chrome/browser/cocoa/extensions/extension_infobar_controller.mm b/chrome/browser/cocoa/extensions/extension_infobar_controller.mm new file mode 100644 index 0000000..1a65161 --- /dev/null +++ b/chrome/browser/cocoa/extensions/extension_infobar_controller.mm @@ -0,0 +1,118 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "chrome/browser/cocoa/extensions/extension_infobar_controller.h" + +#import "chrome/browser/cocoa/animatable_view.h" +#include "chrome/browser/cocoa/infobar.h" +#include "chrome/browser/extensions/extension_host.h" +#include "chrome/browser/extensions/extension_infobar_delegate.h" +#include "chrome/browser/tab_contents/tab_contents.h" + +namespace { +const CGFloat kAnimationDuration = 0.12; +const CGFloat kBottomBorderHeightPx = 1.0; +} // namepsace + +@interface ExtensionInfoBarController(Private) +// Called when the extension's hosted NSView has been resized. +- (void)extensionViewFrameChanged; +// Adjusts the width of the extension's hosted view to match the window's width. +- (void)adjustWidthToFitWindow; +@end + +@implementation ExtensionInfoBarController + +- (id)initWithDelegate:(InfoBarDelegate*)delegate + window:(NSWindow*)window { + if ((self = [super initWithDelegate:delegate])) { + window_ = window; + } + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + +- (void)addAdditionalControls { + [self removeButtons]; + + extensionView_ = delegate_->AsExtensionInfoBarDelegate()-> + extension_host()->view()->native_view(); + + // Add the extension's RenderWidgetHostViewMac to the view hierarchy of the + // InfoBar and make sure to place it below the Close button. + [infoBarView_ addSubview:extensionView_ + positioned:NSWindowBelow + relativeTo:(NSView*)closeButton_]; + + // Because the parent view has a bottom border, account for it during + // positioning. + NSRect extensionFrame = [extensionView_ frame]; + extensionFrame.origin.y = kBottomBorderHeightPx; + + [extensionView_ setFrame:extensionFrame]; + // The extension's native view will only have a height that is non-zero if it + // already has been loaded and rendered, which is the case when you switch + // back to a tab with an extension infobar within it. The reason this is + // needed is because the extension view's frame will not have changed in the + // above case, so the NSViewFrameDidChangeNotification registered below will + // never fire. + if (extensionFrame.size.height > 0.0) { + NSSize infoBarSize = [[self view] frame].size; + infoBarSize.height = extensionFrame.size.height + kBottomBorderHeightPx; + [[self view] setFrameSize:infoBarSize]; + [infoBarView_ setFrameSize:infoBarSize]; + } + + [self adjustWidthToFitWindow]; + + // These two notification handlers are here to ensure the width of the + // native extension view is the same as the browser window's width and that + // the parent infobar view matches the height of the extension's native view. + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(extensionViewFrameChanged) + name:NSViewFrameDidChangeNotification + object:extensionView_]; + + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(adjustWidthToFitWindow) + name:NSWindowDidResizeNotification + object:window_]; +} + +- (void)extensionViewFrameChanged { + [self adjustWidthToFitWindow]; + + AnimatableView* view = [self animatableView]; + NSRect infoBarFrame = [view frame]; + CGFloat newHeight = NSHeight([extensionView_ frame]) + kBottomBorderHeightPx; + [infoBarView_ setPostsFrameChangedNotifications:NO]; + infoBarFrame.size.height = newHeight; + [infoBarView_ setFrame:infoBarFrame]; + [infoBarView_ setPostsFrameChangedNotifications:YES]; + [view animateToNewHeight:newHeight duration:kAnimationDuration]; +} + +- (void)adjustWidthToFitWindow { + [extensionView_ setPostsFrameChangedNotifications:NO]; + NSSize extensionViewSize = [extensionView_ frame].size; + extensionViewSize.width = NSWidth([window_ frame]); + [extensionView_ setFrameSize:extensionViewSize]; + [extensionView_ setPostsFrameChangedNotifications:YES]; +} + +@end + +InfoBar* ExtensionInfoBarDelegate::CreateInfoBar() { + NSWindow* window = [(NSView*)tab_contents_->GetContentNativeView() window]; + ExtensionInfoBarController* controller = + [[ExtensionInfoBarController alloc] initWithDelegate:this + window:window]; + return new InfoBar(controller); +} diff --git a/chrome/browser/cocoa/extensions/extension_popup_controller.h b/chrome/browser/cocoa/extensions/extension_popup_controller.h index ec31816..d7042ea 100644 --- a/chrome/browser/cocoa/extensions/extension_popup_controller.h +++ b/chrome/browser/cocoa/extensions/extension_popup_controller.h @@ -50,7 +50,7 @@ class NotificationRegistrar; scoped_ptr<DevtoolsNotificationBridge> notificationBridge_; // Whether the popup has a devtools window attached to it. - bool beingInspected_; + BOOL beingInspected_; } // Returns the ExtensionHost object associated with this popup. diff --git a/chrome/browser/cocoa/extensions/extension_popup_controller.mm b/chrome/browser/cocoa/extensions/extension_popup_controller.mm index d7a4a66..b2647da 100644 --- a/chrome/browser/cocoa/extensions/extension_popup_controller.mm +++ b/chrome/browser/cocoa/extensions/extension_popup_controller.mm @@ -42,14 +42,12 @@ class DevtoolsNotificationBridge : public NotificationObserver { const NotificationDetails& details) { switch (type.value) { case NotificationType::EXTENSION_HOST_DID_STOP_LOADING: { - if (Details<ExtensionHost>([controller_ extensionHost]) == - details) + if (Details<ExtensionHost>([controller_ extensionHost]) == details) [controller_ showDevTools]; break; } case NotificationType::DEVTOOLS_WINDOW_CLOSING: { - RenderViewHost* rvh = - [controller_ extensionHost]->render_view_host(); + RenderViewHost* rvh = [controller_ extensionHost]->render_view_host(); if (Details<RenderViewHost>(rvh) == details) // Allow the devtools to finish detaching before we close the popup [controller_ performSelector:@selector(close) @@ -92,6 +90,7 @@ class DevtoolsNotificationBridge : public NotificationObserver { parentWindow_ = parentWindow; anchor_ = [parentWindow convertBaseToScreen:anchoredAt]; host_.reset(host); + beingInspected_ = devMode; scoped_nsobject<InfoBubbleView> view([[InfoBubbleView alloc] init]); if (!view.get()) @@ -127,8 +126,7 @@ class DevtoolsNotificationBridge : public NotificationObserver { [window setDelegate:self]; [window setContentView:view]; self = [super initWithWindow:window]; - if (devMode) { - beingInspected_ = true; + if (beingInspected_) { // Listen for the the devtools window closing. notificationBridge_.reset(new DevtoolsNotificationBridge(self)); registrar_.reset(new NotificationRegistrar); @@ -138,15 +136,12 @@ class DevtoolsNotificationBridge : public NotificationObserver { registrar_->Add(notificationBridge_.get(), NotificationType::EXTENSION_HOST_DID_STOP_LOADING, Source<Profile>(host->profile())); - } else { - beingInspected_ = false; } return self; } - (void)showDevTools { - DevToolsManager::GetInstance()->OpenDevToolsWindow( - host_->render_view_host()); + DevToolsManager::GetInstance()->OpenDevToolsWindow(host_->render_view_host()); } - (void)dealloc { |