diff options
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r-- | chrome/browser/cocoa/page_info_window_controller.h | 35 | ||||
-rw-r--r-- | chrome/browser/cocoa/page_info_window_controller.mm | 86 | ||||
-rw-r--r-- | chrome/browser/cocoa/page_info_window_controller_unittest.mm | 50 | ||||
-rw-r--r-- | chrome/browser/cocoa/page_info_window_mac.h | 36 | ||||
-rw-r--r-- | chrome/browser/cocoa/page_info_window_mac.mm | 198 | ||||
-rw-r--r-- | chrome/browser/cocoa/page_info_window_mac_unittest.mm | 195 |
6 files changed, 412 insertions, 188 deletions
diff --git a/chrome/browser/cocoa/page_info_window_controller.h b/chrome/browser/cocoa/page_info_window_controller.h index c8e5564..4a9624c 100644 --- a/chrome/browser/cocoa/page_info_window_controller.h +++ b/chrome/browser/cocoa/page_info_window_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. @@ -16,49 +16,16 @@ class PrefService; @interface PageInfoWindowController : NSWindowController { @private - // We load both images and then we share the refs with our UI elements. - scoped_nsobject<NSImage> goodImg_; - scoped_nsobject<NSImage> badImg_; - - // User interface item values. The NIB uses KVO to get these, so the values - // are not explicitly set in the view by the controller. - NSImage* identityImg_; - NSImage* connectionImg_; - NSImage* historyImg_; - NSString* identityMsg_; - NSString* connectionMsg_; - NSString* historyMsg_; - BOOL enableCertButton_; - - // Box that allows us to show/hide the history information. - IBOutlet NSBox* historyBox_; - // Bridge to Chromium that we own. scoped_ptr<PageInfoWindowMac> pageInfo_; scoped_nsobject<WindowSizeAutosaver> sizeSaver_; } -@property(readwrite, retain) NSImage* identityImg; -@property(readwrite, retain) NSImage* connectionImg; -@property(readwrite, retain) NSImage* historyImg; -@property(readwrite, copy) NSString* identityMsg; -@property(readwrite, copy) NSString* connectionMsg; -@property(readwrite, copy) NSString* historyMsg; -@property(readwrite) BOOL enableCertButton; - // Sets the bridge between Cocoa and Chromium. - (void)setPageInfo:(PageInfoWindowMac*)pageInfo; -// Returns the good and bad image refs. -- (NSImage*)goodImg; -- (NSImage*)badImg; - // Shows the certificate display window - (IBAction)showCertWindow:(id)sender; -// Sets whether or not to show or hide the history box. This will resize the -// frame of the window. -- (void)setShowHistoryBox:(BOOL)show; - @end diff --git a/chrome/browser/cocoa/page_info_window_controller.mm b/chrome/browser/cocoa/page_info_window_controller.mm index 988f6b9..521ab68 100644 --- a/chrome/browser/cocoa/page_info_window_controller.mm +++ b/chrome/browser/cocoa/page_info_window_controller.mm @@ -1,10 +1,10 @@ -// 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. #import "chrome/browser/cocoa/page_info_window_controller.h" -#include "app/resource_bundle.h" +#include "app/l10n_util_mac.h" #include "base/mac_util.h" #include "base/values.h" #include "chrome/browser/browser_process.h" @@ -12,25 +12,30 @@ #include "chrome/browser/cocoa/window_size_autosaver.h" #include "chrome/browser/pref_service.h" #include "chrome/common/pref_names.h" -#include "grit/theme_resources.h" +#include "grit/generated_resources.h" + +namespace { + +// The width of the window. The height will be determined by the content. +const NSInteger kWindowWidth = 460; + +} // namespace @implementation PageInfoWindowController -@synthesize identityImg = identityImg_; -@synthesize connectionImg = connectionImg_; -@synthesize historyImg = historyImg_; -@synthesize identityMsg = identityMsg_; -@synthesize connectionMsg = connectionMsg_; -@synthesize historyMsg = historyMsg_; -@synthesize enableCertButton = enableCertButton_; - (id)init { - NSBundle* bundle = mac_util::MainAppBundle(); - NSString* nibpath = [bundle pathForResource:@"PageInfo" ofType:@"nib"]; - if ((self = [super initWithWindowNibPath:nibpath owner:self])) { - // Load the image refs. - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - goodImg_.reset([rb.GetNSImageNamed(IDR_PAGEINFO_GOOD) retain]); - badImg_.reset([rb.GetNSImageNamed(IDR_PAGEINFO_BAD) retain]); + NSUInteger styleMask = NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask; + scoped_nsobject<NSWindow> window( + // Use an arbitrary height because it will be changed by the bridge. + [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, kWindowWidth, 100) + styleMask:styleMask + backing:NSBackingStoreBuffered + defer:NO]); + if ((self = [super initWithWindow:window.get()])) { + [window setTitle: + l10n_util::GetNSStringWithFixup(IDS_PAGEINFO_WINDOW_TITLE)]; + [window setDelegate:self]; if (g_browser_process && g_browser_process->local_state()) { sizeSaver_.reset([[WindowSizeAutosaver alloc] @@ -38,66 +43,19 @@ prefService:g_browser_process->local_state() path:prefs::kPageInfoWindowPlacement state:kSaveWindowPos]); - // Cascade again to get the offset when opening new windows. - NSRect frame = [[self window] frame]; - NSPoint cascadePoint = [[self window] - cascadeTopLeftFromPoint:NSMakePoint(NSMinX(frame), NSMaxY(frame))]; - [[self window] cascadeTopLeftFromPoint:cascadePoint]; } } return self; } -- (void)awakeFromNib { - // By default, assume we have no history information. - [self setShowHistoryBox:NO]; -} - -- (void)dealloc { - [identityImg_ release]; - [connectionImg_ release]; - [historyImg_ release]; - [identityMsg_ release]; - [connectionMsg_ release]; - [historyMsg_ release]; - [super dealloc]; -} - - (void)setPageInfo:(PageInfoWindowMac*)pageInfo { pageInfo_.reset(pageInfo); } -- (NSImage*)goodImg { - return goodImg_.get(); -} - -- (NSImage*)badImg { - return badImg_.get(); -} - - (IBAction)showCertWindow:(id)sender { pageInfo_->ShowCertDialog(0); // Pass it any int because it's ignored. } -- (void)setShowHistoryBox:(BOOL)show { - [historyBox_ setHidden:!show]; - - NSWindow* window = [self window]; - NSRect frame = [window frame]; - - const NSSize kPageInfoWindowSize = NSMakeSize(460, 235); - const NSSize kPageInfoWindowWithHistorySize = NSMakeSize(460, 310); - - NSSize size = (show ? kPageInfoWindowWithHistorySize : kPageInfoWindowSize); - - // Just setting |size| will cause the window to grow upwards. Shift the - // origin up by grow amount, which causes the window to grow downwards. - frame.origin.y -= size.height - frame.size.height; - frame.size = size; - - [window setFrame:frame display:YES animate:YES]; -} - // If the page info window gets closed, we have nothing left to manage and we // can clean ourselves up. - (void)windowWillClose:(NSNotification*)notif { diff --git a/chrome/browser/cocoa/page_info_window_controller_unittest.mm b/chrome/browser/cocoa/page_info_window_controller_unittest.mm deleted file mode 100644 index 8ca4782..0000000 --- a/chrome/browser/cocoa/page_info_window_controller_unittest.mm +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2009 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. - -#include "base/scoped_nsobject.h" -#import "chrome/browser/cocoa/page_info_window_controller.h" -#include "chrome/browser/cocoa/browser_test_helper.h" -#import "chrome/browser/cocoa/cocoa_test_helper.h" - -class PageInfoWindowControllerTest : public CocoaTest { - virtual void SetUp() { - CocoaTest::SetUp(); - controller_ = [[PageInfoWindowController alloc] init]; - EXPECT_TRUE([controller_ window]); - } - - virtual void TearDown() { - [controller_ close]; - CocoaTest::TearDown(); - } - - public: - BrowserTestHelper helper_; - PageInfoWindowController* controller_; -}; - - -TEST_F(PageInfoWindowControllerTest, TestImages) { - EXPECT_TRUE([controller_ goodImg]); - EXPECT_TRUE([controller_ badImg]); -} - - -TEST_F(PageInfoWindowControllerTest, TestGrow) { - NSRect frame = [[controller_ window] frame]; - [controller_ setShowHistoryBox:YES]; - NSRect newFrame = [[controller_ window] frame]; - EXPECT_GE(newFrame.size.height, frame.size.height); - EXPECT_LE(newFrame.origin.y, frame.origin.y); -} - - -TEST_F(PageInfoWindowControllerTest, TestShrink) { - [controller_ setShowHistoryBox:YES]; - NSRect frame = [[controller_ window] frame]; - [controller_ setShowHistoryBox:NO]; - NSRect newFrame = [[controller_ window] frame]; - EXPECT_LE(newFrame.size.height, frame.size.height); - EXPECT_GE(newFrame.origin.y, frame.origin.y); -} diff --git a/chrome/browser/cocoa/page_info_window_mac.h b/chrome/browser/cocoa/page_info_window_mac.h index da7b2b6..c1beccf 100644 --- a/chrome/browser/cocoa/page_info_window_mac.h +++ b/chrome/browser/cocoa/page_info_window_mac.h @@ -1,16 +1,30 @@ -// 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. #ifndef CHROME_BROWSER_COCOA_PAGE_INFO_WINDOW_MAC_H_ #define CHROME_BROWSER_COCOA_PAGE_INFO_WINDOW_MAC_H_ +#import <Cocoa/Cocoa.h> + +#include "base/scoped_nsobject.h" +#include "base/scoped_ptr.h" #include "chrome/browser/page_info_model.h" #include "chrome/browser/page_info_window.h" class Profile; @class PageInfoWindowController; +namespace { + +class PageInfoWindowMacTest; + +}; + +// This bridge is responsible for getting information from the cross-platform +// model and dynamically creating the contents of the window. The controller is +// responsible for managing the window's memory and user events (pressing on +// the Show Certificate button). class PageInfoWindowMac : public PageInfoModel::PageInfoModelObserver { public: virtual ~PageInfoWindowMac(); @@ -30,19 +44,37 @@ class PageInfoWindowMac : public PageInfoModel::PageInfoModelObserver { virtual void ModelChanged(); private: + friend class ::PageInfoWindowMacTest; + + // Private constructor, called by ShowPageInfo(). PageInfoWindowMac(PageInfoWindowController* controller, Profile* profile, const GURL& url, const NavigationEntry::SSLStatus& ssl, bool show_history); + // Testing constructor. DO NOT USE. + PageInfoWindowMac(PageInfoWindowController* controller, + PageInfoModel* model); + + // Shared constructor initialization. + void Init(); + + // Dynamically creates the window's content section. void LayoutSections(); + // Shows the actual window. void Show(); + // The window controller that manages the memory and window reference. PageInfoWindowController* controller_; // WEAK, owns us. - PageInfoModel model_; + // The platform-independent model for the info window. + scoped_ptr<PageInfoModel> model_; + + // Reference to the good and bad images that are placed within the UI. + scoped_nsobject<NSImage> good_image_; + scoped_nsobject<NSImage> bad_image_; // The certificate ID for the page, 0 if the page is not over HTTPS. int cert_id_; diff --git a/chrome/browser/cocoa/page_info_window_mac.mm b/chrome/browser/cocoa/page_info_window_mac.mm index 0ea0eae..b56192f 100644 --- a/chrome/browser/cocoa/page_info_window_mac.mm +++ b/chrome/browser/cocoa/page_info_window_mac.mm @@ -1,23 +1,52 @@ -// 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. #include "chrome/browser/cocoa/page_info_window_mac.h" +#include <algorithm> #include <Security/Security.h> #include <SecurityInterface/SFCertificatePanel.h> #include "app/l10n_util.h" #include "base/scoped_cftyperef.h" #include "base/i18n/time_formatting.h" +#include "app/resource_bundle.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #import "chrome/browser/cocoa/page_info_window_controller.h" #include "chrome/browser/cert_store.h" #include "chrome/browser/profile.h" #include "grit/generated_resources.h" +#include "grit/theme_resources.h" #include "net/base/cert_status_flags.h" #include "net/base/x509_certificate.h" +#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" + +namespace { + +// Spacing in between section boxes. +const NSInteger kVerticalSpacing = 10; + +// Padding from the edge of the boxes and the window frame. +const NSInteger kFramePadding = 20; + +// Spacing between the frame of the box and the left edge of the image and the +// right edge of the text. +const NSInteger kBoxHorizontalSpacing = 13; + +// Spacing between the top/bottom of the box frame and the top of the image and +// text components. +const NSInteger kBoxTopSpacing = 33; +const NSInteger kBoxBottomSpacing = 7; + +// Spacing between the image and the text. +const NSInteger kImageSpacing = 10; + +// Square size of the image. +const CGFloat kImageSize = 30; + +} // namespace void PageInfoWindowMac::ShowPageInfo(Profile* profile, const GURL& url, @@ -43,8 +72,27 @@ PageInfoWindowMac::PageInfoWindowMac(PageInfoWindowController* controller, const NavigationEntry::SSLStatus& ssl, bool show_history) : controller_(controller), - model_(profile, url, ssl, show_history, this), + model_(new PageInfoModel(profile, url, ssl, show_history, this)), cert_id_(ssl.cert_id()) { + Init(); +} + +PageInfoWindowMac::PageInfoWindowMac(PageInfoWindowController* controller, + PageInfoModel* model) + : controller_(controller), + model_(model) { + Init(); +} + +void PageInfoWindowMac::Init() { + // Load the image refs. + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + good_image_.reset([rb.GetNSImageNamed(IDR_PAGEINFO_GOOD) retain]); + DCHECK_GE(kImageSize, [good_image_ size].width); + DCHECK_GE(kImageSize, [good_image_ size].height); + bad_image_.reset([rb.GetNSImageNamed(IDR_PAGEINFO_BAD) retain]); + DCHECK_GE(kImageSize, [bad_image_ size].width); + DCHECK_GE(kImageSize, [bad_image_ size].height); } PageInfoWindowMac::~PageInfoWindowMac() { @@ -93,42 +141,113 @@ void PageInfoWindowMac::ShowCertDialog(int) { // The SFCertificatePanel releases itself when the sheet is dismissed. } +// This will create the subviews for the page info window. The general layout +// is 2 or 3 boxed and titled sections, each of which has a status image to +// provide visual feedback and a description that explains it. The description +// text is usually only 1 or 2 lines, but can be much longer. At the bottom of +// the window is a button to view the SSL certificate, which is disabled if +// not using HTTPS. void PageInfoWindowMac::LayoutSections() { - // Identity section - PageInfoModel::SectionInfo identity_section = - model_.GetSectionInfo(PageInfoModel::IDENTITY); - if (identity_section.state) - [controller_ setIdentityImg:[controller_ goodImg]]; - else - [controller_ setIdentityImg:[controller_ badImg]]; - [controller_ setIdentityMsg:base::SysUTF16ToNSString( - identity_section.description)]; - - // Connection section. - PageInfoModel::SectionInfo connection_section = - model_.GetSectionInfo(PageInfoModel::CONNECTION); - if (connection_section.state) - [controller_ setConnectionImg:[controller_ goodImg]]; - else - [controller_ setConnectionImg:[controller_ badImg]]; - [controller_ setConnectionMsg: - base::SysUTF16ToNSString(connection_section.description)]; - - if (model_.GetSectionCount() > 2) { - // We have the history info. - PageInfoModel::SectionInfo history_section = - model_.GetSectionInfo(PageInfoModel::HISTORY); - if (history_section.state) - [controller_ setHistoryImg:[controller_ goodImg]]; - else - [controller_ setHistoryImg:[controller_ badImg]]; - - [controller_ setHistoryMsg: - base::SysUTF16ToNSString(history_section.description)]; + NSRect window_frame = [[controller_ window] frame]; + CGFloat window_width = NSWidth(window_frame); + // |offset| is the Y position that should be drawn at next. + CGFloat offset = kFramePadding; + + // Keep the new subviews in an array that gets replaced at the end. + NSMutableArray* subviews = [NSMutableArray array]; + + // Create the certificate button. The frame will be fixed up by GTM, so use + // arbitrary values. + NSRect button_rect = NSMakeRect(kFramePadding, offset, 100, 20); + scoped_nsobject<NSButton> cert_button( + [[NSButton alloc] initWithFrame:button_rect]); + [cert_button setTitle: + l10n_util::GetNSStringWithFixup(IDS_PAGEINFO_CERT_INFO_BUTTON)]; + [cert_button setButtonType:NSMomentaryPushInButton]; + [cert_button setBezelStyle:NSRoundedBezelStyle]; + // The default button will use control size font, not the system/button font. + [cert_button setFont:[NSFont systemFontOfSize:0]]; + [cert_button setTarget:controller_]; + [cert_button setAction:@selector(showCertWindow:)]; + [subviews addObject:cert_button.get()]; + [GTMUILocalizerAndLayoutTweaker sizeToFitView:cert_button]; + offset += NSHeight(button_rect) + kFramePadding; + + // Small font for the description labels. + NSFont* font = [NSFont labelFontOfSize:11]; + + // Calculate some common, constant values. + const CGFloat box_width = window_width - (2 * kFramePadding); + const CGFloat text_width = + box_width - (kBoxHorizontalSpacing + kImageSize + + kImageSpacing + kBoxHorizontalSpacing * 2); + const CGFloat text_x = kBoxHorizontalSpacing + kImageSize + kImageSpacing; + + // Build the window from bottom-up because Cocoa's coordinate origin is the + // lower left. + for (int i = model_->GetSectionCount() - 1; i >= 0; --i) { + PageInfoModel::SectionInfo info = model_->GetSectionInfo(i); + + // Create the text field first, because that informs how large to make the + // box it goes in. + NSRect text_field_rect = + NSMakeRect(text_x, kBoxBottomSpacing, text_width, kImageSpacing); + scoped_nsobject<NSTextField> text_field( + [[NSTextField alloc] initWithFrame:text_field_rect]); + [text_field setEditable:NO]; + [text_field setDrawsBackground:NO]; + [text_field setBezeled:NO]; + [text_field setStringValue:base::SysUTF16ToNSString(info.description)]; + [text_field setFont:font]; + + // If the text is oversized, resize the text field. + text_field_rect.size.height += + [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField: + text_field]; + + // Make the box, sized to fit the text. It should be at least large enough + // to contain the height of the image, which is larger than a single line + // of text. + CGFloat box_height = kBoxTopSpacing + + std::max(NSHeight(text_field_rect), kImageSize) + kBoxBottomSpacing; + NSRect box_rect = NSMakeRect(kFramePadding, offset, box_width, box_height); + scoped_nsobject<NSBox> box([[NSBox alloc] initWithFrame:box_rect]); + [box setTitlePosition:NSAtTop]; + [box setTitle:base::SysUTF16ToNSString(info.title)]; + offset += box_height + kVerticalSpacing; + + // Re-position the text field's origin now that the box height is known. + text_field_rect.origin.y = box_height - + (NSHeight(text_field_rect) + kBoxTopSpacing); + [text_field setFrame:text_field_rect]; + + // Insert the image subview. + NSRect image_view_rect = + NSMakeRect(kBoxHorizontalSpacing, + box_height - (kImageSize + kBoxTopSpacing), + kImageSize, kImageSize); + scoped_nsobject<NSImageView> image_view( + [[NSImageView alloc] initWithFrame:image_view_rect]); + [image_view setImageFrameStyle:NSImageFrameNone]; + [image_view setImage:(info.state) ? good_image_.get() : bad_image_.get()]; + + // Add the box to the list of new subviews. + [box addSubview:image_view.get()]; + [box addSubview:text_field.get()]; + [subviews addObject:box.get()]; } + // Replace the window's content. + [[[controller_ window] contentView] setSubviews:subviews]; + + // Just setting |size| will cause the window to grow upwards. Shift the + // origin up by grow amount, which causes the window to grow downwards. + offset += kFramePadding; + window_frame.origin.y -= offset - window_frame.size.height; + window_frame.size.height = offset; + // By default, assume that we don't have certificate information to show. - [controller_ setEnableCertButton:NO]; + [cert_button setEnabled:NO]; if (cert_id_) { scoped_refptr<net::X509Certificate> cert; CertStore::GetSharedInstance()->RetrieveCert(cert_id_, &cert); @@ -136,14 +255,17 @@ void PageInfoWindowMac::LayoutSections() { // Don't bother showing certificates if there isn't one. Gears runs with no // os root certificate. if (cert.get() && cert->os_cert_handle()) { - [controller_ setEnableCertButton:YES]; + [cert_button setEnabled:YES]; } } + + // Resize the window. Only animate if the window is visible, otherwise it + // could be "growing" while it's opening, looking awkward. + [[controller_ window] setFrame:window_frame + display:YES + animate:[[controller_ window] isVisible]]; } void PageInfoWindowMac::ModelChanged() { - // We have history information, so show the box and extend the window frame. - [controller_ setShowHistoryBox:YES]; LayoutSections(); } - diff --git a/chrome/browser/cocoa/page_info_window_mac_unittest.mm b/chrome/browser/cocoa/page_info_window_mac_unittest.mm new file mode 100644 index 0000000..30becc4 --- /dev/null +++ b/chrome/browser/cocoa/page_info_window_mac_unittest.mm @@ -0,0 +1,195 @@ +// 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. + +#include "app/l10n_util.h" +#include "base/scoped_nsobject.h" +#include "base/string_util.h" +#include "base/sys_string_conversions.h" +#import "chrome/browser/cocoa/page_info_window_mac.h" +#import "chrome/browser/cocoa/page_info_window_controller.h" +#include "chrome/browser/cocoa/browser_test_helper.h" +#import "chrome/browser/cocoa/cocoa_test_helper.h" +#include "chrome/browser/page_info_model.h" +#include "grit/generated_resources.h" + +namespace { + +class FakeModel : public PageInfoModel { + public: + void AddSection(bool state, + const string16& title, + const string16& description) { + sections_.push_back(SectionInfo( + state, + title, + string16(), + description)); + } +}; + +class PageInfoWindowMacTest : public CocoaTest { + public: + virtual void SetUp() { + CocoaTest::SetUp(); + + // The controller cleans up after itself when the window closes. + controller_ = [[PageInfoWindowController alloc] init]; + window_ = [controller_ window]; + + // The bridge will own the model. + model_ = new FakeModel(); + + // The controller will take ownership of the bridge. + bridge_ = new PageInfoWindowMac(controller_, model_); + [controller_ setPageInfo:bridge_]; + EXPECT_TRUE([controller_ window]); + } + + virtual void TearDown() { + [controller_ close]; + CocoaTest::TearDown(); + } + + // Checks the controller's window for the requisite subviews in the given + // numbers. + void CheckWindow(int button_count, int box_count) { + for (NSView* view in [[window_ contentView] subviews]) { + if ([view isKindOfClass:[NSButton class]]) { + --button_count; + CheckButton(static_cast<NSButton*>(view)); + } else if ([view isKindOfClass:[NSBox class]]) { + --box_count; + CheckBox(static_cast<NSBox*>(view)); + } else { + EXPECT_TRUE(false) << "Unknown subview"; + } + } + EXPECT_EQ(0, button_count); + EXPECT_EQ(0, box_count); + EXPECT_EQ([window_ delegate], controller_); + } + + // Checks that a button is hooked up correctly. + void CheckButton(NSButton* button) { + EXPECT_EQ(@selector(showCertWindow:), [button action]); + EXPECT_EQ(controller_, [button target]); + EXPECT_TRUE([button stringValue]); + } + + // Makes sure the box has a valid image and a string. + void CheckBox(NSBox* box) { + EXPECT_TRUE([box title]); + NSArray* subviews = [[box contentView] subviews]; + EXPECT_EQ(2U, [subviews count]); + for (NSView* view in subviews) { + if ([view isKindOfClass:[NSImageView class]]) { + NSImageView* image_view = static_cast<NSImageView*>(view); + EXPECT_TRUE([image_view image] == bridge_->good_image_.get() || + [image_view image] == bridge_->bad_image_.get()); + } else if ([view isKindOfClass:[NSTextField class]]) { + NSTextField* text_field = static_cast<NSTextField*>(view); + EXPECT_LT(0U, [[text_field stringValue] length]); + } else { + EXPECT_TRUE(false) << "Unknown box subview"; + } + } + } + + BrowserTestHelper helper_; + + PageInfoWindowController* controller_; // Weak, owns self. + PageInfoWindowMac* bridge_; // Weak, owned by controller. + FakeModel* model_; // Weak, owned by bridge. + + NSWindow* window_; // Weak, owned by controller. +}; + + +TEST_F(PageInfoWindowMacTest, NoHistoryNoSecurity) { + model_->AddSection(false, + l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_IDENTITY_TITLE), + l10n_util::GetStringFUTF16( + IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY, + ASCIIToUTF16("google.com"))); + model_->AddSection(false, + l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_CONNECTION_TITLE), + l10n_util::GetStringFUTF16( + IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, + ASCIIToUTF16("google.com"))); + + bridge_->ModelChanged(); + + CheckWindow(1, 2); +} + + +TEST_F(PageInfoWindowMacTest, HistoryNoSecurity) { + model_->AddSection(false, + l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_IDENTITY_TITLE), + l10n_util::GetStringFUTF16( + IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY, + ASCIIToUTF16("google.com"))); + model_->AddSection(false, + l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_CONNECTION_TITLE), + l10n_util::GetStringFUTF16( + IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, + ASCIIToUTF16("google.com"))); + + // In practice, the history information comes later because it's queried + // asynchronously, so replicate the double-build here. + bridge_->ModelChanged(); + + model_->AddSection(false, + l10n_util::GetStringUTF16( + IDS_PAGE_INFO_SECURITY_TAB_PERSONAL_HISTORY_TITLE), + l10n_util::GetStringUTF16( + IDS_PAGE_INFO_SECURITY_TAB_FIRST_VISITED_TODAY)); + + bridge_->ModelChanged(); + + CheckWindow(1, 3); +} + + +TEST_F(PageInfoWindowMacTest, NoHistoryMixedSecurity) { + model_->AddSection(true, + l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_IDENTITY_TITLE), + l10n_util::GetStringFUTF16( + IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, + ASCIIToUTF16("Goat Security Systems"))); + + // This string is super long and the text should overflow the default clip + // region (kImageSize). + string16 title = + l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_CONNECTION_TITLE); + model_->AddSection(true, + title, + l10n_util::GetStringFUTF16( + IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK, + l10n_util::GetStringFUTF16( + IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT, + ASCIIToUTF16("chrome.google.com"), + IntToString16(1024)), + l10n_util::GetStringUTF16( + IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_MIXED_CONTENT_WARNING))); + + bridge_->ModelChanged(); + + NSArray* subviews = [[window_ contentView] subviews]; + CheckWindow(1, 2); + + // Look for the over-sized box. + NSString* targetTitle = base::SysUTF16ToNSString(title); + for (NSView* subview in subviews) { + if ([subview isKindOfClass:[NSBox class]]) { + NSBox* box = static_cast<NSBox*>(subview); + if ([[box title] isEqualToString:targetTitle]) { + // Typical box frame is ~55px, make sure this is extra large. + EXPECT_LT(75, NSHeight([box frame])); + } + } + } +} + +} // namespace |