1 /* 2 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 3 * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 #include "config.h" 30 #include "LayoutTestControllerQt.h" 31 #include "DumpRenderTreeSupportQt.h" 32 33 #include "DumpRenderTreeQt.h" 34 #include "WorkQueue.h" 35 #include "WorkQueueItemQt.h" 36 #include <QDir> 37 #include <QLocale> 38 #include <qwebsettings.h> 39 40 LayoutTestController::LayoutTestController(WebCore::DumpRenderTree* drt) 41 : QObject() 42 , m_drt(drt) 43 { 44 qRegisterMetaType<QWebElement>("QWebElement"); 45 reset(); 46 DumpRenderTreeSupportQt::dumpNotification(true); 47 } 48 49 void LayoutTestController::reset() 50 { 51 m_hasDumped = false; 52 m_loadFinished = false; 53 m_textDump = false; 54 m_dumpBackForwardList = false; 55 m_dumpChildrenAsText = false; 56 m_dumpChildFrameScrollPositions = false; 57 m_canOpenWindows = false; 58 m_waitForDone = false; 59 m_dumpTitleChanges = false; 60 m_dumpDatabaseCallbacks = false; 61 m_dumpApplicationCacheDelegateCallbacks = false; 62 m_dumpStatusCallbacks = false; 63 m_timeoutTimer.stop(); 64 m_topLoadingFrame = 0; 65 m_waitForPolicy = false; 66 m_handleErrorPages = false; 67 m_webHistory = 0; 68 m_globalFlag = false; 69 m_userStyleSheetEnabled = false; 70 m_desktopNotificationAllowedOrigins.clear(); 71 m_ignoreDesktopNotification = false; 72 m_isGeolocationPermissionSet = false; 73 m_isPrinting = false; 74 m_geolocationPermission = false; 75 76 DumpRenderTreeSupportQt::dumpEditingCallbacks(false); 77 DumpRenderTreeSupportQt::dumpFrameLoader(false); 78 DumpRenderTreeSupportQt::dumpUserGestureInFrameLoader(false); 79 DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(false); 80 DumpRenderTreeSupportQt::dumpResourceResponseMIMETypes(false); 81 DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(true); 82 DumpRenderTreeSupportQt::setWillSendRequestReturnsNullOnRedirect(false); 83 DumpRenderTreeSupportQt::setWillSendRequestReturnsNull(false); 84 DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(QStringList()); 85 DumpRenderTreeSupportQt::clearScriptWorlds(); 86 DumpRenderTreeSupportQt::setCustomPolicyDelegate(false, false); 87 DumpRenderTreeSupportQt::dumpHistoryCallbacks(false); 88 DumpRenderTreeSupportQt::dumpVisitedLinksCallbacks(false); 89 DumpRenderTreeSupportQt::resetGeolocationMock(m_drt->webPage()); 90 setIconDatabaseEnabled(false); 91 clearAllDatabases(); 92 93 emit hidePage(); 94 } 95 96 void LayoutTestController::processWork() 97 { 98 // qDebug() << ">>>processWork"; 99 100 // if we didn't start a new load, then we finished all the commands, so we're ready to dump state 101 if (WorkQueue::shared()->processWork() && !shouldWaitUntilDone()) { 102 emit done(); 103 m_hasDumped = true; 104 } 105 } 106 107 // Called on loadFinished on WebPage 108 void LayoutTestController::maybeDump(bool success) 109 { 110 111 // This can happen on any of the http/tests/security/window-events-*.html tests, where the test opens 112 // a new window, calls the unload and load event handlers on the window's page, and then immediately 113 // issues a notifyDone. Needs investigation. 114 if (!m_topLoadingFrame) 115 return; 116 117 // It is possible that we get called by windows created from the main page that have finished 118 // loading, so we don't ASSERT here. At the moment we do not gather results from such windows, 119 // but may need to in future. 120 if (sender() != m_topLoadingFrame->page()) 121 return; 122 123 m_loadFinished = true; 124 // as the function is called on loadFinished, the test might 125 // already have dumped and thus no longer be active, thus 126 // bail out here. 127 if (m_hasDumped) 128 return; 129 130 WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test 131 if (WorkQueue::shared()->count()) 132 QTimer::singleShot(0, this, SLOT(processWork())); 133 else if (!shouldWaitUntilDone()) { 134 if (success) 135 emit done(); 136 m_hasDumped = true; 137 } 138 } 139 140 void LayoutTestController::waitUntilDone() 141 { 142 //qDebug() << ">>>>waitForDone"; 143 m_waitForDone = true; 144 m_timeoutTimer.start(30000, this); 145 } 146 147 QString LayoutTestController::counterValueForElementById(const QString& id) 148 { 149 return DumpRenderTreeSupportQt::counterValueForElementById(m_drt->webPage()->mainFrame(), id); 150 } 151 152 void LayoutTestController::setViewModeMediaFeature(const QString& mode) 153 { 154 m_drt->webPage()->setProperty("_q_viewMode", mode); 155 } 156 157 int LayoutTestController::webHistoryItemCount() 158 { 159 if (!m_webHistory) 160 return -1; 161 162 // Subtract one here as our QWebHistory::count() includes the actual page, 163 // which is not considered in the DRT tests. 164 return m_webHistory->count() - 1; 165 } 166 167 void LayoutTestController::keepWebHistory() 168 { 169 m_webHistory = m_drt->webPage()->history(); 170 } 171 172 void LayoutTestController::notifyDone() 173 { 174 qDebug() << ">>>>notifyDone"; 175 176 if (!m_timeoutTimer.isActive()) 177 return; 178 179 m_timeoutTimer.stop(); 180 m_waitForDone = false; 181 182 // If the page has not finished loading (i.e. loadFinished() has not been emitted) then 183 // content created by the likes of document.write() JS methods will not be available yet. 184 // When the page has finished loading, maybeDump above will dump the results now that we have 185 // just set shouldWaitUntilDone to false. 186 if (!m_loadFinished) 187 return; 188 189 emit done(); 190 191 // FIXME: investigate why always resetting these result in timeouts 192 m_hasDumped = true; 193 m_waitForPolicy = false; 194 } 195 196 int LayoutTestController::windowCount() 197 { 198 return m_drt->windowCount(); 199 } 200 201 void LayoutTestController::grantDesktopNotificationPermission(const QString& origin) 202 { 203 QWebFrame* frame = m_drt->webPage()->mainFrame(); 204 m_drt->webPage()->setFeaturePermission(frame, QWebPage::Notifications, QWebPage::PermissionGrantedByUser); 205 m_desktopNotificationAllowedOrigins.append(origin); 206 } 207 208 void LayoutTestController::ignoreDesktopNotificationPermissionRequests() 209 { 210 m_ignoreDesktopNotification = true; 211 } 212 213 bool LayoutTestController::checkDesktopNotificationPermission(const QString& origin) 214 { 215 return !m_ignoreDesktopNotification && m_desktopNotificationAllowedOrigins.contains(origin); 216 } 217 218 void LayoutTestController::simulateDesktopNotificationClick(const QString& title) 219 { 220 DumpRenderTreeSupportQt::simulateDesktopNotificationClick(title); 221 } 222 223 void LayoutTestController::display() 224 { 225 emit showPage(); 226 } 227 228 void LayoutTestController::clearBackForwardList() 229 { 230 m_drt->webPage()->history()->clear(); 231 } 232 233 QString LayoutTestController::pathToLocalResource(const QString& url) 234 { 235 // Function introduced in r28690. 236 return QDir::toNativeSeparators(url); 237 } 238 239 void LayoutTestController::dumpConfigurationForViewport(int deviceDPI, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight) 240 { 241 QString res = DumpRenderTreeSupportQt::viewportAsText(m_drt->webPage(), deviceDPI, QSize(deviceWidth, deviceHeight), QSize(availableWidth, availableHeight)); 242 fputs(qPrintable(res), stdout); 243 } 244 245 void LayoutTestController::dumpEditingCallbacks() 246 { 247 qDebug() << ">>>dumpEditingCallbacks"; 248 DumpRenderTreeSupportQt::dumpEditingCallbacks(true); 249 } 250 251 void LayoutTestController::dumpFrameLoadCallbacks() 252 { 253 DumpRenderTreeSupportQt::dumpFrameLoader(true); 254 } 255 256 void LayoutTestController::dumpUserGestureInFrameLoadCallbacks() 257 { 258 DumpRenderTreeSupportQt::dumpUserGestureInFrameLoader(true); 259 } 260 261 void LayoutTestController::dumpResourceLoadCallbacks() 262 { 263 DumpRenderTreeSupportQt::dumpResourceLoadCallbacks(true); 264 } 265 266 void LayoutTestController::dumpResourceResponseMIMETypes() 267 { 268 DumpRenderTreeSupportQt::dumpResourceResponseMIMETypes(true); 269 } 270 271 void LayoutTestController::dumpHistoryCallbacks() 272 { 273 DumpRenderTreeSupportQt::dumpHistoryCallbacks(true); 274 } 275 276 void LayoutTestController::setWillSendRequestReturnsNullOnRedirect(bool enabled) 277 { 278 DumpRenderTreeSupportQt::setWillSendRequestReturnsNullOnRedirect(enabled); 279 } 280 281 void LayoutTestController::setWillSendRequestReturnsNull(bool enabled) 282 { 283 DumpRenderTreeSupportQt::setWillSendRequestReturnsNull(enabled); 284 } 285 286 void LayoutTestController::setWillSendRequestClearHeader(const QStringList& headers) 287 { 288 DumpRenderTreeSupportQt::setWillSendRequestClearHeaders(headers); 289 } 290 291 void LayoutTestController::setDeferMainResourceDataLoad(bool defer) 292 { 293 DumpRenderTreeSupportQt::setDeferMainResourceDataLoad(defer); 294 } 295 296 void LayoutTestController::queueBackNavigation(int howFarBackward) 297 { 298 //qDebug() << ">>>queueBackNavigation" << howFarBackward; 299 for (int i = 0; i != howFarBackward; ++i) 300 WorkQueue::shared()->queue(new BackItem(1, m_drt->webPage())); 301 } 302 303 void LayoutTestController::queueForwardNavigation(int howFarForward) 304 { 305 //qDebug() << ">>>queueForwardNavigation" << howFarForward; 306 for (int i = 0; i != howFarForward; ++i) 307 WorkQueue::shared()->queue(new ForwardItem(1, m_drt->webPage())); 308 } 309 310 void LayoutTestController::queueLoad(const QString& url, const QString& target) 311 { 312 //qDebug() << ">>>queueLoad" << url << target; 313 QUrl mainResourceUrl = m_drt->webPage()->mainFrame()->url(); 314 QString absoluteUrl = mainResourceUrl.resolved(QUrl(url)).toEncoded(); 315 WorkQueue::shared()->queue(new LoadItem(absoluteUrl, target, m_drt->webPage())); 316 } 317 318 void LayoutTestController::queueLoadHTMLString(const QString& content, const QString& baseURL, const QString& failingURL) 319 { 320 if (failingURL.isEmpty()) 321 WorkQueue::shared()->queue(new LoadHTMLStringItem(content, baseURL, m_drt->webPage())); 322 else 323 WorkQueue::shared()->queue(new LoadAlternateHTMLStringItem(content, baseURL, failingURL, m_drt->webPage())); 324 } 325 326 void LayoutTestController::queueReload() 327 { 328 //qDebug() << ">>>queueReload"; 329 WorkQueue::shared()->queue(new ReloadItem(m_drt->webPage())); 330 } 331 332 void LayoutTestController::queueLoadingScript(const QString& script) 333 { 334 //qDebug() << ">>>queueLoadingScript" << script; 335 WorkQueue::shared()->queue(new LoadingScriptItem(script, m_drt->webPage())); 336 } 337 338 void LayoutTestController::queueNonLoadingScript(const QString& script) 339 { 340 //qDebug() << ">>>queueNonLoadingScript" << script; 341 WorkQueue::shared()->queue(new NonLoadingScriptItem(script, m_drt->webPage())); 342 } 343 344 void LayoutTestController::provisionalLoad() 345 { 346 QWebFrame* frame = qobject_cast<QWebFrame*>(sender()); 347 if (!m_topLoadingFrame && !m_hasDumped) 348 m_topLoadingFrame = frame; 349 } 350 351 void LayoutTestController::timerEvent(QTimerEvent *ev) 352 { 353 if (ev->timerId() == m_timeoutTimer.timerId()) { 354 const char* message = "FAIL: Timed out waiting for notifyDone to be called\n"; 355 fprintf(stderr, "%s", message); 356 fprintf(stdout, "%s", message); 357 notifyDone(); 358 } else 359 QObject::timerEvent(ev); 360 } 361 362 QString LayoutTestController::encodeHostName(const QString& host) 363 { 364 QString encoded = QString::fromLatin1(QUrl::toAce(host + QLatin1String(".no"))); 365 encoded.truncate(encoded.length() - 3); // strip .no 366 return encoded; 367 } 368 369 QString LayoutTestController::decodeHostName(const QString& host) 370 { 371 QString decoded = QUrl::fromAce(host.toLatin1() + QByteArray(".no")); 372 decoded.truncate(decoded.length() - 3); 373 return decoded; 374 } 375 376 void LayoutTestController::setMediaType(const QString& type) 377 { 378 DumpRenderTreeSupportQt::setMediaType(m_drt->webPage()->mainFrame(), type); 379 } 380 381 void LayoutTestController::closeWebInspector() 382 { 383 DumpRenderTreeSupportQt::webInspectorClose(m_drt->webPage()); 384 m_drt->webPage()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, false); 385 } 386 387 void LayoutTestController::setDeveloperExtrasEnabled(bool enabled) 388 { 389 m_drt->webPage()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enabled); 390 } 391 392 void LayoutTestController::setAsynchronousSpellCheckingEnabled(bool) 393 { 394 // FIXME: Implement this. 395 } 396 397 void LayoutTestController::showWebInspector() 398 { 399 m_drt->webPage()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); 400 DumpRenderTreeSupportQt::webInspectorShow(m_drt->webPage()); 401 } 402 403 void LayoutTestController::evaluateInWebInspector(long callId, const QString& script) 404 { 405 DumpRenderTreeSupportQt::webInspectorExecuteScript(m_drt->webPage(), callId, script); 406 } 407 408 void LayoutTestController::setFrameFlatteningEnabled(bool enabled) 409 { 410 DumpRenderTreeSupportQt::setFrameFlatteningEnabled(m_drt->webPage(), enabled); 411 } 412 413 void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled) 414 { 415 m_drt->webPage()->settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, enabled); 416 } 417 418 void LayoutTestController::setAllowFileAccessFromFileURLs(bool enabled) 419 { 420 m_drt->webPage()->settings()->setAttribute(QWebSettings::LocalContentCanAccessFileUrls, enabled); 421 } 422 423 void LayoutTestController::setAppCacheMaximumSize(unsigned long long quota) 424 { 425 m_drt->webPage()->settings()->setOfflineWebApplicationCacheQuota(quota); 426 } 427 428 void LayoutTestController::setJavaScriptProfilingEnabled(bool enable) 429 { 430 setDeveloperExtrasEnabled(enable); 431 DumpRenderTreeSupportQt::setJavaScriptProfilingEnabled(m_topLoadingFrame, enable); 432 } 433 434 void LayoutTestController::setTimelineProfilingEnabled(bool enable) 435 { 436 DumpRenderTreeSupportQt::setTimelineProfilingEnabled(m_drt->webPage(), enable); 437 } 438 439 void LayoutTestController::setFixedContentsSize(int width, int height) 440 { 441 m_topLoadingFrame->page()->setPreferredContentsSize(QSize(width, height)); 442 } 443 444 void LayoutTestController::setPrivateBrowsingEnabled(bool enable) 445 { 446 m_drt->webPage()->settings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, enable); 447 } 448 449 void LayoutTestController::setSpatialNavigationEnabled(bool enable) 450 { 451 m_drt->webPage()->settings()->setAttribute(QWebSettings::SpatialNavigationEnabled, enable); 452 } 453 454 void LayoutTestController::setPopupBlockingEnabled(bool enable) 455 { 456 m_drt->webPage()->settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, !enable); 457 } 458 459 void LayoutTestController::setPluginsEnabled(bool flag) 460 { 461 // FIXME: Implement 462 } 463 464 void LayoutTestController::setPOSIXLocale(const QString& locale) 465 { 466 QLocale qlocale(locale); 467 QLocale::setDefault(qlocale); 468 } 469 470 void LayoutTestController::setWindowIsKey(bool isKey) 471 { 472 m_drt->switchFocus(isKey); 473 } 474 475 void LayoutTestController::setMainFrameIsFirstResponder(bool isFirst) 476 { 477 //FIXME: only need this for the moment: https://bugs.webkit.org/show_bug.cgi?id=32990 478 } 479 480 void LayoutTestController::setJavaScriptCanAccessClipboard(bool enable) 481 { 482 m_drt->webPage()->settings()->setAttribute(QWebSettings::JavascriptCanAccessClipboard, enable); 483 } 484 485 void LayoutTestController::setXSSAuditorEnabled(bool enable) 486 { 487 // Set XSSAuditingEnabled globally so that windows created by the test inherit it too. 488 // resetSettings() will call this to reset the page and global setting to false again. 489 // Needed by http/tests/security/xssAuditor/link-opens-new-window.html 490 QWebSettings* globalSettings = QWebSettings::globalSettings(); 491 globalSettings->setAttribute(QWebSettings::XSSAuditingEnabled, enable); 492 m_drt->webPage()->settings()->setAttribute(QWebSettings::XSSAuditingEnabled, enable); 493 } 494 495 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(const QString& animationName, 496 double time, 497 const QString& elementId) 498 { 499 QWebFrame* frame = m_drt->webPage()->mainFrame(); 500 Q_ASSERT(frame); 501 return DumpRenderTreeSupportQt::pauseAnimation(frame, animationName, time, elementId); 502 } 503 504 bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(const QString& propertyName, 505 double time, 506 const QString& elementId) 507 { 508 QWebFrame* frame = m_drt->webPage()->mainFrame(); 509 Q_ASSERT(frame); 510 return DumpRenderTreeSupportQt::pauseTransitionOfProperty(frame, propertyName, time, elementId); 511 } 512 513 bool LayoutTestController::sampleSVGAnimationForElementAtTime(const QString& animationId, 514 double time, 515 const QString& elementId) 516 { 517 QWebFrame* frame = m_drt->webPage()->mainFrame(); 518 Q_ASSERT(frame); 519 return DumpRenderTreeSupportQt::pauseSVGAnimation(frame, animationId, time, elementId); 520 } 521 522 unsigned LayoutTestController::numberOfActiveAnimations() const 523 { 524 QWebFrame* frame = m_drt->webPage()->mainFrame(); 525 Q_ASSERT(frame); 526 return DumpRenderTreeSupportQt::numberOfActiveAnimations(frame); 527 } 528 529 void LayoutTestController::suspendAnimations() const 530 { 531 QWebFrame* frame = m_drt->webPage()->mainFrame(); 532 Q_ASSERT(frame); 533 DumpRenderTreeSupportQt::suspendAnimations(frame); 534 } 535 536 void LayoutTestController::resumeAnimations() const 537 { 538 QWebFrame* frame = m_drt->webPage()->mainFrame(); 539 Q_ASSERT(frame); 540 DumpRenderTreeSupportQt::resumeAnimations(frame); 541 } 542 543 void LayoutTestController::disableImageLoading() 544 { 545 m_drt->webPage()->settings()->setAttribute(QWebSettings::AutoLoadImages, false); 546 } 547 548 void LayoutTestController::dispatchPendingLoadRequests() 549 { 550 // FIXME: Implement for testing fix for 6727495 551 } 552 553 void LayoutTestController::clearAllApplicationCaches() 554 { 555 DumpRenderTreeSupportQt::clearAllApplicationCaches(); 556 } 557 558 void LayoutTestController::clearApplicationCacheForOrigin(const QString& url) 559 { 560 // FIXME: Implement to support deleting all application caches for an origin. 561 } 562 563 void LayoutTestController::setApplicationCacheOriginQuota(unsigned long long quota) 564 { 565 if (!m_topLoadingFrame) 566 return; 567 m_topLoadingFrame->securityOrigin().setApplicationCacheQuota(quota); 568 } 569 570 QStringList LayoutTestController::originsWithApplicationCache() 571 { 572 // FIXME: Implement to get origins that have application caches. 573 return QStringList(); 574 } 575 576 void LayoutTestController::setDatabaseQuota(int size) 577 { 578 if (!m_topLoadingFrame) 579 return; 580 m_topLoadingFrame->securityOrigin().setDatabaseQuota(size); 581 } 582 583 void LayoutTestController::clearAllDatabases() 584 { 585 QWebDatabase::removeAllDatabases(); 586 } 587 588 void LayoutTestController::addOriginAccessWhitelistEntry(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains) 589 { 590 DumpRenderTreeSupportQt::whiteListAccessFromOrigin(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains); 591 } 592 593 void LayoutTestController::removeOriginAccessWhitelistEntry(const QString& sourceOrigin, const QString& destinationProtocol, const QString& destinationHost, bool allowDestinationSubdomains) 594 { 595 DumpRenderTreeSupportQt::removeWhiteListAccessFromOrigin(sourceOrigin, destinationProtocol, destinationHost, allowDestinationSubdomains); 596 } 597 598 void LayoutTestController::setCustomPolicyDelegate(bool enabled, bool permissive) 599 { 600 DumpRenderTreeSupportQt::setCustomPolicyDelegate(enabled, permissive); 601 } 602 603 void LayoutTestController::waitForPolicyDelegate() 604 { 605 m_waitForPolicy = true; 606 waitUntilDone(); 607 } 608 609 void LayoutTestController::overridePreference(const QString& name, const QVariant& value) 610 { 611 QWebSettings* settings = m_topLoadingFrame->page()->settings(); 612 613 if (name == "WebKitJavaScriptEnabled") 614 settings->setAttribute(QWebSettings::JavascriptEnabled, value.toBool()); 615 else if (name == "WebKitTabToLinksPreferenceKey") 616 settings->setAttribute(QWebSettings::LinksIncludedInFocusChain, value.toBool()); 617 else if (name == "WebKitOfflineWebApplicationCacheEnabled") 618 settings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, value.toBool()); 619 else if (name == "WebKitDefaultFontSize") 620 settings->setFontSize(QWebSettings::DefaultFontSize, value.toInt()); 621 else if (name == "WebKitUsesPageCachePreferenceKey") 622 QWebSettings::setMaximumPagesInCache(value.toInt()); 623 else if (name == "WebKitEnableCaretBrowsing") 624 setCaretBrowsingEnabled(value.toBool()); 625 else if (name == "WebKitPluginsEnabled") 626 settings->setAttribute(QWebSettings::PluginsEnabled, value.toBool()); 627 else if (name == "WebKitWebGLEnabled") 628 settings->setAttribute(QWebSettings::WebGLEnabled, value.toBool()); 629 else if (name == "WebKitHyperlinkAuditingEnabled") 630 settings->setAttribute(QWebSettings::HyperlinkAuditingEnabled, value.toBool()); 631 else 632 printf("ERROR: LayoutTestController::overridePreference() does not support the '%s' preference\n", 633 name.toLatin1().data()); 634 } 635 636 void LayoutTestController::setUserStyleSheetLocation(const QString& url) 637 { 638 m_userStyleSheetLocation = QUrl::fromEncoded(url.toAscii(), QUrl::StrictMode); 639 640 if (m_userStyleSheetEnabled) 641 setUserStyleSheetEnabled(true); 642 } 643 644 void LayoutTestController::setCaretBrowsingEnabled(bool value) 645 { 646 DumpRenderTreeSupportQt::setCaretBrowsingEnabled(m_drt->webPage(), value); 647 } 648 649 void LayoutTestController::setUserStyleSheetEnabled(bool enabled) 650 { 651 m_userStyleSheetEnabled = enabled; 652 653 if (enabled) 654 m_drt->webPage()->settings()->setUserStyleSheetUrl(m_userStyleSheetLocation); 655 else 656 m_drt->webPage()->settings()->setUserStyleSheetUrl(QUrl()); 657 } 658 659 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const QString& scheme) 660 { 661 DumpRenderTreeSupportQt::setDomainRelaxationForbiddenForURLScheme(forbidden, scheme); 662 } 663 664 int LayoutTestController::workerThreadCount() 665 { 666 return DumpRenderTreeSupportQt::workerThreadCount(); 667 } 668 669 int LayoutTestController::pageNumberForElementById(const QString& id, float width, float height) 670 { 671 // If no size specified, webpage viewport size is used 672 if (!width && !height) { 673 width = m_drt->webPage()->viewportSize().width(); 674 height = m_drt->webPage()->viewportSize().height(); 675 } 676 677 return DumpRenderTreeSupportQt::pageNumberForElementById(m_drt->webPage()->mainFrame(), id, width, height); 678 } 679 680 int LayoutTestController::numberOfPages(float width, float height) 681 { 682 return DumpRenderTreeSupportQt::numberOfPages(m_drt->webPage()->mainFrame(), width, height); 683 } 684 685 bool LayoutTestController::callShouldCloseOnWebView() 686 { 687 return DumpRenderTreeSupportQt::shouldClose(m_drt->webPage()->mainFrame()); 688 } 689 690 void LayoutTestController::setScrollbarPolicy(const QString& orientation, const QString& policy) 691 { 692 Qt::Orientation o; 693 Qt::ScrollBarPolicy p; 694 695 if (orientation == "vertical") 696 o = Qt::Vertical; 697 else if (orientation == "horizontal") 698 o = Qt::Horizontal; 699 else 700 return; 701 702 if (policy == "on") 703 p = Qt::ScrollBarAlwaysOn; 704 else if (policy == "auto") 705 p = Qt::ScrollBarAsNeeded; 706 else if (policy == "off") 707 p = Qt::ScrollBarAlwaysOff; 708 else 709 return; 710 711 m_drt->webPage()->mainFrame()->setScrollBarPolicy(o, p); 712 } 713 714 void LayoutTestController::setSmartInsertDeleteEnabled(bool enable) 715 { 716 DumpRenderTreeSupportQt::setSmartInsertDeleteEnabled(m_drt->webPage(), enable); 717 } 718 719 void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool enable) 720 { 721 DumpRenderTreeSupportQt::setSelectTrailingWhitespaceEnabled(m_drt->webPage(), enable); 722 } 723 724 void LayoutTestController::execCommand(const QString& name, const QString& value) 725 { 726 DumpRenderTreeSupportQt::executeCoreCommandByName(m_drt->webPage(), name, value); 727 } 728 729 bool LayoutTestController::isCommandEnabled(const QString& name) const 730 { 731 return DumpRenderTreeSupportQt::isCommandEnabled(m_drt->webPage(), name); 732 } 733 734 bool LayoutTestController::findString(const QString& string, const QStringList& optionArray) 735 { 736 return DumpRenderTreeSupportQt::findString(m_drt->webPage(), string, optionArray); 737 } 738 739 QString LayoutTestController::markerTextForListItem(const QWebElement& listItem) 740 { 741 return DumpRenderTreeSupportQt::markerTextForListItem(listItem); 742 } 743 744 QVariantMap LayoutTestController::computedStyleIncludingVisitedInfo(const QWebElement& element) const 745 { 746 return DumpRenderTreeSupportQt::computedStyleIncludingVisitedInfo(element); 747 } 748 749 bool LayoutTestController::elementDoesAutoCompleteForElementWithId(const QString& elementId) 750 { 751 return DumpRenderTreeSupportQt::elementDoesAutoCompleteForElementWithId(m_drt->webPage()->mainFrame(), elementId); 752 } 753 754 void LayoutTestController::authenticateSession(const QString&, const QString&, const QString&) 755 { 756 // FIXME: If there is a concept per-session (per-process) credential storage, the credentials should be added to it for later use. 757 } 758 759 void LayoutTestController::setIconDatabaseEnabled(bool enable) 760 { 761 if (enable && !m_drt->persistentStoragePath().isEmpty()) 762 QWebSettings::setIconDatabasePath(m_drt->persistentStoragePath()); 763 else 764 QWebSettings::setIconDatabasePath(QString()); 765 } 766 767 void LayoutTestController::setEditingBehavior(const QString& editingBehavior) 768 { 769 DumpRenderTreeSupportQt::setEditingBehavior(m_drt->webPage(), editingBehavior); 770 } 771 772 void LayoutTestController::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma) 773 { 774 DumpRenderTreeSupportQt::setMockDeviceOrientation(canProvideAlpha, alpha, canProvideBeta, beta, canProvideGamma, gamma); 775 } 776 777 void LayoutTestController::setGeolocationPermission(bool allow) 778 { 779 setGeolocationPermissionCommon(allow); 780 DumpRenderTreeSupportQt::setMockGeolocationPermission(m_drt->webPage(), allow); 781 } 782 783 QVariant LayoutTestController::shadowRoot(const QWebElement& element) 784 { 785 return DumpRenderTreeSupportQt::shadowRoot(element); 786 } 787 788 int LayoutTestController::numberOfPendingGeolocationPermissionRequests() 789 { 790 int pendingPermissionCount = 0; 791 QList<WebCore::WebPage*> pages = m_drt->getAllPages(); 792 foreach (WebCore::WebPage* page, pages) 793 pendingPermissionCount += DumpRenderTreeSupportQt::numberOfPendingGeolocationPermissionRequests(page); 794 795 return pendingPermissionCount; 796 } 797 798 void LayoutTestController::setGeolocationPermissionCommon(bool allow) 799 { 800 m_isGeolocationPermissionSet = true; 801 m_geolocationPermission = allow; 802 } 803 804 void LayoutTestController::setMockGeolocationError(int code, const QString& message) 805 { 806 DumpRenderTreeSupportQt::setMockGeolocationError(m_drt->webPage(), code, message); 807 } 808 809 void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy) 810 { 811 DumpRenderTreeSupportQt::setMockGeolocationPosition(m_drt->webPage(), latitude, longitude, accuracy); 812 } 813 814 void LayoutTestController::addMockSpeechInputResult(const QString& result, double confidence, const QString& language) 815 { 816 // FIXME: Implement for speech input layout tests. 817 // See https://bugs.webkit.org/show_bug.cgi?id=39485. 818 } 819 820 void LayoutTestController::evaluateScriptInIsolatedWorld(int worldID, const QString& script) 821 { 822 DumpRenderTreeSupportQt::evaluateScriptInIsolatedWorld(m_drt->webPage()->mainFrame(), worldID, script); 823 } 824 825 bool LayoutTestController::isPageBoxVisible(int pageIndex) 826 { 827 return DumpRenderTreeSupportQt::isPageBoxVisible(m_drt->webPage()->mainFrame(), pageIndex); 828 } 829 830 QString LayoutTestController::pageSizeAndMarginsInPixels(int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) 831 { 832 return DumpRenderTreeSupportQt::pageSizeAndMarginsInPixels(m_drt->webPage()->mainFrame(), pageIndex, 833 width, height, marginTop, marginRight, marginBottom, marginLeft); 834 } 835 836 QString LayoutTestController::pageProperty(const QString& propertyName, int pageNumber) 837 { 838 return DumpRenderTreeSupportQt::pageProperty(m_drt->webPage()->mainFrame(), propertyName, pageNumber); 839 } 840 841 void LayoutTestController::addUserStyleSheet(const QString& sourceCode) 842 { 843 DumpRenderTreeSupportQt::addUserStyleSheet(m_drt->webPage(), sourceCode); 844 } 845 846 void LayoutTestController::removeAllVisitedLinks() 847 { 848 QWebHistory* history = m_drt->webPage()->history(); 849 history->clear(); 850 DumpRenderTreeSupportQt::dumpVisitedLinksCallbacks(true); 851 } 852 853 bool LayoutTestController::hasSpellingMarker(int, int) 854 { 855 // FIXME: Implement. 856 return false; 857 } 858 859 QVariantList LayoutTestController::nodesFromRect(const QWebElement& document, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping) 860 { 861 return DumpRenderTreeSupportQt::nodesFromRect(document, x, y, top, right, bottom, left, ignoreClipping); 862 } 863 864 void LayoutTestController::addURLToRedirect(const QString& origin, const QString& destination) 865 { 866 DumpRenderTreeSupportQt::addURLToRedirect(origin, destination); 867 } 868 869 void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval) 870 { 871 DumpRenderTreeSupportQt::setMinimumTimerInterval(m_drt->webPage(), minimumTimerInterval); 872 } 873 874 void LayoutTestController::originsWithLocalStorage() 875 { 876 // FIXME: Implement. 877 } 878 879 void LayoutTestController::deleteAllLocalStorage() 880 { 881 // FIXME: Implement. 882 } 883 884 void LayoutTestController::deleteLocalStorageForOrigin(const QString& originIdentifier) 885 { 886 // FIXME: Implement. 887 } 888 889 void LayoutTestController::observeStorageTrackerNotifications(unsigned number) 890 { 891 // FIXME: Implement. 892 } 893 894 void LayoutTestController::syncLocalStorage() 895 { 896 // FIXME: Implement. 897 } 898 899 const unsigned LayoutTestController::maxViewWidth = 800; 900 const unsigned LayoutTestController::maxViewHeight = 600; 901