Index: chrome/browser/ui/javascript_dialogs/javascript_dialog_cocoa.mm |
diff --git a/chrome/browser/ui/javascript_dialogs/javascript_dialog_cocoa.mm b/chrome/browser/ui/javascript_dialogs/javascript_dialog_cocoa.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ece29c7d01bb02fcf98f09193666f00b8f8c6249 |
--- /dev/null |
+++ b/chrome/browser/ui/javascript_dialogs/javascript_dialog_cocoa.mm |
@@ -0,0 +1,189 @@ |
+// Copyright 2016 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/ui/javascript_dialogs/javascript_dialog_cocoa.h" |
+ |
+#import "base/mac/scoped_nsobject.h" |
+#include "base/memory/ptr_util.h" |
+#include "base/strings/sys_string_conversions.h" |
+#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_alert.h" |
+#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h" |
+#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h" |
+#import "chrome/browser/ui/cocoa/key_equivalent_constants.h" |
+#include "ui/base/l10n/l10n_util_mac.h" |
+#include "ui/strings/grit/ui_strings.h" |
+ |
+@class JavaScriptDialogCocoaBridge; |
+ |
+class JavaScriptDialogCocoa::JavaScriptDialogCocoaImpl |
+ : public ConstrainedWindowMacDelegate { |
+ public: |
+ JavaScriptDialogCocoaImpl( |
+ JavaScriptDialogCocoa* parent, |
+ content::WebContents* parent_web_contents, |
+ content::WebContents* alerting_web_contents, |
+ const base::string16& title, |
+ content::JavaScriptMessageType message_type, |
+ const base::string16& message_text, |
+ const base::string16& default_prompt_text, |
+ const content::JavaScriptDialogManager::DialogClosedCallback& |
+ dialog_callback); |
+ virtual ~JavaScriptDialogCocoaImpl() = default; |
+ |
+ // Callbacks from the bridge when buttons are clicked. |
+ void Accept(); |
+ void Cancel(); |
+ |
+ // ConstrainedWindowMacDelegate: |
+ void OnConstrainedWindowClosed(ConstrainedWindowMac* window) override; |
+ |
+ private: |
+ friend class JavaScriptDialogCocoa; |
+ |
+ content::JavaScriptDialogManager::DialogClosedCallback dialog_callback_; |
+ |
+ std::unique_ptr<ConstrainedWindowMac> window_; |
+ base::scoped_nsobject<ConstrainedWindowAlert> alert_; |
+ base::scoped_nsobject<JavaScriptDialogCocoaBridge> bridge_; |
+ |
+ base::scoped_nsobject<NSTextField> textField_; |
+ |
+ JavaScriptDialogCocoa* parent_; |
+}; |
+ |
+@interface JavaScriptDialogCocoaBridge : NSObject { |
+ JavaScriptDialogCocoa::JavaScriptDialogCocoaImpl* dialogImpl_; // weak |
+} |
+@end |
+ |
+@implementation JavaScriptDialogCocoaBridge |
+ |
+- (instancetype)initWithDialogImpl: |
+ (JavaScriptDialogCocoa::JavaScriptDialogCocoaImpl*)dialogImpl { |
+ if ((self = [super init])) { |
+ dialogImpl_ = dialogImpl; |
+ } |
+ return self; |
+} |
+ |
+- (void)onAcceptButton:(id)sender { |
+ dialogImpl_->Accept(); |
+} |
+ |
+- (void)onCancelButton:(id)sender { |
+ dialogImpl_->Cancel(); |
+} |
+ |
+@end |
+ |
+JavaScriptDialogCocoa::JavaScriptDialogCocoaImpl::JavaScriptDialogCocoaImpl( |
+ JavaScriptDialogCocoa* parent, |
+ content::WebContents* parent_web_contents, |
+ content::WebContents* alerting_web_contents, |
+ const base::string16& title, |
+ content::JavaScriptMessageType message_type, |
+ const base::string16& message_text, |
+ const base::string16& default_prompt_text, |
+ const content::JavaScriptDialogManager::DialogClosedCallback& |
+ dialog_callback) |
+ : dialog_callback_(dialog_callback), parent_(parent) { |
+ bridge_.reset([[JavaScriptDialogCocoaBridge alloc] initWithDialogImpl:this]); |
+ |
+ alert_.reset([[ConstrainedWindowAlert alloc] init]); |
+ [alert_ setMessageText:base::SysUTF16ToNSString(title)]; |
+ [alert_ setInformativeText:base::SysUTF16ToNSString(message_text)]; |
+ [alert_ addButtonWithTitle:l10n_util::GetNSStringWithFixup(IDS_APP_OK) |
+ keyEquivalent:kKeyEquivalentReturn |
+ target:bridge_ |
+ action:@selector(onAcceptButton:)]; |
+ if (message_type != content::JAVASCRIPT_MESSAGE_TYPE_ALERT) { |
+ [alert_ addButtonWithTitle:l10n_util::GetNSStringWithFixup(IDS_APP_CANCEL) |
+ keyEquivalent:kKeyEquivalentEscape |
+ target:bridge_ |
+ action:@selector(onCancelButton:)]; |
+ } |
+ if (message_type == content::JAVASCRIPT_MESSAGE_TYPE_PROMPT) { |
+ textField_.reset( |
+ [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 460, 22)]); |
Robert Sesek
2016/10/27 15:17:24
Where do these values come from?
Avi (use Gerrit)
2016/10/27 18:41:22
The height, 22, is the standard height of an NSTex
|
+ [[textField_ cell] setLineBreakMode:NSLineBreakByTruncatingTail]; |
+ [textField_ setStringValue:base::SysUTF16ToNSString(default_prompt_text)]; |
+ [alert_ setAccessoryView:textField_]; |
+ } |
+ [[alert_ closeButton] removeFromSuperview]; |
+ [alert_ layout]; |
+ |
+ base::scoped_nsobject<CustomConstrainedWindowSheet> sheet( |
+ [[CustomConstrainedWindowSheet alloc] |
+ initWithCustomWindow:[alert_ window]]); |
+ window_ = CreateAndShowWebModalDialogMac(this, parent_web_contents, sheet); |
+} |
+ |
+void JavaScriptDialogCocoa::JavaScriptDialogCocoaImpl:: |
+ OnConstrainedWindowClosed(ConstrainedWindowMac* window) { |
+ if (dialog_callback_) |
+ dialog_callback_.Run(false, base::string16()); |
+ delete parent_; |
+ // parent_ owns this object, so return immediately. |
+} |
+ |
+void JavaScriptDialogCocoa::JavaScriptDialogCocoaImpl::Cancel() { |
+ if (dialog_callback_) { |
+ dialog_callback_.Run(false, base::string16()); |
+ dialog_callback_.Reset(); |
+ } |
+ window_->CloseWebContentsModalDialog(); |
+} |
+ |
+void JavaScriptDialogCocoa::JavaScriptDialogCocoaImpl::Accept() { |
+ if (dialog_callback_) { |
+ base::string16 input; |
+ if (textField_) |
+ input = base::SysNSStringToUTF16([textField_ stringValue]); |
+ dialog_callback_.Run(true, input); |
+ dialog_callback_.Reset(); |
+ } |
+ window_->CloseWebContentsModalDialog(); |
+} |
+ |
+JavaScriptDialogCocoa::~JavaScriptDialogCocoa() = default; |
+ |
+// static |
+base::WeakPtr<JavaScriptDialogCocoa> JavaScriptDialogCocoa::Create( |
+ content::WebContents* parent_web_contents, |
+ content::WebContents* alerting_web_contents, |
+ const base::string16& title, |
+ content::JavaScriptMessageType message_type, |
+ const base::string16& message_text, |
+ const base::string16& default_prompt_text, |
+ const content::JavaScriptDialogManager::DialogClosedCallback& |
+ dialog_callback) { |
+ return (new JavaScriptDialogCocoa(parent_web_contents, alerting_web_contents, |
+ title, message_type, message_text, |
+ default_prompt_text, dialog_callback)) |
+ ->weak_factory_.GetWeakPtr(); |
+} |
+ |
+void JavaScriptDialogCocoa::CloseDialogWithoutCallback() { |
+ impl_->dialog_callback_.Reset(); |
+ impl_->window_->CloseWebContentsModalDialog(); |
+} |
+ |
+JavaScriptDialogCocoa::JavaScriptDialogCocoa( |
+ content::WebContents* parent_web_contents, |
+ content::WebContents* alerting_web_contents, |
+ const base::string16& title, |
+ content::JavaScriptMessageType message_type, |
+ const base::string16& message_text, |
+ const base::string16& default_prompt_text, |
+ const content::JavaScriptDialogManager::DialogClosedCallback& |
+ dialog_callback) |
+ : impl_(base::MakeUnique<JavaScriptDialogCocoaImpl>(this, |
+ parent_web_contents, |
+ alerting_web_contents, |
+ title, |
+ message_type, |
+ message_text, |
+ default_prompt_text, |
+ dialog_callback)), |
+ weak_factory_(this) {} |