1 /* 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010 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 #include "config.h" 30 #include "LayoutTestController.h" 31 32 #include "DumpRenderTree.h" 33 #include "EditingDelegate.h" 34 #include "PolicyDelegate.h" 35 #include "WorkQueue.h" 36 #include "WorkQueueItem.h" 37 #include <CoreFoundation/CoreFoundation.h> 38 #include <JavaScriptCore/Assertions.h> 39 #include <JavaScriptCore/JSRetainPtr.h> 40 #include <JavaScriptCore/JSStringRefBSTR.h> 41 #include <JavaScriptCore/JavaScriptCore.h> 42 #include <WebCore/COMPtr.h> 43 #include <WebKit/WebKit.h> 44 #include <WebKit/WebKitCOMAPI.h> 45 #include <comutil.h> 46 #include <shlwapi.h> 47 #include <shlguid.h> 48 #include <shobjidl.h> 49 #include <string> 50 #include <wtf/Platform.h> 51 #include <wtf/RetainPtr.h> 52 #include <wtf/Vector.h> 53 54 using std::string; 55 using std::wstring; 56 57 static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath); 58 59 LayoutTestController::~LayoutTestController() 60 { 61 COMPtr<IWebView> webView; 62 if (FAILED(frame->webView(&webView))) 63 return; 64 65 // reset webview-related states back to default values in preparation for next test 66 67 COMPtr<IWebViewPrivate> viewPrivate; 68 if (SUCCEEDED(webView->QueryInterface(&viewPrivate))) 69 viewPrivate->setTabKeyCyclesThroughElements(TRUE); 70 71 COMPtr<IWebViewEditing> viewEditing; 72 if (FAILED(webView->QueryInterface(&viewEditing))) 73 return; 74 COMPtr<IWebEditingDelegate> delegate; 75 if (FAILED(viewEditing->editingDelegate(&delegate))) 76 return; 77 COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get()); 78 if (editingDelegate) 79 editingDelegate->setAcceptsEditing(TRUE); 80 } 81 82 void LayoutTestController::addDisallowedURL(JSStringRef url) 83 { 84 // FIXME: Implement! 85 } 86 87 void LayoutTestController::clearBackForwardList() 88 { 89 COMPtr<IWebView> webView; 90 if (FAILED(frame->webView(&webView))) 91 return; 92 93 COMPtr<IWebBackForwardList> backForwardList; 94 if (FAILED(webView->backForwardList(&backForwardList))) 95 return; 96 97 COMPtr<IWebHistoryItem> item; 98 if (FAILED(backForwardList->currentItem(&item))) 99 return; 100 101 // We clear the history by setting the back/forward list's capacity to 0 102 // then restoring it back and adding back the current item. 103 int capacity; 104 if (FAILED(backForwardList->capacity(&capacity))) 105 return; 106 107 backForwardList->setCapacity(0); 108 backForwardList->setCapacity(capacity); 109 backForwardList->addItem(item.get()); 110 backForwardList->goToItem(item.get()); 111 } 112 113 bool LayoutTestController::callShouldCloseOnWebView() 114 { 115 COMPtr<IWebView> webView; 116 if (FAILED(frame->webView(&webView))) 117 return false; 118 119 COMPtr<IWebViewPrivate> viewPrivate; 120 if (FAILED(webView->QueryInterface(&viewPrivate))) 121 return false; 122 123 BOOL result; 124 viewPrivate->shouldClose(&result); 125 return result; 126 } 127 128 JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name) 129 { 130 // FIXME: Implement! 131 return 0; 132 } 133 134 JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name) 135 { 136 // FIXME: Implement! 137 return 0; 138 } 139 140 void LayoutTestController::disableImageLoading() 141 { 142 COMPtr<IWebView> webView; 143 if (FAILED(frame->webView(&webView))) 144 return; 145 146 COMPtr<IWebPreferences> preferences; 147 if (FAILED(webView->preferences(&preferences))) 148 return; 149 150 preferences->setLoadsImagesAutomatically(FALSE); 151 } 152 153 void LayoutTestController::dispatchPendingLoadRequests() 154 { 155 // FIXME: Implement for testing fix for 6727495 156 } 157 158 void LayoutTestController::display() 159 { 160 displayWebView(); 161 } 162 163 void LayoutTestController::keepWebHistory() 164 { 165 COMPtr<IWebHistory> history; 166 if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history)))) 167 return; 168 169 COMPtr<IWebHistory> sharedHistory; 170 if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(sharedHistory), reinterpret_cast<void**>(&sharedHistory)))) 171 return; 172 173 history->setOptionalSharedHistory(sharedHistory.get()); 174 } 175 176 JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value) 177 { 178 // FIXME: Implement this. 179 return JSValueMakeUndefined(context); 180 } 181 182 JSValueRef LayoutTestController::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping) 183 { 184 // FIXME: Implement this. 185 return JSValueMakeUndefined(context); 186 } 187 188 JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const 189 { 190 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 191 if (!framePrivate) 192 return false; 193 194 BSTR textBSTR = 0; 195 HRESULT hr = framePrivate->layerTreeAsText(&textBSTR); 196 197 wstring text(textBSTR, SysStringLen(textBSTR)); 198 SysFreeString(textBSTR); 199 JSRetainPtr<JSStringRef> textValueJS(Adopt, JSStringCreateWithCharacters(text.data(), text.length())); 200 return textValueJS; 201 } 202 203 JSRetainPtr<JSStringRef> LayoutTestController::markerTextForListItem(JSContextRef context, JSValueRef nodeObject) const 204 { 205 COMPtr<IWebView> webView; 206 if (FAILED(frame->webView(&webView))) 207 return 0; 208 209 COMPtr<IWebViewPrivate> webViewPrivate(Query, webView); 210 if (!webViewPrivate) 211 return 0; 212 213 COMPtr<IDOMElement> element; 214 if (FAILED(webViewPrivate->elementFromJS(context, nodeObject, &element))) 215 return 0; 216 217 COMPtr<IDOMElementPrivate> elementPrivate(Query, element); 218 if (!elementPrivate) 219 return 0; 220 221 BSTR textBSTR = 0; 222 if (FAILED(elementPrivate->markerTextForListItem(&textBSTR))) 223 return 0; 224 225 JSRetainPtr<JSStringRef> markerText(Adopt, JSStringCreateWithBSTR(textBSTR)); 226 SysFreeString(textBSTR); 227 return markerText; 228 } 229 230 void LayoutTestController::waitForPolicyDelegate() 231 { 232 COMPtr<IWebView> webView; 233 if (FAILED(frame->webView(&webView))) 234 return; 235 236 setWaitToDump(true); 237 policyDelegate->setControllerToNotifyDone(this); 238 webView->setPolicyDelegate(policyDelegate); 239 } 240 241 size_t LayoutTestController::webHistoryItemCount() 242 { 243 COMPtr<IWebHistory> history; 244 if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history)))) 245 return 0; 246 247 COMPtr<IWebHistory> sharedHistory; 248 if (FAILED(history->optionalSharedHistory(&sharedHistory)) || !sharedHistory) 249 return 0; 250 251 COMPtr<IWebHistoryPrivate> sharedHistoryPrivate; 252 if (FAILED(sharedHistory->QueryInterface(&sharedHistoryPrivate))) 253 return 0; 254 255 int count; 256 if (FAILED(sharedHistoryPrivate->allItems(&count, 0))) 257 return 0; 258 259 return count; 260 } 261 262 unsigned LayoutTestController::workerThreadCount() const 263 { 264 COMPtr<IWebWorkersPrivate> workers; 265 if (FAILED(WebKitCreateInstance(CLSID_WebWorkersPrivate, 0, __uuidof(workers), reinterpret_cast<void**>(&workers)))) 266 return 0; 267 unsigned count; 268 if (FAILED(workers->workerThreadCount(&count))) 269 return 0; 270 return count; 271 } 272 273 void LayoutTestController::notifyDone() 274 { 275 // Same as on mac. This can be shared. 276 if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count()) 277 dump(); 278 m_waitToDump = false; 279 } 280 281 JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url) 282 { 283 wstring input(JSStringGetCharactersPtr(url), JSStringGetLength(url)); 284 285 wstring localPath; 286 if (!resolveCygwinPath(input, localPath)) { 287 printf("ERROR: Failed to resolve Cygwin path %S\n", input.c_str()); 288 return 0; 289 } 290 291 return JSStringCreateWithCharacters(localPath.c_str(), localPath.length()); 292 } 293 294 static wstring jsStringRefToWString(JSStringRef jsStr) 295 { 296 size_t length = JSStringGetLength(jsStr); 297 Vector<WCHAR> buffer(length + 1); 298 memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR)); 299 buffer[length] = '\0'; 300 301 return buffer.data(); 302 } 303 304 void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target) 305 { 306 COMPtr<IWebDataSource> dataSource; 307 if (FAILED(frame->dataSource(&dataSource))) 308 return; 309 310 COMPtr<IWebURLResponse> response; 311 if (FAILED(dataSource->response(&response)) || !response) 312 return; 313 314 BSTR responseURLBSTR; 315 if (FAILED(response->URL(&responseURLBSTR))) 316 return; 317 wstring responseURL(responseURLBSTR, SysStringLen(responseURLBSTR)); 318 SysFreeString(responseURLBSTR); 319 320 // FIXME: We should do real relative URL resolution here. 321 int lastSlash = responseURL.rfind('/'); 322 if (lastSlash != -1) 323 responseURL = responseURL.substr(0, lastSlash); 324 325 wstring wURL = jsStringRefToWString(url); 326 wstring wAbsoluteURL = responseURL + TEXT("/") + wURL; 327 JSRetainPtr<JSStringRef> jsAbsoluteURL(Adopt, JSStringCreateWithCharacters(wAbsoluteURL.data(), wAbsoluteURL.length())); 328 329 WorkQueue::shared()->queue(new LoadItem(jsAbsoluteURL.get(), target)); 330 } 331 332 void LayoutTestController::setAcceptsEditing(bool acceptsEditing) 333 { 334 COMPtr<IWebView> webView; 335 if (FAILED(frame->webView(&webView))) 336 return; 337 338 COMPtr<IWebViewEditing> viewEditing; 339 if (FAILED(webView->QueryInterface(&viewEditing))) 340 return; 341 342 COMPtr<IWebEditingDelegate> delegate; 343 if (FAILED(viewEditing->editingDelegate(&delegate))) 344 return; 345 346 EditingDelegate* editingDelegate = (EditingDelegate*)(IWebEditingDelegate*)delegate.get(); 347 editingDelegate->setAcceptsEditing(acceptsEditing); 348 } 349 350 void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies) 351 { 352 if (alwaysAcceptCookies == m_alwaysAcceptCookies) 353 return; 354 355 if (!::setAlwaysAcceptCookies(alwaysAcceptCookies)) 356 return; 357 m_alwaysAcceptCookies = alwaysAcceptCookies; 358 } 359 360 void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag) 361 { 362 COMPtr<IWebView> webView; 363 if (FAILED(frame->webView(&webView))) 364 return; 365 366 COMPtr<IWebPreferences> preferences; 367 if (FAILED(webView->preferences(&preferences))) 368 return; 369 370 COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); 371 if (!prefsPrivate) 372 return; 373 374 prefsPrivate->setAuthorAndUserStylesEnabled(flag); 375 } 376 377 void LayoutTestController::setAutofilled(JSContextRef context, JSValueRef nodeObject, bool autofilled) 378 { 379 COMPtr<IWebView> webView; 380 if (FAILED(frame->webView(&webView))) 381 return; 382 383 COMPtr<IWebViewPrivate> webViewPrivate(Query, webView); 384 if (!webViewPrivate) 385 return; 386 387 COMPtr<IDOMElement> element; 388 if (FAILED(webViewPrivate->elementFromJS(context, nodeObject, &element))) 389 return; 390 391 COMPtr<IFormsAutoFillTransition> autofillElement(Query, element); 392 if (!autofillElement) 393 return; 394 395 autofillElement->setAutofilled(autofilled); 396 } 397 398 void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permissive) 399 { 400 COMPtr<IWebView> webView; 401 if (FAILED(frame->webView(&webView))) 402 return; 403 404 if (setDelegate) { 405 policyDelegate->setPermissive(permissive); 406 webView->setPolicyDelegate(policyDelegate); 407 } else 408 webView->setPolicyDelegate(0); 409 } 410 411 void LayoutTestController::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma) 412 { 413 // FIXME: Implement for DeviceOrientation layout tests. 414 // See https://bugs.webkit.org/show_bug.cgi?id=30335. 415 } 416 417 void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy) 418 { 419 // FIXME: Implement for Geolocation layout tests. 420 // See https://bugs.webkit.org/show_bug.cgi?id=28264. 421 } 422 423 void LayoutTestController::setMockGeolocationError(int code, JSStringRef message) 424 { 425 // FIXME: Implement for Geolocation layout tests. 426 // See https://bugs.webkit.org/show_bug.cgi?id=28264. 427 } 428 429 void LayoutTestController::setGeolocationPermission(bool allow) 430 { 431 // FIXME: Implement for Geolocation layout tests. 432 setGeolocationPermissionCommon(allow); 433 } 434 435 int LayoutTestController::numberOfPendingGeolocationPermissionRequests() 436 { 437 // FIXME: Implement for Geolocation layout tests. 438 return -1; 439 } 440 441 void LayoutTestController::addMockSpeechInputResult(JSStringRef result, double confidence, JSStringRef language) 442 { 443 // FIXME: Implement for speech input layout tests. 444 // See https://bugs.webkit.org/show_bug.cgi?id=39485. 445 } 446 447 void LayoutTestController::setIconDatabaseEnabled(bool iconDatabaseEnabled) 448 { 449 // See also <rdar://problem/6480108> 450 COMPtr<IWebIconDatabase> iconDatabase; 451 COMPtr<IWebIconDatabase> tmpIconDatabase; 452 if (FAILED(WebKitCreateInstance(CLSID_WebIconDatabase, 0, IID_IWebIconDatabase, (void**)&tmpIconDatabase))) 453 return; 454 if (FAILED(tmpIconDatabase->sharedIconDatabase(&iconDatabase))) 455 return; 456 457 iconDatabase->setEnabled(iconDatabaseEnabled); 458 } 459 460 void LayoutTestController::setMainFrameIsFirstResponder(bool flag) 461 { 462 // FIXME: Implement! 463 } 464 465 void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled) 466 { 467 COMPtr<IWebView> webView; 468 if (FAILED(frame->webView(&webView))) 469 return; 470 471 COMPtr<IWebPreferences> preferences; 472 if (FAILED(webView->preferences(&preferences))) 473 return; 474 475 preferences->setPrivateBrowsingEnabled(privateBrowsingEnabled); 476 } 477 478 void LayoutTestController::setXSSAuditorEnabled(bool enabled) 479 { 480 COMPtr<IWebView> webView; 481 if (FAILED(frame->webView(&webView))) 482 return; 483 484 COMPtr<IWebPreferences> preferences; 485 if (FAILED(webView->preferences(&preferences))) 486 return; 487 488 COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); 489 if (!prefsPrivate) 490 return; 491 492 prefsPrivate->setXSSAuditorEnabled(enabled); 493 } 494 495 void LayoutTestController::setFrameFlatteningEnabled(bool enabled) 496 { 497 COMPtr<IWebView> webView; 498 if (FAILED(frame->webView(&webView))) 499 return; 500 501 COMPtr<IWebPreferences> preferences; 502 if (FAILED(webView->preferences(&preferences))) 503 return; 504 505 COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); 506 if (!prefsPrivate) 507 return; 508 509 prefsPrivate->setFrameFlatteningEnabled(enabled); 510 } 511 512 void LayoutTestController::setSpatialNavigationEnabled(bool enabled) 513 { 514 // FIXME: Implement for SpatialNavigation layout tests. 515 } 516 517 void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled) 518 { 519 COMPtr<IWebView> webView; 520 if (FAILED(frame->webView(&webView))) 521 return; 522 523 COMPtr<IWebPreferences> preferences; 524 if (FAILED(webView->preferences(&preferences))) 525 return; 526 527 COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); 528 if (!prefsPrivate) 529 return; 530 531 prefsPrivate->setAllowUniversalAccessFromFileURLs(enabled); 532 } 533 534 void LayoutTestController::setAllowFileAccessFromFileURLs(bool enabled) 535 { 536 COMPtr<IWebView> webView; 537 if (FAILED(frame->webView(&webView))) 538 return; 539 540 COMPtr<IWebPreferences> preferences; 541 if (FAILED(webView->preferences(&preferences))) 542 return; 543 544 COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); 545 if (!prefsPrivate) 546 return; 547 548 prefsPrivate->setAllowFileAccessFromFileURLs(enabled); 549 } 550 551 void LayoutTestController::setPopupBlockingEnabled(bool enabled) 552 { 553 COMPtr<IWebView> webView; 554 if (FAILED(frame->webView(&webView))) 555 return; 556 557 COMPtr<IWebPreferences> preferences; 558 if (FAILED(webView->preferences(&preferences))) 559 return; 560 561 preferences->setJavaScriptCanOpenWindowsAutomatically(!enabled); 562 } 563 564 void LayoutTestController::setPluginsEnabled(bool flag) 565 { 566 // FIXME: Implement 567 } 568 569 void LayoutTestController::setJavaScriptCanAccessClipboard(bool enabled) 570 { 571 COMPtr<IWebView> webView; 572 if (FAILED(frame->webView(&webView))) 573 return; 574 575 COMPtr<IWebPreferences> preferences; 576 if (FAILED(webView->preferences(&preferences))) 577 return; 578 579 COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); 580 if (!prefsPrivate) 581 return; 582 583 prefsPrivate->setJavaScriptCanAccessClipboard(enabled); 584 } 585 586 void LayoutTestController::setTabKeyCyclesThroughElements(bool shouldCycle) 587 { 588 COMPtr<IWebView> webView; 589 if (FAILED(frame->webView(&webView))) 590 return; 591 592 COMPtr<IWebViewPrivate> viewPrivate; 593 if (FAILED(webView->QueryInterface(&viewPrivate))) 594 return; 595 596 viewPrivate->setTabKeyCyclesThroughElements(shouldCycle ? TRUE : FALSE); 597 } 598 599 void LayoutTestController::setTimelineProfilingEnabled(bool flag) 600 { 601 COMPtr<IWebView> webView; 602 if (FAILED(frame->webView(&webView))) 603 return; 604 605 COMPtr<IWebViewPrivate> viewPrivate; 606 if (FAILED(webView->QueryInterface(&viewPrivate))) 607 return; 608 609 COMPtr<IWebInspector> inspector; 610 if (FAILED(viewPrivate->inspector(&inspector))) 611 return; 612 613 inspector->setTimelineProfilingEnabled(flag); 614 } 615 616 void LayoutTestController::setUseDashboardCompatibilityMode(bool flag) 617 { 618 // FIXME: Implement! 619 } 620 621 void LayoutTestController::setUserStyleSheetEnabled(bool flag) 622 { 623 COMPtr<IWebView> webView; 624 if (FAILED(frame->webView(&webView))) 625 return; 626 627 COMPtr<IWebPreferences> preferences; 628 if (FAILED(webView->preferences(&preferences))) 629 return; 630 631 preferences->setUserStyleSheetEnabled(flag); 632 } 633 634 bool appendComponentToPath(wstring& path, const wstring& component) 635 { 636 WCHAR buffer[MAX_PATH]; 637 638 if (path.size() + 1 > MAX_PATH) 639 return false; 640 641 memcpy(buffer, path.data(), path.size() * sizeof(WCHAR)); 642 buffer[path.size()] = '\0'; 643 644 if (!PathAppendW(buffer, component.c_str())) 645 return false; 646 647 path = wstring(buffer); 648 return true; 649 } 650 651 static bool followShortcuts(wstring& path) 652 { 653 if (PathFileExists(path.c_str())) 654 return true; 655 656 // Do we have a shortcut? 657 wstring linkPath = path; 658 linkPath.append(TEXT(".lnk")); 659 if (!PathFileExists(linkPath.c_str())) 660 return true; 661 662 // We have a shortcut, find its target. 663 COMPtr<IShellLink> shortcut(Create, CLSID_ShellLink); 664 if (!shortcut) 665 return false; 666 COMPtr<IPersistFile> persistFile(Query, shortcut); 667 if (!shortcut) 668 return false; 669 if (FAILED(persistFile->Load(linkPath.c_str(), STGM_READ))) 670 return false; 671 if (FAILED(shortcut->Resolve(0, 0))) 672 return false; 673 WCHAR targetPath[MAX_PATH]; 674 DWORD targetPathLen = _countof(targetPath); 675 if (FAILED(shortcut->GetPath(targetPath, targetPathLen, 0, 0))) 676 return false; 677 if (!PathFileExists(targetPath)) 678 return false; 679 // Use the target path as the result path instead. 680 path = wstring(targetPath); 681 682 return true; 683 } 684 685 static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath) 686 { 687 wstring fileProtocol = L"file://"; 688 bool isFileProtocol = cygwinPath.find(fileProtocol) != string::npos; 689 if (cygwinPath[isFileProtocol ? 7 : 0] != '/') // ensure path is absolute 690 return false; 691 692 // Get the Root path. 693 WCHAR rootPath[MAX_PATH]; 694 DWORD rootPathSize = _countof(rootPath); 695 DWORD keyType; 696 DWORD result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/"), TEXT("native"), &keyType, &rootPath, &rootPathSize); 697 698 if (result != ERROR_SUCCESS || keyType != REG_SZ) { 699 // Cygwin 1.7 doesn't store Cygwin's root as a mount point anymore, because mount points are now stored in /etc/fstab. 700 // However, /etc/fstab doesn't contain any information about where / is located as a Windows path, so we need to use Cygwin's 701 // new registry key that has the root. 702 result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygwin\\setup"), TEXT("rootdir"), &keyType, &rootPath, &rootPathSize); 703 if (result != ERROR_SUCCESS || keyType != REG_SZ) 704 return false; 705 } 706 707 windowsPath = wstring(rootPath, rootPathSize); 708 709 int oldPos = isFileProtocol ? 8 : 1; 710 while (1) { 711 int newPos = cygwinPath.find('/', oldPos); 712 713 if (newPos == -1) { 714 wstring pathComponent = cygwinPath.substr(oldPos); 715 716 if (!appendComponentToPath(windowsPath, pathComponent)) 717 return false; 718 719 if (!followShortcuts(windowsPath)) 720 return false; 721 722 break; 723 } 724 725 wstring pathComponent = cygwinPath.substr(oldPos, newPos - oldPos); 726 if (!appendComponentToPath(windowsPath, pathComponent)) 727 return false; 728 729 if (!followShortcuts(windowsPath)) 730 return false; 731 732 oldPos = newPos + 1; 733 } 734 735 if (isFileProtocol) 736 windowsPath = fileProtocol + windowsPath; 737 738 return true; 739 } 740 741 void LayoutTestController::setUserStyleSheetLocation(JSStringRef jsURL) 742 { 743 COMPtr<IWebView> webView; 744 if (FAILED(frame->webView(&webView))) 745 return; 746 747 COMPtr<IWebPreferences> preferences; 748 if (FAILED(webView->preferences(&preferences))) 749 return; 750 751 RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL)); 752 RetainPtr<CFURLRef> url(AdoptCF, CFURLCreateWithString(0, urlString.get(), 0)); 753 if (!url) 754 return; 755 756 // Now copy the file system path, POSIX style. 757 RetainPtr<CFStringRef> pathCF(AdoptCF, CFURLCopyFileSystemPath(url.get(), kCFURLPOSIXPathStyle)); 758 if (!pathCF) 759 return; 760 761 wstring path = cfStringRefToWString(pathCF.get()); 762 763 wstring resultPath; 764 if (!resolveCygwinPath(path, resultPath)) 765 return; 766 767 // The path has been resolved, now convert it back to a CFURL. 768 int result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, 0, 0, 0, 0); 769 Vector<char> utf8Vector(result); 770 result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, utf8Vector.data(), result, 0, 0); 771 if (!result) 772 return; 773 774 url = CFURLCreateFromFileSystemRepresentation(0, (const UInt8*)utf8Vector.data(), utf8Vector.size() - 1, false); 775 if (!url) 776 return; 777 778 resultPath = cfStringRefToWString(CFURLGetString(url.get())); 779 780 BSTR resultPathBSTR = SysAllocStringLen(resultPath.data(), resultPath.size()); 781 preferences->setUserStyleSheetLocation(resultPathBSTR); 782 SysFreeString(resultPathBSTR); 783 } 784 785 void LayoutTestController::setValueForUser(JSContextRef context, JSValueRef element, JSStringRef value) 786 { 787 // FIXME: implement 788 } 789 790 void LayoutTestController::setViewModeMediaFeature(JSStringRef mode) 791 { 792 // FIXME: implement 793 } 794 795 void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL) 796 { 797 RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL)); 798 ::setPersistentUserStyleSheetLocation(urlString.get()); 799 } 800 801 void LayoutTestController::clearPersistentUserStyleSheet() 802 { 803 ::setPersistentUserStyleSheetLocation(0); 804 } 805 806 void LayoutTestController::setWindowIsKey(bool flag) 807 { 808 COMPtr<IWebView> webView; 809 if (FAILED(frame->webView(&webView))) 810 return; 811 812 COMPtr<IWebViewPrivate> viewPrivate; 813 if (FAILED(webView->QueryInterface(&viewPrivate))) 814 return; 815 816 HWND webViewWindow; 817 if (FAILED(viewPrivate->viewWindow((OLE_HANDLE*)&webViewWindow))) 818 return; 819 820 ::SendMessage(webViewWindow, flag ? WM_SETFOCUS : WM_KILLFOCUS, (WPARAM)::GetDesktopWindow(), 0); 821 } 822 823 void LayoutTestController::setSmartInsertDeleteEnabled(bool flag) 824 { 825 COMPtr<IWebView> webView; 826 if (FAILED(frame->webView(&webView))) 827 return; 828 829 COMPtr<IWebViewEditing> viewEditing; 830 if (FAILED(webView->QueryInterface(&viewEditing))) 831 return; 832 833 viewEditing->setSmartInsertDeleteEnabled(flag ? TRUE : FALSE); 834 } 835 836 void LayoutTestController::setJavaScriptProfilingEnabled(bool flag) 837 { 838 COMPtr<IWebView> webView; 839 if (FAILED(frame->webView(&webView))) 840 return; 841 842 COMPtr<IWebViewPrivate> viewPrivate; 843 if (FAILED(webView->QueryInterface(&viewPrivate))) 844 return; 845 846 COMPtr<IWebInspector> inspector; 847 if (FAILED(viewPrivate->inspector(&inspector))) 848 return; 849 850 setDeveloperExtrasEnabled(flag); 851 inspector->setJavaScriptProfilingEnabled(flag); 852 } 853 854 void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) 855 { 856 COMPtr<IWebView> webView; 857 if (FAILED(frame->webView(&webView))) 858 return; 859 860 COMPtr<IWebViewEditing> viewEditing; 861 if (FAILED(webView->QueryInterface(&viewEditing))) 862 return; 863 864 viewEditing->setSelectTrailingWhitespaceEnabled(flag ? TRUE : FALSE); 865 } 866 867 static const CFTimeInterval waitToDumpWatchdogInterval = 30.0; 868 869 static void CALLBACK waitUntilDoneWatchdogFired(HWND, UINT, UINT_PTR, DWORD) 870 { 871 gLayoutTestController->waitToDumpWatchdogTimerFired(); 872 } 873 874 void LayoutTestController::setWaitToDump(bool waitUntilDone) 875 { 876 m_waitToDump = waitUntilDone; 877 if (m_waitToDump && !waitToDumpWatchdog) 878 waitToDumpWatchdog = SetTimer(0, 0, waitToDumpWatchdogInterval * 1000, waitUntilDoneWatchdogFired); 879 } 880 881 int LayoutTestController::windowCount() 882 { 883 return openWindows().size(); 884 } 885 886 bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef id) 887 { 888 COMPtr<IDOMDocument> document; 889 if (FAILED(frame->DOMDocument(&document))) 890 return false; 891 892 wstring idWstring = jsStringRefToWString(id); 893 BSTR idBSTR = SysAllocStringLen((OLECHAR*)idWstring.c_str(), idWstring.length()); 894 COMPtr<IDOMElement> element; 895 HRESULT result = document->getElementById(idBSTR, &element); 896 SysFreeString(idBSTR); 897 898 if (FAILED(result)) 899 return false; 900 901 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 902 if (!framePrivate) 903 return false; 904 905 BOOL autoCompletes; 906 if (FAILED(framePrivate->elementDoesAutoComplete(element.get(), &autoCompletes))) 907 return false; 908 909 return autoCompletes; 910 } 911 912 void LayoutTestController::execCommand(JSStringRef name, JSStringRef value) 913 { 914 wstring wName = jsStringRefToWString(name); 915 wstring wValue = jsStringRefToWString(value); 916 917 COMPtr<IWebView> webView; 918 if (FAILED(frame->webView(&webView))) 919 return; 920 921 COMPtr<IWebViewPrivate> viewPrivate; 922 if (FAILED(webView->QueryInterface(&viewPrivate))) 923 return; 924 925 BSTR nameBSTR = SysAllocStringLen((OLECHAR*)wName.c_str(), wName.length()); 926 BSTR valueBSTR = SysAllocStringLen((OLECHAR*)wValue.c_str(), wValue.length()); 927 viewPrivate->executeCoreCommandByName(nameBSTR, valueBSTR); 928 929 SysFreeString(nameBSTR); 930 SysFreeString(valueBSTR); 931 } 932 933 bool LayoutTestController::findString(JSContextRef /* context */, JSStringRef /* target */, JSObjectRef /* optionsArray */) 934 { 935 // FIXME: Implement 936 return false; 937 } 938 939 void LayoutTestController::setCacheModel(int) 940 { 941 // FIXME: Implement 942 } 943 944 bool LayoutTestController::isCommandEnabled(JSStringRef /*name*/) 945 { 946 printf("ERROR: LayoutTestController::isCommandEnabled() not implemented\n"); 947 return false; 948 } 949 950 void LayoutTestController::clearAllApplicationCaches() 951 { 952 // FIXME: Implement to support application cache quotas. 953 } 954 955 void LayoutTestController::clearApplicationCacheForOrigin(JSStringRef origin) 956 { 957 // FIXME: Implement to support deleting all application cache for an origin. 958 } 959 960 void LayoutTestController::setApplicationCacheOriginQuota(unsigned long long quota) 961 { 962 // FIXME: Implement to support application cache quotas. 963 } 964 965 JSValueRef LayoutTestController::originsWithApplicationCache(JSContextRef context) 966 { 967 // FIXME: Implement to get origins that have application caches. 968 return JSValueMakeUndefined(context); 969 } 970 971 void LayoutTestController::clearAllDatabases() 972 { 973 COMPtr<IWebDatabaseManager> databaseManager; 974 COMPtr<IWebDatabaseManager> tmpDatabaseManager; 975 if (FAILED(WebKitCreateInstance(CLSID_WebDatabaseManager, 0, IID_IWebDatabaseManager, (void**)&tmpDatabaseManager))) 976 return; 977 if (FAILED(tmpDatabaseManager->sharedWebDatabaseManager(&databaseManager))) 978 return; 979 980 databaseManager->deleteAllDatabases(); 981 } 982 983 void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value) 984 { 985 COMPtr<IWebView> webView; 986 if (FAILED(frame->webView(&webView))) 987 return; 988 989 COMPtr<IWebPreferences> preferences; 990 if (FAILED(webView->preferences(&preferences))) 991 return; 992 993 COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); 994 if (!prefsPrivate) 995 return; 996 997 BSTR keyBSTR = JSStringCopyBSTR(key); 998 BSTR valueBSTR = JSStringCopyBSTR(value); 999 prefsPrivate->setPreferenceForTest(keyBSTR, valueBSTR); 1000 SysFreeString(keyBSTR); 1001 SysFreeString(valueBSTR); 1002 } 1003 1004 void LayoutTestController::setDatabaseQuota(unsigned long long quota) 1005 { 1006 COMPtr<IWebDatabaseManager> databaseManager; 1007 COMPtr<IWebDatabaseManager> tmpDatabaseManager; 1008 1009 if (FAILED(WebKitCreateInstance(CLSID_WebDatabaseManager, 0, IID_IWebDatabaseManager, (void**)&tmpDatabaseManager))) 1010 return; 1011 if (FAILED(tmpDatabaseManager->sharedWebDatabaseManager(&databaseManager))) 1012 return; 1013 1014 databaseManager->setQuota(TEXT("file:///"), quota); 1015 } 1016 1017 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme) 1018 { 1019 COMPtr<IWebViewPrivate> webView; 1020 if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) 1021 return; 1022 1023 BSTR schemeBSTR = JSStringCopyBSTR(scheme); 1024 webView->setDomainRelaxationForbiddenForURLScheme(forbidden, schemeBSTR); 1025 SysFreeString(schemeBSTR); 1026 } 1027 1028 void LayoutTestController::setAppCacheMaximumSize(unsigned long long size) 1029 { 1030 printf("ERROR: LayoutTestController::setAppCacheMaximumSize() not implemented\n"); 1031 } 1032 1033 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId) 1034 { 1035 COMPtr<IDOMDocument> document; 1036 if (FAILED(frame->DOMDocument(&document))) 1037 return false; 1038 1039 BSTR idBSTR = JSStringCopyBSTR(elementId); 1040 COMPtr<IDOMElement> element; 1041 HRESULT hr = document->getElementById(idBSTR, &element); 1042 SysFreeString(idBSTR); 1043 if (FAILED(hr)) 1044 return false; 1045 1046 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1047 if (!framePrivate) 1048 return false; 1049 1050 BSTR nameBSTR = JSStringCopyBSTR(animationName); 1051 BOOL wasRunning = FALSE; 1052 hr = framePrivate->pauseAnimation(nameBSTR, element.get(), time, &wasRunning); 1053 SysFreeString(nameBSTR); 1054 1055 return SUCCEEDED(hr) && wasRunning; 1056 } 1057 1058 bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId) 1059 { 1060 COMPtr<IDOMDocument> document; 1061 if (FAILED(frame->DOMDocument(&document))) 1062 return false; 1063 1064 BSTR idBSTR = JSStringCopyBSTR(elementId); 1065 COMPtr<IDOMElement> element; 1066 HRESULT hr = document->getElementById(idBSTR, &element); 1067 SysFreeString(idBSTR); 1068 if (FAILED(hr)) 1069 return false; 1070 1071 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1072 if (!framePrivate) 1073 return false; 1074 1075 BSTR nameBSTR = JSStringCopyBSTR(propertyName); 1076 BOOL wasRunning = FALSE; 1077 hr = framePrivate->pauseTransition(nameBSTR, element.get(), time, &wasRunning); 1078 SysFreeString(nameBSTR); 1079 1080 return SUCCEEDED(hr) && wasRunning; 1081 } 1082 1083 bool LayoutTestController::sampleSVGAnimationForElementAtTime(JSStringRef animationId, double time, JSStringRef elementId) 1084 { 1085 COMPtr<IDOMDocument> document; 1086 if (FAILED(frame->DOMDocument(&document))) 1087 return false; 1088 1089 BSTR idBSTR = JSStringCopyBSTR(animationId); 1090 COMPtr<IDOMElement> element; 1091 HRESULT hr = document->getElementById(idBSTR, &element); 1092 SysFreeString(idBSTR); 1093 if (FAILED(hr)) 1094 return false; 1095 1096 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1097 if (!framePrivate) 1098 return false; 1099 1100 BSTR elementIdBSTR = JSStringCopyBSTR(elementId); 1101 BOOL wasRunning = FALSE; 1102 hr = framePrivate->pauseSVGAnimation(elementIdBSTR, element.get(), time, &wasRunning); 1103 SysFreeString(elementIdBSTR); 1104 1105 return SUCCEEDED(hr) && wasRunning; 1106 } 1107 1108 unsigned LayoutTestController::numberOfActiveAnimations() const 1109 { 1110 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1111 if (!framePrivate) 1112 return 0; 1113 1114 UINT number = 0; 1115 if (FAILED(framePrivate->numberOfActiveAnimations(&number))) 1116 return 0; 1117 1118 return number; 1119 } 1120 1121 void LayoutTestController::suspendAnimations() const 1122 { 1123 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1124 if (!framePrivate) 1125 return; 1126 1127 framePrivate->suspendAnimations(); 1128 } 1129 1130 void LayoutTestController::resumeAnimations() const 1131 { 1132 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1133 if (!framePrivate) 1134 return; 1135 1136 framePrivate->resumeAnimations(); 1137 } 1138 1139 static _bstr_t bstrT(JSStringRef jsString) 1140 { 1141 // The false parameter tells the _bstr_t constructor to adopt the BSTR we pass it. 1142 return _bstr_t(JSStringCopyBSTR(jsString), false); 1143 } 1144 1145 void LayoutTestController::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains) 1146 { 1147 COMPtr<IWebViewPrivate> webView; 1148 if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) 1149 return; 1150 1151 webView->addOriginAccessWhitelistEntry(bstrT(sourceOrigin).GetBSTR(), bstrT(destinationProtocol).GetBSTR(), bstrT(destinationHost).GetBSTR(), allowDestinationSubdomains); 1152 } 1153 1154 void LayoutTestController::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains) 1155 { 1156 COMPtr<IWebViewPrivate> webView; 1157 if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) 1158 return; 1159 1160 webView->removeOriginAccessWhitelistEntry(bstrT(sourceOrigin).GetBSTR(), bstrT(destinationProtocol).GetBSTR(), bstrT(destinationHost).GetBSTR(), allowDestinationSubdomains); 1161 } 1162 1163 void LayoutTestController::setScrollbarPolicy(JSStringRef orientation, JSStringRef policy) 1164 { 1165 // FIXME: implement 1166 } 1167 1168 void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart, bool allFrames) 1169 { 1170 COMPtr<IWebViewPrivate> webView; 1171 if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) 1172 return; 1173 1174 COMPtr<IWebScriptWorld> world; 1175 if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world)))) 1176 return; 1177 1178 webView->addUserScriptToGroup(_bstr_t(L"org.webkit.DumpRenderTree").GetBSTR(), world.get(), bstrT(source).GetBSTR(), 0, 0, 0, 0, 0, runAtStart ? WebInjectAtDocumentStart : WebInjectAtDocumentEnd); 1179 } 1180 1181 1182 void LayoutTestController::addUserStyleSheet(JSStringRef source, bool allFrames) 1183 { 1184 COMPtr<IWebViewPrivate> webView; 1185 if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView)))) 1186 return; 1187 1188 COMPtr<IWebScriptWorld> world; 1189 if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world)))) 1190 return; 1191 1192 webView->addUserStyleSheetToGroup(_bstr_t(L"org.webkit.DumpRenderTree").GetBSTR(), world.get(), bstrT(source).GetBSTR(), 0, 0, 0, 0, 0); 1193 } 1194 1195 void LayoutTestController::setDeveloperExtrasEnabled(bool enabled) 1196 { 1197 COMPtr<IWebView> webView; 1198 if (FAILED(frame->webView(&webView))) 1199 return; 1200 1201 COMPtr<IWebPreferences> preferences; 1202 if (FAILED(webView->preferences(&preferences))) 1203 return; 1204 1205 COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); 1206 if (!prefsPrivate) 1207 return; 1208 1209 prefsPrivate->setDeveloperExtrasEnabled(enabled); 1210 } 1211 1212 void LayoutTestController::setAsynchronousSpellCheckingEnabled(bool) 1213 { 1214 // FIXME: Implement this. 1215 } 1216 1217 void LayoutTestController::showWebInspector() 1218 { 1219 COMPtr<IWebView> webView; 1220 if (FAILED(frame->webView(&webView))) 1221 return; 1222 1223 COMPtr<IWebViewPrivate> viewPrivate(Query, webView); 1224 if (!viewPrivate) 1225 return; 1226 1227 COMPtr<IWebInspector> inspector; 1228 if (SUCCEEDED(viewPrivate->inspector(&inspector))) 1229 inspector->show(); 1230 } 1231 1232 void LayoutTestController::closeWebInspector() 1233 { 1234 COMPtr<IWebView> webView; 1235 if (FAILED(frame->webView(&webView))) 1236 return; 1237 1238 COMPtr<IWebViewPrivate> viewPrivate(Query, webView); 1239 if (!viewPrivate) 1240 return; 1241 1242 COMPtr<IWebInspector> inspector; 1243 if (FAILED(viewPrivate->inspector(&inspector))) 1244 return; 1245 1246 inspector->close(); 1247 } 1248 1249 void LayoutTestController::evaluateInWebInspector(long callId, JSStringRef script) 1250 { 1251 COMPtr<IWebView> webView; 1252 if (FAILED(frame->webView(&webView))) 1253 return; 1254 1255 COMPtr<IWebViewPrivate> viewPrivate(Query, webView); 1256 if (!viewPrivate) 1257 return; 1258 1259 COMPtr<IWebInspector> inspector; 1260 if (FAILED(viewPrivate->inspector(&inspector))) 1261 return; 1262 1263 COMPtr<IWebInspectorPrivate> inspectorPrivate(Query, inspector); 1264 if (!inspectorPrivate) 1265 return; 1266 1267 inspectorPrivate->evaluateInFrontend(callId, bstrT(script).GetBSTR()); 1268 } 1269 1270 typedef HashMap<unsigned, COMPtr<IWebScriptWorld> > WorldMap; 1271 static WorldMap& worldMap() 1272 { 1273 static WorldMap& map = *new WorldMap; 1274 return map; 1275 } 1276 1277 unsigned worldIDForWorld(IWebScriptWorld* world) 1278 { 1279 WorldMap::const_iterator end = worldMap().end(); 1280 for (WorldMap::const_iterator it = worldMap().begin(); it != end; ++it) { 1281 if (it->second == world) 1282 return it->first; 1283 } 1284 1285 return 0; 1286 } 1287 1288 void LayoutTestController::evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script) 1289 { 1290 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1291 if (!framePrivate) 1292 return; 1293 1294 // A worldID of 0 always corresponds to a new world. Any other worldID corresponds to a world 1295 // that is created once and cached forever. 1296 COMPtr<IWebScriptWorld> world; 1297 if (!worldID) { 1298 if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world)))) 1299 return; 1300 } else { 1301 COMPtr<IWebScriptWorld>& worldSlot = worldMap().add(worldID, 0).first->second; 1302 if (!worldSlot && FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(worldSlot), reinterpret_cast<void**>(&worldSlot)))) 1303 return; 1304 world = worldSlot; 1305 } 1306 1307 BSTR result; 1308 if (FAILED(framePrivate->stringByEvaluatingJavaScriptInScriptWorld(world.get(), globalObject, bstrT(script).GetBSTR(), &result))) 1309 return; 1310 SysFreeString(result); 1311 } 1312 1313 void LayoutTestController::removeAllVisitedLinks() 1314 { 1315 COMPtr<IWebHistory> history; 1316 if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history)))) 1317 return; 1318 1319 COMPtr<IWebHistory> sharedHistory; 1320 if (FAILED(history->optionalSharedHistory(&sharedHistory)) || !sharedHistory) 1321 return; 1322 1323 COMPtr<IWebHistoryPrivate> sharedHistoryPrivate; 1324 if (FAILED(sharedHistory->QueryInterface(&sharedHistoryPrivate))) 1325 return; 1326 1327 sharedHistoryPrivate->removeAllVisitedLinks(); 1328 } 1329 1330 JSRetainPtr<JSStringRef> LayoutTestController::counterValueForElementById(JSStringRef id) 1331 { 1332 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1333 if (!framePrivate) 1334 return 0; 1335 1336 wstring idWstring = jsStringRefToWString(id); 1337 BSTR idBSTR = SysAllocStringLen((OLECHAR*)idWstring.c_str(), idWstring.length()); 1338 BSTR counterValueBSTR; 1339 if (FAILED(framePrivate->counterValueForElementById(idBSTR, &counterValueBSTR))) 1340 return 0; 1341 1342 wstring counterValue(counterValueBSTR, SysStringLen(counterValueBSTR)); 1343 SysFreeString(idBSTR); 1344 SysFreeString(counterValueBSTR); 1345 JSRetainPtr<JSStringRef> counterValueJS(Adopt, JSStringCreateWithCharacters(counterValue.data(), counterValue.length())); 1346 return counterValueJS; 1347 } 1348 1349 int LayoutTestController::pageNumberForElementById(JSStringRef id, float pageWidthInPixels, float pageHeightInPixels) 1350 { 1351 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1352 if (!framePrivate) 1353 return 0; 1354 1355 wstring idWstring = jsStringRefToWString(id); 1356 BSTR idBSTR = SysAllocStringLen((OLECHAR*)idWstring.c_str(), idWstring.length()); 1357 int pageNumber = -1; 1358 if (FAILED(framePrivate->pageNumberForElementById(idBSTR, pageWidthInPixels, pageHeightInPixels, &pageNumber))) 1359 pageNumber = -1; 1360 SysFreeString(idBSTR); 1361 return pageNumber; 1362 } 1363 1364 int LayoutTestController::numberOfPages(float pageWidthInPixels, float pageHeightInPixels) 1365 { 1366 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1367 if (!framePrivate) 1368 return 0; 1369 1370 int pageNumber = -1; 1371 if (FAILED(framePrivate->numberOfPages(pageWidthInPixels, pageHeightInPixels, &pageNumber))) 1372 pageNumber = -1; 1373 return pageNumber; 1374 } 1375 1376 JSRetainPtr<JSStringRef> LayoutTestController::pageProperty(const char* propertyName, int pageNumber) const 1377 { 1378 // FIXME: Implement this. 1379 return JSRetainPtr<JSStringRef>(); 1380 } 1381 1382 void LayoutTestController::apiTestNewWindowDataLoadBaseURL(JSStringRef utf8Data, JSStringRef baseURL) 1383 { 1384 1385 } 1386 1387 bool LayoutTestController::isPageBoxVisible(int pageNumber) const 1388 { 1389 // FIXME: implement 1390 return false; 1391 } 1392 1393 JSRetainPtr<JSStringRef> LayoutTestController::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) const 1394 { 1395 // FIXME: implement 1396 return JSRetainPtr<JSStringRef>(); 1397 } 1398 1399 void LayoutTestController::apiTestGoToCurrentBackForwardItem() 1400 { 1401 COMPtr<IWebView> webView; 1402 if (FAILED(frame->webView(&webView))) 1403 return; 1404 1405 COMPtr<IWebBackForwardList> backForwardList; 1406 if (FAILED(webView->backForwardList(&backForwardList))) 1407 return; 1408 1409 COMPtr<IWebHistoryItem> item; 1410 if (FAILED(backForwardList->currentItem(&item))) 1411 return; 1412 1413 BOOL success; 1414 webView->goToBackForwardItem(item.get(), &success); 1415 } 1416 1417 void LayoutTestController::setWebViewEditable(bool) 1418 { 1419 } 1420 1421 void LayoutTestController::authenticateSession(JSStringRef, JSStringRef, JSStringRef) 1422 { 1423 } 1424 1425 void LayoutTestController::setEditingBehavior(const char* editingBehavior) 1426 { 1427 COMPtr<IWebView> webView; 1428 if (FAILED(frame->webView(&webView))) 1429 return; 1430 1431 COMPtr<IWebPreferences> preferences; 1432 if (FAILED(webView->preferences(&preferences))) 1433 return; 1434 1435 string behaviorString(editingBehavior); 1436 if (behaviorString == "mac") 1437 preferences->setEditingBehavior(WebKitEditingMacBehavior); 1438 else if (behaviorString == "win") 1439 preferences->setEditingBehavior(WebKitEditingWinBehavior); 1440 else if (behaviorString == "unix") 1441 preferences->setEditingBehavior(WebKitEditingUnixBehavior); 1442 } 1443 1444 JSValueRef LayoutTestController::shadowRoot(JSContextRef context, JSValueRef jsElement) 1445 { 1446 // FIXME: Implement this. 1447 return JSValueMakeUndefined(context); 1448 } 1449 1450 void LayoutTestController::abortModal() 1451 { 1452 } 1453 1454 bool LayoutTestController::hasSpellingMarker(int from, int length) 1455 { 1456 COMPtr<IWebFramePrivate> framePrivate(Query, frame); 1457 if (!framePrivate) 1458 return false; 1459 BOOL ret = FALSE; 1460 if (FAILED(framePrivate->hasSpellingMarker(from, length, &ret))) 1461 return false; 1462 return ret; 1463 } 1464 1465 bool LayoutTestController::hasGrammarMarker(int from, int length) 1466 { 1467 // FIXME: Implement this. 1468 return false; 1469 } 1470 1471 void LayoutTestController::dumpConfigurationForViewport(int /*deviceDPI*/, int /*deviceWidth*/, int /*deviceHeight*/, int /*availableWidth*/, int /*availableHeight*/) 1472 { 1473 // FIXME: Implement this. 1474 } 1475 1476 void LayoutTestController::setSerializeHTTPLoads(bool) 1477 { 1478 // FIXME: Implement. 1479 } 1480 1481 void LayoutTestController::syncLocalStorage() 1482 { 1483 // FIXME: Implement. 1484 } 1485 1486 void LayoutTestController::observeStorageTrackerNotifications(unsigned number) 1487 { 1488 // FIXME: Implement. 1489 } 1490 1491 void LayoutTestController::deleteAllLocalStorage() 1492 { 1493 // FIXME: Implement. 1494 } 1495 1496 JSValueRef LayoutTestController::originsWithLocalStorage(JSContextRef context) 1497 { 1498 // FIXME: Implement. 1499 return JSValueMakeUndefined(context); 1500 } 1501 1502 void LayoutTestController::deleteLocalStorageForOrigin(JSStringRef URL) 1503 { 1504 // FIXME: Implement. 1505 } 1506 1507 void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval) 1508 { 1509 COMPtr<IWebView> webView; 1510 if (FAILED(frame->webView(&webView))) 1511 return; 1512 1513 COMPtr<IWebViewPrivate> viewPrivate(Query, webView); 1514 if (!viewPrivate) 1515 return; 1516 1517 viewPrivate->setMinimumTimerInterval(minimumTimerInterval); 1518 } 1519 1520 1521