summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandybons@chromium.org <andybons@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-28 19:58:54 +0000
committerandybons@chromium.org <andybons@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-28 19:58:54 +0000
commitbeeb134984c5dd8cae93de8fc135384789c253ad (patch)
treea9f088f9c8d617f89b4cb4879fd0afb4731966d0
parent5a80586e9d98cf8b4ead40e181b310f6cb518ee5 (diff)
downloadchromium_src-beeb134984c5dd8cae93de8fc135384789c253ad.zip
chromium_src-beeb134984c5dd8cae93de8fc135384789c253ad.tar.gz
chromium_src-beeb134984c5dd8cae93de8fc135384789c253ad.tar.bz2
[Mac] Base implementation of extension infobars on the mac.
BUG=43168 TEST=install an extension that has an infobar. see if one shows up. Review URL: http://codereview.chromium.org/2858028 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51031 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/cocoa/extension_view_mac.mm4
-rw-r--r--chrome/browser/cocoa/extensions/extension_infobar_controller.h22
-rw-r--r--chrome/browser/cocoa/extensions/extension_infobar_controller.mm118
-rw-r--r--chrome/browser/cocoa/extensions/extension_popup_controller.h2
-rw-r--r--chrome/browser/cocoa/extensions/extension_popup_controller.mm15
-rw-r--r--chrome/browser/cocoa/infobar_controller.h10
-rw-r--r--chrome/browser/cocoa/infobar_controller.mm25
-rw-r--r--chrome/browser/extensions/extension_infobar_delegate.cc7
-rw-r--r--chrome/browser/renderer_host/render_widget_host_view_mac.mm6
-rw-r--r--chrome/chrome_browser.gypi2
10 files changed, 173 insertions, 38 deletions
diff --git a/chrome/browser/cocoa/extension_view_mac.mm b/chrome/browser/cocoa/extension_view_mac.mm
index 6134fcf..feab70c 100644
--- a/chrome/browser/cocoa/extension_view_mac.mm
+++ b/chrome/browser/cocoa/extension_view_mac.mm
@@ -63,7 +63,7 @@ void ExtensionViewMac::UpdatePreferredSize(const gfx::Size& new_size) {
// On first display of some extensions, this function is called with zero
// width after the correct size has been set. Bail if zero is seen, assuming
- // that an extension popup view doesn't want any dimensions to ever be zero.
+ // that an extension's view doesn't want any dimensions to ever be zero.
// TODO(andybons): Verify this assumption and look into WebCore's
// |contentesPreferredWidth| to see why this is occurring.
if (NSIsEmptyRect(frame))
@@ -74,7 +74,7 @@ void ExtensionViewMac::UpdatePreferredSize(const gfx::Size& new_size) {
// RenderWidgetHostViewCocoa overrides setFrame but not setFrameSize.
// We need to defer the update back to the RenderWidgetHost so we don't
- // get the flickering effect on 10.5 of http://crbug.com/31970.
+ // get the flickering effect on 10.5 of http://crbug.com/31970
[hostView setFrameWithDeferredUpdate:frame];
[hostView setNeedsDisplay:YES];
}
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 {
diff --git a/chrome/browser/cocoa/infobar_controller.h b/chrome/browser/cocoa/infobar_controller.h
index 9d557cf..265700c 100644
--- a/chrome/browser/cocoa/infobar_controller.h
+++ b/chrome/browser/cocoa/infobar_controller.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -45,7 +45,7 @@ class InfoBarDelegate;
// Initializes a new InfoBarController.
- (id)initWithDelegate:(InfoBarDelegate*)delegate;
-// Called when someone clicks on the ok or cancel buttons. Subclasses
+// Called when someone clicks on the OK or Cancel buttons. Subclasses
// must override if they do not hide the buttons.
- (void)ok:(id)sender;
- (void)cancel:(id)sender;
@@ -73,6 +73,10 @@ class InfoBarDelegate;
// Sets the info bar message to the specified |message|.
- (void)setLabelToMessage:(NSString*)message;
+// Removes the OK and Cancel buttons and resizes the textfield to use the
+// space.
+- (void)removeButtons;
+
@property(nonatomic, assign) id<InfoBarContainer> containerController;
@property(nonatomic, readonly) InfoBarDelegate* delegate;
@@ -94,7 +98,7 @@ class InfoBarDelegate;
@interface ConfirmInfoBarController : InfoBarController
-// Called when the ok and cancel buttons are clicked.
+// Called when the OK and Cancel buttons are clicked.
- (IBAction)ok:(id)sender;
- (IBAction)cancel:(id)sender;
// Called when there is a click on the link in the infobar.
diff --git a/chrome/browser/cocoa/infobar_controller.mm b/chrome/browser/cocoa/infobar_controller.mm
index 6f743f51..c6f42a4 100644
--- a/chrome/browser/cocoa/infobar_controller.mm
+++ b/chrome/browser/cocoa/infobar_controller.mm
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// 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.
@@ -86,10 +86,6 @@ const float kAnimateCloseDuration = 0.12;
// infobar from its container, if necessary.
- (void)cleanUpAfterAnimation:(BOOL)finished;
-// Removes the ok and cancel buttons, and resizes the textfield to use the
-// space.
-- (void)removeButtons;
-
// Sets the info bar message to the specified |message|, with a hypertext
// style link. |link| will be inserted into message at |linkOffset|.
- (void)setLabelToMessage:(NSString*)message
@@ -215,6 +211,15 @@ const float kAnimateCloseDuration = 0.12;
[[label_.get() textStorage] setAttributedString:attributedString];
}
+- (void)removeButtons {
+ // Extend the label all the way across.
+ NSRect labelFrame = [label_.get() frame];
+ labelFrame.size.width = NSMaxX([cancelButton_ frame]) - NSMinX(labelFrame);
+ [okButton_ removeFromSuperview];
+ [cancelButton_ removeFromSuperview];
+ [label_.get() setFrame:labelFrame];
+}
+
@end
@implementation InfoBarController (PrivateMethods)
@@ -242,16 +247,6 @@ const float kAnimateCloseDuration = 0.12;
[containerController_ removeDelegate:delegate_];
}
-- (void)removeButtons {
- // Extend the label all the way across.
- // Remove the ok and cancel buttons, since they are not needed.
- NSRect labelFrame = [label_.get() frame];
- labelFrame.size.width = NSMaxX([cancelButton_ frame]) - NSMinX(labelFrame);
- [okButton_ removeFromSuperview];
- [cancelButton_ removeFromSuperview];
- [label_.get() setFrame:labelFrame];
-}
-
- (void)cleanUpAfterAnimation:(BOOL)finished {
// Don't need to do any cleanup if the bar was animating open.
if (!infoBarClosing_)
diff --git a/chrome/browser/extensions/extension_infobar_delegate.cc b/chrome/browser/extensions/extension_infobar_delegate.cc
index 7bbc79b..33e16dd 100644
--- a/chrome/browser/extensions/extension_infobar_delegate.cc
+++ b/chrome/browser/extensions/extension_infobar_delegate.cc
@@ -57,13 +57,6 @@ void ExtensionInfoBarDelegate::InfoBarClosed() {
delete this;
}
-#if defined(OS_MACOSX)
-InfoBar* ExtensionInfoBarDelegate::CreateInfoBar() {
- NOTIMPLEMENTED();
- return NULL;
-}
-#endif // OS_MACOSX
-
void ExtensionInfoBarDelegate::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
diff --git a/chrome/browser/renderer_host/render_widget_host_view_mac.mm b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
index ff68b86..3f9a85f 100644
--- a/chrome/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/chrome/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1106,6 +1106,12 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
}
}
+- (void)setFrameSize:(NSSize)newSize {
+ [super setFrameSize:newSize];
+ if (renderWidgetHostView_->render_widget_host_)
+ renderWidgetHostView_->render_widget_host_->WasResized();
+}
+
- (void)setFrame:(NSRect)frameRect {
[super setFrame:frameRect];
if (renderWidgetHostView_->render_widget_host_)
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index a7eedfd..96cecccc8 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -725,6 +725,8 @@
'browser/cocoa/extensions/browser_actions_controller.mm',
'browser/cocoa/extensions/extension_action_context_menu.h',
'browser/cocoa/extensions/extension_action_context_menu.mm',
+ 'browser/cocoa/extensions/extension_infobar_controller.h',
+ 'browser/cocoa/extensions/extension_infobar_controller.mm',
'browser/cocoa/extensions/extension_install_prompt_controller.h',
'browser/cocoa/extensions/extension_install_prompt_controller.mm',
'browser/cocoa/extensions/extension_popup_controller.h',