Index: chrome/browser/ui/cocoa/tab_contents_controller.mm |
=================================================================== |
--- chrome/browser/ui/cocoa/tab_contents_controller.mm (revision 71953) |
+++ chrome/browser/ui/cocoa/tab_contents_controller.mm (working copy) |
@@ -1,211 +0,0 @@ |
-// 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/ui/cocoa/tab_contents_controller.h" |
- |
-#include "base/scoped_nsobject.h" |
-#include "chrome/browser/renderer_host/render_view_host.h" |
-#include "chrome/browser/renderer_host/render_widget_host_view.h" |
-#include "chrome/browser/tab_contents/navigation_controller.h" |
-#include "chrome/browser/tab_contents/tab_contents.h" |
-#include "chrome/common/notification_details.h" |
-#include "chrome/common/notification_observer.h" |
-#include "chrome/common/notification_registrar.h" |
-#include "chrome/common/notification_source.h" |
-#include "chrome/common/notification_type.h" |
- |
- |
-@interface TabContentsController(Private) |
-// Forwards frame update to |delegate_| (ResizeNotificationView calls it). |
-- (void)tabContentsViewFrameWillChange:(NSRect)frameRect; |
-// Notification from TabContents (forwarded by TabContentsNotificationBridge). |
-- (void)tabContentsRenderViewHostChanged:(RenderViewHost*)oldHost |
- newHost:(RenderViewHost*)newHost; |
-@end |
- |
- |
-// A supporting C++ bridge object to register for TabContents notifications. |
- |
-class TabContentsNotificationBridge : public NotificationObserver { |
- public: |
- explicit TabContentsNotificationBridge(TabContentsController* controller); |
- |
- // Overriden from NotificationObserver. |
- virtual void Observe(NotificationType type, |
- const NotificationSource& source, |
- const NotificationDetails& details); |
- // Register for |contents|'s notifications, remove all prior registrations. |
- void ChangeTabContents(TabContents* contents); |
- private: |
- NotificationRegistrar registrar_; |
- TabContentsController* controller_; // weak, owns us |
-}; |
- |
-TabContentsNotificationBridge::TabContentsNotificationBridge( |
- TabContentsController* controller) |
- : controller_(controller) { |
-} |
- |
-void TabContentsNotificationBridge::Observe( |
- NotificationType type, |
- const NotificationSource& source, |
- const NotificationDetails& details) { |
- if (type == NotificationType::RENDER_VIEW_HOST_CHANGED) { |
- RenderViewHostSwitchedDetails* switched_details = |
- Details<RenderViewHostSwitchedDetails>(details).ptr(); |
- [controller_ tabContentsRenderViewHostChanged:switched_details->old_host |
- newHost:switched_details->new_host]; |
- } else { |
- NOTREACHED(); |
- } |
-} |
- |
-void TabContentsNotificationBridge::ChangeTabContents(TabContents* contents) { |
- registrar_.RemoveAll(); |
- if (contents) { |
- registrar_.Add(this, |
- NotificationType::RENDER_VIEW_HOST_CHANGED, |
- Source<NavigationController>(&contents->controller())); |
- } |
-} |
- |
- |
-// A custom view that notifies |controller| that view's frame is changing. |
- |
-@interface ResizeNotificationView : NSView { |
- TabContentsController* controller_; |
-} |
-- (id)initWithController:(TabContentsController*)controller; |
-@end |
- |
-@implementation ResizeNotificationView |
- |
-- (id)initWithController:(TabContentsController*)controller { |
- if ((self = [super initWithFrame:NSZeroRect])) { |
- controller_ = controller; |
- } |
- return self; |
-} |
- |
-- (void)setFrame:(NSRect)frameRect { |
- [controller_ tabContentsViewFrameWillChange:frameRect]; |
- [super setFrame:frameRect]; |
-} |
- |
-@end |
- |
- |
-@implementation TabContentsController |
-@synthesize tabContents = contents_; |
- |
-- (id)initWithContents:(TabContents*)contents |
- delegate:(id<TabContentsControllerDelegate>)delegate { |
- if ((self = [super initWithNibName:nil bundle:nil])) { |
- contents_ = contents; |
- delegate_ = delegate; |
- tabContentsBridge_.reset(new TabContentsNotificationBridge(self)); |
- tabContentsBridge_->ChangeTabContents(contents); |
- } |
- return self; |
-} |
- |
-- (void)dealloc { |
- // make sure our contents have been removed from the window |
- [[self view] removeFromSuperview]; |
- [super dealloc]; |
-} |
- |
-- (void)loadView { |
- scoped_nsobject<ResizeNotificationView> view( |
- [[ResizeNotificationView alloc] initWithController:self]); |
- [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable]; |
- [self setView:view]; |
-} |
- |
-- (void)ensureContentsSizeDoesNotChange { |
- if (contents_) { |
- NSView* contentsContainer = [self view]; |
- NSArray* subviews = [contentsContainer subviews]; |
- if ([subviews count] > 0) |
- [contents_->GetNativeView() setAutoresizingMask:NSViewNotSizable]; |
- } |
-} |
- |
-// Call when the tab view is properly sized and the render widget host view |
-// should be put into the view hierarchy. |
-- (void)ensureContentsVisible { |
- if (!contents_) |
- return; |
- NSView* contentsContainer = [self view]; |
- NSArray* subviews = [contentsContainer subviews]; |
- NSView* contentsNativeView = contents_->GetNativeView(); |
- |
- NSRect contentsNativeViewFrame = [contentsContainer frame]; |
- contentsNativeViewFrame.origin = NSZeroPoint; |
- |
- [delegate_ tabContentsViewFrameWillChange:self |
- frameRect:contentsNativeViewFrame]; |
- |
- // Native view is resized to the actual size before it becomes visible |
- // to avoid flickering. |
- [contentsNativeView setFrame:contentsNativeViewFrame]; |
- if ([subviews count] == 0) { |
- [contentsContainer addSubview:contentsNativeView]; |
- } else if ([subviews objectAtIndex:0] != contentsNativeView) { |
- [contentsContainer replaceSubview:[subviews objectAtIndex:0] |
- with:contentsNativeView]; |
- } |
- // Restore autoresizing properties possibly stripped by |
- // ensureContentsSizeDoesNotChange call. |
- [contentsNativeView setAutoresizingMask:NSViewWidthSizable| |
- NSViewHeightSizable]; |
-} |
- |
-- (void)changeTabContents:(TabContents*)newContents { |
- contents_ = newContents; |
- tabContentsBridge_->ChangeTabContents(contents_); |
-} |
- |
-- (void)tabContentsViewFrameWillChange:(NSRect)frameRect { |
- [delegate_ tabContentsViewFrameWillChange:self frameRect:frameRect]; |
-} |
- |
-- (void)tabContentsRenderViewHostChanged:(RenderViewHost*)oldHost |
- newHost:(RenderViewHost*)newHost { |
- if (oldHost && newHost && oldHost->view() && newHost->view()) { |
- newHost->view()->set_reserved_contents_rect( |
- oldHost->view()->reserved_contents_rect()); |
- } else { |
- [delegate_ tabContentsViewFrameWillChange:self |
- frameRect:[[self view] frame]]; |
- } |
-} |
- |
-- (void)willBecomeUnselectedTab { |
- // The RWHV is ripped out of the view hierarchy on tab switches, so it never |
- // formally resigns first responder status. Handle this by explicitly sending |
- // a Blur() message to the renderer, but only if the RWHV currently has focus. |
- RenderViewHost* rvh = [self tabContents]->render_view_host(); |
- if (rvh && rvh->view() && rvh->view()->HasFocus()) |
- rvh->Blur(); |
-} |
- |
-- (void)willBecomeSelectedTab { |
- // Do not explicitly call Focus() here, as the RWHV may not actually have |
- // focus (for example, if the omnibox has focus instead). The TabContents |
- // logic will restore focus to the appropriate view. |
-} |
- |
-- (void)tabDidChange:(TabContents*)updatedContents { |
- // Calling setContentView: here removes any first responder status |
- // the view may have, so avoid changing the view hierarchy unless |
- // the view is different. |
- if ([self tabContents] != updatedContents) { |
- [self changeTabContents:updatedContents]; |
- if ([self tabContents]) |
- [self ensureContentsVisible]; |
- } |
-} |
- |
-@end |