diff options
author | danno@chromium.org <danno@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-25 11:00:04 +0000 |
---|---|---|
committer | danno@chromium.org <danno@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-25 11:00:04 +0000 |
commit | 9b8b4d375a9ce7cc52b6d42046a4947f58b8648d (patch) | |
tree | aa62820d005c55aebeae5400bf88ff2215de2181 /chrome/browser/cocoa | |
parent | fcdec74769768ae107cc96216175bce243aab995 (diff) | |
download | chromium_src-9b8b4d375a9ce7cc52b6d42046a4947f58b8648d.zip chromium_src-9b8b4d375a9ce7cc52b6d42046a4947f58b8648d.tar.gz chromium_src-9b8b4d375a9ce7cc52b6d42046a4947f58b8648d.tar.bz2 |
[Mac] Make cookie prompt dialog more Mac-like
As per Alcor's recommendations, customize the Mac cookie prompt so that it is a less like windows/linux but more "maccy": add application icon for modal dialog, change layout and make radio buttons in "remember" choice small rather than regular.
Also added unit tests.
xib changes:
- Add application icon to cookie prompt dialog, shifting all other elements to the right accordingly.
- Change the size of the radio buttons in the "remember" choice to be small rather than regular.
- Change the default text in in the information NSTextField to "Label" rather than a really long nonsensical debug string
- Move the details view to be below the accept/block buttons.
- Change the style of the disclosure control to be a button rather than triangle.
Before: http://img257.yfrog.com/img257/3066/picture3fx.png
After: http://img214.imageshack.us/img214/5553/picture9es.png and http://img200.imageshack.us/img200/1558/picture10pm.png
BUG=38208
TEST=manual testing, added unit test for remember/block/accept controls
Review URL: http://codereview.chromium.org/1102005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42597 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
4 files changed, 171 insertions, 11 deletions
diff --git a/chrome/browser/cocoa/cookie_details_view_controller.mm b/chrome/browser/cocoa/cookie_details_view_controller.mm index ea1801f..1c97d19 100644 --- a/chrome/browser/cocoa/cookie_details_view_controller.mm +++ b/chrome/browser/cocoa/cookie_details_view_controller.mm @@ -19,6 +19,7 @@ static const int kMinimalLabelOffsetFromViewBottom = 20; #pragma mark View Controller @implementation CookieDetailsViewController +@dynamic hasExpiration; - (id)init { return [super initWithNibName:@"CookieDetailsView" @@ -97,8 +98,6 @@ static const int kMinimalLabelOffsetFromViewBottom = 20; [[[objectController_ content] details] setHasExpiration:YES]; } -@dynamic hasExpiration; - - (BOOL)hasExpiration { return [[[objectController_ content] details] hasExpiration]; } diff --git a/chrome/browser/cocoa/cookie_prompt_window_controller.h b/chrome/browser/cocoa/cookie_prompt_window_controller.h index 5276d5c..6ae68b4 100644 --- a/chrome/browser/cocoa/cookie_prompt_window_controller.h +++ b/chrome/browser/cocoa/cookie_prompt_window_controller.h @@ -35,8 +35,8 @@ class CookieTreeNode; // in the prompt window. IBOutlet NSTextField* description_; IBOutlet NSView* disclosedViewPlaceholder_; - IBOutlet NSButton* disclosureTriangle_; - IBOutlet NSView* disclosureTriangleSuperView_; + IBOutlet NSButton* disclosureButton_; + IBOutlet NSView* disclosureButtonSuperView_; IBOutlet NSMatrix* radioGroupMatrix_; IBOutlet NSButtonCell* rememberChoiceCell_; } @@ -50,7 +50,7 @@ class CookieTreeNode; // Handles the toggling of the disclosure triangle // to reveal cookie data -- (IBAction)disclosureTrianglePressed:(id)sender; +- (IBAction)disclosureButtonPressed:(id)sender; // Callback for "block" button. - (IBAction)block:(id)sender; @@ -58,4 +58,9 @@ class CookieTreeNode; // Callback for "accept" button. - (IBAction)accept:(id)sender; +// Processes the selection result code made in the cookie prompt. +// Part of the public interface for the tests. +- (void)processModalDialogResult:(void*)contextInfo + returnCode:(int)returnCode; + @end diff --git a/chrome/browser/cocoa/cookie_prompt_window_controller.mm b/chrome/browser/cocoa/cookie_prompt_window_controller.mm index a00e84d..779d506 100644 --- a/chrome/browser/cocoa/cookie_prompt_window_controller.mm +++ b/chrome/browser/cocoa/cookie_prompt_window_controller.mm @@ -19,6 +19,10 @@ #include "grit/generated_resources.h" #import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h" +namespace { +static const CGFloat kExtraMarginForDetailsView = 10; +} + @implementation CookiePromptWindowController - (id)initWithDialog:(CookiePromptModalDialog*)dialog { @@ -76,6 +80,13 @@ descriptionFrame.origin.y -= sizeDelta; [description_ setFrame:descriptionFrame]; + // |wrapRadioGroupForWidth:| takes the font that is set on the + // radio group to do the wrapping. It must be set explicitly, otherwise + // the wrapping is based on the |NSRegularFontSize| rather than + // |NSSmallFontSize| + CGFloat fontSize = [NSFont systemFontSizeForControlSize:NSSmallControlSize]; + [radioGroupMatrix_ setFont:[NSFont controlContentFontOfSize:fontSize]]; + // Wrap the radio buttons to fit if necessary. [GTMUILocalizerAndLayoutTweaker wrapRadioGroupForWidth:radioGroupMatrix_]; @@ -87,14 +98,15 @@ // Adjust views location, they may have moved through the // expansion of the radio buttons and description text. - NSRect disclosureViewFrame = [disclosureTriangleSuperView_ frame]; + NSRect disclosureViewFrame = [disclosureButtonSuperView_ frame]; disclosureViewFrame.origin.y -= sizeDelta; - [disclosureTriangleSuperView_ setFrame:disclosureViewFrame]; + [disclosureButtonSuperView_ setFrame:disclosureViewFrame]; // Adjust the final window size by the size of the cookie details // view, since it will be initially hidden. NSRect detailsViewRect = [disclosedViewPlaceholder_ frame]; sizeDelta -= detailsViewRect.size.height; + sizeDelta -= kExtraMarginForDetailsView; // Final resize the window to fit all of the adjustments NSRect frame = [[self window] frame]; @@ -117,10 +129,10 @@ } - (void)awakeFromNib { - DCHECK(disclosureTriangle_); + DCHECK(disclosureButton_); DCHECK(radioGroupMatrix_); DCHECK(disclosedViewPlaceholder_); - DCHECK(disclosureTriangleSuperView_); + DCHECK(disclosureButtonSuperView_); [self doLocalizationTweaks]; [self doLayoutTweaks]; @@ -162,10 +174,11 @@ [self processModalDialogResult:context returnCode:returnCode]; } -- (IBAction)disclosureTrianglePressed:(id)sender { +- (IBAction)disclosureButtonPressed:(id)sender { NSWindow* window = [self window]; NSRect frame = [[self window] frame]; - CGFloat sizeChange = [[detailsViewController_.get() view] frame].size.height; + CGFloat sizeChange = [[detailsViewController_.get() view] frame].size.height + + kExtraMarginForDetailsView; switch ([sender state]) { case NSOnState: frame.size.height += sizeChange; diff --git a/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm b/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm index 8c9da0d..10d73bc 100644 --- a/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm +++ b/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm @@ -7,8 +7,75 @@ #include "chrome/browser/cocoa/cookie_prompt_window_controller.h" #include "chrome/browser/cookie_modal_dialog.h" +// A mock class which implements just enough functionality to +// act as a radio with a pre-specified selected button. +@interface MockRadioButtonMatrix : NSObject { + @private + NSInteger selectedRow_; +} +- (NSInteger)selectedRow; +@end + +@implementation MockRadioButtonMatrix + +- (id)initWithSelectedRow:(NSInteger)selectedRow { + if ((self = [super init])) { + selectedRow_ = selectedRow; + } + return self; +} + +- (NSInteger)selectedRow { + return selectedRow_; +} +@end + namespace { +// A subclass of the |CookiePromptModalDialog| that allows tests of +// some of the prompt window controller's functionality without having +// a full environment by overriding select methods and intercepting +// calls that would otherwise rely on behavior only present in a full +// environment. +class CookiePromptModalDialogMock : public CookiePromptModalDialog { + public: + CookiePromptModalDialogMock(const GURL& origin, + const std::string& cookie_line); + + virtual void AllowSiteData(bool remember, bool session_expire); + virtual void BlockSiteData(bool remember); + + bool allow() const { return allow_; } + bool remember() const { return remember_; } + + private: + + // The result of the block/unblock decision. + bool allow_; + + // Whether the block/accept decision should be remembered. + bool remember_; +}; + +CookiePromptModalDialogMock::CookiePromptModalDialogMock( + const GURL& origin, + const std::string& cookie_line) + : CookiePromptModalDialog(NULL, NULL, origin, cookie_line, NULL), + allow_(false), + remember_(false) { +} + +void CookiePromptModalDialogMock::AllowSiteData(bool remember, + bool session_expire) { + remember_ = remember; + allow_ = true; +} + +void CookiePromptModalDialogMock::BlockSiteData(bool remember) { + remember_ = remember; + allow_ = false; +} + class CookiePromptWindowControllerTest : public CocoaTest { }; @@ -47,4 +114,80 @@ TEST_F(CookiePromptWindowControllerTest, CreateForLocalStorage) { EXPECT_TRUE([controller.get() window]); } +TEST_F(CookiePromptWindowControllerTest, RememberMyChoiceAllow) { + GURL url("http://chromium.org"); + std::string cookieLine( + "PHPSESSID=0123456789abcdef0123456789abcdef; path=/"); + scoped_ptr<CookiePromptModalDialogMock> dialog( + new CookiePromptModalDialogMock(url, cookieLine)); + scoped_nsobject<CookiePromptWindowController> controller( + [[CookiePromptWindowController alloc] initWithDialog:dialog.get()]); + scoped_nsobject<MockRadioButtonMatrix> checkbox([[MockRadioButtonMatrix alloc] + initWithSelectedRow:0]); + [controller.get() setValue:checkbox.get() forKey:@"radioGroupMatrix_"]; + + [controller.get() processModalDialogResult:dialog.get() + returnCode:NSAlertFirstButtonReturn]; + + EXPECT_TRUE(dialog->remember()); + EXPECT_TRUE(dialog->allow()); +} + +TEST_F(CookiePromptWindowControllerTest, RememberMyChoiceBlock) { + GURL url("http://codereview.chromium.org"); + std::string cookieLine( + "PHPSESSID=0123456789abcdef0123456789abcdef; path=/"); + scoped_ptr<CookiePromptModalDialogMock> dialog( + new CookiePromptModalDialogMock(url, cookieLine)); + scoped_nsobject<CookiePromptWindowController> controller( + [[CookiePromptWindowController alloc] initWithDialog:dialog.get()]); + scoped_nsobject<MockRadioButtonMatrix> checkbox([[MockRadioButtonMatrix alloc] + initWithSelectedRow:0]); + [controller.get() setValue:checkbox.get() forKey:@"radioGroupMatrix_"]; + + [controller.get() processModalDialogResult:dialog.get() + returnCode:NSAlertSecondButtonReturn]; + + EXPECT_TRUE(dialog->remember()); + EXPECT_FALSE(dialog->allow()); +} + +TEST_F(CookiePromptWindowControllerTest, DontRememberMyChoiceAllow) { + GURL url("http://chromium.org"); + std::string cookieLine( + "PHPSESSID=0123456789abcdef0123456789abcdef; path=/"); + scoped_ptr<CookiePromptModalDialogMock> dialog( + new CookiePromptModalDialogMock(url, cookieLine)); + scoped_nsobject<CookiePromptWindowController> controller( + [[CookiePromptWindowController alloc] initWithDialog:dialog.get()]); + scoped_nsobject<MockRadioButtonMatrix> checkbox([[MockRadioButtonMatrix alloc] + initWithSelectedRow:1]); + [controller.get() setValue:checkbox.get() forKey:@"radioGroupMatrix_"]; + + [controller.get() processModalDialogResult:dialog.get() + returnCode:NSAlertFirstButtonReturn]; + + EXPECT_FALSE(dialog->remember()); + EXPECT_TRUE(dialog->allow()); +} + +TEST_F(CookiePromptWindowControllerTest, DontRememberMyChoiceBlock) { + GURL url("http://codereview.chromium.org"); + std::string cookieLine( + "PHPSESSID=0123456789abcdef0123456789abcdef; path=/"); + scoped_ptr<CookiePromptModalDialogMock> dialog( + new CookiePromptModalDialogMock(url, cookieLine)); + scoped_nsobject<CookiePromptWindowController> controller( + [[CookiePromptWindowController alloc] initWithDialog:dialog.get()]); + scoped_nsobject<MockRadioButtonMatrix> checkbox([[MockRadioButtonMatrix alloc] + initWithSelectedRow:1]); + [controller.get() setValue:checkbox.get() forKey:@"radioGroupMatrix_"]; + + [controller.get() processModalDialogResult:dialog.get() + returnCode:NSAlertSecondButtonReturn]; + + EXPECT_FALSE(dialog->remember()); + EXPECT_FALSE(dialog->allow()); +} + } // namespace |