Home | History | Annotate | Download | only in WebCoreSupport
      1 /*
      2  * Copyright (C) 2006 Zack Rusin <zack (at) kde.org>
      3  * Copyright (C) 2006, 2011 Apple Inc. All rights reserved.
      4  * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
      5  * Copyright (C) 2008 Collabora Ltd. All rights reserved.
      6  * Coypright (C) 2008 Holger Hans Peter Freyther
      7  * Coypright (C) 2009, 2010 Girish Ramakrishnan <girish (at) forwardbias.in>
      8  *
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     28  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #include "config.h"
     34 #include "FrameLoaderClientQt.h"
     35 
     36 #include "CSSComputedStyleDeclaration.h"
     37 #include "CSSPropertyNames.h"
     38 #include "DocumentLoader.h"
     39 #include "FormState.h"
     40 #include "FrameNetworkingContextQt.h"
     41 #include "FrameTree.h"
     42 #include "FrameView.h"
     43 #include "HTMLAppletElement.h"
     44 #include "HTMLFormElement.h"
     45 #include "HTMLPlugInElement.h"
     46 #include "HTTPParsers.h"
     47 #include "HistoryItem.h"
     48 #include "HitTestResult.h"
     49 #if ENABLE(ICONDATABASE)
     50 #include "IconDatabaseClientQt.h"
     51 #endif
     52 #if USE(JSC)
     53 #include "JSDOMWindowBase.h"
     54 #endif
     55 #include "MIMETypeRegistry.h"
     56 #include "MouseEvent.h"
     57 #include "NotImplemented.h"
     58 #include "Page.h"
     59 #include "PluginData.h"
     60 #include "PluginDatabase.h"
     61 #include "ProgressTracker.h"
     62 #include "QNetworkReplyHandler.h"
     63 #include "QWebPageClient.h"
     64 #include "RenderPart.h"
     65 #include "ResourceHandle.h"
     66 #include "ResourceHandleInternal.h"
     67 #include "ResourceRequest.h"
     68 #include "ResourceResponse.h"
     69 #include "ScriptController.h"
     70 #include "Settings.h"
     71 #if USE(V8)
     72 #include "V8DOMWindow.h"
     73 #endif
     74 #include "ViewportArguments.h"
     75 
     76 #include "qwebframe.h"
     77 #include "qwebframe_p.h"
     78 #include "qwebhistory_p.h"
     79 #include "qwebhistoryinterface.h"
     80 #include "qwebpage.h"
     81 #include "qwebpage_p.h"
     82 #include "qwebpluginfactory.h"
     83 
     84 #include <QCoreApplication>
     85 #include <QDebug>
     86 #include <QFileInfo>
     87 #include <QGraphicsScene>
     88 #include <QGraphicsWidget>
     89 #include <QNetworkReply>
     90 #include <QNetworkRequest>
     91 #include <QStringList>
     92 #include <wtf/OwnPtr.h>
     93 
     94 static QMap<unsigned long, QString> dumpAssignedUrls;
     95 
     96 // Compare with the file "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm".
     97 static QString drtDescriptionSuitableForTestResult(WebCore::Frame* webCoreFrame)
     98 {
     99     QWebFrame* frame = QWebFramePrivate::kit(webCoreFrame);
    100     QString name = frame->frameName();
    101 
    102     bool isMainFrame = frame == frame->page()->mainFrame();
    103     if (isMainFrame) {
    104         if (!name.isEmpty())
    105             return QString::fromLatin1("main frame \"%1\"").arg(name);
    106         return QLatin1String("main frame");
    107     }
    108     if (!name.isEmpty())
    109         return QString::fromLatin1("frame \"%1\"").arg(name);
    110     return QLatin1String("frame (anonymous)");
    111 }
    112 
    113 static QString drtPrintFrameUserGestureStatus(WebCore::Frame* frame)
    114 {
    115     if (frame->loader()->isProcessingUserGesture())
    116         return QString::fromLatin1("Frame with user gesture \"%1\"").arg(QLatin1String("true"));
    117     return QString::fromLatin1("Frame with user gesture \"%1\"").arg(QLatin1String("false"));
    118 }
    119 
    120 static QString drtDescriptionSuitableForTestResult(const WebCore::KURL& kurl)
    121 {
    122     if (kurl.isEmpty() || !kurl.isLocalFile())
    123         return kurl.string();
    124     // Remove the leading path from file urls.
    125     return QString(kurl.string()).remove(WebCore::FrameLoaderClientQt::dumpResourceLoadCallbacksPath).mid(1);
    126 }
    127 
    128 static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceError& error)
    129 {
    130     QString failingURL = error.failingURL();
    131     return QString::fromLatin1("<NSError domain NSURLErrorDomain, code %1, failing URL \"%2\">").arg(error.errorCode()).arg(failingURL);
    132 }
    133 
    134 static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceRequest& request)
    135 {
    136     QString url = drtDescriptionSuitableForTestResult(request.url());
    137     QString httpMethod = request.httpMethod();
    138     QString mainDocumentUrl = drtDescriptionSuitableForTestResult(request.firstPartyForCookies());
    139     return QString::fromLatin1("<NSURLRequest URL %1, main document URL %2, http method %3>").arg(url).arg(mainDocumentUrl).arg(httpMethod);
    140 }
    141 
    142 static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceResponse& response)
    143 {
    144     QString url = drtDescriptionSuitableForTestResult(response.url());
    145     int httpStatusCode = response.httpStatusCode();
    146     return QString::fromLatin1("<NSURLResponse %1, http status code %2>").arg(url).arg(httpStatusCode);
    147 }
    148 
    149 static QString drtDescriptionSuitableForTestResult(const RefPtr<WebCore::Node> node, int exception)
    150 {
    151     QString result;
    152     if (exception) {
    153         result.append(QLatin1String("ERROR"));
    154         return result;
    155     }
    156     if (!node) {
    157         result.append(QLatin1String("NULL"));
    158         return result;
    159     }
    160     result.append(node->nodeName());
    161     RefPtr<WebCore::Node> parent = node->parentNode();
    162     if (parent) {
    163         result.append(QLatin1String(" > "));
    164         result.append(drtDescriptionSuitableForTestResult(parent, 0));
    165     }
    166     return result;
    167 }
    168 
    169 namespace WebCore {
    170 
    171 bool FrameLoaderClientQt::dumpFrameLoaderCallbacks = false;
    172 bool FrameLoaderClientQt::dumpUserGestureInFrameLoaderCallbacks = false;
    173 bool FrameLoaderClientQt::dumpResourceLoadCallbacks = false;
    174 bool FrameLoaderClientQt::sendRequestReturnsNullOnRedirect = false;
    175 bool FrameLoaderClientQt::sendRequestReturnsNull = false;
    176 bool FrameLoaderClientQt::dumpResourceResponseMIMETypes = false;
    177 bool FrameLoaderClientQt::deferMainResourceDataLoad = true;
    178 bool FrameLoaderClientQt::dumpHistoryCallbacks = false;
    179 
    180 QStringList FrameLoaderClientQt::sendRequestClearHeaders;
    181 QString FrameLoaderClientQt::dumpResourceLoadCallbacksPath;
    182 bool FrameLoaderClientQt::policyDelegateEnabled = false;
    183 bool FrameLoaderClientQt::policyDelegatePermissive = false;
    184 QMap<QString, QString> FrameLoaderClientQt::URLsToRedirect = QMap<QString, QString>();
    185 
    186 // Taken from the file "WebKit/Tools/DumpRenderTree/chromium/WebViewHost.cpp".
    187 static const char* navigationTypeToString(NavigationType type)
    188 {
    189     switch (type) {
    190     case NavigationTypeLinkClicked:
    191         return "link clicked";
    192     case NavigationTypeFormSubmitted:
    193         return "form submitted";
    194     case NavigationTypeBackForward:
    195         return "back/forward";
    196     case NavigationTypeReload:
    197         return "reload";
    198     case NavigationTypeFormResubmitted:
    199         return "form resubmitted";
    200     case NavigationTypeOther:
    201         return "other";
    202     }
    203     return "illegal value";
    204 }
    205 
    206 FrameLoaderClientQt::FrameLoaderClientQt()
    207     : m_frame(0)
    208     , m_webFrame(0)
    209     , m_pluginView(0)
    210     , m_hasSentResponseToPlugin(false)
    211     , m_hasRepresentation(false)
    212     , m_loadError(ResourceError())
    213 {
    214 }
    215 
    216 
    217 FrameLoaderClientQt::~FrameLoaderClientQt()
    218 {
    219 }
    220 
    221 void FrameLoaderClientQt::setFrame(QWebFrame* webFrame, Frame* frame)
    222 {
    223     m_webFrame = webFrame;
    224     m_frame = frame;
    225 
    226     if (!m_webFrame || !m_webFrame->page()) {
    227         qWarning("FrameLoaderClientQt::setFrame frame without Page!");
    228         return;
    229     }
    230 
    231     connect(this, SIGNAL(loadStarted()),
    232             m_webFrame->page(), SIGNAL(loadStarted()));
    233     connect(this, SIGNAL(loadStarted()),
    234             m_webFrame, SIGNAL(loadStarted()));
    235     connect(this, SIGNAL(loadProgress(int)),
    236             m_webFrame->page(), SIGNAL(loadProgress(int)));
    237     connect(this, SIGNAL(loadFinished(bool)),
    238             m_webFrame->page(), SIGNAL(loadFinished(bool)));
    239     connect(this, SIGNAL(loadFinished(bool)),
    240             m_webFrame, SIGNAL(loadFinished(bool)));
    241     connect(this, SIGNAL(titleChanged(QString)),
    242             m_webFrame, SIGNAL(titleChanged(QString)));
    243 }
    244 
    245 void FrameLoaderClientQt::callPolicyFunction(FramePolicyFunction function, PolicyAction action)
    246 {
    247     (m_frame->loader()->policyChecker()->*function)(action);
    248 }
    249 
    250 bool FrameLoaderClientQt::hasWebView() const
    251 {
    252     // notImplemented();
    253     return true;
    254 }
    255 
    256 void FrameLoaderClientQt::savePlatformDataToCachedFrame(CachedFrame*)
    257 {
    258     notImplemented();
    259 }
    260 
    261 void FrameLoaderClientQt::transitionToCommittedFromCachedFrame(CachedFrame*)
    262 {
    263 }
    264 
    265 void FrameLoaderClientQt::transitionToCommittedForNewPage()
    266 {
    267     ASSERT(m_frame);
    268     ASSERT(m_webFrame);
    269 
    270     QBrush brush = m_webFrame->page()->palette().brush(QPalette::Base);
    271     QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
    272 
    273     QWebPage* page = m_webFrame->page();
    274     const QSize preferredLayoutSize = page->preferredContentsSize();
    275 
    276     ScrollbarMode hScrollbar = (ScrollbarMode) m_webFrame->scrollBarPolicy(Qt::Horizontal);
    277     ScrollbarMode vScrollbar = (ScrollbarMode) m_webFrame->scrollBarPolicy(Qt::Vertical);
    278     bool hLock = hScrollbar != ScrollbarAuto;
    279     bool vLock = vScrollbar != ScrollbarAuto;
    280 
    281     IntSize currentVisibleContentSize = m_frame->view() ? m_frame->view()->actualVisibleContentRect().size() : IntSize();
    282 
    283     m_frame->createView(m_webFrame->page()->viewportSize(),
    284                         backgroundColor, !backgroundColor.alpha(),
    285                         preferredLayoutSize.isValid() ? IntSize(preferredLayoutSize) : IntSize(),
    286                         preferredLayoutSize.isValid(),
    287                         hScrollbar, hLock,
    288                         vScrollbar, vLock);
    289 
    290     bool isMainFrame = m_frame == m_frame->page()->mainFrame();
    291     if (isMainFrame && page->d->client) {
    292         m_frame->view()->setPaintsEntireContents(page->d->client->viewResizesToContentsEnabled());
    293         m_frame->view()->setDelegatesScrolling(page->d->client->viewResizesToContentsEnabled());
    294     }
    295 
    296     // The HistoryController will update the scroll position later if needed.
    297     m_frame->view()->setActualVisibleContentRect(IntRect(IntPoint::zero(), currentVisibleContentSize));
    298 }
    299 
    300 void FrameLoaderClientQt::didSaveToPageCache()
    301 {
    302 }
    303 
    304 void FrameLoaderClientQt::didRestoreFromPageCache()
    305 {
    306 }
    307 
    308 void FrameLoaderClientQt::dispatchDidBecomeFrameset(bool)
    309 {
    310 }
    311 
    312 void FrameLoaderClientQt::makeRepresentation(DocumentLoader*)
    313 {
    314     m_hasRepresentation = true;
    315 }
    316 
    317 
    318 void FrameLoaderClientQt::forceLayout()
    319 {
    320     FrameView* view = m_frame->view();
    321     if (view)
    322         view->layout(true);
    323 }
    324 
    325 
    326 void FrameLoaderClientQt::forceLayoutForNonHTML()
    327 {
    328 }
    329 
    330 
    331 void FrameLoaderClientQt::setCopiesOnScroll()
    332 {
    333     // Apparently this is mac specific.
    334 }
    335 
    336 
    337 void FrameLoaderClientQt::detachedFromParent2()
    338 {
    339 }
    340 
    341 
    342 void FrameLoaderClientQt::detachedFromParent3()
    343 {
    344 }
    345 
    346 void FrameLoaderClientQt::dispatchDidHandleOnloadEvents()
    347 {
    348     // Don't need this one.
    349     if (dumpFrameLoaderCallbacks)
    350         printf("%s - didHandleOnloadEventsForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    351 }
    352 
    353 
    354 void FrameLoaderClientQt::dispatchDidReceiveServerRedirectForProvisionalLoad()
    355 {
    356     if (dumpFrameLoaderCallbacks)
    357         printf("%s - didReceiveServerRedirectForProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    358 
    359     notImplemented();
    360 }
    361 
    362 
    363 void FrameLoaderClientQt::dispatchDidCancelClientRedirect()
    364 {
    365     if (dumpFrameLoaderCallbacks)
    366         printf("%s - didCancelClientRedirectForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    367 
    368     notImplemented();
    369 }
    370 
    371 
    372 void FrameLoaderClientQt::dispatchWillPerformClientRedirect(const KURL& url, double, double)
    373 {
    374     if (dumpFrameLoaderCallbacks)
    375         printf("%s - willPerformClientRedirectToURL: %s \n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(drtDescriptionSuitableForTestResult(url)));
    376 
    377     notImplemented();
    378 }
    379 
    380 
    381 void FrameLoaderClientQt::dispatchDidChangeLocationWithinPage()
    382 {
    383     if (dumpFrameLoaderCallbacks)
    384         printf("%s - didChangeLocationWithinPageForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    385 
    386     if (!m_webFrame)
    387         return;
    388 
    389     m_webFrame->d->emitUrlChanged();
    390     m_webFrame->page()->d->updateNavigationActions();
    391 }
    392 
    393 #if USE(V8)
    394 void FrameLoaderClientQt::didCreateScriptContextForFrame()
    395 {
    396 }
    397 void FrameLoaderClientQt::didDestroyScriptContextForFrame()
    398 {
    399 }
    400 void FrameLoaderClientQt::didCreateIsolatedScriptContext()
    401 {
    402 }
    403 #endif
    404 
    405 void FrameLoaderClientQt::dispatchDidPushStateWithinPage()
    406 {
    407     if (dumpFrameLoaderCallbacks)
    408         printf("%s - dispatchDidPushStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    409 
    410     notImplemented();
    411 }
    412 
    413 void FrameLoaderClientQt::dispatchDidReplaceStateWithinPage()
    414 {
    415     if (dumpFrameLoaderCallbacks)
    416         printf("%s - dispatchDidReplaceStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    417 
    418     notImplemented();
    419 }
    420 
    421 void FrameLoaderClientQt::dispatchDidPopStateWithinPage()
    422 {
    423     if (dumpFrameLoaderCallbacks)
    424         printf("%s - dispatchDidPopStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    425 
    426     notImplemented();
    427 }
    428 
    429 void FrameLoaderClientQt::dispatchWillClose()
    430 {
    431 }
    432 
    433 
    434 void FrameLoaderClientQt::dispatchDidStartProvisionalLoad()
    435 {
    436     if (dumpFrameLoaderCallbacks)
    437         printf("%s - didStartProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    438 
    439     if (dumpUserGestureInFrameLoaderCallbacks)
    440         printf("%s - in didStartProvisionalLoadForFrame\n", qPrintable(drtPrintFrameUserGestureStatus(m_frame)));
    441 
    442     m_lastRequestedUrl = m_frame->loader()->activeDocumentLoader()->requestURL();
    443 
    444     if (m_webFrame)
    445         emit m_webFrame->provisionalLoad();
    446 }
    447 
    448 
    449 void FrameLoaderClientQt::dispatchDidReceiveTitle(const StringWithDirection& title)
    450 {
    451     // FIXME: Use direction of title.
    452     if (dumpFrameLoaderCallbacks)
    453         printf("%s - didReceiveTitle: %s\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(QString(title.string())));
    454 
    455     if (!m_webFrame)
    456         return;
    457 
    458     emit titleChanged(title.string());
    459 }
    460 
    461 
    462 void FrameLoaderClientQt::dispatchDidChangeIcons()
    463 {
    464     if (dumpFrameLoaderCallbacks)
    465         printf("%s - didChangeIcons\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    466 
    467     if (!m_webFrame)
    468         return;
    469 
    470     // FIXME: In order to get notified of icon URLS' changes, add a notification.
    471     // emit iconsChanged();
    472 }
    473 
    474 
    475 void FrameLoaderClientQt::dispatchDidCommitLoad()
    476 {
    477     if (dumpFrameLoaderCallbacks)
    478         printf("%s - didCommitLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    479 
    480     if (m_frame->tree()->parent() || !m_webFrame)
    481         return;
    482 
    483     m_webFrame->d->emitUrlChanged();
    484     m_webFrame->page()->d->updateNavigationActions();
    485 
    486     // We should assume first the frame has no title. If it has, then the above dispatchDidReceiveTitle()
    487     // will be called very soon with the correct title.
    488     // This properly resets the title when we navigate to a URI without a title.
    489     emit titleChanged(QString());
    490 
    491     bool isMainFrame = (m_frame == m_frame->page()->mainFrame());
    492     if (!isMainFrame)
    493         return;
    494 
    495     emit m_webFrame->page()->viewportChangeRequested();
    496 }
    497 
    498 
    499 void FrameLoaderClientQt::dispatchDidFinishDocumentLoad()
    500 {
    501     if (dumpFrameLoaderCallbacks)
    502         printf("%s - didFinishDocumentLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    503 
    504     if (QWebPagePrivate::drtRun) {
    505         int unloadEventCount = m_frame->domWindow()->pendingUnloadEventListeners();
    506         if (unloadEventCount)
    507             printf("%s - has %u onunload handler(s)\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), unloadEventCount);
    508     }
    509 
    510     if (m_frame->tree()->parent() || !m_webFrame)
    511         return;
    512 
    513     m_webFrame->page()->d->updateNavigationActions();
    514 }
    515 
    516 
    517 void FrameLoaderClientQt::dispatchDidFinishLoad()
    518 {
    519     if (dumpFrameLoaderCallbacks)
    520         printf("%s - didFinishLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
    521 
    522     // Clears the previous error.
    523     m_loadError = ResourceError();
    524 
    525     if (!m_webFrame)
    526         return;
    527     m_webFrame->page()->d->updateNavigationActions();
    528 }
    529 
    530 
    531 void FrameLoaderClientQt::dispatchDidFirstLayout()
    532 {
    533 }
    534 
    535 void FrameLoaderClientQt::dispatchDidFirstVisuallyNonEmptyLayout()
    536 {
    537     if (m_webFrame)
    538         emit m_webFrame->initialLayoutCompleted();
    539 }
    540 
    541 void FrameLoaderClientQt::dispatchShow()
    542 {
    543     notImplemented();
    544 }
    545 
    546 
    547 void FrameLoaderClientQt::cancelPolicyCheck()
    548 {
    549     // qDebug() << "FrameLoaderClientQt::cancelPolicyCheck";
    550 }
    551 
    552 
    553 void FrameLoaderClientQt::dispatchWillSubmitForm(FramePolicyFunction function,
    554                                                  PassRefPtr<FormState>)
    555 {
    556     notImplemented();
    557     // FIXME: This is surely too simple.
    558     callPolicyFunction(function, PolicyUse);
    559 }
    560 
    561 
    562 void FrameLoaderClientQt::dispatchDidLoadMainResource(DocumentLoader*)
    563 {
    564 }
    565 
    566 
    567 void FrameLoaderClientQt::revertToProvisionalState(DocumentLoader*)
    568 {
    569     m_hasRepresentation = true;
    570 }
    571 
    572 
    573 void FrameLoaderClientQt::postProgressStartedNotification()
    574 {
    575     if (m_webFrame && m_frame->page()) {
    576         // As a new load have started, clear the previous error.
    577         m_loadError = ResourceError();
    578         emit loadStarted();
    579         postProgressEstimateChangedNotification();
    580     }
    581     if (m_frame->tree()->parent() || !m_webFrame)
    582         return;
    583     m_webFrame->page()->d->updateNavigationActions();
    584 }
    585 
    586 void FrameLoaderClientQt::postProgressEstimateChangedNotification()
    587 {
    588     if (m_webFrame && m_frame->page())
    589         emit loadProgress(qRound(m_frame->page()->progress()->estimatedProgress() * 100));
    590 }
    591 
    592 void FrameLoaderClientQt::postProgressFinishedNotification()
    593 {
    594     // Send a mousemove event to:
    595     // (1) update the cursor to change according to whatever is underneath the mouse cursor right now;
    596     // (2) display the tool tip if the mouse hovers a node which has a tool tip.
    597     if (m_frame && m_frame->eventHandler() && m_webFrame->page()) {
    598         QWidget* view = m_webFrame->page()->view();
    599         if (view && view->hasFocus()) {
    600             QPoint localPos = view->mapFromGlobal(QCursor::pos());
    601             if (view->rect().contains(localPos)) {
    602                 QMouseEvent event(QEvent::MouseMove, localPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
    603                 m_frame->eventHandler()->mouseMoved(PlatformMouseEvent(&event, 0));
    604             }
    605         }
    606     }
    607 
    608     if (m_webFrame && m_frame->page())
    609         emit loadFinished(m_loadError.isNull());
    610 }
    611 
    612 void FrameLoaderClientQt::setMainFrameDocumentReady(bool)
    613 {
    614     // This is only interesting once we provide an external API for the DOM.
    615 }
    616 
    617 
    618 void FrameLoaderClientQt::willChangeTitle(DocumentLoader*)
    619 {
    620     // No need for, dispatchDidReceiveTitle is the right callback.
    621 }
    622 
    623 
    624 void FrameLoaderClientQt::didChangeTitle(DocumentLoader*)
    625 {
    626     // No need for, dispatchDidReceiveTitle is the right callback.
    627 }
    628 
    629 
    630 void FrameLoaderClientQt::finishedLoading(DocumentLoader* loader)
    631 {
    632     if (!m_pluginView) {
    633         // This is necessary to create an empty document. See bug 634004.
    634         // However, we only want to do this if makeRepresentation has been called,
    635         // to match the behavior on the Mac.
    636         if (m_hasRepresentation)
    637             loader->writer()->setEncoding("", false);
    638         return;
    639     }
    640     if (m_pluginView->isPluginView())
    641         m_pluginView->didFinishLoading();
    642     m_pluginView = 0;
    643     m_hasSentResponseToPlugin = false;
    644 }
    645 
    646 bool FrameLoaderClientQt::canShowMIMETypeAsHTML(const String& MIMEType) const
    647 {
    648     notImplemented();
    649     return false;
    650 }
    651 
    652 bool FrameLoaderClientQt::canShowMIMEType(const String& MIMEType) const
    653 {
    654     String type = MIMEType;
    655     type.makeLower();
    656     if (MIMETypeRegistry::isSupportedImageMIMEType(type))
    657         return true;
    658 
    659     if (MIMETypeRegistry::isSupportedNonImageMIMEType(type))
    660         return true;
    661 
    662     if (m_frame && m_frame->settings()  && m_frame->settings()->arePluginsEnabled()
    663         && PluginDatabase::installedPlugins()->isMIMETypeRegistered(type))
    664         return true;
    665 
    666     return false;
    667 }
    668 
    669 bool FrameLoaderClientQt::representationExistsForURLScheme(const String&) const
    670 {
    671     return false;
    672 }
    673 
    674 
    675 String FrameLoaderClientQt::generatedMIMETypeForURLScheme(const String&) const
    676 {
    677     notImplemented();
    678     return String();
    679 }
    680 
    681 
    682 void FrameLoaderClientQt::frameLoadCompleted()
    683 {
    684     // Note that this can be called multiple times.
    685 }
    686 
    687 
    688 void FrameLoaderClientQt::restoreViewState()
    689 {
    690     if (!m_webFrame)
    691         return;
    692     emit m_webFrame->page()->restoreFrameStateRequested(m_webFrame);
    693 }
    694 
    695 
    696 void FrameLoaderClientQt::provisionalLoadStarted()
    697 {
    698     // Don't need to do anything here.
    699 }
    700 
    701 
    702 void FrameLoaderClientQt::didFinishLoad()
    703 {
    704     // notImplemented();
    705 }
    706 
    707 
    708 void FrameLoaderClientQt::prepareForDataSourceReplacement()
    709 {
    710 }
    711 
    712 void FrameLoaderClientQt::setTitle(const StringWithDirection& title, const KURL& url)
    713 {
    714     // Used by Apple WebKit to update the title of an existing history item.
    715     // QtWebKit doesn't accomodate this on history items. If it ever does,
    716     // it should be privateBrowsing-aware. For now, we are just passing
    717     // globalhistory layout tests.
    718     // FIXME: Use direction of title.
    719     if (dumpHistoryCallbacks) {
    720         printf("WebView updated the title for history URL \"%s\" to \"%s\".\n",
    721             qPrintable(drtDescriptionSuitableForTestResult(url)),
    722             qPrintable(QString(title.string())));
    723     }
    724 }
    725 
    726 
    727 String FrameLoaderClientQt::userAgent(const KURL& url)
    728 {
    729     if (m_webFrame) {
    730         return m_webFrame->page()->userAgentForUrl(url);
    731     }
    732     return String();
    733 }
    734 
    735 void FrameLoaderClientQt::dispatchDidReceiveIcon()
    736 {
    737     if (m_webFrame)
    738         emit m_webFrame->iconChanged();
    739 }
    740 
    741 void FrameLoaderClientQt::frameLoaderDestroyed()
    742 {
    743     delete m_webFrame;
    744     m_frame = 0;
    745     m_webFrame = 0;
    746 
    747     delete this;
    748 }
    749 
    750 bool FrameLoaderClientQt::canHandleRequest(const WebCore::ResourceRequest&) const
    751 {
    752     return true;
    753 }
    754 
    755 void FrameLoaderClientQt::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
    756 {
    757     if (world != mainThreadNormalWorld())
    758         return;
    759 
    760     if (m_webFrame)
    761         emit m_webFrame->javaScriptWindowObjectCleared();
    762 }
    763 
    764 void FrameLoaderClientQt::documentElementAvailable()
    765 {
    766     return;
    767 }
    768 
    769 void FrameLoaderClientQt::didPerformFirstNavigation() const
    770 {
    771     if (m_frame->tree()->parent() || !m_webFrame)
    772         return;
    773     m_webFrame->page()->d->updateNavigationActions();
    774 }
    775 
    776 void FrameLoaderClientQt::registerForIconNotification(bool shouldRegister)
    777 {
    778 #if ENABLE(ICONDATABASE)
    779     if (shouldRegister)
    780         connect(IconDatabaseClientQt::instance(), SIGNAL(iconLoadedForPageURL(QString)), this, SLOT(onIconLoadedForPageURL(QString)), Qt::UniqueConnection);
    781     else
    782         disconnect(IconDatabaseClientQt::instance(), SIGNAL(iconLoadedForPageURL(QString)), this, SLOT(onIconLoadedForPageURL(QString)));
    783 #endif
    784 }
    785 
    786 void FrameLoaderClientQt::onIconLoadedForPageURL(const QString& url)
    787 {
    788 #if ENABLE(ICONDATABASE)
    789     if (m_webFrame && m_webFrame->url() == url)
    790         emit m_webFrame->iconChanged();
    791 #endif
    792 }
    793 
    794 
    795 void FrameLoaderClientQt::updateGlobalHistory()
    796 {
    797     QWebHistoryInterface* history = QWebHistoryInterface::defaultInterface();
    798     WebCore::DocumentLoader* loader = m_frame->loader()->documentLoader();
    799     if (history)
    800         history->addHistoryEntry(loader->urlForHistory().string());
    801 
    802     if (dumpHistoryCallbacks) {
    803         printf("WebView navigated to url \"%s\" with title \"%s\" with HTTP equivalent method \"%s\".  The navigation was %s and was %s%s.\n",
    804             qPrintable(drtDescriptionSuitableForTestResult(loader->urlForHistory())),
    805             qPrintable(QString(loader->title().string())),
    806             qPrintable(QString(loader->request().httpMethod())),
    807             ((loader->substituteData().isValid() || (loader->response().httpStatusCode() >= 400)) ? "a failure" : "successful"),
    808             ((!loader->clientRedirectSourceForHistory().isEmpty()) ? "a client redirect from " : "not a client redirect"),
    809             (!loader->clientRedirectSourceForHistory().isEmpty()) ? qPrintable(drtDescriptionSuitableForTestResult(loader->clientRedirectSourceForHistory())) : "");
    810     }
    811 }
    812 
    813 void FrameLoaderClientQt::updateGlobalHistoryRedirectLinks()
    814 {
    815     // Apple WebKit is the only port that makes use of this callback. It calls
    816     // WebCore::HistoryItem::addRedirectURL() with the contents of
    817     // loader->[server|client]RedirectDestinationForHistory().
    818     // WebCore can associate a bunch of redirect URLs with a particular
    819     // item in the history, presumably this allows Safari to skip the redirections
    820     // when navigating to that history item. That might be a feature Qt wants to
    821     // offer through QWebHistoryInterface in the future. For now, we're just
    822     // passing tests in LayoutTests/http/tests/globalhistory.
    823     WebCore::DocumentLoader* loader = m_frame->loader()->documentLoader();
    824 
    825     if (!loader->clientRedirectSourceForHistory().isNull()) {
    826         if (dumpHistoryCallbacks) {
    827             printf("WebView performed a client redirect from \"%s\" to \"%s\".\n",
    828                   qPrintable(QString(loader->clientRedirectSourceForHistory())),
    829                   qPrintable(QString(loader->clientRedirectDestinationForHistory())));
    830         }
    831     }
    832 
    833     if (!loader->serverRedirectSourceForHistory().isNull()) {
    834         if (dumpHistoryCallbacks) {
    835             printf("WebView performed a server redirect from \"%s\" to \"%s\".\n",
    836                   qPrintable(QString(loader->serverRedirectSourceForHistory())),
    837                   qPrintable(QString(loader->serverRedirectDestinationForHistory())));
    838         }
    839     }
    840 }
    841 
    842 bool FrameLoaderClientQt::shouldGoToHistoryItem(WebCore::HistoryItem*) const
    843 {
    844     return true;
    845 }
    846 
    847 bool FrameLoaderClientQt::shouldStopLoadingForHistoryItem(WebCore::HistoryItem*) const
    848 {
    849     return true;
    850 }
    851 
    852 void FrameLoaderClientQt::dispatchDidAddBackForwardItem(WebCore::HistoryItem*) const
    853 {
    854 }
    855 
    856 void FrameLoaderClientQt::dispatchDidRemoveBackForwardItem(WebCore::HistoryItem*) const
    857 {
    858 }
    859 
    860 void FrameLoaderClientQt::dispatchDidChangeBackForwardIndex() const
    861 {
    862 }
    863 
    864 void FrameLoaderClientQt::didDisplayInsecureContent()
    865 {
    866     if (dumpFrameLoaderCallbacks)
    867         printf("didDisplayInsecureContent\n");
    868 
    869     notImplemented();
    870 }
    871 
    872 void FrameLoaderClientQt::didRunInsecureContent(WebCore::SecurityOrigin*, const KURL&)
    873 {
    874     if (dumpFrameLoaderCallbacks)
    875         printf("didRunInsecureContent\n");
    876 
    877     notImplemented();
    878 }
    879 
    880 void FrameLoaderClientQt::saveViewStateToItem(WebCore::HistoryItem* item)
    881 {
    882     QWebHistoryItem historyItem(new QWebHistoryItemPrivate(item));
    883     emit m_webFrame->page()->saveFrameStateRequested(m_webFrame, &historyItem);
    884 }
    885 
    886 bool FrameLoaderClientQt::canCachePage() const
    887 {
    888     return true;
    889 }
    890 
    891 void FrameLoaderClientQt::setMainDocumentError(WebCore::DocumentLoader* loader, const WebCore::ResourceError& error)
    892 {
    893     if (!m_pluginView)
    894         return;
    895     if (m_pluginView->isPluginView())
    896         m_pluginView->didFail(error);
    897     m_pluginView = 0;
    898     m_hasSentResponseToPlugin = false;
    899 }
    900 
    901 // FIXME: This function should be moved into WebCore.
    902 void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length)
    903 {
    904     if (!m_pluginView)
    905         loader->commitData(data, length);
    906 
    907     // We re-check here as the plugin can have been created.
    908     if (m_pluginView && m_pluginView->isPluginView()) {
    909         if (!m_hasSentResponseToPlugin) {
    910             m_pluginView->didReceiveResponse(loader->response());
    911             // The function didReceiveResponse sets up a new stream to the plug-in.
    912             // On a full-page plug-in, a failure in setting up this stream can cause the
    913             // main document load to be cancelled, setting m_pluginView to null.
    914             if (!m_pluginView)
    915                 return;
    916             m_hasSentResponseToPlugin = true;
    917         }
    918         m_pluginView->didReceiveData(data, length);
    919     }
    920 }
    921 
    922 WebCore::ResourceError FrameLoaderClientQt::cancelledError(const WebCore::ResourceRequest& request)
    923 {
    924     ResourceError error = ResourceError("QtNetwork", QNetworkReply::OperationCanceledError, request.url().string(),
    925             QCoreApplication::translate("QWebFrame", "Request cancelled", 0, QCoreApplication::UnicodeUTF8));
    926     error.setIsCancellation(true);
    927     return error;
    928 }
    929 
    930 // This was copied from file "WebKit/Source/WebKit/mac/Misc/WebKitErrors.h".
    931 enum {
    932     WebKitErrorCannotShowMIMEType =                             100,
    933     WebKitErrorCannotShowURL =                                  101,
    934     WebKitErrorFrameLoadInterruptedByPolicyChange =             102,
    935     WebKitErrorCannotUseRestrictedPort =                        103,
    936     WebKitErrorCannotFindPlugIn =                               200,
    937     WebKitErrorCannotLoadPlugIn =                               201,
    938     WebKitErrorJavaUnavailable =                                202,
    939     WebKitErrorPluginWillHandleLoad =                           203
    940 };
    941 
    942 WebCore::ResourceError FrameLoaderClientQt::blockedError(const WebCore::ResourceRequest& request)
    943 {
    944     return ResourceError("WebKitErrorDomain", WebKitErrorCannotUseRestrictedPort, request.url().string(),
    945             QCoreApplication::translate("QWebFrame", "Request blocked", 0, QCoreApplication::UnicodeUTF8));
    946 }
    947 
    948 
    949 WebCore::ResourceError FrameLoaderClientQt::cannotShowURLError(const WebCore::ResourceRequest& request)
    950 {
    951     return ResourceError("WebKitErrorDomain", WebKitErrorCannotShowURL, request.url().string(),
    952             QCoreApplication::translate("QWebFrame", "Cannot show URL", 0, QCoreApplication::UnicodeUTF8));
    953 }
    954 
    955 WebCore::ResourceError FrameLoaderClientQt::interruptForPolicyChangeError(const WebCore::ResourceRequest& request)
    956 {
    957     return ResourceError("WebKitErrorDomain", WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(),
    958             QCoreApplication::translate("QWebFrame", "Frame load interrupted by policy change", 0, QCoreApplication::UnicodeUTF8));
    959 }
    960 
    961 WebCore::ResourceError FrameLoaderClientQt::cannotShowMIMETypeError(const WebCore::ResourceResponse& response)
    962 {
    963     return ResourceError("WebKitErrorDomain", WebKitErrorCannotShowMIMEType, response.url().string(),
    964             QCoreApplication::translate("QWebFrame", "Cannot show mimetype", 0, QCoreApplication::UnicodeUTF8));
    965 }
    966 
    967 WebCore::ResourceError FrameLoaderClientQt::fileDoesNotExistError(const WebCore::ResourceResponse& response)
    968 {
    969     return ResourceError("QtNetwork", QNetworkReply::ContentNotFoundError, response.url().string(),
    970             QCoreApplication::translate("QWebFrame", "File does not exist", 0, QCoreApplication::UnicodeUTF8));
    971 }
    972 
    973 WebCore::ResourceError FrameLoaderClientQt::pluginWillHandleLoadError(const WebCore::ResourceResponse& response)
    974 {
    975     return ResourceError("WebKit", WebKitErrorPluginWillHandleLoad, response.url().string(),
    976                          QCoreApplication::translate("QWebFrame", "Loading is handled by the media engine", 0, QCoreApplication::UnicodeUTF8));
    977 }
    978 
    979 bool FrameLoaderClientQt::shouldFallBack(const WebCore::ResourceError&)
    980 {
    981     notImplemented();
    982     return false;
    983 }
    984 
    985 WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClientQt::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData)
    986 {
    987     RefPtr<DocumentLoader> loader = DocumentLoader::create(request, substituteData);
    988     if (!deferMainResourceDataLoad || substituteData.isValid()) {
    989         loader->setDeferMainResourceDataLoad(false);
    990         // Use the default timeout interval for JS as the HTML tokenizer delay. This ensures
    991         // that long-running JavaScript will still allow setHtml() to be synchronous, while
    992         // still giving a reasonable timeout to prevent deadlock.
    993 #if USE(JSC)
    994         double delay = JSDOMWindowBase::commonJSGlobalData()->timeoutChecker.timeoutInterval() / 1000.0f;
    995 #elif USE(V8)
    996         // FIXME: Hard coded for now.
    997         double delay = 10000 / 1000.0f;
    998 #endif
    999         m_frame->page()->setCustomHTMLTokenizerTimeDelay(delay);
   1000     } else
   1001         m_frame->page()->setCustomHTMLTokenizerTimeDelay(-1);
   1002     return loader.release();
   1003 }
   1004 
   1005 void FrameLoaderClientQt::download(WebCore::ResourceHandle* handle, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&)
   1006 {
   1007     if (!m_webFrame)
   1008         return;
   1009 
   1010     QNetworkReplyHandler* handler = handle->getInternal()->m_job;
   1011     QNetworkReply* reply = handler->release();
   1012     if (reply) {
   1013         QWebPage* page = m_webFrame->page();
   1014         if (page->forwardUnsupportedContent())
   1015             emit page->unsupportedContent(reply);
   1016         else
   1017             reply->abort();
   1018     }
   1019 }
   1020 
   1021 void FrameLoaderClientQt::assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest& request)
   1022 {
   1023     if (dumpResourceLoadCallbacks)
   1024         dumpAssignedUrls[identifier] = drtDescriptionSuitableForTestResult(request.url());
   1025 }
   1026 
   1027 void FrameLoaderClientQt::dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest& newRequest, const WebCore::ResourceResponse& redirectResponse)
   1028 {
   1029     QUrl url = newRequest.url();
   1030 
   1031     if (dumpResourceLoadCallbacks)
   1032         printf("%s - willSendRequest %s redirectResponse %s\n",
   1033                qPrintable(dumpAssignedUrls[identifier]),
   1034                qPrintable(drtDescriptionSuitableForTestResult(newRequest)),
   1035                (redirectResponse.isNull()) ? "(null)" : qPrintable(drtDescriptionSuitableForTestResult(redirectResponse)));
   1036 
   1037     if (sendRequestReturnsNull) {
   1038         newRequest.setURL(QUrl());
   1039         return;
   1040     }
   1041 
   1042     if (sendRequestReturnsNullOnRedirect && !redirectResponse.isNull()) {
   1043         printf("Returning null for this redirect\n");
   1044         newRequest.setURL(QUrl());
   1045         return;
   1046     }
   1047 
   1048     if (QWebPagePrivate::drtRun
   1049         && url.isValid()
   1050         && (url.scheme().toLower() == QLatin1String("http") || url.scheme().toLower() == QLatin1String("https"))
   1051         && url.host() != QLatin1String("127.0.0.1")
   1052         && url.host() != QLatin1String("255.255.255.255")
   1053         && url.host().toLower() != QLatin1String("localhost")) {
   1054 
   1055         printf("Blocked access to external URL %s\n", qPrintable(drtDescriptionSuitableForTestResult(newRequest.url())));
   1056         newRequest.setURL(QUrl());
   1057         return;
   1058     }
   1059 
   1060     for (int i = 0; i < sendRequestClearHeaders.size(); ++i)
   1061           newRequest.setHTTPHeaderField(sendRequestClearHeaders.at(i).toLocal8Bit().constData(), QString());
   1062 
   1063     if (QWebPagePrivate::drtRun) {
   1064         QMap<QString, QString>::const_iterator it = URLsToRedirect.constFind(url.toString());
   1065         if (it != URLsToRedirect.constEnd())
   1066             newRequest.setURL(QUrl(it.value()));
   1067     }
   1068     // Seems like the Mac code doesn't do anything here by default neither.
   1069     // qDebug() << "FrameLoaderClientQt::dispatchWillSendRequest" << request.isNull() << url;
   1070 }
   1071 
   1072 bool FrameLoaderClientQt::shouldUseCredentialStorage(DocumentLoader*, unsigned long)
   1073 {
   1074     notImplemented();
   1075     return false;
   1076 }
   1077 
   1078 void FrameLoaderClientQt::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
   1079 {
   1080     notImplemented();
   1081 }
   1082 
   1083 void FrameLoaderClientQt::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
   1084 {
   1085     notImplemented();
   1086 }
   1087 
   1088 void FrameLoaderClientQt::dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse& response)
   1089 {
   1090 
   1091     m_response = response;
   1092     if (dumpResourceLoadCallbacks)
   1093         printf("%s - didReceiveResponse %s\n",
   1094                qPrintable(dumpAssignedUrls[identifier]),
   1095                qPrintable(drtDescriptionSuitableForTestResult(response)));
   1096 
   1097     if (dumpResourceResponseMIMETypes) {
   1098         printf("%s has MIME type %s\n",
   1099                qPrintable(QString(response.url().lastPathComponent())),
   1100                qPrintable(QString(response.mimeType())));
   1101     }
   1102 }
   1103 
   1104 void FrameLoaderClientQt::dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long, int)
   1105 {
   1106 }
   1107 
   1108 void FrameLoaderClientQt::dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier)
   1109 {
   1110     if (dumpResourceLoadCallbacks)
   1111         printf("%s - didFinishLoading\n",
   1112                (dumpAssignedUrls.contains(identifier) ? qPrintable(dumpAssignedUrls[identifier]) : "<unknown>"));
   1113 }
   1114 
   1115 void FrameLoaderClientQt::dispatchDidFailLoading(WebCore::DocumentLoader* loader, unsigned long identifier, const WebCore::ResourceError& error)
   1116 {
   1117     if (dumpResourceLoadCallbacks)
   1118         printf("%s - didFailLoadingWithError: %s\n",
   1119                (dumpAssignedUrls.contains(identifier) ? qPrintable(dumpAssignedUrls[identifier]) : "<unknown>"),
   1120                qPrintable(drtDescriptionSuitableForTestResult(error)));
   1121 }
   1122 
   1123 bool FrameLoaderClientQt::dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int)
   1124 {
   1125     notImplemented();
   1126     return false;
   1127 }
   1128 
   1129 void FrameLoaderClientQt::callErrorPageExtension(const WebCore::ResourceError& error)
   1130 {
   1131     QWebPage* page = m_webFrame->page();
   1132     if (page->supportsExtension(QWebPage::ErrorPageExtension)) {
   1133         QWebPage::ErrorPageExtensionOption option;
   1134 
   1135         if (error.domain() == "QtNetwork")
   1136             option.domain = QWebPage::QtNetwork;
   1137         else if (error.domain() == "HTTP")
   1138             option.domain = QWebPage::Http;
   1139         else if (error.domain() == "WebKit")
   1140             option.domain = QWebPage::WebKit;
   1141         else
   1142             return;
   1143 
   1144         option.url = QUrl(error.failingURL());
   1145         option.frame = m_webFrame;
   1146         option.error = error.errorCode();
   1147         option.errorString = error.localizedDescription();
   1148 
   1149         QWebPage::ErrorPageExtensionReturn output;
   1150         if (!page->extension(QWebPage::ErrorPageExtension, &option, &output))
   1151             return;
   1152 
   1153         KURL baseUrl(output.baseUrl);
   1154         KURL failingUrl(option.url);
   1155 
   1156         WebCore::ResourceRequest request(baseUrl);
   1157         WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(output.content.constData(), output.content.length());
   1158         WebCore::SubstituteData substituteData(buffer, output.contentType, output.encoding, failingUrl);
   1159         m_frame->loader()->load(request, substituteData, false);
   1160     }
   1161 }
   1162 
   1163 void FrameLoaderClientQt::dispatchDidFailProvisionalLoad(const WebCore::ResourceError& error)
   1164 {
   1165     if (dumpFrameLoaderCallbacks)
   1166         printf("%s - didFailProvisionalLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
   1167 
   1168     m_loadError = error;
   1169     if (!error.isNull() && !error.isCancellation())
   1170         callErrorPageExtension(error);
   1171 }
   1172 
   1173 void FrameLoaderClientQt::dispatchDidFailLoad(const WebCore::ResourceError& error)
   1174 {
   1175     if (dumpFrameLoaderCallbacks)
   1176         printf("%s - didFailLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
   1177 
   1178     m_loadError = error;
   1179     if (!error.isNull() && !error.isCancellation())
   1180         callErrorPageExtension(error);
   1181 }
   1182 
   1183 WebCore::Frame* FrameLoaderClientQt::dispatchCreatePage(const WebCore::NavigationAction&)
   1184 {
   1185     if (!m_webFrame)
   1186         return 0;
   1187     QWebPage *newPage = m_webFrame->page()->createWindow(QWebPage::WebBrowserWindow);
   1188     if (!newPage)
   1189         return 0;
   1190     return newPage->mainFrame()->d->frame;
   1191 }
   1192 
   1193 void FrameLoaderClientQt::dispatchDecidePolicyForResponse(FramePolicyFunction function, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest&)
   1194 {
   1195     // We need to call directly here.
   1196     if (WebCore::contentDispositionType(response.httpHeaderField("Content-Disposition")) == WebCore::ContentDispositionAttachment)
   1197         callPolicyFunction(function, PolicyDownload);
   1198     else if (canShowMIMEType(response.mimeType()))
   1199         callPolicyFunction(function, PolicyUse);
   1200     else
   1201         callPolicyFunction(function, PolicyDownload);
   1202 }
   1203 
   1204 void FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>, const WTF::String&)
   1205 {
   1206     Q_ASSERT(m_webFrame);
   1207     QNetworkRequest r(request.toNetworkRequest(m_webFrame));
   1208     QWebPage* page = m_webFrame->page();
   1209 
   1210     if (!page->d->acceptNavigationRequest(0, r, QWebPage::NavigationType(action.type()))) {
   1211         if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
   1212             m_frame->loader()->resetMultipleFormSubmissionProtection();
   1213 
   1214         if (action.type() == NavigationTypeLinkClicked && r.url().hasFragment()) {
   1215             ResourceRequest emptyRequest;
   1216             m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest);
   1217         }
   1218 
   1219         callPolicyFunction(function, PolicyIgnore);
   1220         return;
   1221     }
   1222     callPolicyFunction(function, PolicyUse);
   1223 }
   1224 
   1225 void FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>)
   1226 {
   1227     Q_ASSERT(m_webFrame);
   1228     QNetworkRequest r(request.toNetworkRequest(m_webFrame));
   1229     QWebPage*page = m_webFrame->page();
   1230     PolicyAction result;
   1231 
   1232     // Currently, this is only enabled by DRT.
   1233     if (policyDelegateEnabled) {
   1234         RefPtr<Node> node;
   1235         for (const Event* event = action.event(); event; event = event->underlyingEvent()) {
   1236             if (event->isMouseEvent()) {
   1237                 const MouseEvent* mouseEvent =  static_cast<const MouseEvent*>(event);
   1238                 node = QWebFramePrivate::core(m_webFrame)->eventHandler()->hitTestResultAtPoint(
   1239                     mouseEvent->absoluteLocation(), false).innerNonSharedNode();
   1240                 break;
   1241             }
   1242         }
   1243 
   1244         printf("Policy delegate: attempt to load %s with navigation type '%s'%s\n",
   1245                qPrintable(drtDescriptionSuitableForTestResult(request.url())), navigationTypeToString(action.type()),
   1246                (node) ? qPrintable(QString::fromLatin1(" originating from ") + drtDescriptionSuitableForTestResult(node, 0)) : "");
   1247 
   1248         if (policyDelegatePermissive)
   1249             result = PolicyUse;
   1250         else
   1251             result = PolicyIgnore;
   1252 
   1253         callPolicyFunction(function, result);
   1254         return;
   1255     }
   1256 
   1257     if (!page->d->acceptNavigationRequest(m_webFrame, r, QWebPage::NavigationType(action.type()))) {
   1258         if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
   1259             m_frame->loader()->resetMultipleFormSubmissionProtection();
   1260 
   1261         if (action.type() == NavigationTypeLinkClicked && r.url().hasFragment()) {
   1262             ResourceRequest emptyRequest;
   1263             m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest);
   1264         }
   1265 
   1266         callPolicyFunction(function, PolicyIgnore);
   1267         return;
   1268     }
   1269     callPolicyFunction(function, PolicyUse);
   1270 }
   1271 
   1272 void FrameLoaderClientQt::dispatchUnableToImplementPolicy(const WebCore::ResourceError&)
   1273 {
   1274     notImplemented();
   1275 }
   1276 
   1277 void FrameLoaderClientQt::startDownload(const WebCore::ResourceRequest& request)
   1278 {
   1279     if (!m_webFrame)
   1280         return;
   1281 
   1282     emit m_webFrame->page()->downloadRequested(request.toNetworkRequest(m_webFrame));
   1283 }
   1284 
   1285 PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
   1286                                         const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
   1287 {
   1288     if (!m_webFrame)
   1289         return 0;
   1290 
   1291     QWebFrameData frameData(m_frame->page(), m_frame, ownerElement, name);
   1292 
   1293     if (url.isEmpty())
   1294         frameData.url = blankURL();
   1295     else
   1296         frameData.url = url;
   1297 
   1298     frameData.referrer = referrer;
   1299     frameData.allowsScrolling = allowsScrolling;
   1300     frameData.marginWidth = marginWidth;
   1301     frameData.marginHeight = marginHeight;
   1302 
   1303     QPointer<QWebFrame> webFrame = new QWebFrame(m_webFrame, &frameData);
   1304     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
   1305     if (!webFrame->d->frame->page()) {
   1306         frameData.frame.release();
   1307         ASSERT(webFrame.isNull());
   1308         return 0;
   1309     }
   1310 
   1311     emit m_webFrame->page()->frameCreated(webFrame);
   1312 
   1313     // FIXME: Set override encoding if we have one.
   1314 
   1315     m_frame->loader()->loadURLIntoChildFrame(frameData.url, frameData.referrer, frameData.frame.get());
   1316 
   1317     // The frame's onload handler may have removed it from the document.
   1318     if (!frameData.frame->tree()->parent())
   1319         return 0;
   1320 
   1321     return frameData.frame.release();
   1322 }
   1323 
   1324 void FrameLoaderClientQt::didTransferChildFrameToNewDocument(Page*)
   1325 {
   1326     ASSERT(m_frame->ownerElement());
   1327 
   1328     if (!m_webFrame)
   1329         return;
   1330 
   1331     Frame* parentFrame = m_webFrame->d->frame->tree()->parent();
   1332     ASSERT(parentFrame);
   1333 
   1334     if (QWebFrame* parent = QWebFramePrivate::kit(parentFrame)) {
   1335         m_webFrame->d->setPage(parent->page());
   1336 
   1337         if (m_webFrame->parent() != qobject_cast<QObject*>(parent))
   1338             m_webFrame->setParent(parent);
   1339     }
   1340 }
   1341 
   1342 void FrameLoaderClientQt::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*)
   1343 {
   1344 }
   1345 
   1346 ObjectContentType FrameLoaderClientQt::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
   1347 {
   1348     // qDebug()<<" ++++++++++++++++ url is "<<url.string()<<", mime = "<<mimeTypeIn;
   1349     QFileInfo fi(url.path());
   1350     String extension = fi.suffix();
   1351     if (mimeTypeIn == "application/x-qt-plugin" || mimeTypeIn == "application/x-qt-styled-widget")
   1352         return ObjectContentOtherPlugin;
   1353 
   1354     if (url.isEmpty() && !mimeTypeIn.length())
   1355         return ObjectContentNone;
   1356 
   1357     String mimeType = mimeTypeIn;
   1358     if (!mimeType.length())
   1359         mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
   1360 
   1361     if (!mimeType.length())
   1362         mimeType = PluginDatabase::installedPlugins()->MIMETypeForExtension(extension);
   1363 
   1364     if (!mimeType.length())
   1365         return ObjectContentFrame;
   1366 
   1367     ObjectContentType plugInType = ObjectContentNone;
   1368     if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
   1369         plugInType = ObjectContentNetscapePlugin;
   1370     else if (m_frame->page() && m_frame->page()->pluginData() && m_frame->page()->pluginData()->supportsMimeType(mimeType))
   1371         plugInType = ObjectContentOtherPlugin;
   1372 
   1373     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
   1374         return shouldPreferPlugInsForImages && plugInType != ObjectContentNone ? plugInType : ObjectContentImage;
   1375 
   1376     if (plugInType != ObjectContentNone)
   1377         return plugInType;
   1378 
   1379     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
   1380         return ObjectContentFrame;
   1381 
   1382     if (url.protocol() == "about")
   1383         return ObjectContentFrame;
   1384 
   1385     return ObjectContentNone;
   1386 }
   1387 
   1388 static const CSSPropertyID qstyleSheetProperties[] = {
   1389     CSSPropertyColor,
   1390     CSSPropertyFontFamily,
   1391     CSSPropertyFontSize,
   1392     CSSPropertyFontStyle,
   1393     CSSPropertyFontWeight
   1394 };
   1395 
   1396 const unsigned numqStyleSheetProperties = sizeof(qstyleSheetProperties) / sizeof(qstyleSheetProperties[0]);
   1397 
   1398 class QtPluginWidget: public Widget
   1399 {
   1400 public:
   1401     QtPluginWidget(QWidget* w = 0): Widget(w) {}
   1402     ~QtPluginWidget()
   1403     {
   1404         if (platformWidget())
   1405             platformWidget()->deleteLater();
   1406     }
   1407     virtual void invalidateRect(const IntRect& r)
   1408     {
   1409         if (platformWidget())
   1410             platformWidget()->update(r);
   1411     }
   1412     virtual void frameRectsChanged()
   1413     {
   1414         if (!platformWidget())
   1415             return;
   1416 
   1417         IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height()));
   1418         platformWidget()->setGeometry(windowRect);
   1419 
   1420         ScrollView* parentScrollView = parent();
   1421         if (!parentScrollView)
   1422             return;
   1423 
   1424         ASSERT(parentScrollView->isFrameView());
   1425         IntRect clipRect(static_cast<FrameView*>(parentScrollView)->windowClipRect());
   1426         clipRect.move(-windowRect.x(), -windowRect.y());
   1427         clipRect.intersect(platformWidget()->rect());
   1428 
   1429         QRegion clipRegion = QRegion(clipRect);
   1430         platformWidget()->setMask(clipRegion);
   1431 
   1432         handleVisibility();
   1433 
   1434         platformWidget()->update();
   1435     }
   1436 
   1437     virtual void show()
   1438     {
   1439         Widget::show();
   1440         handleVisibility();
   1441     }
   1442 
   1443 private:
   1444     void handleVisibility()
   1445     {
   1446         if (!isVisible())
   1447             return;
   1448 
   1449         // If setMask is set with an empty QRegion, no clipping will
   1450         // be performed, so in that case we hide the platformWidget.
   1451         QRegion mask = platformWidget()->mask();
   1452         platformWidget()->setVisible(!mask.isEmpty());
   1453     }
   1454 };
   1455 
   1456 #if !defined(QT_NO_GRAPHICSVIEW)
   1457 class QtPluginGraphicsWidget: public Widget
   1458 {
   1459 public:
   1460     static RefPtr<QtPluginGraphicsWidget> create(QGraphicsWidget* w = 0)
   1461     {
   1462         return adoptRef(new QtPluginGraphicsWidget(w));
   1463     }
   1464 
   1465     ~QtPluginGraphicsWidget()
   1466     {
   1467         if (graphicsWidget)
   1468             graphicsWidget->deleteLater();
   1469     }
   1470     virtual void invalidateRect(const IntRect& r)
   1471     {
   1472         QGraphicsScene* scene = graphicsWidget ? graphicsWidget->scene() : 0;
   1473         if (scene)
   1474             scene->update(QRect(r));
   1475     }
   1476     virtual void frameRectsChanged()
   1477     {
   1478         if (!graphicsWidget)
   1479             return;
   1480 
   1481         IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height()));
   1482         graphicsWidget->setGeometry(QRect(windowRect));
   1483 
   1484         // FIXME: Make the code handle clipping of graphics widgets.
   1485     }
   1486     virtual void show()
   1487     {
   1488         if (graphicsWidget)
   1489             graphicsWidget->show();
   1490     }
   1491     virtual void hide()
   1492     {
   1493         if (graphicsWidget)
   1494             graphicsWidget->hide();
   1495     }
   1496 private:
   1497     QtPluginGraphicsWidget(QGraphicsWidget* w = 0)
   1498         : Widget(0)
   1499         , graphicsWidget(w)
   1500     {
   1501         setBindingObject(graphicsWidget);
   1502     }
   1503 
   1504     QGraphicsWidget* graphicsWidget;
   1505 };
   1506 #endif // QT_NO_GRAPHICSVIEW
   1507 
   1508 PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames,
   1509                                           const Vector<String>& paramValues, const String& mimeType, bool loadManually)
   1510 {
   1511     // qDebug()<<"------ Creating plugin in FrameLoaderClientQt::createPlugin for "<<url.string() << mimeType;
   1512     // qDebug()<<"------\t url = "<<url.string();
   1513 
   1514     if (!m_webFrame)
   1515         return 0;
   1516 
   1517     QStringList params;
   1518     QStringList values;
   1519     QString classid(element->getAttribute("classid"));
   1520 
   1521     for (unsigned i = 0; i < paramNames.size(); ++i) {
   1522         params.append(paramNames[i]);
   1523         if (paramNames[i] == "classid")
   1524             classid = paramValues[i];
   1525     }
   1526     for (unsigned i = 0; i < paramValues.size(); ++i)
   1527         values.append(paramValues[i]);
   1528 
   1529     QString urlStr(url.string());
   1530     QUrl qurl = urlStr;
   1531 
   1532     QObject* object = 0;
   1533 
   1534     if (mimeType == "application/x-qt-plugin" || mimeType == "application/x-qt-styled-widget") {
   1535         object = m_webFrame->page()->createPlugin(classid, qurl, params, values);
   1536 #ifndef QT_NO_STYLE_STYLESHEET
   1537         QWidget* widget = qobject_cast<QWidget*>(object);
   1538         if (widget && mimeType == "application/x-qt-styled-widget") {
   1539 
   1540             QString styleSheet = element->getAttribute("style");
   1541             if (!styleSheet.isEmpty())
   1542                 styleSheet += QLatin1Char(';');
   1543 
   1544             for (unsigned i = 0; i < numqStyleSheetProperties; ++i) {
   1545                 CSSPropertyID property = qstyleSheetProperties[i];
   1546 
   1547                 styleSheet += QString::fromLatin1(getPropertyName(property));
   1548                 styleSheet += QLatin1Char(':');
   1549                 styleSheet += computedStyle(element)->getPropertyValue(property);
   1550                 styleSheet += QLatin1Char(';');
   1551             }
   1552 
   1553             widget->setStyleSheet(styleSheet);
   1554         }
   1555 #endif // QT_NO_STYLE_STYLESHEET
   1556     }
   1557 
   1558     if (!object) {
   1559         QWebPluginFactory* factory = m_webFrame->page()->pluginFactory();
   1560         if (factory)
   1561             object = factory->create(mimeType, qurl, params, values);
   1562     }
   1563 
   1564     if (object) {
   1565         QWidget* widget = qobject_cast<QWidget*>(object);
   1566         if (widget) {
   1567             QWidget* parentWidget = 0;
   1568             if (m_webFrame->page()->d->client)
   1569                 parentWidget = qobject_cast<QWidget*>(m_webFrame->page()->d->client->pluginParent());
   1570             if (parentWidget) // Don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose.
   1571                 widget->setParent(parentWidget);
   1572             widget->hide();
   1573             RefPtr<QtPluginWidget> w = adoptRef(new QtPluginWidget());
   1574             w->setPlatformWidget(widget);
   1575             // Make sure it's invisible until properly placed into the layout.
   1576             w->setFrameRect(IntRect(0, 0, 0, 0));
   1577             return w;
   1578         }
   1579 
   1580 #if !defined(QT_NO_GRAPHICSVIEW)
   1581         QGraphicsWidget* graphicsWidget = qobject_cast<QGraphicsWidget*>(object);
   1582         if (graphicsWidget) {
   1583             QGraphicsObject* parentWidget = 0;
   1584             if (m_webFrame->page()->d->client)
   1585                 parentWidget = qobject_cast<QGraphicsObject*>(m_webFrame->page()->d->client->pluginParent());
   1586             graphicsWidget->hide();
   1587             if (parentWidget) // Don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose.
   1588                 graphicsWidget->setParentItem(parentWidget);
   1589             RefPtr<QtPluginGraphicsWidget> w = QtPluginGraphicsWidget::create(graphicsWidget);
   1590             // Make sure it's invisible until properly placed into the layout.
   1591             w->setFrameRect(IntRect(0, 0, 0, 0));
   1592             return w;
   1593         }
   1594 #endif // QT_NO_GRAPHICSVIEW
   1595 
   1596         // FIXME: Make things work for widgetless plugins as well.
   1597         delete object;
   1598     }
   1599 #if ENABLE(NETSCAPE_PLUGIN_API)
   1600     else { // NPAPI Plugins
   1601         Vector<String> params = paramNames;
   1602         Vector<String> values = paramValues;
   1603         if (mimeType == "application/x-shockwave-flash") {
   1604             QWebPageClient* client = m_webFrame->page()->d->client.get();
   1605             const bool isQWebView = client && qobject_cast<QWidget*>(client->pluginParent());
   1606 #if defined(MOZ_PLATFORM_MAEMO) && (MOZ_PLATFORM_MAEMO >= 5)
   1607             size_t wmodeIndex = params.find("wmode");
   1608             if (wmodeIndex == -1) {
   1609                 // Disable XEmbed mode and force it to opaque mode.
   1610                 params.append("wmode");
   1611                 values.append("opaque");
   1612             } else if (!isQWebView) {
   1613                 // Disable transparency if client is not a QWebView.
   1614                 values[wmodeIndex] = "opaque";
   1615             }
   1616 #else
   1617             if (!isQWebView) {
   1618                 // Inject wmode=opaque when there is no client or the client is not a QWebView.
   1619                 size_t wmodeIndex = params.find("wmode");
   1620                 if (wmodeIndex == -1) {
   1621                     params.append("wmode");
   1622                     values.append("opaque");
   1623                 } else if (equalIgnoringCase(values[wmodeIndex], "window"))
   1624                     values[wmodeIndex] = "opaque";
   1625             }
   1626 #endif
   1627         }
   1628 
   1629         RefPtr<PluginView> pluginView = PluginView::create(m_frame, pluginSize, element, url,
   1630             params, values, mimeType, loadManually);
   1631         return pluginView;
   1632     }
   1633 #endif // ENABLE(NETSCAPE_PLUGIN_API)
   1634 
   1635     return 0;
   1636 }
   1637 
   1638 void FrameLoaderClientQt::redirectDataToPlugin(Widget* pluginWidget)
   1639 {
   1640     ASSERT(!m_pluginView);
   1641     m_pluginView = static_cast<PluginView*>(pluginWidget);
   1642     m_hasSentResponseToPlugin = false;
   1643 }
   1644 
   1645 PassRefPtr<Widget> FrameLoaderClientQt::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const KURL& url,
   1646                                                     const Vector<String>& paramNames, const Vector<String>& paramValues)
   1647 {
   1648     return createPlugin(pluginSize, element, url, paramNames, paramValues, "application/x-java-applet", true);
   1649 }
   1650 
   1651 String FrameLoaderClientQt::overrideMediaType() const
   1652 {
   1653     return String();
   1654 }
   1655 
   1656 QString FrameLoaderClientQt::chooseFile(const QString& oldFile)
   1657 {
   1658     return m_webFrame->page()->chooseFile(m_webFrame, oldFile);
   1659 }
   1660 
   1661 PassRefPtr<FrameNetworkingContext> FrameLoaderClientQt::createNetworkingContext()
   1662 {
   1663     QVariant value = m_webFrame->page()->property("_q_MIMESniffingDisabled");
   1664     bool MIMESniffingDisabled = value.isValid() && value.toBool();
   1665 
   1666     return FrameNetworkingContextQt::create(m_frame, m_webFrame, !MIMESniffingDisabled, m_webFrame->page()->networkAccessManager());
   1667 }
   1668 
   1669 }
   1670 
   1671 #include "moc_FrameLoaderClientQt.cpp"
   1672