Home | History | Annotate | Download | only in mac
      1 /*
      2  * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #import "config.h"
     30 #import "DumpRenderTree.h"
     31 #import "LayoutTestController.h"
     32 
     33 #import "EditingDelegate.h"
     34 #import "MockGeolocationProvider.h"
     35 #import "PolicyDelegate.h"
     36 #import "StorageTrackerDelegate.h"
     37 #import "UIDelegate.h"
     38 #import "WorkQueue.h"
     39 #import "WorkQueueItem.h"
     40 #import <Foundation/Foundation.h>
     41 #import <JavaScriptCore/JSRetainPtr.h>
     42 #import <JavaScriptCore/JSStringRef.h>
     43 #import <JavaScriptCore/JSStringRefCF.h>
     44 #import <WebKit/DOMDocument.h>
     45 #import <WebKit/DOMElement.h>
     46 #import <WebKit/WebApplicationCache.h>
     47 #import <WebKit/WebBackForwardList.h>
     48 #import <WebKit/WebCoreStatistics.h>
     49 #import <WebKit/WebDOMOperationsPrivate.h>
     50 #import <WebKit/WebDataSource.h>
     51 #import <WebKit/WebDatabaseManagerPrivate.h>
     52 #import <WebKit/WebDeviceOrientation.h>
     53 #import <WebKit/WebDeviceOrientationProviderMock.h>
     54 #import <WebKit/WebFrame.h>
     55 #import <WebKit/WebFrameViewPrivate.h>
     56 #import <WebKit/WebGeolocationPosition.h>
     57 #import <WebKit/WebHTMLRepresentation.h>
     58 #import <WebKit/WebHTMLViewPrivate.h>
     59 #import <WebKit/WebHistory.h>
     60 #import <WebKit/WebHistoryPrivate.h>
     61 #import <WebKit/WebIconDatabasePrivate.h>
     62 #import <WebKit/WebInspectorPrivate.h>
     63 #import <WebKit/WebNSURLExtras.h>
     64 #import <WebKit/WebKitErrors.h>
     65 #import <WebKit/WebPreferences.h>
     66 #import <WebKit/WebPreferencesPrivate.h>
     67 #import <WebKit/WebQuotaManager.h>
     68 #import <WebKit/WebScriptWorld.h>
     69 #import <WebKit/WebSecurityOriginPrivate.h>
     70 #import <WebKit/WebStorageManagerPrivate.h>
     71 #import <WebKit/WebTypesInternal.h>
     72 #import <WebKit/WebView.h>
     73 #import <WebKit/WebViewPrivate.h>
     74 #import <WebKit/WebWorkersPrivate.h>
     75 #import <wtf/CurrentTime.h>
     76 #import <wtf/HashMap.h>
     77 #import <wtf/RetainPtr.h>
     78 
     79 @interface CommandValidationTarget : NSObject <NSValidatedUserInterfaceItem>
     80 {
     81     SEL _action;
     82 }
     83 - (id)initWithAction:(SEL)action;
     84 @end
     85 
     86 @implementation CommandValidationTarget
     87 
     88 - (id)initWithAction:(SEL)action
     89 {
     90     self = [super init];
     91     if (!self)
     92         return nil;
     93 
     94     _action = action;
     95     return self;
     96 }
     97 
     98 - (SEL)action
     99 {
    100     return _action;
    101 }
    102 
    103 - (NSInteger)tag
    104 {
    105     return 0;
    106 }
    107 
    108 @end
    109 
    110 LayoutTestController::~LayoutTestController()
    111 {
    112 }
    113 
    114 void LayoutTestController::addDisallowedURL(JSStringRef url)
    115 {
    116     RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
    117 
    118     if (!disallowedURLs)
    119         disallowedURLs = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
    120 
    121     // Canonicalize the URL
    122     NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:(NSString *)urlCF.get()]];
    123     request = [NSURLProtocol canonicalRequestForRequest:request];
    124 
    125     CFSetAddValue(disallowedURLs, [request URL]);
    126 }
    127 
    128 bool LayoutTestController::callShouldCloseOnWebView()
    129 {
    130     return [[mainFrame webView] shouldClose];
    131 }
    132 
    133 void LayoutTestController::clearAllApplicationCaches()
    134 {
    135     [WebApplicationCache deleteAllApplicationCaches];
    136 }
    137 
    138 void LayoutTestController::syncLocalStorage()
    139 {
    140     [[WebStorageManager sharedWebStorageManager] syncLocalStorage];
    141 }
    142 
    143 void LayoutTestController::observeStorageTrackerNotifications(unsigned number)
    144 {
    145     [storageDelegate logNotifications:number controller:this];
    146 }
    147 
    148 void LayoutTestController::clearApplicationCacheForOrigin(JSStringRef url)
    149 {
    150     RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
    151 
    152     WebSecurityOrigin *origin = [[WebSecurityOrigin alloc] initWithURL:[NSURL URLWithString:(NSString *)urlCF.get()]];
    153     [WebApplicationCache deleteCacheForOrigin:origin];
    154     [origin release];
    155 }
    156 
    157 JSValueRef originsArrayToJS(JSContextRef context, NSArray* origins)
    158 {
    159     NSUInteger count = [origins count];
    160 
    161     JSValueRef jsOriginsArray[count];
    162     for (NSUInteger i = 0; i < count; i++) {
    163         NSString *origin = [[origins objectAtIndex:i] databaseIdentifier];
    164         JSRetainPtr<JSStringRef> originJS(Adopt, JSStringCreateWithCFString((CFStringRef)origin));
    165         jsOriginsArray[i] = JSValueMakeString(context, originJS.get());
    166     }
    167 
    168     return JSObjectMakeArray(context, count, jsOriginsArray, NULL);
    169 }
    170 
    171 JSValueRef LayoutTestController::originsWithApplicationCache(JSContextRef context)
    172 {
    173     return originsArrayToJS(context, [WebApplicationCache originsWithCache]);
    174 }
    175 
    176 void LayoutTestController::clearAllDatabases()
    177 {
    178     [[WebDatabaseManager sharedWebDatabaseManager] deleteAllDatabases];
    179 }
    180 
    181 void LayoutTestController::deleteAllLocalStorage()
    182 {
    183     [[WebStorageManager sharedWebStorageManager] deleteAllOrigins];
    184 }
    185 
    186 JSValueRef LayoutTestController::originsWithLocalStorage(JSContextRef context)
    187 {
    188     return originsArrayToJS(context, [[WebStorageManager sharedWebStorageManager] origins]);
    189 }
    190 
    191 void LayoutTestController::deleteLocalStorageForOrigin(JSStringRef URL)
    192 {
    193     RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, URL));
    194 
    195     WebSecurityOrigin *origin = [[WebSecurityOrigin alloc] initWithURL:[NSURL URLWithString:(NSString *)urlCF.get()]];
    196     [[WebStorageManager sharedWebStorageManager] deleteOrigin:origin];
    197     [origin release];
    198 }
    199 
    200 void LayoutTestController::clearBackForwardList()
    201 {
    202     WebBackForwardList *backForwardList = [[mainFrame webView] backForwardList];
    203     WebHistoryItem *item = [[backForwardList currentItem] retain];
    204 
    205     // We clear the history by setting the back/forward list's capacity to 0
    206     // then restoring it back and adding back the current item.
    207     int capacity = [backForwardList capacity];
    208     [backForwardList setCapacity:0];
    209     [backForwardList setCapacity:capacity];
    210     [backForwardList addItem:item];
    211     [backForwardList goToItem:item];
    212     [item release];
    213 }
    214 
    215 JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
    216 {
    217     RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
    218     NSString *nameNS = (NSString *)nameCF.get();
    219     return JSStringCreateWithCFString((CFStringRef)[nameNS _web_decodeHostName]);
    220 }
    221 
    222 JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
    223 {
    224     RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
    225     NSString *nameNS = (NSString *)nameCF.get();
    226     return JSStringCreateWithCFString((CFStringRef)[nameNS _web_encodeHostName]);
    227 }
    228 
    229 void LayoutTestController::display()
    230 {
    231     displayWebView();
    232 }
    233 
    234 JSRetainPtr<JSStringRef> LayoutTestController::counterValueForElementById(JSStringRef id)
    235 {
    236     RetainPtr<CFStringRef> idCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, id));
    237     NSString *idNS = (NSString *)idCF.get();
    238 
    239     DOMElement *element = [[mainFrame DOMDocument] getElementById:idNS];
    240     if (!element)
    241         return 0;
    242 
    243     JSRetainPtr<JSStringRef> counterValue(Adopt, JSStringCreateWithCFString((CFStringRef)[mainFrame counterValueForElement:element]));
    244     return counterValue;
    245 }
    246 
    247 void LayoutTestController::keepWebHistory()
    248 {
    249     if (![WebHistory optionalSharedHistory]) {
    250         WebHistory *history = [[WebHistory alloc] init];
    251         [WebHistory setOptionalSharedHistory:history];
    252         [history release];
    253     }
    254 }
    255 
    256 JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value)
    257 {
    258     return [[mainFrame webView] _computedStyleIncludingVisitedInfo:context forElement:value];
    259 }
    260 
    261 JSValueRef LayoutTestController::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
    262 {
    263     return [[mainFrame webView] _nodesFromRect:context forDocument:value x:x y:y top:top right:right bottom:bottom left:left ignoreClipping:ignoreClipping];
    264 }
    265 
    266 JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
    267 {
    268     JSRetainPtr<JSStringRef> string(Adopt, JSStringCreateWithCFString((CFStringRef)[mainFrame _layerTreeAsText]));
    269     return string;
    270 }
    271 
    272 JSRetainPtr<JSStringRef> LayoutTestController::markerTextForListItem(JSContextRef context, JSValueRef nodeObject) const
    273 {
    274     DOMElement *element = [DOMElement _DOMElementFromJSContext:context value:nodeObject];
    275     if (!element)
    276         return JSRetainPtr<JSStringRef>();
    277 
    278     JSRetainPtr<JSStringRef> markerText(Adopt, JSStringCreateWithCFString((CFStringRef)[element _markerTextForListItem]));
    279     return markerText;
    280 }
    281 
    282 int LayoutTestController::pageNumberForElementById(JSStringRef id, float pageWidthInPixels, float pageHeightInPixels)
    283 {
    284     RetainPtr<CFStringRef> idCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, id));
    285     NSString *idNS = (NSString *)idCF.get();
    286 
    287     DOMElement *element = [[mainFrame DOMDocument] getElementById:idNS];
    288     if (!element)
    289         return -1;
    290 
    291     return [mainFrame pageNumberForElement:element:pageWidthInPixels:pageHeightInPixels];
    292 }
    293 
    294 JSRetainPtr<JSStringRef> LayoutTestController::pageProperty(const char* propertyName, int pageNumber) const
    295 {
    296     JSRetainPtr<JSStringRef> propertyValue(Adopt, JSStringCreateWithCFString((CFStringRef)[mainFrame pageProperty:propertyName:pageNumber]));
    297     return propertyValue;
    298 }
    299 
    300 bool LayoutTestController::isPageBoxVisible(int pageNumber) const
    301 {
    302     return [mainFrame isPageBoxVisible:pageNumber];
    303 }
    304 
    305 JSRetainPtr<JSStringRef> LayoutTestController::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) const
    306 {
    307     JSRetainPtr<JSStringRef> propertyValue(Adopt, JSStringCreateWithCFString((CFStringRef)[mainFrame pageSizeAndMarginsInPixels:pageNumber:width:height:marginTop:marginRight:marginBottom:marginLeft]));
    308     return propertyValue;
    309 }
    310 
    311 int LayoutTestController::numberOfPages(float pageWidthInPixels, float pageHeightInPixels)
    312 {
    313     return [mainFrame numberOfPages:pageWidthInPixels:pageHeightInPixels];
    314 }
    315 
    316 int LayoutTestController::numberOfPendingGeolocationPermissionRequests()
    317 {
    318     return [[[mainFrame webView] UIDelegate] numberOfPendingGeolocationPermissionRequests];
    319 }
    320 
    321 size_t LayoutTestController::webHistoryItemCount()
    322 {
    323     return [[[WebHistory optionalSharedHistory] allItems] count];
    324 }
    325 
    326 unsigned LayoutTestController::workerThreadCount() const
    327 {
    328     return [WebWorkersPrivate workerThreadCount];
    329 }
    330 
    331 void LayoutTestController::notifyDone()
    332 {
    333     if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
    334         dump();
    335     m_waitToDump = false;
    336 }
    337 
    338 JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url)
    339 {
    340     return JSStringRetain(url); // Do nothing on mac.
    341 }
    342 
    343 void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
    344 {
    345     RetainPtr<CFStringRef> urlCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
    346     NSString *urlNS = (NSString *)urlCF.get();
    347 
    348     NSURL *nsurl = [NSURL URLWithString:urlNS relativeToURL:[[[mainFrame dataSource] response] URL]];
    349     NSString* nsurlString = [nsurl absoluteString];
    350 
    351     JSRetainPtr<JSStringRef> absoluteURL(Adopt, JSStringCreateWithUTF8CString([nsurlString UTF8String]));
    352     WorkQueue::shared()->queue(new LoadItem(absoluteURL.get(), target));
    353 }
    354 
    355 void LayoutTestController::setAcceptsEditing(bool newAcceptsEditing)
    356 {
    357     [(EditingDelegate *)[[mainFrame webView] editingDelegate] setAcceptsEditing:newAcceptsEditing];
    358 }
    359 
    360 void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies)
    361 {
    362     if (alwaysAcceptCookies == m_alwaysAcceptCookies)
    363         return;
    364 
    365     m_alwaysAcceptCookies = alwaysAcceptCookies;
    366     NSHTTPCookieAcceptPolicy cookieAcceptPolicy = alwaysAcceptCookies ? NSHTTPCookieAcceptPolicyAlways : NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain;
    367     [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:cookieAcceptPolicy];
    368 }
    369 
    370 void LayoutTestController::setAppCacheMaximumSize(unsigned long long size)
    371 {
    372     [WebApplicationCache setMaximumSize:size];
    373 }
    374 
    375 void LayoutTestController::setApplicationCacheOriginQuota(unsigned long long quota)
    376 {
    377     WebSecurityOrigin *origin = [[WebSecurityOrigin alloc] initWithURL:[NSURL URLWithString:@"http://127.0.0.1:8000"]];
    378     [[origin applicationCacheQuotaManager] setQuota:quota];
    379     [origin release];
    380 }
    381 
    382 void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag)
    383 {
    384     [[[mainFrame webView] preferences] setAuthorAndUserStylesEnabled:flag];
    385 }
    386 
    387 void LayoutTestController::setAutofilled(JSContextRef context, JSValueRef nodeObject, bool autofilled)
    388 {
    389     DOMElement *element = [DOMElement _DOMElementFromJSContext:context value:nodeObject];
    390     if (!element || ![element isKindOfClass:[DOMHTMLInputElement class]])
    391         return;
    392 
    393     [(DOMHTMLInputElement *)element _setAutofilled:autofilled];
    394 }
    395 
    396 void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permissive)
    397 {
    398     if (setDelegate) {
    399         [policyDelegate setPermissive:permissive];
    400         [[mainFrame webView] setPolicyDelegate:policyDelegate];
    401     } else
    402         [[mainFrame webView] setPolicyDelegate:nil];
    403 }
    404 
    405 void LayoutTestController::setDatabaseQuota(unsigned long long quota)
    406 {
    407     WebSecurityOrigin *origin = [[WebSecurityOrigin alloc] initWithURL:[NSURL URLWithString:@"file:///"]];
    408     [[origin databaseQuotaManager] setQuota:quota];
    409     [origin release];
    410 }
    411 
    412 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme)
    413 {
    414     RetainPtr<CFStringRef> schemeCFString(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, scheme));
    415     [WebView _setDomainRelaxationForbidden:forbidden forURLScheme:(NSString *)schemeCFString.get()];
    416 }
    417 
    418 void LayoutTestController::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma)
    419 {
    420     // DumpRenderTree configured the WebView to use WebDeviceOrientationProviderMock.
    421     id<WebDeviceOrientationProvider> provider = [[mainFrame webView] _deviceOrientationProvider];
    422     WebDeviceOrientationProviderMock* mockProvider = static_cast<WebDeviceOrientationProviderMock*>(provider);
    423     WebDeviceOrientation* orientation = [[WebDeviceOrientation alloc] initWithCanProvideAlpha:canProvideAlpha alpha:alpha canProvideBeta:canProvideBeta beta:beta canProvideGamma:canProvideGamma gamma:gamma];
    424     [mockProvider setOrientation:orientation];
    425     [orientation release];
    426 }
    427 
    428 void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy)
    429 {
    430     WebGeolocationPosition *position = [[WebGeolocationPosition alloc] initWithTimestamp:currentTime() latitude:latitude longitude:longitude accuracy:accuracy];
    431     [[MockGeolocationProvider shared] setPosition:position];
    432     [position release];
    433 }
    434 
    435 void LayoutTestController::setMockGeolocationError(int code, JSStringRef message)
    436 {
    437     RetainPtr<CFStringRef> messageCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, message));
    438     NSString *messageNS = (NSString *)messageCF.get();
    439     NSError *error = [NSError errorWithDomain:WebKitErrorDomain code:code userInfo:[NSDictionary dictionaryWithObject:messageNS forKey:NSLocalizedDescriptionKey]];
    440     [[MockGeolocationProvider shared] setError:error];
    441 }
    442 
    443 void LayoutTestController::setGeolocationPermission(bool allow)
    444 {
    445     setGeolocationPermissionCommon(allow);
    446     [[[mainFrame webView] UIDelegate] didSetMockGeolocationPermission];
    447 }
    448 
    449 void LayoutTestController::addMockSpeechInputResult(JSStringRef result, double confidence, JSStringRef language)
    450 {
    451     // FIXME: Implement for speech input layout tests.
    452     // See https://bugs.webkit.org/show_bug.cgi?id=39485.
    453 }
    454 
    455 void LayoutTestController::setIconDatabaseEnabled(bool iconDatabaseEnabled)
    456 {
    457     // FIXME: Workaround <rdar://problem/6480108>
    458     static WebIconDatabase* sharedWebIconDatabase = NULL;
    459     if (!sharedWebIconDatabase) {
    460         if (!iconDatabaseEnabled)
    461             return;
    462         sharedWebIconDatabase = [WebIconDatabase sharedIconDatabase];
    463         if ([sharedWebIconDatabase isEnabled] == iconDatabaseEnabled)
    464             return;
    465     }
    466     [sharedWebIconDatabase setEnabled:iconDatabaseEnabled];
    467 }
    468 
    469 void LayoutTestController::setJavaScriptProfilingEnabled(bool profilingEnabled)
    470 {
    471     setDeveloperExtrasEnabled(profilingEnabled);
    472     [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:profilingEnabled];
    473 }
    474 
    475 void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
    476 {
    477     NSView *documentView = [[mainFrame frameView] documentView];
    478 
    479     NSResponder *firstResponder = flag ? documentView : nil;
    480     [[[mainFrame webView] window] makeFirstResponder:firstResponder];
    481 }
    482 
    483 void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
    484 {
    485     [[[mainFrame webView] preferences] setPrivateBrowsingEnabled:privateBrowsingEnabled];
    486 }
    487 
    488 void LayoutTestController::setXSSAuditorEnabled(bool enabled)
    489 {
    490     [[[mainFrame webView] preferences] setXSSAuditorEnabled:enabled];
    491 }
    492 
    493 void LayoutTestController::setFrameFlatteningEnabled(bool enabled)
    494 {
    495     [[[mainFrame webView] preferences] setFrameFlatteningEnabled:enabled];
    496 }
    497 
    498 void LayoutTestController::setSpatialNavigationEnabled(bool enabled)
    499 {
    500     [[[mainFrame webView] preferences] setSpatialNavigationEnabled:enabled];
    501 }
    502 
    503 void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled)
    504 {
    505     [[[mainFrame webView] preferences] setAllowUniversalAccessFromFileURLs:enabled];
    506 }
    507 
    508 void LayoutTestController::setAllowFileAccessFromFileURLs(bool enabled)
    509 {
    510     [[[mainFrame webView] preferences] setAllowFileAccessFromFileURLs:enabled];
    511 }
    512 
    513 void LayoutTestController::setPopupBlockingEnabled(bool popupBlockingEnabled)
    514 {
    515     [[[mainFrame webView] preferences] setJavaScriptCanOpenWindowsAutomatically:!popupBlockingEnabled];
    516 }
    517 
    518 void LayoutTestController::setPluginsEnabled(bool pluginsEnabled)
    519 {
    520     [[[mainFrame webView] preferences] setPlugInsEnabled:pluginsEnabled];
    521 }
    522 
    523 void LayoutTestController::setJavaScriptCanAccessClipboard(bool enabled)
    524 {
    525     [[[mainFrame webView] preferences] setJavaScriptCanAccessClipboard:enabled];
    526 }
    527 
    528 void LayoutTestController::setTabKeyCyclesThroughElements(bool cycles)
    529 {
    530     [[mainFrame webView] setTabKeyCyclesThroughElements:cycles];
    531 }
    532 
    533 void LayoutTestController::setTimelineProfilingEnabled(bool enabled)
    534 {
    535     [[[mainFrame webView] inspector] setTimelineProfilingEnabled:enabled];
    536 }
    537 
    538 void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
    539 {
    540     [[mainFrame webView] _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:flag];
    541 }
    542 
    543 void LayoutTestController::setUserStyleSheetEnabled(bool flag)
    544 {
    545     [[WebPreferences standardPreferences] setUserStyleSheetEnabled:flag];
    546 }
    547 
    548 void LayoutTestController::setUserStyleSheetLocation(JSStringRef path)
    549 {
    550     RetainPtr<CFStringRef> pathCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, path));
    551     NSURL *url = [NSURL URLWithString:(NSString *)pathCF.get()];
    552     [[WebPreferences standardPreferences] setUserStyleSheetLocation:url];
    553 }
    554 
    555 void LayoutTestController::setValueForUser(JSContextRef context, JSValueRef nodeObject, JSStringRef value)
    556 {
    557     DOMElement *element = [DOMElement _DOMElementFromJSContext:context value:nodeObject];
    558     if (!element || ![element isKindOfClass:[DOMHTMLInputElement class]])
    559         return;
    560 
    561     RetainPtr<CFStringRef> valueCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, value));
    562     [(DOMHTMLInputElement *)element _setValueForUser:(NSString *)valueCF.get()];
    563 }
    564 
    565 void LayoutTestController::setViewModeMediaFeature(JSStringRef mode)
    566 {
    567     // FIXME: implement
    568 }
    569 
    570 void LayoutTestController::disableImageLoading()
    571 {
    572     [[WebPreferences standardPreferences] setLoadsImagesAutomatically:NO];
    573 }
    574 
    575 void LayoutTestController::dispatchPendingLoadRequests()
    576 {
    577     [[mainFrame webView] _dispatchPendingLoadRequests];
    578 }
    579 
    580 void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value)
    581 {
    582     RetainPtr<CFStringRef> keyCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, key));
    583     NSString *keyNS = (NSString *)keyCF.get();
    584 
    585     RetainPtr<CFStringRef> valueCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, value));
    586     NSString *valueNS = (NSString *)valueCF.get();
    587 
    588     [[WebPreferences standardPreferences] _setPreferenceForTestWithValue:valueNS forKey:keyNS];
    589 }
    590 
    591 void LayoutTestController::removeAllVisitedLinks()
    592 {
    593     [WebHistory _removeAllVisitedLinks];
    594 }
    595 
    596 void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
    597 {
    598     RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
    599     ::setPersistentUserStyleSheetLocation(urlString.get());
    600 }
    601 
    602 void LayoutTestController::clearPersistentUserStyleSheet()
    603 {
    604     ::setPersistentUserStyleSheetLocation(0);
    605 }
    606 
    607 void LayoutTestController::setWindowIsKey(bool windowIsKey)
    608 {
    609     m_windowIsKey = windowIsKey;
    610     [[mainFrame webView] _updateActiveState];
    611 }
    612 
    613 void LayoutTestController::setSmartInsertDeleteEnabled(bool flag)
    614 {
    615     [[mainFrame webView] setSmartInsertDeleteEnabled:flag];
    616 }
    617 
    618 void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag)
    619 {
    620     [[mainFrame webView] setSelectTrailingWhitespaceEnabled:flag];
    621 }
    622 
    623 static const CFTimeInterval waitToDumpWatchdogInterval = 30.0;
    624 
    625 static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
    626 {
    627     gLayoutTestController->waitToDumpWatchdogTimerFired();
    628 }
    629 
    630 void LayoutTestController::setWaitToDump(bool waitUntilDone)
    631 {
    632     m_waitToDump = waitUntilDone;
    633     if (m_waitToDump && !waitToDumpWatchdog) {
    634         waitToDumpWatchdog = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + waitToDumpWatchdogInterval, 0, 0, 0, waitUntilDoneWatchdogFired, NULL);
    635         CFRunLoopAddTimer(CFRunLoopGetCurrent(), waitToDumpWatchdog, kCFRunLoopCommonModes);
    636     }
    637 }
    638 
    639 int LayoutTestController::windowCount()
    640 {
    641     return CFArrayGetCount(openWindowsRef);
    642 }
    643 
    644 bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef jsString)
    645 {
    646     RetainPtr<CFStringRef> idCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, jsString));
    647     NSString *idNS = (NSString *)idCF.get();
    648 
    649     DOMElement *element = [[mainFrame DOMDocument] getElementById:idNS];
    650     id rep = [[mainFrame dataSource] representation];
    651 
    652     if ([rep class] == [WebHTMLRepresentation class])
    653         return [(WebHTMLRepresentation *)rep elementDoesAutoComplete:element];
    654 
    655     return false;
    656 }
    657 
    658 void LayoutTestController::execCommand(JSStringRef name, JSStringRef value)
    659 {
    660     RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
    661     NSString *nameNS = (NSString *)nameCF.get();
    662 
    663     RetainPtr<CFStringRef> valueCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, value));
    664     NSString *valueNS = (NSString *)valueCF.get();
    665 
    666     [[mainFrame webView] _executeCoreCommandByName:nameNS value:valueNS];
    667 }
    668 
    669 bool LayoutTestController::findString(JSContextRef context, JSStringRef target, JSObjectRef optionsArray)
    670 {
    671     WebFindOptions options = 0;
    672 
    673     JSRetainPtr<JSStringRef> lengthPropertyName(Adopt, JSStringCreateWithUTF8CString("length"));
    674     JSValueRef lengthValue = JSObjectGetProperty(context, optionsArray, lengthPropertyName.get(), 0);
    675     if (!JSValueIsNumber(context, lengthValue))
    676         return false;
    677 
    678     RetainPtr<CFStringRef> targetCFString(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, target));
    679 
    680     size_t length = static_cast<size_t>(JSValueToNumber(context, lengthValue, 0));
    681     for (size_t i = 0; i < length; ++i) {
    682         JSValueRef value = JSObjectGetPropertyAtIndex(context, optionsArray, i, 0);
    683         if (!JSValueIsString(context, value))
    684             continue;
    685 
    686         JSRetainPtr<JSStringRef> optionName(Adopt, JSValueToStringCopy(context, value, 0));
    687 
    688         if (JSStringIsEqualToUTF8CString(optionName.get(), "CaseInsensitive"))
    689             options |= WebFindOptionsCaseInsensitive;
    690         else if (JSStringIsEqualToUTF8CString(optionName.get(), "AtWordStarts"))
    691             options |= WebFindOptionsAtWordStarts;
    692         else if (JSStringIsEqualToUTF8CString(optionName.get(), "TreatMedialCapitalAsWordStart"))
    693             options |= WebFindOptionsTreatMedialCapitalAsWordStart;
    694         else if (JSStringIsEqualToUTF8CString(optionName.get(), "Backwards"))
    695             options |= WebFindOptionsBackwards;
    696         else if (JSStringIsEqualToUTF8CString(optionName.get(), "WrapAround"))
    697             options |= WebFindOptionsWrapAround;
    698         else if (JSStringIsEqualToUTF8CString(optionName.get(), "StartInSelection"))
    699             options |= WebFindOptionsStartInSelection;
    700     }
    701 
    702     return [[mainFrame webView] findString:(NSString *)targetCFString.get() options:options];
    703 }
    704 
    705 void LayoutTestController::setCacheModel(int cacheModel)
    706 {
    707     [[WebPreferences standardPreferences] setCacheModel:cacheModel];
    708 }
    709 
    710 bool LayoutTestController::isCommandEnabled(JSStringRef name)
    711 {
    712     RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, name));
    713     NSString *nameNS = (NSString *)nameCF.get();
    714 
    715     // Accept command strings with capital letters for first letter without trailing colon.
    716     if (![nameNS hasSuffix:@":"] && [nameNS length]) {
    717         nameNS = [[[[nameNS substringToIndex:1] lowercaseString]
    718             stringByAppendingString:[nameNS substringFromIndex:1]]
    719             stringByAppendingString:@":"];
    720     }
    721 
    722     SEL selector = NSSelectorFromString(nameNS);
    723     RetainPtr<CommandValidationTarget> target(AdoptNS, [[CommandValidationTarget alloc] initWithAction:selector]);
    724     id validator = [NSApp targetForAction:selector to:[mainFrame webView] from:target.get()];
    725     if (!validator)
    726         return false;
    727     if (![validator respondsToSelector:selector])
    728         return false;
    729     if (![validator respondsToSelector:@selector(validateUserInterfaceItem:)])
    730         return true;
    731     return [validator validateUserInterfaceItem:target.get()];
    732 }
    733 
    734 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId)
    735 {
    736     RetainPtr<CFStringRef> idCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, elementId));
    737     NSString *idNS = (NSString *)idCF.get();
    738     RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, animationName));
    739     NSString *nameNS = (NSString *)nameCF.get();
    740 
    741     return [mainFrame _pauseAnimation:nameNS onNode:[[mainFrame DOMDocument] getElementById:idNS] atTime:time];
    742 }
    743 
    744 bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId)
    745 {
    746     RetainPtr<CFStringRef> idCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, elementId));
    747     NSString *idNS = (NSString *)idCF.get();
    748     RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, propertyName));
    749     NSString *nameNS = (NSString *)nameCF.get();
    750 
    751     return [mainFrame _pauseTransitionOfProperty:nameNS onNode:[[mainFrame DOMDocument] getElementById:idNS] atTime:time];
    752 }
    753 
    754 bool LayoutTestController::sampleSVGAnimationForElementAtTime(JSStringRef animationId, double time, JSStringRef elementId)
    755 {
    756     RetainPtr<CFStringRef> animationIDCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, animationId));
    757     NSString *animationIDNS = (NSString *)animationIDCF.get();
    758     RetainPtr<CFStringRef> elementIDCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, elementId));
    759     NSString *elementIDNS = (NSString *)elementIDCF.get();
    760 
    761     return [mainFrame _pauseSVGAnimation:elementIDNS onSMILNode:[[mainFrame DOMDocument] getElementById:animationIDNS] atTime:time];
    762 }
    763 
    764 unsigned LayoutTestController::numberOfActiveAnimations() const
    765 {
    766     return [mainFrame _numberOfActiveAnimations];
    767 }
    768 
    769 void LayoutTestController::suspendAnimations() const
    770 {
    771     return [mainFrame _suspendAnimations];
    772 }
    773 
    774 void LayoutTestController::resumeAnimations() const
    775 {
    776     return [mainFrame _resumeAnimations];
    777 }
    778 
    779 void LayoutTestController::waitForPolicyDelegate()
    780 {
    781     setWaitToDump(true);
    782     [policyDelegate setControllerToNotifyDone:this];
    783     [[mainFrame webView] setPolicyDelegate:policyDelegate];
    784 }
    785 
    786 void LayoutTestController::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
    787 {
    788     RetainPtr<CFStringRef> sourceOriginCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, sourceOrigin));
    789     NSString *sourceOriginNS = (NSString *)sourceOriginCF.get();
    790     RetainPtr<CFStringRef> protocolCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, destinationProtocol));
    791     NSString *destinationProtocolNS = (NSString *)protocolCF.get();
    792     RetainPtr<CFStringRef> hostCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, destinationHost));
    793     NSString *destinationHostNS = (NSString *)hostCF.get();
    794     [WebView _addOriginAccessWhitelistEntryWithSourceOrigin:sourceOriginNS destinationProtocol:destinationProtocolNS destinationHost:destinationHostNS allowDestinationSubdomains:allowDestinationSubdomains];
    795 }
    796 
    797 void LayoutTestController::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
    798 {
    799     RetainPtr<CFStringRef> sourceOriginCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, sourceOrigin));
    800     NSString *sourceOriginNS = (NSString *)sourceOriginCF.get();
    801     RetainPtr<CFStringRef> protocolCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, destinationProtocol));
    802     NSString *destinationProtocolNS = (NSString *)protocolCF.get();
    803     RetainPtr<CFStringRef> hostCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, destinationHost));
    804     NSString *destinationHostNS = (NSString *)hostCF.get();
    805     [WebView _removeOriginAccessWhitelistEntryWithSourceOrigin:sourceOriginNS destinationProtocol:destinationProtocolNS destinationHost:destinationHostNS allowDestinationSubdomains:allowDestinationSubdomains];
    806 }
    807 
    808 void LayoutTestController::setScrollbarPolicy(JSStringRef orientation, JSStringRef policy)
    809 {
    810     // FIXME: implement
    811 }
    812 
    813 void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart, bool allFrames)
    814 {
    815     RetainPtr<CFStringRef> sourceCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, source));
    816     NSString *sourceNS = (NSString *)sourceCF.get();
    817     [WebView _addUserScriptToGroup:@"org.webkit.DumpRenderTree" world:[WebScriptWorld world] source:sourceNS url:nil whitelist:nil blacklist:nil injectionTime:(runAtStart ? WebInjectAtDocumentStart : WebInjectAtDocumentEnd) injectedFrames:(allFrames ? WebInjectInAllFrames : WebInjectInTopFrameOnly)];
    818 }
    819 
    820 void LayoutTestController::addUserStyleSheet(JSStringRef source, bool allFrames)
    821 {
    822     RetainPtr<CFStringRef> sourceCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, source));
    823     NSString *sourceNS = (NSString *)sourceCF.get();
    824     [WebView _addUserStyleSheetToGroup:@"org.webkit.DumpRenderTree" world:[WebScriptWorld world] source:sourceNS url:nil whitelist:nil blacklist:nil injectedFrames:(allFrames ? WebInjectInAllFrames : WebInjectInTopFrameOnly)];
    825 }
    826 
    827 void LayoutTestController::setDeveloperExtrasEnabled(bool enabled)
    828 {
    829     [[[mainFrame webView] preferences] setDeveloperExtrasEnabled:enabled];
    830 }
    831 
    832 void LayoutTestController::setAsynchronousSpellCheckingEnabled(bool enabled)
    833 {
    834     [[[mainFrame webView] preferences] setAsynchronousSpellCheckingEnabled:enabled];
    835 }
    836 
    837 void LayoutTestController::showWebInspector()
    838 {
    839     [[[mainFrame webView] inspector] show:nil];
    840 }
    841 
    842 void LayoutTestController::closeWebInspector()
    843 {
    844     [[[mainFrame webView] inspector] close:nil];
    845 }
    846 
    847 void LayoutTestController::evaluateInWebInspector(long callId, JSStringRef script)
    848 {
    849     RetainPtr<CFStringRef> scriptCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, script));
    850     NSString *scriptNS = (NSString *)scriptCF.get();
    851     [[[mainFrame webView] inspector] evaluateInFrontend:nil callId:callId script:scriptNS];
    852 }
    853 
    854 typedef HashMap<unsigned, RetainPtr<WebScriptWorld> > WorldMap;
    855 static WorldMap& worldMap()
    856 {
    857     static WorldMap& map = *new WorldMap;
    858     return map;
    859 }
    860 
    861 unsigned worldIDForWorld(WebScriptWorld *world)
    862 {
    863     WorldMap::const_iterator end = worldMap().end();
    864     for (WorldMap::const_iterator it = worldMap().begin(); it != end; ++it) {
    865         if (it->second == world)
    866             return it->first;
    867     }
    868 
    869     return 0;
    870 }
    871 
    872 void LayoutTestController::evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script)
    873 {
    874     RetainPtr<CFStringRef> scriptCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, script));
    875     NSString *scriptNS = (NSString *)scriptCF.get();
    876 
    877     // A worldID of 0 always corresponds to a new world. Any other worldID corresponds to a world
    878     // that is created once and cached forever.
    879     WebScriptWorld *world;
    880     if (!worldID)
    881         world = [WebScriptWorld world];
    882     else {
    883         RetainPtr<WebScriptWorld>& worldSlot = worldMap().add(worldID, 0).first->second;
    884         if (!worldSlot)
    885             worldSlot.adoptNS([[WebScriptWorld alloc] init]);
    886         world = worldSlot.get();
    887     }
    888 
    889     [mainFrame _stringByEvaluatingJavaScriptFromString:scriptNS withGlobalObject:globalObject inScriptWorld:world];
    890 }
    891 
    892 @interface APITestDelegate : NSObject
    893 {
    894     bool* m_condition;
    895 }
    896 @end
    897 
    898 @implementation APITestDelegate
    899 
    900 - (id)initWithCompletionCondition:(bool*)condition
    901 {
    902     [super init];
    903     ASSERT(condition);
    904     m_condition = condition;
    905     *m_condition = false;
    906     return self;
    907 }
    908 
    909 - (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
    910 {
    911     printf("API Test load failed\n");
    912     *m_condition = true;
    913 }
    914 
    915 - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
    916 {
    917     printf("API Test load failed provisional\n");
    918     *m_condition = true;
    919 }
    920 
    921 - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
    922 {
    923     printf("API Test load succeeded\n");
    924     *m_condition = true;
    925 }
    926 
    927 @end
    928 
    929 void LayoutTestController::apiTestNewWindowDataLoadBaseURL(JSStringRef utf8Data, JSStringRef baseURL)
    930 {
    931     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    932 
    933     RetainPtr<CFStringRef> utf8DataCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, utf8Data));
    934     RetainPtr<CFStringRef> baseURLCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, baseURL));
    935 
    936     WebView *webView = [[WebView alloc] initWithFrame:NSZeroRect frameName:@"" groupName:@""];
    937 
    938     bool done = false;
    939     APITestDelegate *delegate = [[APITestDelegate alloc] initWithCompletionCondition:&done];
    940     [webView setFrameLoadDelegate:delegate];
    941 
    942     [[webView mainFrame] loadData:[(NSString *)utf8DataCF.get() dataUsingEncoding:NSUTF8StringEncoding] MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:[NSURL URLWithString:(NSString *)baseURLCF.get()]];
    943 
    944     while (!done) {
    945         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    946         [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
    947         [pool release];
    948     }
    949 
    950     [webView close];
    951     [webView release];
    952     [delegate release];
    953     [pool release];
    954 }
    955 
    956 void LayoutTestController::apiTestGoToCurrentBackForwardItem()
    957 {
    958     WebView *view = [mainFrame webView];
    959     [view goToBackForwardItem:[[view backForwardList] currentItem]];
    960 }
    961 
    962 void LayoutTestController::setWebViewEditable(bool editable)
    963 {
    964     WebView *view = [mainFrame webView];
    965     [view setEditable:editable];
    966 }
    967 
    968 #ifndef BUILDING_ON_TIGER
    969 static NSString *SynchronousLoaderRunLoopMode = @"DumpRenderTreeSynchronousLoaderRunLoopMode";
    970 
    971 #if defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD)
    972 @protocol NSURLConnectionDelegate <NSObject>
    973 @end
    974 #endif
    975 
    976 @interface SynchronousLoader : NSObject <NSURLConnectionDelegate>
    977 {
    978     NSString *m_username;
    979     NSString *m_password;
    980     BOOL m_isDone;
    981 }
    982 + (void)makeRequest:(NSURLRequest *)request withUsername:(NSString *)username password:(NSString *)password;
    983 @end
    984 
    985 @implementation SynchronousLoader : NSObject
    986 - (void)dealloc
    987 {
    988     [m_username release];
    989     [m_password release];
    990 
    991     [super dealloc];
    992 }
    993 
    994 - (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection
    995 {
    996     return YES;
    997 }
    998 
    999 - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
   1000 {
   1001     if ([challenge previousFailureCount] == 0) {
   1002         RetainPtr<NSURLCredential> credential(AdoptNS, [[NSURLCredential alloc]  initWithUser:m_username password:m_password persistence:NSURLCredentialPersistenceForSession]);
   1003         [[challenge sender] useCredential:credential.get() forAuthenticationChallenge:challenge];
   1004         return;
   1005     }
   1006     [[challenge sender] cancelAuthenticationChallenge:challenge];
   1007 }
   1008 
   1009 - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
   1010 {
   1011     printf("SynchronousLoader failed: %s\n", [[error description] UTF8String]);
   1012     m_isDone = YES;
   1013 }
   1014 
   1015 - (void)connectionDidFinishLoading:(NSURLConnection *)connection
   1016 {
   1017     m_isDone = YES;
   1018 }
   1019 
   1020 + (void)makeRequest:(NSURLRequest *)request withUsername:(NSString *)username password:(NSString *)password
   1021 {
   1022     ASSERT(![[request URL] user]);
   1023     ASSERT(![[request URL] password]);
   1024 
   1025     SynchronousLoader *delegate = [[SynchronousLoader alloc] init];
   1026     delegate->m_username = [username copy];
   1027     delegate->m_password = [password copy];
   1028 
   1029     NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:delegate startImmediately:NO];
   1030     [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:SynchronousLoaderRunLoopMode];
   1031     [connection start];
   1032 
   1033     while (!delegate->m_isDone)
   1034         [[NSRunLoop currentRunLoop] runMode:SynchronousLoaderRunLoopMode beforeDate:[NSDate distantFuture]];
   1035 
   1036     [connection cancel];
   1037 
   1038     [connection release];
   1039     [delegate release];
   1040 }
   1041 
   1042 @end
   1043 #endif
   1044 
   1045 void LayoutTestController::authenticateSession(JSStringRef url, JSStringRef username, JSStringRef password)
   1046 {
   1047     // See <rdar://problem/7880699>.
   1048 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
   1049     RetainPtr<CFStringRef> urlStringCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, url));
   1050     RetainPtr<CFStringRef> usernameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, username));
   1051     RetainPtr<CFStringRef> passwordCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, password));
   1052 
   1053     RetainPtr<NSURLRequest> request(AdoptNS, [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:(NSString *)urlStringCF.get()]]);
   1054 
   1055     [SynchronousLoader makeRequest:request.get() withUsername:(NSString *)usernameCF.get() password:(NSString *)passwordCF.get()];
   1056 #endif
   1057 }
   1058 
   1059 void LayoutTestController::setEditingBehavior(const char* editingBehavior)
   1060 {
   1061     NSString* editingBehaviorNS = [[NSString alloc] initWithUTF8String:editingBehavior];
   1062     if ([editingBehaviorNS isEqualToString:@"mac"])
   1063         [[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingMacBehavior];
   1064     else if ([editingBehaviorNS isEqualToString:@"win"])
   1065         [[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingWinBehavior];
   1066     else if ([editingBehaviorNS isEqualToString:@"unix"])
   1067         [[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingUnixBehavior];
   1068     [editingBehaviorNS release];
   1069 }
   1070 
   1071 JSValueRef LayoutTestController::shadowRoot(JSContextRef context, JSValueRef jsElement)
   1072 {
   1073     DOMElement *element = [DOMElement _DOMElementFromJSContext:context value:jsElement];
   1074     if (!element)
   1075         return JSValueMakeNull(context);
   1076     return [element _shadowRoot:context];
   1077 }
   1078 
   1079 void LayoutTestController::abortModal()
   1080 {
   1081     [NSApp abortModal];
   1082 }
   1083 
   1084 bool LayoutTestController::hasSpellingMarker(int from, int length)
   1085 {
   1086     return [mainFrame hasSpellingMarker:from length:length];
   1087 }
   1088 
   1089 bool LayoutTestController::hasGrammarMarker(int from, int length)
   1090 {
   1091     return [mainFrame hasGrammarMarker:from length:length];
   1092 }
   1093 
   1094 void LayoutTestController::dumpConfigurationForViewport(int /*deviceDPI*/, int /*deviceWidth*/, int /*deviceHeight*/, int /*availableWidth*/, int /*availableHeight*/)
   1095 {
   1096 
   1097 }
   1098 
   1099 void LayoutTestController::setSerializeHTTPLoads(bool serialize)
   1100 {
   1101     [WebView _setLoadResourcesSerially:serialize];
   1102 }
   1103 
   1104 void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval)
   1105 {
   1106     [[mainFrame webView] _setMinimumTimerInterval:minimumTimerInterval];
   1107 }
   1108