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 110LayoutTestController::~LayoutTestController() 111{ 112} 113 114void 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 128bool LayoutTestController::callShouldCloseOnWebView() 129{ 130 return [[mainFrame webView] shouldClose]; 131} 132 133void LayoutTestController::clearAllApplicationCaches() 134{ 135 [WebApplicationCache deleteAllApplicationCaches]; 136} 137 138void LayoutTestController::syncLocalStorage() 139{ 140 [[WebStorageManager sharedWebStorageManager] syncLocalStorage]; 141} 142 143void LayoutTestController::observeStorageTrackerNotifications(unsigned number) 144{ 145 [storageDelegate logNotifications:number controller:this]; 146} 147 148void 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 157JSValueRef 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 171JSValueRef LayoutTestController::originsWithApplicationCache(JSContextRef context) 172{ 173 return originsArrayToJS(context, [WebApplicationCache originsWithCache]); 174} 175 176void LayoutTestController::clearAllDatabases() 177{ 178 [[WebDatabaseManager sharedWebDatabaseManager] deleteAllDatabases]; 179} 180 181void LayoutTestController::deleteAllLocalStorage() 182{ 183 [[WebStorageManager sharedWebStorageManager] deleteAllOrigins]; 184} 185 186JSValueRef LayoutTestController::originsWithLocalStorage(JSContextRef context) 187{ 188 return originsArrayToJS(context, [[WebStorageManager sharedWebStorageManager] origins]); 189} 190 191void 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 200void 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 215JSStringRef 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 222JSStringRef 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 229void LayoutTestController::display() 230{ 231 displayWebView(); 232} 233 234JSRetainPtr<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 247void LayoutTestController::keepWebHistory() 248{ 249 if (![WebHistory optionalSharedHistory]) { 250 WebHistory *history = [[WebHistory alloc] init]; 251 [WebHistory setOptionalSharedHistory:history]; 252 [history release]; 253 } 254} 255 256JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value) 257{ 258 return [[mainFrame webView] _computedStyleIncludingVisitedInfo:context forElement:value]; 259} 260 261JSValueRef 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 266JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const 267{ 268 JSRetainPtr<JSStringRef> string(Adopt, JSStringCreateWithCFString((CFStringRef)[mainFrame _layerTreeAsText])); 269 return string; 270} 271 272JSRetainPtr<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 282int 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 294JSRetainPtr<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 300bool LayoutTestController::isPageBoxVisible(int pageNumber) const 301{ 302 return [mainFrame isPageBoxVisible:pageNumber]; 303} 304 305JSRetainPtr<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 311int LayoutTestController::numberOfPages(float pageWidthInPixels, float pageHeightInPixels) 312{ 313 return [mainFrame numberOfPages:pageWidthInPixels:pageHeightInPixels]; 314} 315 316int LayoutTestController::numberOfPendingGeolocationPermissionRequests() 317{ 318 return [[[mainFrame webView] UIDelegate] numberOfPendingGeolocationPermissionRequests]; 319} 320 321size_t LayoutTestController::webHistoryItemCount() 322{ 323 return [[[WebHistory optionalSharedHistory] allItems] count]; 324} 325 326unsigned LayoutTestController::workerThreadCount() const 327{ 328 return [WebWorkersPrivate workerThreadCount]; 329} 330 331void LayoutTestController::notifyDone() 332{ 333 if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count()) 334 dump(); 335 m_waitToDump = false; 336} 337 338JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url) 339{ 340 return JSStringRetain(url); // Do nothing on mac. 341} 342 343void 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 355void LayoutTestController::setAcceptsEditing(bool newAcceptsEditing) 356{ 357 [(EditingDelegate *)[[mainFrame webView] editingDelegate] setAcceptsEditing:newAcceptsEditing]; 358} 359 360void 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 370void LayoutTestController::setAppCacheMaximumSize(unsigned long long size) 371{ 372 [WebApplicationCache setMaximumSize:size]; 373} 374 375void 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 382void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag) 383{ 384 [[[mainFrame webView] preferences] setAuthorAndUserStylesEnabled:flag]; 385} 386 387void 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 396void 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 405void 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 412void 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 418void 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 428void 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 435void 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 443void LayoutTestController::setGeolocationPermission(bool allow) 444{ 445 setGeolocationPermissionCommon(allow); 446 [[[mainFrame webView] UIDelegate] didSetMockGeolocationPermission]; 447} 448 449void 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 455void 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 469void LayoutTestController::setJavaScriptProfilingEnabled(bool profilingEnabled) 470{ 471 setDeveloperExtrasEnabled(profilingEnabled); 472 [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:profilingEnabled]; 473} 474 475void 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 483void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled) 484{ 485 [[[mainFrame webView] preferences] setPrivateBrowsingEnabled:privateBrowsingEnabled]; 486} 487 488void LayoutTestController::setXSSAuditorEnabled(bool enabled) 489{ 490 [[[mainFrame webView] preferences] setXSSAuditorEnabled:enabled]; 491} 492 493void LayoutTestController::setFrameFlatteningEnabled(bool enabled) 494{ 495 [[[mainFrame webView] preferences] setFrameFlatteningEnabled:enabled]; 496} 497 498void LayoutTestController::setSpatialNavigationEnabled(bool enabled) 499{ 500 [[[mainFrame webView] preferences] setSpatialNavigationEnabled:enabled]; 501} 502 503void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled) 504{ 505 [[[mainFrame webView] preferences] setAllowUniversalAccessFromFileURLs:enabled]; 506} 507 508void LayoutTestController::setAllowFileAccessFromFileURLs(bool enabled) 509{ 510 [[[mainFrame webView] preferences] setAllowFileAccessFromFileURLs:enabled]; 511} 512 513void LayoutTestController::setPopupBlockingEnabled(bool popupBlockingEnabled) 514{ 515 [[[mainFrame webView] preferences] setJavaScriptCanOpenWindowsAutomatically:!popupBlockingEnabled]; 516} 517 518void LayoutTestController::setPluginsEnabled(bool pluginsEnabled) 519{ 520 [[[mainFrame webView] preferences] setPlugInsEnabled:pluginsEnabled]; 521} 522 523void LayoutTestController::setJavaScriptCanAccessClipboard(bool enabled) 524{ 525 [[[mainFrame webView] preferences] setJavaScriptCanAccessClipboard:enabled]; 526} 527 528void LayoutTestController::setTabKeyCyclesThroughElements(bool cycles) 529{ 530 [[mainFrame webView] setTabKeyCyclesThroughElements:cycles]; 531} 532 533void LayoutTestController::setTimelineProfilingEnabled(bool enabled) 534{ 535 [[[mainFrame webView] inspector] setTimelineProfilingEnabled:enabled]; 536} 537 538void LayoutTestController::setUseDashboardCompatibilityMode(bool flag) 539{ 540 [[mainFrame webView] _setDashboardBehavior:WebDashboardBehaviorUseBackwardCompatibilityMode to:flag]; 541} 542 543void LayoutTestController::setUserStyleSheetEnabled(bool flag) 544{ 545 [[WebPreferences standardPreferences] setUserStyleSheetEnabled:flag]; 546} 547 548void 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 555void 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 565void LayoutTestController::setViewModeMediaFeature(JSStringRef mode) 566{ 567 // FIXME: implement 568} 569 570void LayoutTestController::disableImageLoading() 571{ 572 [[WebPreferences standardPreferences] setLoadsImagesAutomatically:NO]; 573} 574 575void LayoutTestController::dispatchPendingLoadRequests() 576{ 577 [[mainFrame webView] _dispatchPendingLoadRequests]; 578} 579 580void 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 591void LayoutTestController::removeAllVisitedLinks() 592{ 593 [WebHistory _removeAllVisitedLinks]; 594} 595 596void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL) 597{ 598 RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL)); 599 ::setPersistentUserStyleSheetLocation(urlString.get()); 600} 601 602void LayoutTestController::clearPersistentUserStyleSheet() 603{ 604 ::setPersistentUserStyleSheetLocation(0); 605} 606 607void LayoutTestController::setWindowIsKey(bool windowIsKey) 608{ 609 m_windowIsKey = windowIsKey; 610 [[mainFrame webView] _updateActiveState]; 611} 612 613void LayoutTestController::setSmartInsertDeleteEnabled(bool flag) 614{ 615 [[mainFrame webView] setSmartInsertDeleteEnabled:flag]; 616} 617 618void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) 619{ 620 [[mainFrame webView] setSelectTrailingWhitespaceEnabled:flag]; 621} 622 623static const CFTimeInterval waitToDumpWatchdogInterval = 30.0; 624 625static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info) 626{ 627 gLayoutTestController->waitToDumpWatchdogTimerFired(); 628} 629 630void 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 639int LayoutTestController::windowCount() 640{ 641 return CFArrayGetCount(openWindowsRef); 642} 643 644bool 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 658void 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 669bool 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 705void LayoutTestController::setCacheModel(int cacheModel) 706{ 707 [[WebPreferences standardPreferences] setCacheModel:cacheModel]; 708} 709 710bool 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 734bool 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 744bool 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 754bool 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 764unsigned LayoutTestController::numberOfActiveAnimations() const 765{ 766 return [mainFrame _numberOfActiveAnimations]; 767} 768 769void LayoutTestController::suspendAnimations() const 770{ 771 return [mainFrame _suspendAnimations]; 772} 773 774void LayoutTestController::resumeAnimations() const 775{ 776 return [mainFrame _resumeAnimations]; 777} 778 779void LayoutTestController::waitForPolicyDelegate() 780{ 781 setWaitToDump(true); 782 [policyDelegate setControllerToNotifyDone:this]; 783 [[mainFrame webView] setPolicyDelegate:policyDelegate]; 784} 785 786void 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 797void 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 808void LayoutTestController::setScrollbarPolicy(JSStringRef orientation, JSStringRef policy) 809{ 810 // FIXME: implement 811} 812 813void 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 820void 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 827void LayoutTestController::setDeveloperExtrasEnabled(bool enabled) 828{ 829 [[[mainFrame webView] preferences] setDeveloperExtrasEnabled:enabled]; 830} 831 832void LayoutTestController::setAsynchronousSpellCheckingEnabled(bool enabled) 833{ 834 [[[mainFrame webView] preferences] setAsynchronousSpellCheckingEnabled:enabled]; 835} 836 837void LayoutTestController::showWebInspector() 838{ 839 [[[mainFrame webView] inspector] show:nil]; 840} 841 842void LayoutTestController::closeWebInspector() 843{ 844 [[[mainFrame webView] inspector] close:nil]; 845} 846 847void 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 854typedef HashMap<unsigned, RetainPtr<WebScriptWorld> > WorldMap; 855static WorldMap& worldMap() 856{ 857 static WorldMap& map = *new WorldMap; 858 return map; 859} 860 861unsigned 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 872void 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 929void 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 956void LayoutTestController::apiTestGoToCurrentBackForwardItem() 957{ 958 WebView *view = [mainFrame webView]; 959 [view goToBackForwardItem:[[view backForwardList] currentItem]]; 960} 961 962void LayoutTestController::setWebViewEditable(bool editable) 963{ 964 WebView *view = [mainFrame webView]; 965 [view setEditable:editable]; 966} 967 968#ifndef BUILDING_ON_TIGER 969static 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 1045void 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 1059void 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 1071JSValueRef 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 1079void LayoutTestController::abortModal() 1080{ 1081 [NSApp abortModal]; 1082} 1083 1084bool LayoutTestController::hasSpellingMarker(int from, int length) 1085{ 1086 return [mainFrame hasSpellingMarker:from length:length]; 1087} 1088 1089bool LayoutTestController::hasGrammarMarker(int from, int length) 1090{ 1091 return [mainFrame hasGrammarMarker:from length:length]; 1092} 1093 1094void LayoutTestController::dumpConfigurationForViewport(int /*deviceDPI*/, int /*deviceWidth*/, int /*deviceHeight*/, int /*availableWidth*/, int /*availableHeight*/) 1095{ 1096 1097} 1098 1099void LayoutTestController::setSerializeHTTPLoads(bool serialize) 1100{ 1101 [WebView _setLoadResourcesSerially:serialize]; 1102} 1103 1104void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval) 1105{ 1106 [[mainFrame webView] _setMinimumTimerInterval:minimumTimerInterval]; 1107} 1108