• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4
5#include "content/shell/browser/shell_javascript_dialog.h"
6
7#import <Cocoa/Cocoa.h>
8
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"
12
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_
19
20  // Copies of the fields in ShellJavaScriptDialog because they're private.
21  content::ShellJavaScriptDialogManager* manager_;
22  content::JavaScriptDialogManager::DialogClosedCallback callback_;
23}
24
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;
33
34@end
35
36@implementation ShellJavaScriptDialogHelper
37
38- (id)initHelperWithManager:(content::ShellJavaScriptDialogManager*)manager
39  andCallback:(content::JavaScriptDialogManager::DialogClosedCallback)callback {
40  if (self = [super init]) {
41    manager_ = manager;
42    callback_ = callback;
43  }
44
45  return self;
46}
47
48- (NSAlert*)alert {
49  alert_.reset([[NSAlert alloc] init]);
50  return alert_;
51}
52
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];
58
59  return textField_;
60}
61
62- (void)alertDidEnd:(NSAlert*)alert
63         returnCode:(int)returnCode
64        contextInfo:(void*)contextInfo {
65  if (returnCode == NSRunStoppedResponse)
66    return;
67
68  bool success = returnCode == NSAlertFirstButtonReturn;
69  base::string16 input;
70  if (textField_)
71    input = base::SysNSStringToUTF16([textField_ stringValue]);
72
73  content::ShellJavaScriptDialog* native_dialog =
74      reinterpret_cast<content::ShellJavaScriptDialog*>(contextInfo);
75  callback_.Run(success, input);
76  manager_->DialogClosed(native_dialog);
77}
78
79- (void)cancel {
80  [NSApp endSheet:[alert_ window]];
81  alert_.reset();
82}
83
84@end
85
86namespace content {
87
88ShellJavaScriptDialog::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;
99
100  helper_ =
101      [[ShellJavaScriptDialogHelper alloc] initHelperWithManager:manager
102                                                     andCallback:callback];
103
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  }
119
120  [alert
121      beginSheetModalForWindow:nil  // nil here makes it app-modal
122                 modalDelegate:helper_
123                didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
124                   contextInfo:this];
125
126  if ([alert accessoryView])
127    [[alert window] makeFirstResponder:[alert accessoryView]];
128}
129
130ShellJavaScriptDialog::~ShellJavaScriptDialog() {
131  [helper_ release];
132}
133
134void ShellJavaScriptDialog::Cancel() {
135  [helper_ cancel];
136}
137
138}  // namespace content
139