18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     documentation and/or other materials provided with the distribution.
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     its contributors may be used to endorse or promote products derived
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *     from this software without specific prior written permission.
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <WebKit/WebAuthenticationPanel.h>
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#import "WebLocalizableStringsInternal.h"
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <Foundation/NSURLAuthenticationChallenge.h>
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <Foundation/NSURLProtectionSpace.h>
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <Foundation/NSURLCredential.h>
35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#import <WebKit/WebKitNSStringExtras.h>
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <WebKit/WebNSURLExtras.h>
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <wtf/Assertions.h>
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <WebKit/WebNSControlExtras.h>
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define WebAuthenticationPanelNibName @"WebAuthenticationPanel"
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@implementation WebAuthenticationPanel
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project-(id)initWithCallback:(id)cb selector:(SEL)sel
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    self = [self init];
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (self != nil) {
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        callback = [cb retain];
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        selector = sel;
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return self;
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)dealloc
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [panel release];
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [callback release];
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [super dealloc];
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// IB actions
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (IBAction)cancel:(id)sender
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This is required because the body of this method is going to
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // remove all of the panel's remaining refs, which can cause a
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // crash later when finishing button hit tracking.  So we make
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // sure it lives on a bit longer.
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [[panel retain] autorelease];
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This is required as a workaround for AppKit issue 4118422
768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [[self retain] autorelease];
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [panel close];
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (usingSheet) {
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [[NSApplication sharedApplication] endSheet:panel returnCode:1];
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [[NSApplication sharedApplication] stopModalWithCode:1];
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (IBAction)logIn:(id)sender
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This is required because the body of this method is going to
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // remove all of the panel's remaining refs, which can cause a
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // crash later when finishing button hit tracking.  So we make
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // sure it lives on a bit longer.
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [[panel retain] autorelease];
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [panel close];
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (usingSheet) {
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [[NSApplication sharedApplication] endSheet:panel returnCode:0];
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [[NSApplication sharedApplication] stopModalWithCode:0];
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (BOOL)loadNib
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!nibLoaded) {
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ([NSBundle loadNibNamed:WebAuthenticationPanelNibName owner:self]) {
1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            nibLoaded = YES;
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            [imageView setImage:[NSImage imageNamed:@"NSApplicationIcon"]];
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            LOG_ERROR("couldn't load nib named '%@'", WebAuthenticationPanelNibName);
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            return FALSE;
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return TRUE;
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Methods related to displaying the panel
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project-(void)setUpForChallenge:(NSURLAuthenticationChallenge *)chall
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [self loadNib];
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSURLProtectionSpace *space = [chall protectionSpace];
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSString *host;
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ([space port] == 0) {
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        host = [[space host] _web_decodeHostName];
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        host = [NSString stringWithFormat:@"%@:%u", [[space host] _web_decodeHostName], [space port]];
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSString *realm = [space realm];
132f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    if (!realm)
133f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        realm = @"";
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSString *message;
1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // Consider the realm name to be "simple" if it does not contain any whitespace or newline characters.
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // If the realm name is determined to be complex, we will use a slightly different sheet layout, designed
1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // to keep a malicious realm name from spoofing the wording in the sheet text.
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    BOOL realmNameIsSimple = [realm rangeOfCharacterFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].location == NSNotFound;
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ([chall previousFailureCount] == 0) {
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ([space isProxy]) {
14381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            message = [NSString stringWithFormat:UI_STRING_INTERNAL("To view this page, you must log in to the %@ proxy server %@.",
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                           "prompt string in authentication panel"),
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                [space proxyType], host];
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (realmNameIsSimple)
14881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                message = [NSString stringWithFormat:UI_STRING_INTERNAL("To view this page, you must log in to area “%@” on %@.",
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                               "prompt string in authentication panel"), realm, host];
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            else
15181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                message = [NSString stringWithFormat:UI_STRING_INTERNAL("To view this page, you must log in to this area on %@:",
1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                               "prompt string in authentication panel"), host];
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if ([space isProxy]) {
15681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            message = [NSString stringWithFormat:UI_STRING_INTERNAL("The user name or password you entered for the %@ proxy server %@ was incorrect. Make sure you’re entering them correctly, and then try again.",
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                                                           "prompt string in authentication panel"),
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                [space proxyType], host];
1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        } else {
1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            if (realmNameIsSimple)
16181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                message = [NSString stringWithFormat:UI_STRING_INTERNAL("The user name or password you entered for area “%@” on %@ was incorrect. Make sure you’re entering them correctly, and then try again.",
1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                               "prompt string in authentication panel"), realm, host];
1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            else
16481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                message = [NSString stringWithFormat:UI_STRING_INTERNAL("The user name or password you entered for this area on %@ was incorrect. Make sure you’re entering them correctly, and then try again.",
1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                                                               "prompt string in authentication panel"), host];
1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (![space isProxy] && !realmNameIsSimple) {
1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        [separateRealmLabel setHidden:NO];
1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        [separateRealmLabel setStringValue:realm];
1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        [separateRealmLabel setAutoresizingMask:NSViewMinYMargin];
1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        [separateRealmLabel sizeToFitAndAdjustWindowHeight];
1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        [separateRealmLabel setAutoresizingMask:NSViewMaxYMargin];
1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    } else {
1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // In the proxy or "simple" realm name case, we need to hide the 'separateRealmLabel'
1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // and move the rest of the contents up appropriately to fill the space.
1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        NSRect mainLabelFrame = [mainLabel frame];
1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        NSRect realmFrame = [separateRealmLabel frame];
1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        NSRect smallLabelFrame = [smallLabel frame];
1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Find the distance between the 'smallLabel' and the label above it, initially the 'separateRealmLabel'.
1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Then, find the current distance between 'smallLabel' and 'mainLabel'.  The difference between
1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // these two is how much shorter the panel needs to be after hiding the 'separateRealmLabel'.
1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        CGFloat smallLabelMargin = NSMinY(realmFrame) - NSMaxY(smallLabelFrame);
1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        CGFloat smallLabelToMainLabel = NSMinY(mainLabelFrame) - NSMaxY(smallLabelFrame);
1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        CGFloat deltaMargin = smallLabelToMainLabel - smallLabelMargin;
1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        [separateRealmLabel setHidden:YES];
1900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        NSRect windowFrame = [panel frame];
1910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        windowFrame.size.height -= deltaMargin;
1920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        [panel setFrame:windowFrame display:NO];
1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [mainLabel setStringValue:message];
1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [mainLabel sizeToFitAndAdjustWindowHeight];
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
198635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    if ([space receivesCredentialSecurely] || [[space protocol] _webkit_isCaseInsensitiveEqualToString:@"https"]) {
1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [smallLabel setStringValue:
20081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            UI_STRING_INTERNAL("Your login information will be sent securely.",
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                "message in authentication panel")];
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
203635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // Use this scary-sounding phrase only when using basic auth with non-https servers. In this case the password
204635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        // could be sniffed by intercepting the network traffic.
2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [smallLabel setStringValue:
20681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            UI_STRING_INTERNAL("Your password will be sent unencrypted.",
2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                "message in authentication panel")];
2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ([[chall proposedCredential] user] != nil) {
2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [username setStringValue:[[chall proposedCredential] user]];
2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [panel setInitialFirstResponder:password];
2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } else {
2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [username setStringValue:@""];
2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [password setStringValue:@""];
2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        [panel setInitialFirstResponder:username];
2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)runAsModalDialogWithChallenge:(NSURLAuthenticationChallenge *)chall
2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [self setUpForChallenge:chall];
223dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    usingSheet = FALSE;
225dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    [chall retain];
2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSURLCredential *credential = nil;
2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if ([[NSApplication sharedApplication] runModalForWindow:panel] == 0) {
2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        credential = [[NSURLCredential alloc] initWithUser:[username stringValue] password:[password stringValue] persistence:([remember state] == NSOnState) ? NSURLCredentialPersistencePermanent : NSURLCredentialPersistenceForSession];
2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [callback performSelector:selector withObject:chall withObject:credential];
2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [credential release];
234dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    [chall release];
2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)runAsSheetOnWindow:(NSWindow *)window withChallenge:(NSURLAuthenticationChallenge *)chall
2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(!usingSheet);
2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [self setUpForChallenge:chall];
2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    usingSheet = TRUE;
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    challenge = [chall retain];
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [[NSApplication sharedApplication] beginSheet:panel modalForWindow:window modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:NULL];
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void  *)contextInfo
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSURLCredential *credential = nil;
2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    NSURLAuthenticationChallenge *chall;
2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(usingSheet);
2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    ASSERT(challenge != nil);
2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (returnCode == 0) {
2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        credential = [[NSURLCredential alloc] initWithUser:[username stringValue] password:[password stringValue] persistence:([remember state] == NSOnState) ? NSURLCredentialPersistencePermanent : NSURLCredentialPersistenceForSession];
2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // We take this tricky approach to nilling out and releasing the challenge
2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // because the callback below might remove our last ref.
2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    chall = challenge;
2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    challenge = nil;
2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [callback performSelector:selector withObject:chall withObject:credential];
2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [credential release];
2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    [chall release];
2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end
2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@implementation NonBlockingPanel
2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (BOOL)_blocksActionWhenModal:(SEL)theAction
2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This override of a private AppKit method allows the user to quit when a login dialog
2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // is onscreen, which is nice in general but in particular prevents pathological cases
2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // like 3744583 from requiring a Force Quit.
2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    //
2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // It would be nice to allow closing the individual window as well as quitting the app when
2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // a login sheet is up, but this _blocksActionWhenModal: mechanism doesn't support that.
2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // This override matches those in NSOpenPanel and NSToolbarConfigPanel.
2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (theAction == @selector(terminate:)) {
2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return NO;
2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return YES;
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end
290