Home | History | Annotate | Download | only in browser
      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_login_dialog.h"
      6 
      7 #import <Cocoa/Cocoa.h>
      8 
      9 #include "base/logging.h"
     10 #include "base/mac/bundle_locations.h"
     11 #import "base/mac/scoped_nsobject.h"
     12 #include "base/strings/sys_string_conversions.h"
     13 #include "content/public/browser/browser_thread.h"
     14 #import "ui/base/cocoa/nib_loading.h"
     15 
     16 namespace {
     17 
     18 const int kUsernameFieldTag = 1;
     19 const int kPasswordFieldTag = 2;
     20 
     21 }  // namespace
     22 
     23 // Helper object that receives the notification that the dialog/sheet is
     24 // going away.
     25 @interface ShellLoginDialogHelper : NSObject<NSAlertDelegate> {
     26  @private
     27   base::scoped_nsobject<NSAlert> alert_;
     28   NSTextField* usernameField_;  // WEAK; owned by alert_
     29   NSSecureTextField* passwordField_;  // WEAK; owned by alert_
     30 }
     31 
     32 - (NSAlert*)alert;
     33 - (NSView*)accessoryView;
     34 - (void)focus;
     35 - (void)alertDidEnd:(NSAlert*)alert
     36          returnCode:(int)returnCode
     37         contextInfo:(void*)contextInfo;
     38 - (void)cancel;
     39 
     40 @end
     41 
     42 @implementation ShellLoginDialogHelper
     43 
     44 - (NSAlert*)alert {
     45   alert_.reset([[NSAlert alloc] init]);
     46   [alert_ setAccessoryView:[self accessoryView]];
     47   return alert_;
     48 }
     49 
     50 - (NSView*)accessoryView {
     51   NSView* accessory_view = ui::GetViewFromNib(@"HttpAuth");
     52   if (!accessory_view)
     53     return nil;
     54 
     55   usernameField_ = [accessory_view viewWithTag:kUsernameFieldTag];
     56   passwordField_ = [accessory_view viewWithTag:kPasswordFieldTag];
     57   return accessory_view;
     58 }
     59 
     60 - (void)focus {
     61   [[alert_ window] makeFirstResponder:usernameField_];
     62 }
     63 
     64 - (void)alertDidEnd:(NSAlert*)alert
     65          returnCode:(int)returnCode
     66         contextInfo:(void*)contextInfo {
     67   if (returnCode == NSRunStoppedResponse)
     68     return;
     69 
     70   content::ShellLoginDialog* this_dialog =
     71       reinterpret_cast<content::ShellLoginDialog*>(contextInfo);
     72   if (returnCode == NSAlertFirstButtonReturn) {
     73     this_dialog->UserAcceptedAuth(
     74         base::SysNSStringToUTF16([usernameField_ stringValue]),
     75         base::SysNSStringToUTF16([passwordField_ stringValue]));
     76   } else {
     77     this_dialog->UserCancelledAuth();
     78   }
     79 }
     80 
     81 - (void)cancel {
     82   [NSApp endSheet:[alert_ window]];
     83   alert_.reset();
     84 }
     85 
     86 @end
     87 
     88 namespace content {
     89 
     90 void ShellLoginDialog::PlatformCreateDialog(const base::string16& message) {
     91   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
     92   helper_ = [[ShellLoginDialogHelper alloc] init];
     93 
     94   // Show the modal dialog.
     95   NSAlert* alert = [helper_ alert];
     96   [alert setDelegate:helper_];
     97   [alert setInformativeText:base::SysUTF16ToNSString(message)];
     98   [alert setMessageText:@"Please log in."];
     99   [alert addButtonWithTitle:@"OK"];
    100   NSButton* other = [alert addButtonWithTitle:@"Cancel"];
    101   [other setKeyEquivalent:@"\e"];
    102   [alert
    103       beginSheetModalForWindow:nil  // nil here makes it app-modal
    104                  modalDelegate:helper_
    105                 didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:)
    106                    contextInfo:this];
    107 
    108   [helper_ focus];
    109 }
    110 
    111 void ShellLoginDialog::PlatformCleanUp() {
    112   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    113   [helper_ release];
    114   helper_ = nil;
    115 }
    116 
    117 void ShellLoginDialog::PlatformRequestCancelled() {
    118   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    119   [helper_ cancel];
    120 }
    121 
    122 }  // namespace content
    123