| /* |
| * 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" |