summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/app_modal_dialog.cc4
-rw-r--r--chrome/browser/app_modal_dialog.h11
-rw-r--r--chrome/browser/app_modal_dialog_mac.mm5
-rw-r--r--chrome/browser/cocoa/cookie_details_view_controller.h40
-rw-r--r--chrome/browser/cocoa/cookie_details_view_controller.mm80
-rw-r--r--chrome/browser/cocoa/cookie_details_view_controller_unittest.mm142
-rw-r--r--chrome/browser/cocoa/cookie_prompt_window_controller.h61
-rw-r--r--chrome/browser/cocoa/cookie_prompt_window_controller.mm416
-rw-r--r--chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm50
-rw-r--r--chrome/browser/cocoa/cookie_tree_node.h6
-rw-r--r--chrome/browser/cocoa/cookie_tree_node.mm41
-rw-r--r--chrome/browser/cocoa/cookies_window_controller.h12
-rw-r--r--chrome/browser/cocoa/cookies_window_controller.mm42
-rw-r--r--chrome/browser/cocoa/cookies_window_controller_unittest.mm9
-rw-r--r--chrome/browser/cookie_modal_dialog.h17
-rw-r--r--chrome/browser/cookie_modal_dialog_mac.mm110
-rw-r--r--chrome/browser/js_modal_dialog.h16
-rw-r--r--chrome/browser/js_modal_dialog_mac.mm7
18 files changed, 910 insertions, 159 deletions
diff --git a/chrome/browser/app_modal_dialog.cc b/chrome/browser/app_modal_dialog.cc
index 2eea602..e8f306d 100644
--- a/chrome/browser/app_modal_dialog.cc
+++ b/chrome/browser/app_modal_dialog.cc
@@ -11,7 +11,11 @@
AppModalDialog::AppModalDialog(TabContents* tab_contents,
const std::wstring& title)
+#if defined(OS_WIN) || defined(OS_LINUX)
: dialog_(NULL),
+#elif defined(OS_MACOSX)
+ :
+#endif
tab_contents_(tab_contents),
title_(title),
skip_this_dialog_(false) {
diff --git a/chrome/browser/app_modal_dialog.h b/chrome/browser/app_modal_dialog.h
index 6567db8..92ac494 100644
--- a/chrome/browser/app_modal_dialog.h
+++ b/chrome/browser/app_modal_dialog.h
@@ -17,12 +17,7 @@
class ModalDialogDelegate;
typedef ModalDialogDelegate* NativeDialog;
#elif defined(OS_MACOSX)
-#if __OBJC__
-@class NSAlert;
-#else
-class NSAlert;
-#endif
-typedef NSAlert* NativeDialog;
+typedef void* NativeDialog;
#elif defined(TOOLKIT_USES_GTK)
typedef struct _GtkDialog GtkDialog;
typedef struct _GtkWidget GtkWidget;
@@ -71,7 +66,7 @@ class AppModalDialog {
#endif
// Close the dialog if it is showing.
- void CloseModalDialog();
+ virtual void CloseModalDialog();
// Called by the app modal window queue to activate the window.
void ActivateModalDialog();
@@ -97,7 +92,9 @@ class AppModalDialog {
virtual NativeDialog CreateNativeDialog() = 0;
// A reference to the platform native dialog box.
+#if defined(OS_LINUX) || defined(OS_WIN)
NativeDialog dialog_;
+#endif
// Parent tab contents.
TabContents* tab_contents_;
diff --git a/chrome/browser/app_modal_dialog_mac.mm b/chrome/browser/app_modal_dialog_mac.mm
index 2a21c1da..8d23387 100644
--- a/chrome/browser/app_modal_dialog_mac.mm
+++ b/chrome/browser/app_modal_dialog_mac.mm
@@ -20,8 +20,5 @@ void AppModalDialog::ActivateModalDialog() {
}
void AppModalDialog::CloseModalDialog() {
- NSAlert* alert = dialog_;
- DCHECK([alert isKindOfClass:[NSAlert class]]);
- [NSApp endSheet:[alert window]];
- dialog_ = nil;
+ NOTIMPLEMENTED();
}
diff --git a/chrome/browser/cocoa/cookie_details_view_controller.h b/chrome/browser/cocoa/cookie_details_view_controller.h
new file mode 100644
index 0000000..04b8db7
--- /dev/null
+++ b/chrome/browser/cocoa/cookie_details_view_controller.h
@@ -0,0 +1,40 @@
+// 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 <Cocoa/Cocoa.h>
+
+#include "base/cocoa_protocols_mac.h"
+#include "base/scoped_nsobject.h"
+#include "base/scoped_ptr.h"
+#include "net/base/cookie_monster.h"
+
+@class CocoaCookieTreeNode;
+
+// Controller for the view that displays the details of a cookie,
+// used both in the cookie prompt dialog as well as the
+// show cookies preference sheet of content settings preferences.
+@interface CookieDetailsViewController : NSViewController {
+ @private
+ // Allows direct access to the object controller for
+ // the displayed cookie information.
+ IBOutlet NSObjectController* objectController_;
+}
+
+- (id)init;
+
+// Configures the cookie detail view that is managed by the controller
+// to display the information about a single cookie, the information
+// for which is explicitly passed in the parameter |content|.
+- (void)setContentObject:(id)content;
+
+// Adjust the size of the view to exactly fix the information text fields
+// that are visible inside it.
+- (void)shrinkViewToFit;
+
+// Called by the cookie tree dialog to establish a binding between
+// the the detail view's object controller and the tree controller.
+// This binding allows the cookie tree to use the detail view unmodified.
+- (void)configureBindingsForTreeController:(NSTreeController*)controller;
+@end
+
diff --git a/chrome/browser/cocoa/cookie_details_view_controller.mm b/chrome/browser/cocoa/cookie_details_view_controller.mm
new file mode 100644
index 0000000..70da2a5
--- /dev/null
+++ b/chrome/browser/cocoa/cookie_details_view_controller.mm
@@ -0,0 +1,80 @@
+// 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/cookie_details_view_controller.h"
+
+#include "app/l10n_util_mac.h"
+#include "app/resource_bundle.h"
+#import "base/mac_util.h"
+#include "base/sys_string_conversions.h"
+#import "chrome/browser/cocoa/cookie_tree_node.h"
+#import "chrome/browser/cookie_modal_dialog.h"
+
+namespace {
+static const int kMinimalLabelOffsetFromViewBottom = 20;
+}
+
+#pragma mark View Controller
+
+@implementation CookieDetailsViewController
+
+- (id)init {
+ return [super initWithNibName:@"CookieDetailsView"
+ bundle:mac_util::MainAppBundle()];
+}
+
+- (void)awakeFromNib {
+ DCHECK(objectController_);
+}
+
+// Finds and returns the y offset of the lowest-most non-hidden
+// text field in the view. This is used to shrink the view
+// appropriately so that it just fits its visible content.
+- (void)getLowestLabelVerticalPosition:(NSView*)view
+ lowestLabelPosition:(float&)lowestLabelPosition {
+ if (![view isHidden]) {
+ if ([view isKindOfClass:[NSTextField class]]) {
+ NSRect frame = [view frame];
+ if (frame.origin.y < lowestLabelPosition) {
+ lowestLabelPosition = frame.origin.y;
+ }
+ }
+ for (NSView* subview in [view subviews]) {
+ [self getLowestLabelVerticalPosition:subview
+ lowestLabelPosition:lowestLabelPosition];
+ }
+ }
+}
+
+- (void)setContentObject:(id)content {
+ [objectController_ setValue:content forKey:@"content"];
+}
+
+- (void)shrinkViewToFit {
+ // Adjust the information pane to be exactly the right size
+ // to hold the visible text information fields.
+ NSView* view = [self view];
+ NSRect frame = [view frame];
+ float lowestLabelPosition = frame.origin.y + frame.size.height;
+ [self getLowestLabelVerticalPosition:view
+ lowestLabelPosition:lowestLabelPosition];
+ float verticalDelta = lowestLabelPosition - frame.origin.y -
+ kMinimalLabelOffsetFromViewBottom;
+ frame.origin.y += verticalDelta;
+ frame.size.height -= verticalDelta;
+ [[self view] setFrame:frame];
+}
+
+- (void)configureBindingsForTreeController:(NSTreeController*)treeController {
+ // There seems to be a bug in the binding logic that it's not possible
+ // to bind to the selection of the tree controller, the bind seems to
+ // require an additional path segment in the key, thus the use of
+ // selection.self rather than just selection below.
+ [objectController_ bind:@"contentObject"
+ toObject:treeController
+ withKeyPath:@"selection.self"
+ options:nil];
+}
+
+@end
diff --git a/chrome/browser/cocoa/cookie_details_view_controller_unittest.mm b/chrome/browser/cocoa/cookie_details_view_controller_unittest.mm
new file mode 100644
index 0000000..a1d6a67
--- /dev/null
+++ b/chrome/browser/cocoa/cookie_details_view_controller_unittest.mm
@@ -0,0 +1,142 @@
+// 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/cocoa_test_helper.h"
+#include "chrome/browser/cocoa/cookie_details_view_controller.h"
+#include "chrome/browser/cookie_modal_dialog.h"
+
+// Mock apapter that returns dummy values for the details view
+@interface MockCookieDetailsViewContentAdapter : NSObject {
+ @private
+ // The type of fake cookie data to display
+ CookiePromptModalDialog::DialogType promptType_;
+}
+
+- (id)initWithType:(CookiePromptModalDialog::DialogType)type;
+
+// The following methods are all used in the bindings
+// inside the cookie detail view.
+@property (readonly) BOOL isFolderOrCookieTreeDetails;
+@property (readonly) BOOL isLocalStorageTreeDetails;
+@property (readonly) BOOL isDatabaseTreeDetails;
+@property (readonly) BOOL isDatabasePromptDetails;
+@property (readonly) BOOL isLocalStoragePromptDetails;
+@property (readonly) NSString* name;
+@property (readonly) NSString* content;
+@property (readonly) NSString* domain;
+@property (readonly) NSString* path;
+@property (readonly) NSString* sendFor;
+@property (readonly) NSString* created;
+@property (readonly) NSString* expires;
+@property (readonly) NSString* fileSize;
+@property (readonly) NSString* lastModified;
+@property (readonly) NSString* databaseDescription;
+@property (readonly) NSString* localStorageKey;
+@property (readonly) NSString* localStorageValue;
+
+@end
+
+@implementation MockCookieDetailsViewContentAdapter
+
+- (id)initWithType:(CookiePromptModalDialog::DialogType)type {
+ if ((self = [super init])) {
+ promptType_ = type;
+ }
+ return self;
+}
+
+- (BOOL)isFolderOrCookieTreeDetails {
+ return promptType_ == CookiePromptModalDialog::DIALOG_TYPE_COOKIE;
+}
+
+- (BOOL)isLocalStorageTreeDetails {
+ return false;
+}
+
+- (BOOL)isDatabaseTreeDetails {
+ return false;
+}
+
+- (BOOL) isDatabasePromptDetails {
+ return promptType_ == CookiePromptModalDialog::DIALOG_TYPE_DATABASE;
+}
+
+- (BOOL) isLocalStoragePromptDetails {
+ return promptType_ == CookiePromptModalDialog::DIALOG_TYPE_LOCAL_STORAGE;
+}
+
+- (NSString*)name {
+ return @"dummyName";
+}
+
+- (NSString*)content {
+ return @"dummyContent";
+}
+
+- (NSString*)domain {
+ return @"dummyDomain";
+}
+
+- (NSString*)path {
+ return @"dummyPath";
+}
+
+- (NSString*)sendFor {
+ return @"dummySendFor";
+}
+
+- (NSString*)created {
+ return @"dummyCreated";
+}
+
+- (NSString*)expires {
+ return @"dummyExpires";
+}
+
+- (NSString*)fileSize {
+ return @"dummyFileSize";
+}
+
+- (NSString*)lastModified {
+ return @"dummyLastModified";
+}
+
+- (NSString*)databaseDescription {
+ return @"dummyDatabaseDescription";
+}
+
+- (NSString*)localStorageKey {
+ return @"dummyLocalStorageKey";
+}
+
+- (NSString*)localStorageValue {
+ return @"dummyLocalStorageValue";
+}
+
+@end
+
+namespace {
+
+class CookieDetailsViewControllerTest : public CocoaTest {
+};
+
+TEST_F(CookieDetailsViewControllerTest, Create) {
+ scoped_nsobject<CookieDetailsViewController> detailsViewController;
+ detailsViewController.reset([[CookieDetailsViewController alloc] init]);
+}
+
+TEST_F(CookieDetailsViewControllerTest, ShrinkToFit) {
+ scoped_nsobject<CookieDetailsViewController> detailsViewController;
+ detailsViewController.reset([[CookieDetailsViewController alloc] init]);
+ scoped_nsobject<MockCookieDetailsViewContentAdapter> mockAdapter;
+ mockAdapter.reset([[MockCookieDetailsViewContentAdapter alloc]
+ initWithType:CookiePromptModalDialog::DIALOG_TYPE_DATABASE]);
+ [detailsViewController.get() setContentObject:mockAdapter.get()];
+ NSRect beforeFrame = [[detailsViewController.get() view] frame];
+ [detailsViewController.get() shrinkViewToFit];
+ NSRect afterFrame = [[detailsViewController.get() view] frame];
+ EXPECT_TRUE(afterFrame.size.height < beforeFrame.size.width);
+}
+
+} // namespace
diff --git a/chrome/browser/cocoa/cookie_prompt_window_controller.h b/chrome/browser/cocoa/cookie_prompt_window_controller.h
new file mode 100644
index 0000000..5276d5c
--- /dev/null
+++ b/chrome/browser/cocoa/cookie_prompt_window_controller.h
@@ -0,0 +1,61 @@
+// 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 <Cocoa/Cocoa.h>
+
+#include "base/cocoa_protocols_mac.h"
+#include "base/scoped_nsobject.h"
+#include "base/scoped_ptr.h"
+
+class CookiePromptModalDialog;
+class CookieTreeNode;
+
+@class CookieDetailsViewController;
+@class CocoaCookieTreeNode;
+
+// This class is the controller for the window displayed
+// to the user as a modal dialog prompting them to accept or
+// block new cookies and other browser data.
+@interface CookiePromptWindowController : NSWindowController {
+ @private
+ // Provides access to platform independent information for
+ // the cookie prompt dialog.
+ CookiePromptModalDialog* dialog_; // weak;
+
+ // The controller managing the instances of the cookies details view
+ // embedded in the prompt window.
+ scoped_nsobject<CookieDetailsViewController> detailsViewController_;
+
+ // The adapter object that supplies the methods expected by
+ // the cookie details view.
+ scoped_nsobject<NSObject> selectionAdapterObject_;
+
+ // Outlets to provide quick access to subviews
+ // in the prompt window.
+ IBOutlet NSTextField* description_;
+ IBOutlet NSView* disclosedViewPlaceholder_;
+ IBOutlet NSButton* disclosureTriangle_;
+ IBOutlet NSView* disclosureTriangleSuperView_;
+ IBOutlet NSMatrix* radioGroupMatrix_;
+ IBOutlet NSButtonCell* rememberChoiceCell_;
+}
+
+// Designated initializer.
+- (id)initWithDialog:(CookiePromptModalDialog*)bridge;
+
+// Performs the modal dialog loop for the cookie prompt dialog
+// and processes the result.
+- (void)doModalDialog:(void*)context;
+
+// Handles the toggling of the disclosure triangle
+// to reveal cookie data
+- (IBAction)disclosureTrianglePressed:(id)sender;
+
+// Callback for "block" button.
+- (IBAction)block:(id)sender;
+
+// Callback for "accept" button.
+- (IBAction)accept:(id)sender;
+
+@end
diff --git a/chrome/browser/cocoa/cookie_prompt_window_controller.mm b/chrome/browser/cocoa/cookie_prompt_window_controller.mm
new file mode 100644
index 0000000..5b85397
--- /dev/null
+++ b/chrome/browser/cocoa/cookie_prompt_window_controller.mm
@@ -0,0 +1,416 @@
+// 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/cookie_prompt_window_controller.h"
+
+#include <string>
+#include <vector>
+
+#include "app/l10n_util_mac.h"
+#include "app/resource_bundle.h"
+#import "base/i18n/time_formatting.h"
+#import "base/mac_util.h"
+#include "base/sys_string_conversions.h"
+#import "chrome/browser/cocoa/cookie_details_view_controller.h"
+#include "chrome/browser/cocoa/cookie_tree_node.h"
+#include "chrome/browser/cookie_modal_dialog.h"
+#include "chrome/browser/cookies_tree_model.h"
+#include "grit/generated_resources.h"
+#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
+
+#pragma mark Window Controller
+
+// This class is an apapter allows the cookie details view to be shared
+// by the cookie prompt window and the cookie tree in the cookies and
+// other site data window. As instance of the class is set as the
+// content object of the object controller for the details view and
+// implements the methods expected by bindings inside that view.
+@interface CookiePromptSelectionAdapter : NSObject {
+ @private
+ // The type of the cookie prompt being displayed, used to
+ // determine which subview of the details view is visible
+ CookiePromptModalDialog::DialogType promptType_;
+
+ // The following members are used to hold information used in the
+ // cookie prompt detailed information for cookies and web databases.
+ scoped_nsobject<NSString> name_;
+ scoped_nsobject<NSString> domain_;
+ scoped_nsobject<NSString> content_;
+
+ // The following members are used to hold information used in the
+ // cookie prompt detailed information for cookies only.
+ scoped_nsobject<NSString> path_;
+ scoped_nsobject<NSString> sendFor_;
+ scoped_nsobject<NSString> created_;
+ scoped_nsobject<NSString> expires_;
+
+ // The following members are used to hold information used in the
+ // cookie prompt detailed information for local storage only.
+ scoped_nsobject<NSString> localStorageKey_;
+ scoped_nsobject<NSString> localStorageValue_;
+}
+
+// Creates and returns an instance approriate for displaying information
+// about a cookie.
+- (id)initWithCookie:(const std::string&)cookie_line
+ url:(const GURL&)url;
+
+// Creates and returns an instance approriate for displaying information
+// about a local storage.
+- (id)initWithLocalStorage:(const std::string&)domain
+ key:(const string16&)key
+ value:(const string16&)value;
+
+// Creates and returns an instance approriate for displaying information
+// about a web database.
+- (id)initWithDatabase:(const std::string&)domain
+ name:(const string16&)name;
+
+// The following methods are all used in the bindings inside the cookie
+// detail view.
+@property (readonly) BOOL isFolderOrCookieTreeDetails;
+@property (readonly) BOOL isLocalStorageTreeDetails;
+@property (readonly) BOOL isDatabaseTreeDetails;
+@property (readonly) BOOL isDatabasePromptDetails;
+@property (readonly) BOOL isLocalStoragePromptDetails;
+@property (readonly) NSString* name;
+@property (readonly) NSString* content;
+@property (readonly) NSString* domain;
+@property (readonly) NSString* path;
+@property (readonly) NSString* sendFor;
+@property (readonly) NSString* created;
+@property (readonly) NSString* expires;
+@property (readonly) NSString* fileSize;
+@property (readonly) NSString* lastModified;
+@property (readonly) NSString* databaseDescription;
+@property (readonly) NSString* localStorageKey;
+@property (readonly) NSString* localStorageValue;
+
+@end
+
+@implementation CookiePromptSelectionAdapter
+
+- (id)initWithCookie:(const std::string&)cookie_line
+ url:(const GURL&)url {
+ if ((self = [super init])) {
+ promptType_ = CookiePromptModalDialog::DIALOG_TYPE_COOKIE;
+ net::CookieMonster::ParsedCookie pc(cookie_line);
+ net::CookieMonster::CanonicalCookie cookie(url, pc);
+ const std::string& domain(pc.HasDomain() ? pc.Domain() : url.host());
+ domain_.reset([base::SysUTF8ToNSString(domain) retain]);
+ name_.reset([base::SysUTF8ToNSString(cookie.Name()) retain]);
+ content_.reset([base::SysUTF8ToNSString(cookie.Value()) retain]);
+ path_.reset([base::SysUTF8ToNSString(cookie.Path()) retain]);
+
+ if (cookie.DoesExpire()) {
+ expires_.reset([base::SysWideToNSString(
+ base::TimeFormatFriendlyDateAndTime(cookie.ExpiryDate()))
+ retain]);
+ } else {
+ expires_.reset([l10n_util::GetNSStringWithFixup(
+ IDS_COOKIES_COOKIE_EXPIRES_SESSION) retain]);
+ }
+
+ created_.reset([base::SysWideToNSString(
+ base::TimeFormatFriendlyDateAndTime(cookie.CreationDate()))
+ retain]);
+
+ if (cookie.IsSecure()) {
+ sendFor_.reset([l10n_util::GetNSStringWithFixup(
+ IDS_COOKIES_COOKIE_SENDFOR_SECURE) retain]);
+ } else {
+ sendFor_.reset([l10n_util::GetNSStringWithFixup(
+ IDS_COOKIES_COOKIE_SENDFOR_ANY) retain]);
+ }
+ }
+ return self;
+}
+
+- (id)initWithLocalStorage:(const std::string&)domain
+ key:(const string16&)key
+ value:(const string16&)value {
+ if ((self = [super init])) {
+ promptType_ = CookiePromptModalDialog::DIALOG_TYPE_LOCAL_STORAGE;
+ domain_.reset([base::SysUTF8ToNSString(domain) retain]);
+ localStorageKey_.reset([base::SysUTF16ToNSString(key) retain]);
+ localStorageValue_.reset([base::SysUTF16ToNSString(value) retain]);
+ }
+ return self;
+}
+
+- (id)initWithDatabase:(const std::string&)domain
+ name:(const string16&)name {
+ if ((self = [super init])) {
+ promptType_ = CookiePromptModalDialog::DIALOG_TYPE_DATABASE;
+ name_.reset([base::SysUTF16ToNSString(name) retain]);
+ domain_.reset([base::SysUTF8ToNSString(domain) retain]);
+ }
+ return self;
+}
+
+- (BOOL)isFolderOrCookieTreeDetails {
+ return promptType_ == CookiePromptModalDialog::DIALOG_TYPE_COOKIE;
+}
+
+- (BOOL)isLocalStorageTreeDetails {
+ return false;
+}
+
+- (BOOL)isDatabaseTreeDetails {
+ return false;
+}
+
+- (BOOL) isDatabasePromptDetails {
+ return promptType_ == CookiePromptModalDialog::DIALOG_TYPE_DATABASE;
+}
+
+- (BOOL) isLocalStoragePromptDetails {
+ return promptType_ == CookiePromptModalDialog::DIALOG_TYPE_LOCAL_STORAGE;
+}
+
+- (NSString*)name {
+ return name_;
+}
+
+- (NSString*)content {
+ return content_;
+}
+
+- (NSString*)domain {
+ return domain_;
+}
+
+- (NSString*)path {
+ return path_;
+}
+
+- (NSString*)sendFor {
+ return sendFor_;
+}
+
+- (NSString*)created {
+ return created_;
+}
+
+- (NSString*)expires {
+ return expires_;
+}
+
+- (NSString*)fileSize {
+ return nil;
+}
+
+- (NSString*)lastModified {
+ return nil;
+}
+
+- (NSString*)databaseDescription {
+ return nil;
+}
+
+- (NSString*)localStorageKey {
+ return localStorageKey_;
+}
+
+- (NSString*)localStorageValue {
+ return localStorageValue_;
+}
+
+@end
+
+@implementation CookiePromptWindowController
+
+- (id)initWithDialog:(CookiePromptModalDialog*)dialog {
+ NSString* nibpath = [mac_util::MainAppBundle()
+ pathForResource:@"CookiePrompt"
+ ofType:@"nib"];
+ if ((self = [super initWithWindowNibPath:nibpath owner:self])) {
+ dialog_ = dialog;
+ CookiePromptModalDialog::DialogType type(dialog_->dialog_type());
+ if (type == CookiePromptModalDialog::DIALOG_TYPE_COOKIE) {
+ selectionAdapterObject_.reset([[CookiePromptSelectionAdapter alloc]
+ initWithCookie:dialog_->cookie_line()
+ url:dialog_->origin()]);
+ } else if (type == CookiePromptModalDialog::DIALOG_TYPE_LOCAL_STORAGE) {
+ selectionAdapterObject_.reset([[CookiePromptSelectionAdapter alloc]
+ initWithLocalStorage:dialog_->origin().host()
+ key:dialog_->local_storage_key()
+ value:dialog_->local_storage_value()]);
+ } else if (type == CookiePromptModalDialog::DIALOG_TYPE_DATABASE) {
+ selectionAdapterObject_.reset([[CookiePromptSelectionAdapter alloc]
+ initWithDatabase:dialog_->origin().host()
+ name:dialog_->database_name()]);
+ } else {
+ NOTIMPLEMENTED();
+ }
+ }
+ return self;
+}
+
+// Ensures that all parameterized localized strings are filled in.
+- (void)doLocalizationTweaks {
+ int descriptionStringId = 0;
+ switch (dialog_->dialog_type()) {
+ case CookiePromptModalDialog::DIALOG_TYPE_COOKIE:
+ descriptionStringId = IDS_COOKIE_ALERT_LABEL;
+ break;
+ case CookiePromptModalDialog::DIALOG_TYPE_LOCAL_STORAGE:
+ descriptionStringId = IDS_DATA_ALERT_LABEL;
+ break;
+ case CookiePromptModalDialog::DIALOG_TYPE_DATABASE:
+ descriptionStringId = IDS_DATA_ALERT_LABEL;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ string16 displayHost = UTF8ToUTF16(dialog_->origin().host());
+ NSString* description = l10n_util::GetNSStringF(
+ descriptionStringId, displayHost);
+ [description_ setStringValue:description];
+
+ // Add the host to the "remember for future prompts" radio button.
+ NSString* allowText = l10n_util::GetNSStringWithFixup(
+ IDS_COOKIE_ALERT_REMEMBER_RADIO);
+ NSString* replacedCellText = base::SysUTF16ToNSString(
+ ReplaceStringPlaceholders(base::SysNSStringToUTF16(allowText),
+ displayHost, NULL));
+ [rememberChoiceCell_ setTitle:replacedCellText];
+}
+
+// Adjust the vertical layout of the views in the window so that
+// they are spaced correctly with their fully localized contents.
+- (void)doLayoutTweaks {
+ // Wrap the description text.
+ CGFloat sizeDelta = [GTMUILocalizerAndLayoutTweaker
+ sizeToFitFixedWidthTextField:description_];
+ NSRect descriptionFrame = [description_ frame];
+ descriptionFrame.origin.y -= sizeDelta;
+ [description_ setFrame:descriptionFrame];
+
+ // Wrap the radio buttons to fit if necessary.
+ [GTMUILocalizerAndLayoutTweaker
+ wrapRadioGroupForWidth:radioGroupMatrix_];
+ sizeDelta += [GTMUILocalizerAndLayoutTweaker
+ sizeToFitView:radioGroupMatrix_].height;
+ NSRect radioGroupFrame = [radioGroupMatrix_ frame];
+ radioGroupFrame.origin.y -= sizeDelta;
+ [radioGroupMatrix_ setFrame:radioGroupFrame];
+
+ // Adjust views location, they may have moved through the
+ // expansion of the radio buttons and description text.
+ NSRect disclosureViewFrame = [disclosureTriangleSuperView_ frame];
+ disclosureViewFrame.origin.y -= sizeDelta;
+ [disclosureTriangleSuperView_ 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;
+
+ // Final resize the window to fit all of the adjustments
+ NSRect frame = [[self window] frame];
+ frame.origin.y -= sizeDelta;
+ frame.size.height += sizeDelta;
+ [[self window] setFrame:frame display:NO animate:NO];
+}
+
+- (void)replaceCookieDetailsView {
+ detailsViewController_.reset([[CookieDetailsViewController alloc] init]);
+
+ NSRect viewFrameRect = [disclosedViewPlaceholder_ frame];
+ [[disclosedViewPlaceholder_ superview]
+ replaceSubview:disclosedViewPlaceholder_
+ with:[detailsViewController_.get() view]];
+}
+
+- (void)awakeFromNib {
+ DCHECK(disclosureTriangle_);
+ DCHECK(radioGroupMatrix_);
+ DCHECK(disclosedViewPlaceholder_);
+ DCHECK(disclosureTriangleSuperView_);
+
+ [self doLocalizationTweaks];
+ [self doLayoutTweaks];
+ [self replaceCookieDetailsView];
+
+ [detailsViewController_ setContentObject:selectionAdapterObject_.get()];
+ [detailsViewController_ shrinkViewToFit];
+
+ [[detailsViewController_ view] setHidden:YES];
+}
+
+- (void)windowWillClose:(NSNotification*)notif {
+ [self autorelease];
+}
+
+// |contextInfo| is the bridge back to the C++ CookiePromptModalDialog.
+- (void)processModalDialogResult:(void*)contextInfo
+ returnCode:(int)returnCode {
+ CookiePromptModalDialog* bridge =
+ reinterpret_cast<CookiePromptModalDialog*>(contextInfo);
+ bool remember = [radioGroupMatrix_ selectedRow] == 0;
+ switch (returnCode) {
+ case NSAlertFirstButtonReturn: { // OK
+ bool sessionExpire = false;
+ bridge->AllowSiteData(remember, sessionExpire);
+ break;
+ }
+ case NSAlertSecondButtonReturn: { // Cancel
+ bridge->BlockSiteData(remember);
+ break;
+ }
+ default: {
+ NOTREACHED();
+ remember = false;
+ bridge->BlockSiteData(remember);
+ }
+ }
+}
+
+- (void)doModalDialog:(void*)context {
+ NSInteger returnCode = [NSApp runModalForWindow:[self window]];
+ [self processModalDialogResult:context returnCode:returnCode];
+}
+
+- (IBAction)disclosureTrianglePressed:(id)sender {
+ NSWindow* window = [self window];
+ NSRect frame = [[self window] frame];
+ CGFloat sizeChange = [[detailsViewController_.get() view] frame].size.height;
+ switch ([sender state]) {
+ case NSOnState:
+ frame.size.height += sizeChange;
+ frame.origin.y -= sizeChange;
+ break;
+ case NSOffState:
+ frame.size.height -= sizeChange;
+ frame.origin.y += sizeChange;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ if ([sender state] == NSOffState) {
+ [[detailsViewController_ view] setHidden:YES];
+ }
+ [window setFrame:frame display:YES animate:YES];
+ if ([sender state] == NSOnState) {
+ [[detailsViewController_ view] setHidden:NO];
+ }
+}
+
+// Callback for "accept" button.
+- (IBAction)accept:(id)sender {
+ [[self window] close];
+ [NSApp stopModalWithCode:NSAlertFirstButtonReturn];
+}
+
+// Callback for "block" button.
+- (IBAction)block:(id)sender {
+ [[self window] close];
+ [NSApp stopModalWithCode:NSAlertSecondButtonReturn];
+}
+
+@end
diff --git a/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm b/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm
new file mode 100644
index 0000000..8c9da0d
--- /dev/null
+++ b/chrome/browser/cocoa/cookie_prompt_window_controller_unittest.mm
@@ -0,0 +1,50 @@
+// 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 "base/sys_string_conversions.h"
+#include "chrome/browser/cocoa/cocoa_test_helper.h"
+#include "chrome/browser/cocoa/cookie_prompt_window_controller.h"
+#include "chrome/browser/cookie_modal_dialog.h"
+
+namespace {
+
+class CookiePromptWindowControllerTest : public CocoaTest {
+};
+
+TEST_F(CookiePromptWindowControllerTest, CreateForCookie) {
+ GURL url("http://chromium.org");
+ std::string cookieLine(
+ "PHPSESSID=0123456789abcdef0123456789abcdef; path=/");
+ scoped_ptr<CookiePromptModalDialog> dialog(
+ new CookiePromptModalDialog(NULL, NULL, url, cookieLine, NULL));
+ scoped_nsobject<CookiePromptWindowController> controller(
+ [[CookiePromptWindowController alloc] initWithDialog:dialog.get()]);
+ EXPECT_TRUE(controller.get());
+ EXPECT_TRUE([controller.get() window]);
+}
+
+TEST_F(CookiePromptWindowControllerTest, CreateForDatabase) {
+ GURL url("http://google.com");
+ string16 databaseName(base::SysNSStringToUTF16(@"some database"));
+ scoped_ptr<CookiePromptModalDialog> dialog(
+ new CookiePromptModalDialog(NULL, NULL, url, databaseName, NULL));
+ scoped_nsobject<CookiePromptWindowController> controller(
+ [[CookiePromptWindowController alloc] initWithDialog:dialog.get()]);
+ EXPECT_TRUE(controller.get());
+ EXPECT_TRUE([controller.get() window]);
+}
+
+TEST_F(CookiePromptWindowControllerTest, CreateForLocalStorage) {
+ GURL url("http://chromium.org");
+ string16 key(base::SysNSStringToUTF16(@"key"));
+ string16 value(base::SysNSStringToUTF16(@"value"));
+ scoped_ptr<CookiePromptModalDialog> dialog(
+ new CookiePromptModalDialog(NULL, NULL, url, key, value, NULL));
+ scoped_nsobject<CookiePromptWindowController> controller(
+ [[CookiePromptWindowController alloc] initWithDialog:dialog.get()]);
+ EXPECT_TRUE(controller.get());
+ EXPECT_TRUE([controller.get() window]);
+}
+
+} // namespace
diff --git a/chrome/browser/cocoa/cookie_tree_node.h b/chrome/browser/cocoa/cookie_tree_node.h
index 5101157..66f5851 100644
--- a/chrome/browser/cocoa/cookie_tree_node.h
+++ b/chrome/browser/cocoa/cookie_tree_node.h
@@ -75,6 +75,12 @@ enum CocoaCookieTreeNodeType {
- (NSArray*)children;
- (BOOL)isLeaf;
+- (BOOL)isFolderOrCookieTreeDetails;
+- (BOOL)isLocalStorageTreeDetails;
+- (BOOL)isDatabaseTreeDetails;
+- (BOOL)isLocalStoragePromptDetails;
+- (BOOL)isDatabasePromptDetails;
+
// Used only by kCocoaCookieTreeNodeTypeCookie. Nil for other types.
- (NSString*)name;
- (NSString*)content;
diff --git a/chrome/browser/cocoa/cookie_tree_node.mm b/chrome/browser/cocoa/cookie_tree_node.mm
index 3d9eeaa..376df82 100644
--- a/chrome/browser/cocoa/cookie_tree_node.mm
+++ b/chrome/browser/cocoa/cookie_tree_node.mm
@@ -121,6 +121,27 @@
[self nodeType], [[self children] count]];
}
+- (BOOL)isFolderOrCookieTreeDetails {
+ return [self nodeType] == kCocoaCookieTreeNodeTypeFolder ||
+ [self nodeType] == kCocoaCookieTreeNodeTypeCookie;
+}
+
+- (BOOL)isDatabaseTreeDetails {
+ return [self nodeType] == kCocoaCookieTreeNodeTypeDatabaseStorage;
+}
+
+- (BOOL)isLocalStorageTreeDetails {
+ return [self nodeType] == kCocoaCookieTreeNodeTypeLocalStorage;
+}
+
+- (BOOL)isDatabasePromptDetails {
+ return false;
+}
+
+- (BOOL)isLocalStoragePromptDetails {
+ return false;
+}
+
#pragma mark Cookie Accessors
- (NSString*)name {
@@ -167,4 +188,24 @@
return databaseDescription_.get();
}
+#pragma mark Unused Accessors
+
+// This method is never called for the cookie tree, it is only
+// only included because the Cocoa bindings for the shared view
+// used to display browser data details always expects the method
+// even though it is only used in the cookie prompt window.
+- (id)localStorageKey {
+ NOTIMPLEMENTED();
+ return nil;
+}
+
+// This method is never called for the cookie tree, it is only
+// only included because the Cocoa bindings for the shared view
+// used to display browser data details always expects the method
+// even though it is only used in the cookie prompt window.
+- (id)localStorageValue {
+ NOTIMPLEMENTED();
+ return nil;
+}
+
@end
diff --git a/chrome/browser/cocoa/cookies_window_controller.h b/chrome/browser/cocoa/cookies_window_controller.h
index 8f85285..be38fb5 100644
--- a/chrome/browser/cocoa/cookies_window_controller.h
+++ b/chrome/browser/cocoa/cookies_window_controller.h
@@ -13,6 +13,7 @@
#include "net/base/cookie_monster.h"
@class CookiesWindowController;
+@class CookieDetailsViewController;
class Profile;
namespace {
@@ -101,13 +102,9 @@ class CookiesTreeModelObserverBridge : public CookiesTreeModel::Observer {
IBOutlet NSTreeController* treeController_;
IBOutlet NSOutlineView* outlineView_;
IBOutlet NSSearchField* searchField_;
+ IBOutlet NSView* cookieDetailsViewPlaceholder_;
- // These views are laid out inside a NSBox and are shown/hidden to detail
- // information about the selected node.
- IBOutlet NSView* cookieInfo_;
- IBOutlet NSView* databaseInfo_;
- IBOutlet NSView* localStorageInfo_;
-
+ scoped_nsobject<CookieDetailsViewController> detailsViewController_;
Profile* profile_; // weak
BrowsingDataDatabaseHelper* databaseHelper_; // weak
BrowsingDataLocalStorageHelper* storageHelper_; // weak
@@ -146,8 +143,5 @@ class CookiesTreeModelObserverBridge : public CookiesTreeModel::Observer {
- (void)clearBrowsingDataNotification:(NSNotification*)notif;
- (CookiesTreeModelObserverBridge*)modelObserver;
- (NSArray*)icons;
-- (NSView*)cookieInfoView;
-- (NSView*)localStorageInfoView;
-- (NSView*)databaseInfoInfoView;
- (void)loadTreeModelFromProfile;
@end
diff --git a/chrome/browser/cocoa/cookies_window_controller.mm b/chrome/browser/cocoa/cookies_window_controller.mm
index e2f53c5..d3b6035 100644
--- a/chrome/browser/cocoa/cookies_window_controller.mm
+++ b/chrome/browser/cocoa/cookies_window_controller.mm
@@ -14,6 +14,7 @@
#include "base/sys_string_conversions.h"
#include "chrome/browser/browsing_data_remover.h"
#include "chrome/browser/cocoa/clear_browsing_data_controller.h"
+#include "chrome/browser/cocoa/cookie_details_view_controller.h"
#include "chrome/browser/profile.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -226,6 +227,17 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() {
- (void)awakeFromNib {
DCHECK([self window]);
DCHECK_EQ(self, [[self window] delegate]);
+
+ detailsViewController_.reset([[CookieDetailsViewController alloc] init]);
+
+ NSView* detailView = [detailsViewController_.get() view];
+ NSRect viewFrameRect = [cookieDetailsViewPlaceholder_ frame];
+ [[detailsViewController_.get() view] setFrame:viewFrameRect];
+ [[cookieDetailsViewPlaceholder_ superview]
+ replaceSubview:cookieDetailsViewPlaceholder_
+ with:detailView];
+
+ [detailsViewController_ configureBindingsForTreeController:treeController_];
}
- (void)windowWillClose:(NSNotification*)notif {
@@ -356,12 +368,6 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() {
if (count != 1U) {
DCHECK_LT(count, 1U) << "User was able to select more than 1 cookie node!";
[self setRemoveButtonEnabled:NO];
-
- // Make sure that the cookie info pane is shown when there is no selection.
- // That's what windows does.
- [cookieInfo_ setHidden:NO];
- [localStorageInfo_ setHidden:YES];
- [databaseInfo_ setHidden:YES];
return;
}
@@ -378,18 +384,6 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() {
}
node = [[node children] objectAtIndex:childIndex];
}
-
- [self setRemoveButtonEnabled:YES];
- CocoaCookieTreeNodeType nodeType = [[selectedObjects lastObject] nodeType];
- bool hideCookieInfoView = nodeType != kCocoaCookieTreeNodeTypeCookie &&
- nodeType != kCocoaCookieTreeNodeTypeFolder;
- bool hideLocaStorageInfoView =
- nodeType != kCocoaCookieTreeNodeTypeLocalStorage;
- bool hideDatabaseInfoView =
- nodeType != kCocoaCookieTreeNodeTypeDatabaseStorage;
- [cookieInfo_ setHidden:hideCookieInfoView];
- [localStorageInfo_ setHidden:hideLocaStorageInfoView];
- [databaseInfo_ setHidden:hideDatabaseInfoView];
}
#pragma mark Unit Testing
@@ -402,18 +396,6 @@ bool CookiesTreeModelObserverBridge::HasCocoaModel() {
return icons_.get();
}
-- (NSView*)cookieInfoView {
- return cookieInfo_;
-}
-
-- (NSView*)localStorageInfoView {
- return localStorageInfo_;
-}
-
-- (NSView*)databaseInfoView {
- return databaseInfo_;
-}
-
// Re-initializes the |treeModel_|, creates a new observer for it, and re-
// builds the |cocoaTreeModel_|. We use this to initialize the controller and
// to rebuild after the user clears browsing data. Because the models get
diff --git a/chrome/browser/cocoa/cookies_window_controller_unittest.mm b/chrome/browser/cocoa/cookies_window_controller_unittest.mm
index b58c584..fb19db3 100644
--- a/chrome/browser/cocoa/cookies_window_controller_unittest.mm
+++ b/chrome/browser/cocoa/cookies_window_controller_unittest.mm
@@ -480,8 +480,6 @@ TEST_F(CookiesWindowControllerTest, FLAKY_RemoveButtonEnabled) {
[[controller treeController] setSelectionIndexPath:indexPath];
[controller outlineViewSelectionDidChange:nil];
EXPECT_TRUE([controller removeButtonEnabled]);
- EXPECT_FALSE([[controller cookieInfoView] isHidden]);
- EXPECT_TRUE([[controller localStorageInfoView] isHidden]);
}
{
@@ -491,8 +489,6 @@ TEST_F(CookiesWindowControllerTest, FLAKY_RemoveButtonEnabled) {
[[controller treeController] setSelectionIndexPath:indexPath];
[controller outlineViewSelectionDidChange:nil];
EXPECT_TRUE([controller removeButtonEnabled]);
- EXPECT_FALSE([[controller cookieInfoView] isHidden]);
- EXPECT_TRUE([[controller localStorageInfoView] isHidden]);
}
{
@@ -502,8 +498,6 @@ TEST_F(CookiesWindowControllerTest, FLAKY_RemoveButtonEnabled) {
[[controller treeController] setSelectionIndexPath:indexPath];
[controller outlineViewSelectionDidChange:nil];
EXPECT_TRUE([controller removeButtonEnabled]);
- EXPECT_TRUE([[controller cookieInfoView] isHidden]);
- EXPECT_FALSE([[controller localStorageInfoView] isHidden]);
}
{
@@ -527,8 +521,7 @@ TEST_F(CookiesWindowControllerTest, FLAKY_RemoveButtonEnabled) {
[controller closeSheet:nil];
}
-TEST_F(CookiesWindowControllerTest, UpdateFilter)
-{
+TEST_F(CookiesWindowControllerTest, UpdateFilter) {
const GURL url = GURL("http://foo.com");
TestingProfile* profile = browser_helper_.profile();
net::CookieMonster* cm = profile->GetCookieMonster();
diff --git a/chrome/browser/cookie_modal_dialog.h b/chrome/browser/cookie_modal_dialog.h
index 7a6ae50..997dd7f 100644
--- a/chrome/browser/cookie_modal_dialog.h
+++ b/chrome/browser/cookie_modal_dialog.h
@@ -13,6 +13,14 @@
#include "chrome/browser/cookie_prompt_modal_dialog_delegate.h"
#include "googleurl/src/gurl.h"
+#if defined(OS_MACOSX)
+#if __OBJC__
+@class NSWindow;
+#else
+class NSWindow;
+#endif
+#endif
+
class HostContentSettingsMap;
class PrefService;
@@ -58,6 +66,10 @@ class CookiePromptModalDialog : public AppModalDialog {
virtual void CancelWindow();
virtual bool IsValid();
+#if defined(OS_MACOSX)
+ virtual void CloseModalDialog();
+#endif
+
DialogType dialog_type() const { return dialog_type_; }
const GURL& origin() const { return origin_; }
const std::string& cookie_line() const { return cookie_line_; }
@@ -78,6 +90,11 @@ class CookiePromptModalDialog : public AppModalDialog {
#endif
private:
+
+#if defined(OS_MACOSX)
+ NSWindow* dialog_;
+#endif
+
// Used to verify our request is still necessary and when the response should
// persist.
scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
diff --git a/chrome/browser/cookie_modal_dialog_mac.mm b/chrome/browser/cookie_modal_dialog_mac.mm
index e80c2d6..35a54e0 100644
--- a/chrome/browser/cookie_modal_dialog_mac.mm
+++ b/chrome/browser/cookie_modal_dialog_mac.mm
@@ -3,118 +3,22 @@
// found in the LICENSE file.
#include "chrome/browser/cookie_modal_dialog.h"
+#import "chrome/browser/cocoa/cookie_prompt_window_controller.h"
#import <Cocoa/Cocoa.h>
#include "app/l10n_util_mac.h"
#import "base/cocoa_protocols_mac.h"
+#include "base/mac_util.h"
#include "base/scoped_nsobject.h"
#include "base/logging.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "grit/generated_resources.h"
-// Helper object that will become a real NSWindowController in the future.
-@interface CookiePromptModalDialogHelper : NSObject<NSAlertDelegate> {
- @private
- scoped_nsobject<NSAlert> alert_;
- scoped_nsobject<NSMatrix> matrix_;
-}
-
-- (id)initWithBridge:(CookiePromptModalDialog*)bridge;
-- (NSAlert*)alert;
-- (void)alertDidEnd:(NSAlert*)alert
- returnCode:(int)returnCode
- contextInfo:(void*)contextInfo;
-@end
-
-@implementation CookiePromptModalDialogHelper
-
-- (id)initWithBridge:(CookiePromptModalDialog*)bridge {
- // The cookie confirmation dialog needs both a radio group and a disclosure
- // triangle, so it's too complex to be shown as an NSAlert -- a custom window
- // is required. However, that requires small modifications to the parent class
- // AppModalDialog, so I'll do that in another CL.
- if ((self = [super init])) {
- alert_.reset([[NSAlert alloc] init]);
-
- string16 displayHost = UTF8ToUTF16(bridge->origin().host());
- int descriptionStringId =
- bridge->dialog_type() == CookiePromptModalDialog::DIALOG_TYPE_COOKIE ?
- IDS_COOKIE_ALERT_LABEL : IDS_DATA_ALERT_LABEL;
- NSString* description = l10n_util::GetNSStringF(
- descriptionStringId, displayHost);
- NSString* allow =
- l10n_util::GetNSStringWithFixup(IDS_COOKIE_ALERT_ALLOW_BUTTON);
- NSString* block =
- l10n_util::GetNSStringWithFixup(IDS_COOKIE_ALERT_BLOCK_BUTTON);
-
- NSString* remember = l10n_util::GetNSStringF(
- IDS_COOKIE_ALERT_REMEMBER_RADIO, displayHost);
- NSString* ask = l10n_util::GetNSStringWithFixup(IDS_COOKIE_ALERT_ASK_RADIO);
-
- scoped_nsobject<NSButtonCell> prototype([[NSButtonCell alloc] init]);
- [prototype.get() setButtonType:NSRadioButton];
- matrix_.reset(
- [[NSMatrix alloc] initWithFrame:NSZeroRect
- mode:NSRadioModeMatrix
- prototype:prototype
- numberOfRows:2
- numberOfColumns:1]);
- NSArray *cellArray = [matrix_.get() cells];
- [[cellArray objectAtIndex:0] setTitle:remember];
- [[cellArray objectAtIndex:1] setTitle:ask];
- [matrix_.get() sizeToFit];
- [alert_.get() setAccessoryView:matrix_.get()];
-
- [alert_.get() setMessageText:description];
- [alert_.get() addButtonWithTitle:allow];
- [alert_.get() addButtonWithTitle:block];
- }
- return self;
-}
-
-- (NSAlert*)alert {
- return alert_.get();
-}
-
-// |contextInfo| is the bridge back to the C++ CookiePromptModalDialog.
-- (void)alertDidEnd:(NSAlert*)alert
- returnCode:(int)returnCode
- contextInfo:(void*)contextInfo {
- CookiePromptModalDialog* bridge =
- reinterpret_cast<CookiePromptModalDialog*>(contextInfo);
- bool remember = [matrix_.get() selectedRow] == 0;
- switch (returnCode) {
- case NSAlertFirstButtonReturn: { // OK
- bool sessionExpire = false;
- bridge->AllowSiteData(remember, sessionExpire);
- break;
- }
- case NSAlertSecondButtonReturn: { // Cancel
- bridge->BlockSiteData(remember);
- break;
- }
- case NSRunStoppedResponse: { // Window was closed underneath us
- bridge->BlockSiteData(remember);
- break;
- }
- default: {
- NOTREACHED();
- remember = false;
- bridge->BlockSiteData(remember);
- }
- }
-}
-@end
-
void CookiePromptModalDialog::CreateAndShowDialog() {
- scoped_nsobject<CookiePromptModalDialogHelper> helper(
- [[CookiePromptModalDialogHelper alloc] initWithBridge:this]);
- NSAlert* alert = [helper alert];
- DCHECK(alert);
-
- NSInteger result = [alert runModal];
- [helper.get() alertDidEnd:alert returnCode:result contextInfo:this];
+ scoped_nsobject<CookiePromptWindowController> controller(
+ [[CookiePromptWindowController alloc] initWithDialog:this]);
+ [controller.get() doModalDialog:this];
// Other than JavaScriptAppModalDialog, the cross-platform part of this class
// does not call |CompleteDialog()|, an explicit call is required.
@@ -133,6 +37,10 @@ void CookiePromptModalDialog::CancelWindow() {
NOTIMPLEMENTED();
}
+void CookiePromptModalDialog::CloseModalDialog() {
+ dialog_ = nil;
+}
+
// This is only used by the app-modal dialog machinery on windows.
NativeDialog CookiePromptModalDialog::CreateNativeDialog() {
NOTIMPLEMENTED();
diff --git a/chrome/browser/js_modal_dialog.h b/chrome/browser/js_modal_dialog.h
index 51b9c81..65ed1ae 100644
--- a/chrome/browser/js_modal_dialog.h
+++ b/chrome/browser/js_modal_dialog.h
@@ -13,6 +13,14 @@
#include "chrome/common/notification_registrar.h"
#include "net/base/cookie_monster.h"
+#if defined(OS_MACOSX)
+#if __OBJC__
+@class NSAlert;
+#else
+class NSAlert;
+#endif
+#endif
+
class ExtensionHost;
class JavaScriptMessageBoxClient;
@@ -56,6 +64,10 @@ class JavaScriptAppModalDialog : public AppModalDialog,
return is_before_unload_dialog_;
}
+#if defined(OS_MACOSX)
+ virtual void CloseModalDialog();
+#endif
+
// Callbacks from NativeDialog when the user accepts or cancels the dialog.
void OnCancel();
void OnAccept(const std::wstring& prompt_text, bool suppress_js_messages);
@@ -75,6 +87,10 @@ class JavaScriptAppModalDialog : public AppModalDialog,
// Initializes for notifications to listen.
void InitNotifications();
+#if defined(OS_MACOSX)
+ NSAlert* dialog_;
+#endif
+
NotificationRegistrar registrar_;
// An implementation of the client interface to provide supporting methods
diff --git a/chrome/browser/js_modal_dialog_mac.mm b/chrome/browser/js_modal_dialog_mac.mm
index 44eb86e..3bdc9aa 100644
--- a/chrome/browser/js_modal_dialog_mac.mm
+++ b/chrome/browser/js_modal_dialog_mac.mm
@@ -172,3 +172,10 @@ NativeDialog JavaScriptAppModalDialog::CreateNativeDialog() {
NOTIMPLEMENTED();
return nil;
}
+
+void JavaScriptAppModalDialog::CloseModalDialog() {
+ NSAlert* alert = dialog_;
+ DCHECK([alert isKindOfClass:[NSAlert class]]);
+ [NSApp endSheet:[alert window]];
+ dialog_ = nil;
+}