blob: 7dd09bfcff7747df0a244b7f6457fd2b3d60f7c2 [file] [log] [blame]
/*
* Copyright (C) 2006 Zack Rusin <zack@kde.org>
* Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
* Copyright (C) 2008 Collabora Ltd. All rights reserved.
* Coypright (C) 2008 Holger Hans Peter Freyther
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "CSSComputedStyleDeclaration.h"
#include "CSSPropertyNames.h"
#include "FormState.h"
#include "FrameLoaderClientQt.h"
#include "FrameTree.h"
#include "FrameView.h"
#include "DocumentLoader.h"
#include "MIMETypeRegistry.h"
#include "ResourceResponse.h"
#include "Page.h"
#include "PluginData.h"
#include "PluginDatabase.h"
#include "ProgressTracker.h"
#include "RenderPart.h"
#include "ResourceRequest.h"
#include "HistoryItem.h"
#include "HTMLAppletElement.h"
#include "HTMLFormElement.h"
#include "HTMLPlugInElement.h"
#include "NotImplemented.h"
#include "QNetworkReplyHandler.h"
#include "ResourceHandleInternal.h"
#include "ResourceHandle.h"
#include "Settings.h"
#include "ScriptString.h"
#include "qwebpage.h"
#include "qwebframe.h"
#include "qwebframe_p.h"
#include "qwebhistoryinterface.h"
#include "qwebpluginfactory.h"
#include <qfileinfo.h>
#include <QCoreApplication>
#include <QDebug>
#if QT_VERSION >= 0x040400
#include <QNetworkRequest>
#include <QNetworkReply>
#else
#include "qwebnetworkinterface_p.h"
#endif
#include "qwebhistory_p.h"
static bool dumpFrameLoaderCallbacks = false;
static bool dumpResourceLoadCallbacks = false;
static QMap<unsigned long, QString> dumpAssignedUrls;
void QWEBKIT_EXPORT qt_dump_frame_loader(bool b)
{
dumpFrameLoaderCallbacks = b;
}
void QWEBKIT_EXPORT qt_dump_resource_load_callbacks(bool b)
{
dumpResourceLoadCallbacks = b;
}
// Compare with WebKitTools/DumpRenderTree/mac/FrameLoadDelegate.mm
static QString drtDescriptionSuitableForTestResult(WebCore::Frame* _frame)
{
QWebFrame* frame = QWebFramePrivate::kit(_frame);
QString name = frame->frameName();
bool isMainFrame = frame == frame->page()->mainFrame();
if (isMainFrame) {
if (!name.isEmpty())
return QString::fromLatin1("main frame \"%1\"").arg(name);
return QLatin1String("main frame");
} else {
if (!name.isEmpty())
return QString::fromLatin1("frame \"%1\"").arg(name);
return QLatin1String("frame (anonymous)");
}
}
static QString drtDescriptionSuitableForTestResult(const WebCore::KURL& _url)
{
QUrl url = _url;
return url.toString();
}
static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceError& error)
{
QString failingURL = error.failingURL();
return QString::fromLatin1("<NSError domain NSURLErrorDomain, code %1, failing URL \"%2\">").arg(error.errorCode()).arg(failingURL);
}
static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceRequest& request)
{
QString url = request.url().string();
return QString::fromLatin1("<NSURLRequest %1>").arg(url);
}
static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceResponse& response)
{
QString text = response.httpStatusText();
if (text.isEmpty())
return QLatin1String("(null)");
return text;
}
namespace WebCore
{
FrameLoaderClientQt::FrameLoaderClientQt()
: m_frame(0)
, m_webFrame(0)
, m_pluginView(0)
, m_hasSentResponseToPlugin(false)
, m_firstData(false)
, m_loadSucceeded(false)
{
}
FrameLoaderClientQt::~FrameLoaderClientQt()
{
}
void FrameLoaderClientQt::setFrame(QWebFrame* webFrame, Frame* frame)
{
m_webFrame = webFrame;
m_frame = frame;
if (!m_webFrame || !m_webFrame->page()) {
qWarning("FrameLoaderClientQt::setFrame frame without Page!");
return;
}
connect(this, SIGNAL(loadStarted()),
m_webFrame->page(), SIGNAL(loadStarted()));
connect(this, SIGNAL(loadProgress(int)),
m_webFrame->page(), SIGNAL(loadProgress(int)));
connect(this, SIGNAL(loadFinished(bool)),
m_webFrame->page(), SIGNAL(loadFinished(bool)));
connect(this, SIGNAL(titleChanged(const QString&)),
m_webFrame, SIGNAL(titleChanged(const QString&)));
}
QWebFrame* FrameLoaderClientQt::webFrame() const
{
return m_webFrame;
}
void FrameLoaderClientQt::callPolicyFunction(FramePolicyFunction function, PolicyAction action)
{
(m_frame->loader()->*function)(action);
}
bool FrameLoaderClientQt::hasWebView() const
{
//notImplemented();
return true;
}
void FrameLoaderClientQt::savePlatformDataToCachedFrame(CachedFrame*)
{
notImplemented();
}
void FrameLoaderClientQt::transitionToCommittedFromCachedFrame(CachedFrame*)
{
}
void FrameLoaderClientQt::transitionToCommittedForNewPage()
{
ASSERT(m_frame);
ASSERT(m_webFrame);
QBrush brush = m_webFrame->page()->palette().brush(QPalette::Base);
QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
QWebPage* page = m_webFrame->page();
const QSize fixedLayoutSize = page->fixedContentsSize();
m_frame->createView(m_webFrame->page()->viewportSize(),
backgroundColor, !backgroundColor.alpha(),
fixedLayoutSize,
fixedLayoutSize.isValid(),
(ScrollbarMode)m_webFrame->scrollBarPolicy(Qt::Horizontal),
(ScrollbarMode)m_webFrame->scrollBarPolicy(Qt::Vertical));
}
void FrameLoaderClientQt::makeRepresentation(DocumentLoader*)
{
// don't need this for now I think.
}
void FrameLoaderClientQt::forceLayout()
{
FrameView* view = m_frame->view();
if (view)
view->forceLayout(true);
}
void FrameLoaderClientQt::forceLayoutForNonHTML()
{
}
void FrameLoaderClientQt::setCopiesOnScroll()
{
// apparently mac specific
}
void FrameLoaderClientQt::detachedFromParent2()
{
}
void FrameLoaderClientQt::detachedFromParent3()
{
}
void FrameLoaderClientQt::dispatchDidHandleOnloadEvents()
{
// don't need this one
if (dumpFrameLoaderCallbacks)
printf("%s - didHandleOnloadEventsForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
}
void FrameLoaderClientQt::dispatchDidReceiveServerRedirectForProvisionalLoad()
{
if (dumpFrameLoaderCallbacks)
printf("%s - didReceiveServerRedirectForProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
notImplemented();
}
void FrameLoaderClientQt::dispatchDidCancelClientRedirect()
{
if (dumpFrameLoaderCallbacks)
printf("%s - didCancelClientRedirectForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
notImplemented();
}
void FrameLoaderClientQt::dispatchWillPerformClientRedirect(const KURL& url,
double interval,
double fireDate)
{
if (dumpFrameLoaderCallbacks)
printf("%s - willPerformClientRedirectToURL: %s \n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(drtDescriptionSuitableForTestResult(url)));
notImplemented();
}
void FrameLoaderClientQt::dispatchDidChangeLocationWithinPage()
{
if (dumpFrameLoaderCallbacks)
printf("%s - didChangeLocationWithinPageForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
if (!m_webFrame)
return;
emit m_webFrame->urlChanged(m_webFrame->url());
m_webFrame->page()->d->updateNavigationActions();
}
void FrameLoaderClientQt::dispatchWillClose()
{
if (dumpFrameLoaderCallbacks)
printf("%s - willCloseFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
}
void FrameLoaderClientQt::dispatchDidStartProvisionalLoad()
{
if (dumpFrameLoaderCallbacks)
printf("%s - didStartProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
if (m_webFrame)
emit m_webFrame->provisionalLoad();
}
void FrameLoaderClientQt::dispatchDidReceiveTitle(const String& title)
{
if (dumpFrameLoaderCallbacks)
printf("%s - didReceiveTitle: %s\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(QString(title)));
if (!m_webFrame)
return;
emit titleChanged(title);
}
void FrameLoaderClientQt::dispatchDidCommitLoad()
{
if (dumpFrameLoaderCallbacks)
printf("%s - didCommitLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
if (m_frame->tree()->parent() || !m_webFrame)
return;
emit m_webFrame->urlChanged(m_webFrame->url());
m_webFrame->page()->d->updateNavigationActions();
// We should assume first the frame has no title. If it has, then the above dispatchDidReceiveTitle()
// will be called very soon with the correct title.
// This properly resets the title when we navigate to a URI without a title.
emit titleChanged(String());
}
void FrameLoaderClientQt::dispatchDidFinishDocumentLoad()
{
if (dumpFrameLoaderCallbacks)
printf("%s - didFinishDocumentLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
if (QWebPagePrivate::drtRun) {
int unloadEventCount = m_frame->domWindow()->pendingUnloadEventListeners();
if (unloadEventCount)
printf("%s - has %u onunload handler(s)\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), unloadEventCount);
}
if (m_frame->tree()->parent() || !m_webFrame)
return;
m_webFrame->page()->d->updateNavigationActions();
}
void FrameLoaderClientQt::dispatchDidFinishLoad()
{
if (dumpFrameLoaderCallbacks)
printf("%s - didFinishLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
m_loadSucceeded = true;
if (!m_webFrame)
return;
m_webFrame->page()->d->updateNavigationActions();
}
void FrameLoaderClientQt::dispatchDidFirstLayout()
{
if (m_webFrame)
emit m_webFrame->initialLayoutCompleted();
}
void FrameLoaderClientQt::dispatchDidFirstVisuallyNonEmptyLayout()
{
notImplemented();
}
void FrameLoaderClientQt::dispatchShow()
{
notImplemented();
}
void FrameLoaderClientQt::cancelPolicyCheck()
{
// qDebug() << "FrameLoaderClientQt::cancelPolicyCheck";
}
void FrameLoaderClientQt::dispatchWillSubmitForm(FramePolicyFunction function,
PassRefPtr<FormState>)
{
notImplemented();
// FIXME: This is surely too simple
callPolicyFunction(function, PolicyUse);
}
void FrameLoaderClientQt::dispatchDidLoadMainResource(DocumentLoader*)
{
}
void FrameLoaderClientQt::revertToProvisionalState(DocumentLoader*)
{
notImplemented();
}
void FrameLoaderClientQt::postProgressStartedNotification()
{
if (m_webFrame && m_frame->page()) {
emit loadStarted();
postProgressEstimateChangedNotification();
}
if (m_frame->tree()->parent() || !m_webFrame)
return;
m_webFrame->page()->d->updateNavigationActions();
}
void FrameLoaderClientQt::postProgressEstimateChangedNotification()
{
if (m_webFrame && m_frame->page())
emit loadProgress(qRound(m_frame->page()->progress()->estimatedProgress() * 100));
}
void FrameLoaderClientQt::postProgressFinishedNotification()
{
// send a mousemove event to
// (1) update the cursor to change according to whatever is underneath the mouse cursor right now
// (2) display the tool tip if the mouse hovers a node which has a tool tip
if (m_frame && m_frame->eventHandler() && m_webFrame->page()) {
QWidget* view = m_webFrame->page()->view();
if (view && view->hasFocus()) {
QPoint localPos = view->mapFromGlobal(QCursor::pos());
if (view->rect().contains(localPos)) {
QMouseEvent event(QEvent::MouseMove, localPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
m_frame->eventHandler()->mouseMoved(PlatformMouseEvent(&event, 0));
}
}
}
if (m_webFrame && m_frame->page())
emit loadFinished(m_loadSucceeded);
}
void FrameLoaderClientQt::setMainFrameDocumentReady(bool b)
{
// this is only interesting once we provide an external API for the DOM
}
void FrameLoaderClientQt::willChangeTitle(DocumentLoader*)
{
// no need for, dispatchDidReceiveTitle is the right callback
}
void FrameLoaderClientQt::didChangeTitle(DocumentLoader *)
{
// no need for, dispatchDidReceiveTitle is the right callback
}
void FrameLoaderClientQt::finishedLoading(DocumentLoader* loader)
{
if (!m_pluginView) {
if(m_firstData) {
FrameLoader *fl = loader->frameLoader();
fl->setEncoding(m_response.textEncodingName(), false);
m_firstData = false;
}
}
else {
m_pluginView->didFinishLoading();
m_pluginView = 0;
m_hasSentResponseToPlugin = false;
}
}
bool FrameLoaderClientQt::canShowMIMEType(const String& MIMEType) const
{
if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType))
return true;
if (MIMETypeRegistry::isSupportedNonImageMIMEType(MIMEType))
return true;
if (m_frame && m_frame->settings() && m_frame->settings()->arePluginsEnabled()
&& PluginDatabase::installedPlugins()->isMIMETypeRegistered(MIMEType))
return true;
return false;
}
bool FrameLoaderClientQt::representationExistsForURLScheme(const String& URLScheme) const
{
return false;
}
String FrameLoaderClientQt::generatedMIMETypeForURLScheme(const String& URLScheme) const
{
notImplemented();
return String();
}
void FrameLoaderClientQt::frameLoadCompleted()
{
// Note: Can be called multiple times.
}
void FrameLoaderClientQt::restoreViewState()
{
if (!m_webFrame)
return;
emit m_webFrame->page()->restoreFrameStateRequested(m_webFrame);
}
void FrameLoaderClientQt::provisionalLoadStarted()
{
// don't need to do anything here
}
void FrameLoaderClientQt::didFinishLoad()
{
// notImplemented();
}
void FrameLoaderClientQt::prepareForDataSourceReplacement()
{
}
void FrameLoaderClientQt::setTitle(const String&, const KURL&)
{
// no need for, dispatchDidReceiveTitle is the right callback
}
String FrameLoaderClientQt::userAgent(const KURL& url)
{
if (m_webFrame) {
return m_webFrame->page()->userAgentForUrl(url);
}
return String();
}
void FrameLoaderClientQt::dispatchDidReceiveIcon()
{
if (dumpFrameLoaderCallbacks)
printf("%s - didReceiveIconForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
if (m_webFrame) {
emit m_webFrame->iconChanged();
}
}
void FrameLoaderClientQt::frameLoaderDestroyed()
{
delete m_webFrame;
m_frame = 0;
m_webFrame = 0;
delete this;
}
bool FrameLoaderClientQt::canHandleRequest(const WebCore::ResourceRequest&) const
{
return true;
}
void FrameLoaderClientQt::windowObjectCleared()
{
if (dumpFrameLoaderCallbacks)
printf("%s - didClearWindowObjectForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
if (m_webFrame)
emit m_webFrame->javaScriptWindowObjectCleared();
}
void FrameLoaderClientQt::documentElementAvailable()
{
return;
}
void FrameLoaderClientQt::didPerformFirstNavigation() const
{
if (m_frame->tree()->parent() || !m_webFrame)
return;
m_webFrame->page()->d->updateNavigationActions();
}
void FrameLoaderClientQt::registerForIconNotification(bool)
{
notImplemented();
}
void FrameLoaderClientQt::updateGlobalHistory()
{
QWebHistoryInterface *history = QWebHistoryInterface::defaultInterface();
if (history)
history->addHistoryEntry(m_frame->loader()->documentLoader()->urlForHistory().prettyURL());
}
void FrameLoaderClientQt::updateGlobalHistoryRedirectLinks()
{
}
bool FrameLoaderClientQt::shouldGoToHistoryItem(WebCore::HistoryItem *item) const
{
return true;
}
void FrameLoaderClientQt::saveViewStateToItem(WebCore::HistoryItem* item)
{
QWebHistoryItem historyItem(new QWebHistoryItemPrivate(item));
emit m_webFrame->page()->saveFrameStateRequested(m_webFrame, &historyItem);
}
bool FrameLoaderClientQt::canCachePage() const
{
return true;
}
void FrameLoaderClientQt::setMainDocumentError(WebCore::DocumentLoader* loader, const WebCore::ResourceError& error)
{
if (!m_pluginView) {
if (m_firstData) {
loader->frameLoader()->setEncoding(m_response.textEncodingName(), false);
m_firstData = false;
}
} else {
m_pluginView->didFail(error);
m_pluginView = 0;
m_hasSentResponseToPlugin = false;
}
}
void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length)
{
if (!m_pluginView) {
if (!m_frame)
return;
FrameLoader *fl = loader->frameLoader();
if (m_firstData) {
fl->setEncoding(m_response.textEncodingName(), false);
m_firstData = false;
}
fl->addData(data, length);
}
// We re-check here as the plugin can have been created
if (m_pluginView) {
if (!m_hasSentResponseToPlugin) {
m_pluginView->didReceiveResponse(loader->response());
m_hasSentResponseToPlugin = true;
}
m_pluginView->didReceiveData(data, length);
}
}
WebCore::ResourceError FrameLoaderClientQt::cancelledError(const WebCore::ResourceRequest& request)
{
return ResourceError("Error", -999, request.url().prettyURL(),
QCoreApplication::translate("QWebFrame", "Request cancelled", 0, QCoreApplication::UnicodeUTF8));
}
// copied from WebKit/Misc/WebKitErrors[Private].h
enum {
WebKitErrorCannotShowMIMEType = 100,
WebKitErrorCannotShowURL = 101,
WebKitErrorFrameLoadInterruptedByPolicyChange = 102,
WebKitErrorCannotUseRestrictedPort = 103,
WebKitErrorCannotFindPlugIn = 200,
WebKitErrorCannotLoadPlugIn = 201,
WebKitErrorJavaUnavailable = 202,
};
WebCore::ResourceError FrameLoaderClientQt::blockedError(const WebCore::ResourceRequest& request)
{
return ResourceError("Error", WebKitErrorCannotUseRestrictedPort, request.url().prettyURL(),
QCoreApplication::translate("QWebFrame", "Request blocked", 0, QCoreApplication::UnicodeUTF8));
}
WebCore::ResourceError FrameLoaderClientQt::cannotShowURLError(const WebCore::ResourceRequest& request)
{
return ResourceError("Error", WebKitErrorCannotShowURL, request.url().string(),
QCoreApplication::translate("QWebFrame", "Cannot show URL", 0, QCoreApplication::UnicodeUTF8));
}
WebCore::ResourceError FrameLoaderClientQt::interruptForPolicyChangeError(const WebCore::ResourceRequest& request)
{
return ResourceError("Error", WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(),
QCoreApplication::translate("QWebFrame", "Frame load interruped by policy change", 0, QCoreApplication::UnicodeUTF8));
}
WebCore::ResourceError FrameLoaderClientQt::cannotShowMIMETypeError(const WebCore::ResourceResponse& response)
{
return ResourceError("Error", WebKitErrorCannotShowMIMEType, response.url().string(),
QCoreApplication::translate("QWebFrame", "Cannot show mimetype", 0, QCoreApplication::UnicodeUTF8));
}
WebCore::ResourceError FrameLoaderClientQt::fileDoesNotExistError(const WebCore::ResourceResponse& response)
{
return ResourceError("Error", -998 /* ### */, response.url().string(),
QCoreApplication::translate("QWebFrame", "File does not exist", 0, QCoreApplication::UnicodeUTF8));
}
WebCore::ResourceError FrameLoaderClientQt::pluginWillHandleLoadError(const WebCore::ResourceResponse& response)
{
notImplemented();
return ResourceError();
}
bool FrameLoaderClientQt::shouldFallBack(const WebCore::ResourceError&)
{
notImplemented();
return false;
}
WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClientQt::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData)
{
RefPtr<DocumentLoader> loader = DocumentLoader::create(request, substituteData);
if (substituteData.isValid())
loader->setDeferMainResourceDataLoad(false);
return loader.release();
}
void FrameLoaderClientQt::download(WebCore::ResourceHandle* handle, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&)
{
#if QT_VERSION >= 0x040400
if (!m_webFrame)
return;
QNetworkReplyHandler* handler = handle->getInternal()->m_job;
QNetworkReply* reply = handler->release();
if (reply) {
QWebPage *page = m_webFrame->page();
if (page->forwardUnsupportedContent())
emit m_webFrame->page()->unsupportedContent(reply);
else
reply->abort();
}
#endif
}
void FrameLoaderClientQt::assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader* loader, const WebCore::ResourceRequest& request)
{
if (dumpResourceLoadCallbacks)
dumpAssignedUrls[identifier] = drtDescriptionSuitableForTestResult(request.url());
}
void FrameLoaderClientQt::dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest& newRequest, const WebCore::ResourceResponse& redirectResponse)
{
if (dumpResourceLoadCallbacks)
printf("%s - willSendRequest %s redirectResponse %s\n",
qPrintable(dumpAssignedUrls[identifier]),
qPrintable(drtDescriptionSuitableForTestResult(newRequest)),
qPrintable(drtDescriptionSuitableForTestResult(redirectResponse)));
// seems like the Mac code doesn't do anything here by default neither
//qDebug() << "FrameLoaderClientQt::dispatchWillSendRequest" << request.isNull() << request.url().string`();
}
bool
FrameLoaderClientQt::shouldUseCredentialStorage(DocumentLoader*, unsigned long)
{
notImplemented();
return false;
}
void FrameLoaderClientQt::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
{
notImplemented();
}
void FrameLoaderClientQt::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
{
notImplemented();
}
void FrameLoaderClientQt::dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long, const WebCore::ResourceResponse& response)
{
m_response = response;
m_firstData = true;
//qDebug() << " got response from" << response.url().string();
}
void FrameLoaderClientQt::dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long, int)
{
}
void FrameLoaderClientQt::dispatchDidFinishLoading(WebCore::DocumentLoader* loader, unsigned long)
{
}
void FrameLoaderClientQt::dispatchDidFailLoading(WebCore::DocumentLoader* loader, unsigned long identifier, const WebCore::ResourceError& error)
{
if (dumpResourceLoadCallbacks)
printf("%s - didFailLoadingWithError: %s\n", qPrintable(dumpAssignedUrls[identifier]), qPrintable(drtDescriptionSuitableForTestResult(error)));
if (m_firstData) {
FrameLoader *fl = loader->frameLoader();
fl->setEncoding(m_response.textEncodingName(), false);
m_firstData = false;
}
}
bool FrameLoaderClientQt::dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int)
{
notImplemented();
return false;
}
void FrameLoaderClientQt::dispatchDidLoadResourceByXMLHttpRequest(unsigned long, const WebCore::ScriptString&)
{
notImplemented();
}
void FrameLoaderClientQt::dispatchDidFailProvisionalLoad(const WebCore::ResourceError&)
{
if (dumpFrameLoaderCallbacks)
printf("%s - didFailProvisionalLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
m_loadSucceeded = false;
}
void FrameLoaderClientQt::dispatchDidFailLoad(const WebCore::ResourceError&)
{
if (dumpFrameLoaderCallbacks)
printf("%s - didFailLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
m_loadSucceeded = false;
}
WebCore::Frame* FrameLoaderClientQt::dispatchCreatePage()
{
if (!m_webFrame)
return 0;
QWebPage *newPage = m_webFrame->page()->createWindow(QWebPage::WebBrowserWindow);
if (!newPage)
return 0;
return newPage->mainFrame()->d->frame;
}
void FrameLoaderClientQt::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const WebCore::String& MIMEType, const WebCore::ResourceRequest&)
{
// we need to call directly here
if (canShowMIMEType(MIMEType))
callPolicyFunction(function, PolicyUse);
else
callPolicyFunction(function, PolicyDownload);
}
void FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>, const WebCore::String&)
{
Q_ASSERT(m_webFrame);
#if QT_VERSION < 0x040400
QWebNetworkRequest r(request);
#else
QNetworkRequest r(request.toNetworkRequest());
#endif
QWebPage* page = m_webFrame->page();
if (!page->d->acceptNavigationRequest(0, r, QWebPage::NavigationType(action.type()))) {
if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
m_frame->loader()->resetMultipleFormSubmissionProtection();
if (action.type() == NavigationTypeLinkClicked && r.url().hasFragment()) {
ResourceRequest emptyRequest;
m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest);
}
callPolicyFunction(function, PolicyIgnore);
return;
}
callPolicyFunction(function, PolicyUse);
}
void FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>)
{
Q_ASSERT(m_webFrame);
#if QT_VERSION < 0x040400
QWebNetworkRequest r(request);
#else
QNetworkRequest r(request.toNetworkRequest());
#endif
QWebPage*page = m_webFrame->page();
if (!page->d->acceptNavigationRequest(m_webFrame, r, QWebPage::NavigationType(action.type()))) {
if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
m_frame->loader()->resetMultipleFormSubmissionProtection();
if (action.type() == NavigationTypeLinkClicked && r.url().hasFragment()) {
ResourceRequest emptyRequest;
m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest);
}
callPolicyFunction(function, PolicyIgnore);
return;
}
callPolicyFunction(function, PolicyUse);
}
void FrameLoaderClientQt::dispatchUnableToImplementPolicy(const WebCore::ResourceError&)
{
notImplemented();
}
void FrameLoaderClientQt::startDownload(const WebCore::ResourceRequest& request)
{
#if QT_VERSION >= 0x040400
if (!m_webFrame)
return;
QWebPage *page = m_webFrame->page();
emit m_webFrame->page()->downloadRequested(request.toNetworkRequest());
#endif
}
PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
{
if (!m_webFrame)
return 0;
QWebFrameData frameData;
frameData.url = url;
frameData.name = name;
frameData.ownerElement = ownerElement;
frameData.referrer = referrer;
frameData.allowsScrolling = allowsScrolling;
frameData.marginWidth = marginWidth;
frameData.marginHeight = marginHeight;
QWebFrame* webFrame = new QWebFrame(m_webFrame, &frameData);
emit m_webFrame->page()->frameCreated(webFrame);
RefPtr<Frame> childFrame = adoptRef(webFrame->d->frame);
// ### set override encoding if we have one
FrameLoadType loadType = m_frame->loader()->loadType();
FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedBackForwardList;
childFrame->loader()->loadURLIntoChildFrame(frameData.url, frameData.referrer, childFrame.get());
// The frame's onload handler may have removed it from the document.
if (!childFrame->tree()->parent())
return 0;
return childFrame.release();
}
ObjectContentType FrameLoaderClientQt::objectContentType(const KURL& url, const String& _mimeType)
{
// qDebug()<<" ++++++++++++++++ url is "<<url.prettyURL()<<", mime = "<<_mimeType;
if (_mimeType == "application/x-qt-plugin" || _mimeType == "application/x-qt-styled-widget")
return ObjectContentOtherPlugin;
if (url.isEmpty() && !_mimeType.length())
return ObjectContentNone;
String mimeType = _mimeType;
if (!mimeType.length()) {
QFileInfo fi(url.path());
mimeType = MIMETypeRegistry::getMIMETypeForExtension(fi.suffix());
}
if (!mimeType.length())
return ObjectContentFrame;
if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
return ObjectContentImage;
if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
return ObjectContentNetscapePlugin;
if (m_frame->page() && m_frame->page()->pluginData() && m_frame->page()->pluginData()->supportsMimeType(mimeType))
return ObjectContentOtherPlugin;
if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
return ObjectContentFrame;
if (url.protocol() == "about")
return ObjectContentFrame;
return ObjectContentNone;
}
static const CSSPropertyID qstyleSheetProperties[] = {
CSSPropertyColor,
CSSPropertyFontFamily,
CSSPropertyFontSize,
CSSPropertyFontStyle,
CSSPropertyFontWeight
};
const unsigned numqStyleSheetProperties = sizeof(qstyleSheetProperties) / sizeof(qstyleSheetProperties[0]);
class QtPluginWidget: public Widget
{
public:
QtPluginWidget(QWidget* w = 0): Widget(w) {}
~QtPluginWidget()
{
if (platformWidget())
platformWidget()->deleteLater();
}
virtual void invalidateRect(const IntRect& r)
{
if (platformWidget())
platformWidget()->update(r);
}
virtual void frameRectsChanged()
{
if (!platformWidget())
return;
IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height()));
platformWidget()->setGeometry(windowRect);
ScrollView* parentScrollView = parent();
if (!parentScrollView)
return;
ASSERT(parentScrollView->isFrameView());
IntRect clipRect(static_cast<FrameView*>(parentScrollView)->windowClipRect());
clipRect.move(-windowRect.x(), -windowRect.y());
clipRect.intersect(platformWidget()->rect());
QRegion clipRegion = QRegion(clipRect);
platformWidget()->setMask(clipRegion);
// if setMask is set with an empty QRegion, no clipping will
// be performed, so in that case we hide the platformWidget
platformWidget()->setVisible(!clipRegion.isEmpty());
}
};
PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames,
const Vector<String>& paramValues, const String& mimeType, bool loadManually)
{
// qDebug()<<"------ Creating plugin in FrameLoaderClientQt::createPlugin for "<<url.prettyURL() << mimeType;
// qDebug()<<"------\t url = "<<url.prettyURL();
if (!m_webFrame)
return 0;
QStringList params;
QStringList values;
QString classid(element->getAttribute("classid"));
for (int i = 0; i < paramNames.size(); ++i) {
params.append(paramNames[i]);
if (paramNames[i] == "classid")
classid = paramValues[i];
}
for (int i = 0; i < paramValues.size(); ++i)
values.append(paramValues[i]);
QString urlStr(url.string());
QUrl qurl = urlStr;
QObject* object = 0;
if (mimeType == "application/x-qt-plugin" || mimeType == "application/x-qt-styled-widget") {
object = m_webFrame->page()->createPlugin(classid, qurl, params, values);
#ifndef QT_NO_STYLE_STYLESHEET
QWidget* widget = qobject_cast<QWidget*>(object);
if (widget && mimeType == "application/x-qt-styled-widget") {
QString styleSheet = element->getAttribute("style");
if (!styleSheet.isEmpty())
styleSheet += QLatin1Char(';');
for (int i = 0; i < numqStyleSheetProperties; ++i) {
CSSPropertyID property = qstyleSheetProperties[i];
styleSheet += QString::fromLatin1(::getPropertyName(property));
styleSheet += QLatin1Char(':');
styleSheet += computedStyle(element)->getPropertyValue(property);
styleSheet += QLatin1Char(';');
}
widget->setStyleSheet(styleSheet);
}
#endif // QT_NO_STYLE_STYLESHEET
}
#if QT_VERSION >= 0x040400
if (!object) {
QWebPluginFactory* factory = m_webFrame->page()->pluginFactory();
if (factory)
object = factory->create(mimeType, qurl, params, values);
}
#endif
if (object) {
QWidget* widget = qobject_cast<QWidget*>(object);
if (widget) {
QWidget* view = m_webFrame->page()->view();
if (view)
widget->setParent(view);
RefPtr<QtPluginWidget> w = adoptRef(new QtPluginWidget());
w->setPlatformWidget(widget);
// Make sure it's invisible until properly placed into the layout
w->setFrameRect(IntRect(0, 0, 0, 0));
return w;
}
// FIXME: make things work for widgetless plugins as well
delete object;
} else { // NPAPI Plugins
RefPtr<PluginView> pluginView = PluginView::create(m_frame, pluginSize, element, url,
paramNames, paramValues, mimeType, loadManually);
return pluginView;
}
return 0;
}
void FrameLoaderClientQt::redirectDataToPlugin(Widget* pluginWidget)
{
ASSERT(!m_pluginView);
m_pluginView = static_cast<PluginView*>(pluginWidget);
m_hasSentResponseToPlugin = false;
}
PassRefPtr<Widget> FrameLoaderClientQt::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL,
const Vector<String>& paramNames, const Vector<String>& paramValues)
{
notImplemented();
return 0;
}
String FrameLoaderClientQt::overrideMediaType() const
{
return String();
}
QString FrameLoaderClientQt::chooseFile(const QString& oldFile)
{
return webFrame()->page()->chooseFile(webFrame(), oldFile);
}
}
#include "moc_FrameLoaderClientQt.cpp"