Home | History | Annotate | Download | only in qt
      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