Aggregate consequtive rescan request as much as possible.
[chromium-blink-merge.git] / content / shell / browser / shell_javascript_dialog_mac.mm
blobe74800038360f409d0a8853ac80d6978e819dc85
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/shell/browser/shell_javascript_dialog.h"
7 #import <Cocoa/Cocoa.h>
9 #import "base/mac/scoped_nsobject.h"
10 #include "base/strings/sys_string_conversions.h"
11 #include "content/shell/browser/shell_javascript_dialog_manager.h"
13 // Helper object that receives the notification that the dialog/sheet is
14 // going away. Is responsible for cleaning itself up.
15 @interface ShellJavaScriptDialogHelper : NSObject<NSAlertDelegate> {
16  @private
17   base::scoped_nsobject<NSAlert> alert_;
18   NSTextField* textField_;  // WEAK; owned by alert_
20   // Copies of the fields in ShellJavaScriptDialog because they're private.
21   content::ShellJavaScriptDialogManager* manager_;
22   content::JavaScriptDialogManager::DialogClosedCallback callback_;
25 - (id)initHelperWithManager:(content::ShellJavaScriptDialogManager*)manager
26    andCallback:(content::JavaScriptDialogManager::DialogClosedCallback)callback;
27 - (NSAlert*)alert;
28 - (NSTextField*)textField;
29 - (void)alertDidEnd:(NSAlert*)alert
30          returnCode:(int)returnCode
31         contextInfo:(void*)contextInfo;
32 - (void)cancel;
34 @end
36 @implementation ShellJavaScriptDialogHelper
38 - (id)initHelperWithManager:(content::ShellJavaScriptDialogManager*)manager
39   andCallback:(content::JavaScriptDialogManager::DialogClosedCallback)callback {
40   if (self = [super init]) {
41     manager_ = manager;
42     callback_ = callback;
43   }
45   return self;
48 - (NSAlert*)alert {
49   alert_.reset([[NSAlert alloc] init]);
50   return alert_;
53 - (NSTextField*)textField {
54   textField_ = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 300, 22)];
55   [[textField_ cell] setLineBreakMode:NSLineBreakByTruncatingTail];
56   [alert_ setAccessoryView:textField_];
57   [textField_ release];
59   return textField_;
62 - (void)alertDidEnd:(NSAlert*)alert
63          returnCode:(int)returnCode
64         contextInfo:(void*)contextInfo {
65   if (returnCode == NSRunStoppedResponse)
66     return;
68   bool success = returnCode == NSAlertFirstButtonReturn;
69   base::string16 input;
70   if (textField_)
71     input = base::SysNSStringToUTF16([textField_ stringValue]);
73   content::ShellJavaScriptDialog* native_dialog =
74       reinterpret_cast<content::ShellJavaScriptDialog*>(contextInfo);
75   callback_.Run(success, input);
76   manager_->DialogClosed(native_dialog);
79 - (void)cancel {
80   [NSApp endSheet:[alert_ window]];
81   alert_.reset();
84 @end
86 namespace content {
88 ShellJavaScriptDialog::ShellJavaScriptDialog(
89     ShellJavaScriptDialogManager* manager,
90     gfx::NativeWindow parent_window,
91     JavaScriptMessageType message_type,
92     const base::string16& message_text,
93     const base::string16& default_prompt_text,
94     const JavaScriptDialogManager::DialogClosedCallback& callback)
95     : manager_(manager),
96       callback_(callback) {
97   bool text_field = message_type == JAVASCRIPT_MESSAGE_TYPE_PROMPT;
98   bool one_button = message_type == JAVASCRIPT_MESSAGE_TYPE_ALERT;
100   helper_ =
101       [[ShellJavaScriptDialogHelper alloc] initHelperWithManager:manager
102                                                      andCallback:callback];
104   // Show the modal dialog.
105   NSAlert* alert = [helper_ alert];
106   NSTextField* field = nil;
107   if (text_field) {
108     field = [helper_ textField];
109     [field setStringValue:base::SysUTF16ToNSString(default_prompt_text)];
110   }
111   [alert setDelegate:helper_];
112   [alert setInformativeText:base::SysUTF16ToNSString(message_text)];
113   [alert setMessageText:@"Javascript alert"];
114   [alert addButtonWithTitle:@"OK"];
115   if (!one_button) {
116     NSButton* other = [alert addButtonWithTitle:@"Cancel"];
117     [other setKeyEquivalent:@"\e"];
118   }
120   [alert
121       beginSheetModalForWindow:nil  // nil here makes it app-modal
122                  modalDelegate:helper_
123                 didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
124                    contextInfo:this];
126   if ([alert accessoryView])
127     [[alert window] makeFirstResponder:[alert accessoryView]];
130 ShellJavaScriptDialog::~ShellJavaScriptDialog() {
131   [helper_ release];
134 void ShellJavaScriptDialog::Cancel() {
135   [helper_ cancel];
138 }  // namespace content