2 * Copyright (C) 2006 Zack Rusin <zack@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@forwardbias.in>
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
34 #include "FrameLoaderClientQt.h"
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 "HTTPStatusCodes.h"
48 #include "HistoryItem.h"
49 #include "HitTestResult.h"
50 #if ENABLE(ICONDATABASE)
51 #include "IconDatabaseClientQt.h"
54 #include "JSDOMWindowBase.h"
56 #include "MIMETypeRegistry.h"
57 #include "MouseEvent.h"
58 #include "NotImplemented.h"
60 #include "PluginData.h"
61 #include "PluginDatabase.h"
62 #include "ProgressTracker.h"
63 #include "QNetworkReplyHandler.h"
64 #include "QWebPageClient.h"
65 #include "RenderPart.h"
66 #include "ResourceHandle.h"
67 #include "ResourceHandleInternal.h"
68 #include "ResourceRequest.h"
69 #include "ResourceResponse.h"
70 #include "ScriptController.h"
73 #include "V8DOMWindow.h"
75 #include "ViewportArguments.h"
77 #include "qwebframe.h"
78 #include "qwebframe_p.h"
79 #include "qwebhistory_p.h"
80 #include "qwebhistoryinterface.h"
82 #include "qwebpage_p.h"
83 #include "qwebpluginfactory.h"
85 #include <QCoreApplication>
88 #include <QGraphicsScene>
89 #include <QGraphicsWidget>
90 #include <QNetworkReply>
91 #include <QNetworkRequest>
92 #include <QStringList>
93 #include <wtf/OwnPtr.h>
95 static QMap<unsigned long, QString> dumpAssignedUrls;
97 // Compare with the file "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm".
98 static QString drtDescriptionSuitableForTestResult(WebCore::Frame* webCoreFrame)
100 QWebFrame* frame = QWebFramePrivate::kit(webCoreFrame);
101 QString name = frame->frameName();
103 bool isMainFrame = frame == frame->page()->mainFrame();
106 return QString::fromLatin1("main frame \"%1\"").arg(name);
107 return QLatin1String("main frame");
110 return QString::fromLatin1("frame \"%1\"").arg(name);
111 return QLatin1String("frame (anonymous)");
114 static QString drtPrintFrameUserGestureStatus(WebCore::Frame* frame)
116 if (WebCore::ScriptController::processingUserGesture())
117 return QString::fromLatin1("Frame with user gesture \"%1\"").arg(QLatin1String("true"));
118 return QString::fromLatin1("Frame with user gesture \"%1\"").arg(QLatin1String("false"));
121 static QString drtDescriptionSuitableForTestResult(const WebCore::KURL& kurl)
123 if (kurl.isEmpty() || !kurl.isLocalFile())
124 return kurl.string();
125 // Remove the leading path from file urls.
126 return QString(kurl.string()).remove(WebCore::FrameLoaderClientQt::dumpResourceLoadCallbacksPath).mid(1);
129 static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceError& error)
131 QString failingURL = error.failingURL();
132 return QString::fromLatin1("<NSError domain NSURLErrorDomain, code %1, failing URL \"%2\">").arg(error.errorCode()).arg(failingURL);
135 static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceRequest& request)
137 QString url = drtDescriptionSuitableForTestResult(request.url());
138 QString httpMethod = request.httpMethod();
139 QString mainDocumentUrl = drtDescriptionSuitableForTestResult(request.firstPartyForCookies());
140 return QString::fromLatin1("<NSURLRequest URL %1, main document URL %2, http method %3>").arg(url).arg(mainDocumentUrl).arg(httpMethod);
143 static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceResponse& response)
145 QString url = drtDescriptionSuitableForTestResult(response.url());
146 int httpStatusCode = response.httpStatusCode();
147 return QString::fromLatin1("<NSURLResponse %1, http status code %2>").arg(url).arg(httpStatusCode);
150 static QString drtDescriptionSuitableForTestResult(const RefPtr<WebCore::Node> node, int exception)
154 result.append(QLatin1String("ERROR"));
158 result.append(QLatin1String("NULL"));
161 result.append(node->nodeName());
162 RefPtr<WebCore::Node> parent = node->parentNode();
164 result.append(QLatin1String(" > "));
165 result.append(drtDescriptionSuitableForTestResult(parent, 0));
172 bool FrameLoaderClientQt::dumpFrameLoaderCallbacks = false;
173 bool FrameLoaderClientQt::dumpProgressFinishedCallback = false;
174 bool FrameLoaderClientQt::dumpUserGestureInFrameLoaderCallbacks = false;
175 bool FrameLoaderClientQt::dumpWillCacheResponseCallbacks = false;
176 bool FrameLoaderClientQt::dumpResourceLoadCallbacks = false;
177 bool FrameLoaderClientQt::sendRequestReturnsNullOnRedirect = false;
178 bool FrameLoaderClientQt::sendRequestReturnsNull = false;
179 bool FrameLoaderClientQt::dumpResourceResponseMIMETypes = false;
180 bool FrameLoaderClientQt::deferMainResourceDataLoad = true;
181 bool FrameLoaderClientQt::dumpHistoryCallbacks = false;
183 QStringList FrameLoaderClientQt::sendRequestClearHeaders;
184 QString FrameLoaderClientQt::dumpResourceLoadCallbacksPath;
185 bool FrameLoaderClientQt::policyDelegateEnabled = false;
186 bool FrameLoaderClientQt::policyDelegatePermissive = false;
187 QMap<QString, QString> FrameLoaderClientQt::URLsToRedirect = QMap<QString, QString>();
189 // Taken from the file "WebKit/Tools/DumpRenderTree/chromium/WebViewHost.cpp".
190 static const char* navigationTypeToString(NavigationType type)
193 case NavigationTypeLinkClicked:
194 return "link clicked";
195 case NavigationTypeFormSubmitted:
196 return "form submitted";
197 case NavigationTypeBackForward:
198 return "back/forward";
199 case NavigationTypeReload:
201 case NavigationTypeFormResubmitted:
202 return "form resubmitted";
203 case NavigationTypeOther:
206 return "illegal value";
209 FrameLoaderClientQt::FrameLoaderClientQt()
213 , m_hasSentResponseToPlugin(false)
214 , m_hasRepresentation(false)
215 , m_isOriginatingLoad(false)
220 FrameLoaderClientQt::~FrameLoaderClientQt()
224 void FrameLoaderClientQt::setFrame(QWebFrame* webFrame, Frame* frame)
226 m_webFrame = webFrame;
229 if (!m_webFrame || !m_webFrame->page()) {
230 qWarning("FrameLoaderClientQt::setFrame frame without Page!");
234 connect(this, SIGNAL(loadProgress(int)),
235 m_webFrame->page(), SIGNAL(loadProgress(int)));
237 connect(this, SIGNAL(unsupportedContent(QNetworkReply*)),
238 m_webFrame->page(), SIGNAL(unsupportedContent(QNetworkReply*)));
240 connect(this, SIGNAL(titleChanged(QString)),
241 m_webFrame, SIGNAL(titleChanged(QString)));
244 void FrameLoaderClientQt::callPolicyFunction(FramePolicyFunction function, PolicyAction action)
246 (m_frame->loader()->policyChecker()->*function)(action);
249 bool FrameLoaderClientQt::hasWebView() const
255 void FrameLoaderClientQt::savePlatformDataToCachedFrame(CachedFrame*)
260 void FrameLoaderClientQt::transitionToCommittedFromCachedFrame(CachedFrame*)
264 void FrameLoaderClientQt::transitionToCommittedForNewPage()
269 QBrush brush = m_webFrame->page()->palette().brush(QPalette::Base);
270 QColor backgroundColor = brush.style() == Qt::SolidPattern ? brush.color() : QColor();
272 QWebPage* page = m_webFrame->page();
273 const QSize preferredLayoutSize = page->preferredContentsSize();
275 ScrollbarMode hScrollbar = (ScrollbarMode) m_webFrame->scrollBarPolicy(Qt::Horizontal);
276 ScrollbarMode vScrollbar = (ScrollbarMode) m_webFrame->scrollBarPolicy(Qt::Vertical);
277 bool hLock = hScrollbar != ScrollbarAuto;
278 bool vLock = vScrollbar != ScrollbarAuto;
280 IntSize currentVisibleContentSize = m_frame->view() ? m_frame->view()->visibleContentRect().size() : IntSize();
282 m_frame->createView(m_webFrame->page()->viewportSize(),
283 backgroundColor, !backgroundColor.alpha(),
284 preferredLayoutSize.isValid() ? IntSize(preferredLayoutSize) : IntSize(),
285 preferredLayoutSize.isValid(),
289 bool isMainFrame = m_frame == m_frame->page()->mainFrame();
290 if (isMainFrame && page->d->client) {
291 bool resizesToContents = page->d->client->viewResizesToContentsEnabled();
293 m_frame->view()->setPaintsEntireContents(resizesToContents);
294 m_frame->view()->setDelegatesScrolling(resizesToContents);
296 // The HistoryController will update the scroll position later if needed.
297 IntRect rect = resizesToContents ? IntRect(IntPoint::zero(), currentVisibleContentSize) : IntRect();
298 m_frame->view()->setFixedVisibleContentRect(rect);
302 void FrameLoaderClientQt::didSaveToPageCache()
306 void FrameLoaderClientQt::didRestoreFromPageCache()
310 void FrameLoaderClientQt::dispatchDidBecomeFrameset(bool)
314 void FrameLoaderClientQt::makeRepresentation(DocumentLoader*)
316 m_hasRepresentation = true;
320 void FrameLoaderClientQt::forceLayout()
322 FrameView* view = m_frame->view();
328 void FrameLoaderClientQt::forceLayoutForNonHTML()
333 void FrameLoaderClientQt::setCopiesOnScroll()
335 // Apparently this is mac specific.
339 void FrameLoaderClientQt::detachedFromParent2()
344 void FrameLoaderClientQt::detachedFromParent3()
348 void FrameLoaderClientQt::dispatchDidHandleOnloadEvents()
350 // Don't need this one.
351 if (dumpFrameLoaderCallbacks)
352 printf("%s - didHandleOnloadEventsForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
356 void FrameLoaderClientQt::dispatchDidReceiveServerRedirectForProvisionalLoad()
358 if (dumpFrameLoaderCallbacks)
359 printf("%s - didReceiveServerRedirectForProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
365 void FrameLoaderClientQt::dispatchDidCancelClientRedirect()
367 if (dumpFrameLoaderCallbacks)
368 printf("%s - didCancelClientRedirectForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
374 void FrameLoaderClientQt::dispatchWillPerformClientRedirect(const KURL& url, double, double)
376 if (dumpFrameLoaderCallbacks)
377 printf("%s - willPerformClientRedirectToURL: %s \n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(drtDescriptionSuitableForTestResult(url)));
379 if (dumpUserGestureInFrameLoaderCallbacks)
380 printf("%s - in willPerformClientRedirect\n", qPrintable(drtPrintFrameUserGestureStatus(m_frame)));
386 void FrameLoaderClientQt::dispatchDidChangeLocationWithinPage()
388 if (dumpFrameLoaderCallbacks)
389 printf("%s - didChangeLocationWithinPageForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
394 m_webFrame->d->emitUrlChanged();
395 m_webFrame->page()->d->updateNavigationActions();
399 void FrameLoaderClientQt::didCreateScriptContext(v8::Handle<v8::Context>, int)
402 void FrameLoaderClientQt::willReleaseScriptContext(v8::Handle<v8::Context>, int)
405 void FrameLoaderClientQt::didCreateIsolatedScriptContext()
410 void FrameLoaderClientQt::dispatchDidPushStateWithinPage()
412 if (dumpFrameLoaderCallbacks)
413 printf("%s - dispatchDidPushStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
418 void FrameLoaderClientQt::dispatchDidReplaceStateWithinPage()
420 if (dumpFrameLoaderCallbacks)
421 printf("%s - dispatchDidReplaceStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
426 void FrameLoaderClientQt::dispatchDidPopStateWithinPage()
428 if (dumpFrameLoaderCallbacks)
429 printf("%s - dispatchDidPopStateWithinPage\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
434 void FrameLoaderClientQt::dispatchWillClose()
439 void FrameLoaderClientQt::dispatchDidStartProvisionalLoad()
441 if (dumpFrameLoaderCallbacks)
442 printf("%s - didStartProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
444 if (dumpUserGestureInFrameLoaderCallbacks)
445 printf("%s - in didStartProvisionalLoadForFrame\n", qPrintable(drtPrintFrameUserGestureStatus(m_frame)));
447 m_lastRequestedUrl = m_frame->loader()->activeDocumentLoader()->requestURL();
452 postProgressEstimateChangedNotification();
453 emit m_webFrame->provisionalLoad();
457 void FrameLoaderClientQt::dispatchDidReceiveTitle(const StringWithDirection& title)
459 // FIXME: Use direction of title.
460 if (dumpFrameLoaderCallbacks)
461 printf("%s - didReceiveTitle: %s\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(QString(title.string())));
466 emit titleChanged(title.string());
470 void FrameLoaderClientQt::dispatchDidChangeIcons(WebCore::IconType)
472 if (dumpFrameLoaderCallbacks)
473 printf("%s - didChangeIcons\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
478 // FIXME: In order to get notified of icon URLS' changes, add a notification.
479 // emit iconsChanged();
483 void FrameLoaderClientQt::dispatchDidCommitLoad()
485 if (dumpFrameLoaderCallbacks)
486 printf("%s - didCommitLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
488 if (m_frame->tree()->parent() || !m_webFrame)
491 m_webFrame->d->emitUrlChanged();
492 m_webFrame->page()->d->updateNavigationActions();
494 // We should assume first the frame has no title. If it has, then the above dispatchDidReceiveTitle()
495 // will be called very soon with the correct title.
496 // This properly resets the title when we navigate to a URI without a title.
497 emit titleChanged(QString());
499 bool isMainFrame = (m_frame == m_frame->page()->mainFrame());
503 emit m_webFrame->page()->viewportChangeRequested();
507 void FrameLoaderClientQt::dispatchDidFinishDocumentLoad()
509 if (dumpFrameLoaderCallbacks)
510 printf("%s - didFinishDocumentLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
512 if (QWebPagePrivate::drtRun) {
513 int unloadEventCount = m_frame->domWindow()->pendingUnloadEventListeners();
514 if (unloadEventCount)
515 printf("%s - has %u onunload handler(s)\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), unloadEventCount);
518 if (m_frame->tree()->parent() || !m_webFrame)
521 m_webFrame->page()->d->updateNavigationActions();
525 void FrameLoaderClientQt::dispatchDidFinishLoad()
527 if (dumpFrameLoaderCallbacks)
528 printf("%s - didFinishLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
533 m_webFrame->page()->d->updateNavigationActions();
534 emitLoadFinished(true);
538 void FrameLoaderClientQt::dispatchDidFirstLayout()
542 void FrameLoaderClientQt::dispatchDidFirstVisuallyNonEmptyLayout()
545 emit m_webFrame->initialLayoutCompleted();
548 void FrameLoaderClientQt::dispatchShow()
554 void FrameLoaderClientQt::cancelPolicyCheck()
556 // qDebug() << "FrameLoaderClientQt::cancelPolicyCheck";
560 void FrameLoaderClientQt::dispatchWillSubmitForm(FramePolicyFunction function,
561 PassRefPtr<FormState>)
564 // FIXME: This is surely too simple.
565 callPolicyFunction(function, PolicyUse);
569 void FrameLoaderClientQt::dispatchDidLoadMainResource(DocumentLoader*)
574 void FrameLoaderClientQt::revertToProvisionalState(DocumentLoader*)
576 m_hasRepresentation = true;
580 void FrameLoaderClientQt::postProgressStartedNotification()
582 if (m_webFrame && m_frame->page())
583 m_isOriginatingLoad = true;
584 if (m_frame->tree()->parent() || !m_webFrame)
586 m_webFrame->page()->d->updateNavigationActions();
589 void FrameLoaderClientQt::postProgressEstimateChangedNotification()
591 if (m_webFrame && m_frame->page())
592 emit loadProgress(qRound(m_frame->page()->progress()->estimatedProgress() * 100));
595 void FrameLoaderClientQt::postProgressFinishedNotification()
597 if (dumpProgressFinishedCallback)
598 printf("postProgressFinishedNotification\n");
600 // Send a mousemove event to:
601 // (1) update the cursor to change according to whatever is underneath the mouse cursor right now;
602 // (2) display the tool tip if the mouse hovers a node which has a tool tip.
603 if (m_frame && m_frame->eventHandler() && m_webFrame->page()) {
604 QWidget* view = m_webFrame->page()->view();
605 if (view && view->hasFocus()) {
606 QPoint localPos = view->mapFromGlobal(QCursor::pos());
607 if (view->rect().contains(localPos)) {
608 QMouseEvent event(QEvent::MouseMove, localPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
609 m_frame->eventHandler()->mouseMoved(PlatformMouseEvent(&event, 0));
615 void FrameLoaderClientQt::setMainFrameDocumentReady(bool)
617 // This is only interesting once we provide an external API for the DOM.
621 void FrameLoaderClientQt::willChangeTitle(DocumentLoader*)
623 // No need for, dispatchDidReceiveTitle is the right callback.
627 void FrameLoaderClientQt::didChangeTitle(DocumentLoader*)
629 // No need for, dispatchDidReceiveTitle is the right callback.
633 void FrameLoaderClientQt::finishedLoading(DocumentLoader* loader)
636 // This is necessary to create an empty document. See bug 634004.
637 // However, we only want to do this if makeRepresentation has been called,
638 // to match the behavior on the Mac.
639 if (m_hasRepresentation)
640 loader->writer()->setEncoding("", false);
643 if (m_pluginView->isPluginView())
644 m_pluginView->didFinishLoading();
646 m_hasSentResponseToPlugin = false;
649 bool FrameLoaderClientQt::canShowMIMETypeAsHTML(const String& MIMEType) const
655 bool FrameLoaderClientQt::canShowMIMEType(const String& MIMEType) const
657 String type = MIMEType;
659 if (MIMETypeRegistry::isSupportedImageMIMEType(type))
662 if (MIMETypeRegistry::isSupportedNonImageMIMEType(type))
665 if (MIMETypeRegistry::isSupportedMediaMIMEType(type))
668 if (m_frame && m_frame->settings() && m_frame->settings()->arePluginsEnabled()
669 && PluginDatabase::installedPlugins()->isMIMETypeRegistered(type))
675 bool FrameLoaderClientQt::representationExistsForURLScheme(const String&) const
681 String FrameLoaderClientQt::generatedMIMETypeForURLScheme(const String&) const
688 void FrameLoaderClientQt::frameLoadCompleted()
690 // Note that this can be called multiple times.
693 m_webFrame->page()->d->updateNavigationActions();
697 void FrameLoaderClientQt::restoreViewState()
701 emit m_webFrame->page()->restoreFrameStateRequested(m_webFrame);
705 void FrameLoaderClientQt::provisionalLoadStarted()
707 // Don't need to do anything here.
711 void FrameLoaderClientQt::didFinishLoad()
717 void FrameLoaderClientQt::prepareForDataSourceReplacement()
721 void FrameLoaderClientQt::setTitle(const StringWithDirection& title, const KURL& url)
723 // Used by Apple WebKit to update the title of an existing history item.
724 // QtWebKit doesn't accomodate this on history items. If it ever does,
725 // it should be privateBrowsing-aware. For now, we are just passing
726 // globalhistory layout tests.
727 // FIXME: Use direction of title.
728 if (dumpHistoryCallbacks) {
729 printf("WebView updated the title for history URL \"%s\" to \"%s\".\n",
730 qPrintable(drtDescriptionSuitableForTestResult(url)),
731 qPrintable(QString(title.string())));
736 String FrameLoaderClientQt::userAgent(const KURL& url)
739 return m_webFrame->page()->userAgentForUrl(url).remove(QLatin1Char('\n')).remove(QLatin1Char('\r'));
744 void FrameLoaderClientQt::dispatchDidReceiveIcon()
747 emit m_webFrame->iconChanged();
750 void FrameLoaderClientQt::frameLoaderDestroyed()
759 bool FrameLoaderClientQt::canHandleRequest(const WebCore::ResourceRequest&) const
764 void FrameLoaderClientQt::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
766 if (world != mainThreadNormalWorld())
770 m_webFrame->d->didClearWindowObject();
773 void FrameLoaderClientQt::documentElementAvailable()
778 void FrameLoaderClientQt::didPerformFirstNavigation() const
780 if (m_frame->tree()->parent() || !m_webFrame)
782 m_webFrame->page()->d->updateNavigationActions();
785 void FrameLoaderClientQt::registerForIconNotification(bool shouldRegister)
787 #if ENABLE(ICONDATABASE)
789 connect(IconDatabaseClientQt::instance(), SIGNAL(iconLoadedForPageURL(QString)), this, SLOT(onIconLoadedForPageURL(QString)), Qt::UniqueConnection);
791 disconnect(IconDatabaseClientQt::instance(), SIGNAL(iconLoadedForPageURL(QString)), this, SLOT(onIconLoadedForPageURL(QString)));
795 void FrameLoaderClientQt::onIconLoadedForPageURL(const QString& url)
797 #if ENABLE(ICONDATABASE)
798 if (m_webFrame && m_webFrame->url() == url)
799 emit m_webFrame->iconChanged();
804 void FrameLoaderClientQt::updateGlobalHistory()
806 QWebHistoryInterface* history = QWebHistoryInterface::defaultInterface();
807 WebCore::DocumentLoader* loader = m_frame->loader()->documentLoader();
809 history->addHistoryEntry(loader->urlForHistory().string());
811 if (dumpHistoryCallbacks) {
812 printf("WebView navigated to url \"%s\" with title \"%s\" with HTTP equivalent method \"%s\". The navigation was %s and was %s%s.\n",
813 qPrintable(drtDescriptionSuitableForTestResult(loader->urlForHistory())),
814 qPrintable(QString(loader->title().string())),
815 qPrintable(QString(loader->request().httpMethod())),
816 ((loader->substituteData().isValid() || (loader->response().httpStatusCode() >= 400)) ? "a failure" : "successful"),
817 ((!loader->clientRedirectSourceForHistory().isEmpty()) ? "a client redirect from " : "not a client redirect"),
818 (!loader->clientRedirectSourceForHistory().isEmpty()) ? qPrintable(drtDescriptionSuitableForTestResult(loader->clientRedirectSourceForHistory())) : "");
822 void FrameLoaderClientQt::updateGlobalHistoryRedirectLinks()
824 // Apple WebKit is the only port that makes use of this callback. It calls
825 // WebCore::HistoryItem::addRedirectURL() with the contents of
826 // loader->[server|client]RedirectDestinationForHistory().
827 // WebCore can associate a bunch of redirect URLs with a particular
828 // item in the history, presumably this allows Safari to skip the redirections
829 // when navigating to that history item. That might be a feature Qt wants to
830 // offer through QWebHistoryInterface in the future. For now, we're just
831 // passing tests in LayoutTests/http/tests/globalhistory.
832 WebCore::DocumentLoader* loader = m_frame->loader()->documentLoader();
834 if (!loader->clientRedirectSourceForHistory().isNull()) {
835 if (dumpHistoryCallbacks) {
836 printf("WebView performed a client redirect from \"%s\" to \"%s\".\n",
837 qPrintable(QString(loader->clientRedirectSourceForHistory())),
838 qPrintable(QString(loader->clientRedirectDestinationForHistory())));
842 if (!loader->serverRedirectSourceForHistory().isNull()) {
843 if (dumpHistoryCallbacks) {
844 printf("WebView performed a server redirect from \"%s\" to \"%s\".\n",
845 qPrintable(QString(loader->serverRedirectSourceForHistory())),
846 qPrintable(QString(loader->serverRedirectDestinationForHistory())));
851 bool FrameLoaderClientQt::shouldGoToHistoryItem(WebCore::HistoryItem*) const
856 bool FrameLoaderClientQt::shouldStopLoadingForHistoryItem(WebCore::HistoryItem*) const
861 void FrameLoaderClientQt::didDisplayInsecureContent()
863 if (dumpFrameLoaderCallbacks)
864 printf("didDisplayInsecureContent\n");
869 void FrameLoaderClientQt::didRunInsecureContent(WebCore::SecurityOrigin*, const KURL&)
871 if (dumpFrameLoaderCallbacks)
872 printf("didRunInsecureContent\n");
877 void FrameLoaderClientQt::didDetectXSS(const KURL&, bool)
879 if (dumpFrameLoaderCallbacks)
880 printf("didDetectXSS\n");
885 void FrameLoaderClientQt::saveViewStateToItem(WebCore::HistoryItem* item)
887 QWebHistoryItem historyItem(new QWebHistoryItemPrivate(item));
888 emit m_webFrame->page()->saveFrameStateRequested(m_webFrame, &historyItem);
891 bool FrameLoaderClientQt::canCachePage() const
896 void FrameLoaderClientQt::setMainDocumentError(WebCore::DocumentLoader* loader, const WebCore::ResourceError& error)
900 if (m_pluginView->isPluginView())
901 m_pluginView->didFail(error);
903 m_hasSentResponseToPlugin = false;
906 // FIXME: This function should be moved into WebCore.
907 void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length)
910 loader->commitData(data, length);
912 // If we are sending data to MediaDocument, we should stop here and cancel the request.
913 if (m_frame->document()->isMediaDocument())
914 loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
916 // We re-check here as the plugin can have been created.
917 if (m_pluginView && m_pluginView->isPluginView()) {
918 if (!m_hasSentResponseToPlugin) {
919 m_pluginView->didReceiveResponse(loader->response());
920 // The function didReceiveResponse sets up a new stream to the plug-in.
921 // On a full-page plug-in, a failure in setting up this stream can cause the
922 // main document load to be cancelled, setting m_pluginView to null.
925 m_hasSentResponseToPlugin = true;
927 m_pluginView->didReceiveData(data, length);
931 WebCore::ResourceError FrameLoaderClientQt::cancelledError(const WebCore::ResourceRequest& request)
933 ResourceError error = ResourceError("QtNetwork", QNetworkReply::OperationCanceledError, request.url().string(),
934 QCoreApplication::translate("QWebFrame", "Request cancelled", 0, QCoreApplication::UnicodeUTF8));
935 error.setIsCancellation(true);
939 // This was copied from file "WebKit/Source/WebKit/mac/Misc/WebKitErrors.h".
941 WebKitErrorCannotShowMIMEType = 100,
942 WebKitErrorCannotShowURL = 101,
943 WebKitErrorFrameLoadInterruptedByPolicyChange = 102,
944 WebKitErrorCannotUseRestrictedPort = 103,
945 WebKitErrorCannotFindPlugIn = 200,
946 WebKitErrorCannotLoadPlugIn = 201,
947 WebKitErrorJavaUnavailable = 202,
948 WebKitErrorPluginWillHandleLoad = 203
951 WebCore::ResourceError FrameLoaderClientQt::blockedError(const WebCore::ResourceRequest& request)
953 return ResourceError("WebKitErrorDomain", WebKitErrorCannotUseRestrictedPort, request.url().string(),
954 QCoreApplication::translate("QWebFrame", "Request blocked", 0, QCoreApplication::UnicodeUTF8));
958 WebCore::ResourceError FrameLoaderClientQt::cannotShowURLError(const WebCore::ResourceRequest& request)
960 return ResourceError("WebKitErrorDomain", WebKitErrorCannotShowURL, request.url().string(),
961 QCoreApplication::translate("QWebFrame", "Cannot show URL", 0, QCoreApplication::UnicodeUTF8));
964 WebCore::ResourceError FrameLoaderClientQt::interruptedForPolicyChangeError(const WebCore::ResourceRequest& request)
966 return ResourceError("WebKitErrorDomain", WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(),
967 QCoreApplication::translate("QWebFrame", "Frame load interrupted by policy change", 0, QCoreApplication::UnicodeUTF8));
970 WebCore::ResourceError FrameLoaderClientQt::cannotShowMIMETypeError(const WebCore::ResourceResponse& response)
972 return ResourceError("WebKitErrorDomain", WebKitErrorCannotShowMIMEType, response.url().string(),
973 QCoreApplication::translate("QWebFrame", "Cannot show mimetype", 0, QCoreApplication::UnicodeUTF8));
976 WebCore::ResourceError FrameLoaderClientQt::fileDoesNotExistError(const WebCore::ResourceResponse& response)
978 return ResourceError("QtNetwork", QNetworkReply::ContentNotFoundError, response.url().string(),
979 QCoreApplication::translate("QWebFrame", "File does not exist", 0, QCoreApplication::UnicodeUTF8));
982 WebCore::ResourceError FrameLoaderClientQt::pluginWillHandleLoadError(const WebCore::ResourceResponse& response)
984 return ResourceError("WebKit", WebKitErrorPluginWillHandleLoad, response.url().string(),
985 QCoreApplication::translate("QWebFrame", "Loading is handled by the media engine", 0, QCoreApplication::UnicodeUTF8));
988 bool FrameLoaderClientQt::shouldFallBack(const WebCore::ResourceError& error)
990 DEFINE_STATIC_LOCAL(const ResourceError, cancelledError, (this->cancelledError(ResourceRequest())));
991 DEFINE_STATIC_LOCAL(const ResourceError, pluginWillHandleLoadError, (this->pluginWillHandleLoadError(ResourceResponse())));
992 DEFINE_STATIC_LOCAL(const ResourceError, errorInterruptedForPolicyChange, (this->interruptedForPolicyChangeError(ResourceRequest())));
994 if (error.errorCode() == cancelledError.errorCode() && error.domain() == cancelledError.domain())
997 if (error.errorCode() == errorInterruptedForPolicyChange.errorCode() && error.domain() == errorInterruptedForPolicyChange.domain())
1000 if (error.errorCode() == pluginWillHandleLoadError.errorCode() && error.domain() == pluginWillHandleLoadError.domain())
1006 WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClientQt::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData)
1008 RefPtr<DocumentLoader> loader = DocumentLoader::create(request, substituteData);
1009 if (!deferMainResourceDataLoad || substituteData.isValid()) {
1010 loader->setDeferMainResourceDataLoad(false);
1011 // Use the default timeout interval for JS as the HTML tokenizer delay. This ensures
1012 // that long-running JavaScript will still allow setHtml() to be synchronous, while
1013 // still giving a reasonable timeout to prevent deadlock.
1015 double delay = JSDOMWindowBase::commonJSGlobalData()->timeoutChecker.timeoutInterval() / 1000.0f;
1017 // FIXME: Hard coded for now.
1018 double delay = 10000 / 1000.0f;
1020 m_frame->page()->setCustomHTMLTokenizerTimeDelay(delay);
1022 m_frame->page()->setCustomHTMLTokenizerTimeDelay(-1);
1023 return loader.release();
1026 void FrameLoaderClientQt::download(WebCore::ResourceHandle* handle, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&)
1031 QNetworkReplyHandler* handler = handle->getInternal()->m_job;
1032 QNetworkReply* reply = handler->release();
1034 QWebPage* page = m_webFrame->page();
1035 if (page->forwardUnsupportedContent())
1036 emit unsupportedContent(reply);
1042 void FrameLoaderClientQt::assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader*, const WebCore::ResourceRequest& request)
1044 if (dumpResourceLoadCallbacks)
1045 dumpAssignedUrls[identifier] = drtDescriptionSuitableForTestResult(request.url());
1048 void FrameLoaderClientQt::dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest& newRequest, const WebCore::ResourceResponse& redirectResponse)
1050 QUrl url = newRequest.url();
1052 if (dumpResourceLoadCallbacks)
1053 printf("%s - willSendRequest %s redirectResponse %s\n",
1054 qPrintable(dumpAssignedUrls[identifier]),
1055 qPrintable(drtDescriptionSuitableForTestResult(newRequest)),
1056 (redirectResponse.isNull()) ? "(null)" : qPrintable(drtDescriptionSuitableForTestResult(redirectResponse)));
1058 if (sendRequestReturnsNull) {
1059 newRequest.setURL(QUrl());
1063 if (sendRequestReturnsNullOnRedirect && !redirectResponse.isNull()) {
1064 printf("Returning null for this redirect\n");
1065 newRequest.setURL(QUrl());
1069 if (QWebPagePrivate::drtRun
1071 && (url.scheme().toLower() == QLatin1String("http") || url.scheme().toLower() == QLatin1String("https"))
1072 && url.host() != QLatin1String("127.0.0.1")
1073 && url.host() != QLatin1String("255.255.255.255")
1074 && url.host().toLower() != QLatin1String("localhost")) {
1076 printf("Blocked access to external URL %s\n", qPrintable(drtDescriptionSuitableForTestResult(newRequest.url())));
1077 newRequest.setURL(QUrl());
1081 for (int i = 0; i < sendRequestClearHeaders.size(); ++i)
1082 newRequest.setHTTPHeaderField(sendRequestClearHeaders.at(i).toLocal8Bit().constData(), QString());
1084 if (QWebPagePrivate::drtRun) {
1085 QMap<QString, QString>::const_iterator it = URLsToRedirect.constFind(url.toString());
1086 if (it != URLsToRedirect.constEnd())
1087 newRequest.setURL(QUrl(it.value()));
1089 // Seems like the Mac code doesn't do anything here by default neither.
1090 // qDebug() << "FrameLoaderClientQt::dispatchWillSendRequest" << request.isNull() << url;
1093 bool FrameLoaderClientQt::shouldUseCredentialStorage(DocumentLoader*, unsigned long)
1099 void FrameLoaderClientQt::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
1104 void FrameLoaderClientQt::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
1109 void FrameLoaderClientQt::dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceResponse& response)
1112 m_response = response;
1113 if (dumpWillCacheResponseCallbacks)
1114 printf("%s - willCacheResponse: called\n",
1115 qPrintable(dumpAssignedUrls[identifier]));
1117 if (dumpResourceLoadCallbacks)
1118 printf("%s - didReceiveResponse %s\n",
1119 qPrintable(dumpAssignedUrls[identifier]),
1120 qPrintable(drtDescriptionSuitableForTestResult(response)));
1122 if (dumpResourceResponseMIMETypes) {
1123 printf("%s has MIME type %s\n",
1124 qPrintable(QString(response.url().lastPathComponent())),
1125 qPrintable(QString(response.mimeType())));
1129 void FrameLoaderClientQt::dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long, int)
1133 void FrameLoaderClientQt::dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier)
1135 if (dumpResourceLoadCallbacks)
1136 printf("%s - didFinishLoading\n",
1137 (dumpAssignedUrls.contains(identifier) ? qPrintable(dumpAssignedUrls[identifier]) : "<unknown>"));
1140 void FrameLoaderClientQt::dispatchDidFailLoading(WebCore::DocumentLoader* loader, unsigned long identifier, const WebCore::ResourceError& error)
1142 if (dumpResourceLoadCallbacks)
1143 printf("%s - didFailLoadingWithError: %s\n",
1144 (dumpAssignedUrls.contains(identifier) ? qPrintable(dumpAssignedUrls[identifier]) : "<unknown>"),
1145 qPrintable(drtDescriptionSuitableForTestResult(error)));
1148 bool FrameLoaderClientQt::dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int)
1154 bool FrameLoaderClientQt::callErrorPageExtension(const WebCore::ResourceError& error)
1156 QWebPage* page = m_webFrame->page();
1157 if (!page->supportsExtension(QWebPage::ErrorPageExtension))
1160 QWebPage::ErrorPageExtensionOption option;
1161 if (error.domain() == "QtNetwork")
1162 option.domain = QWebPage::QtNetwork;
1163 else if (error.domain() == "HTTP")
1164 option.domain = QWebPage::Http;
1165 else if (error.domain() == "WebKit")
1166 option.domain = QWebPage::WebKit;
1170 option.url = QUrl(error.failingURL());
1171 option.frame = m_webFrame;
1172 option.error = error.errorCode();
1173 option.errorString = error.localizedDescription();
1175 QWebPage::ErrorPageExtensionReturn output;
1176 if (!page->extension(QWebPage::ErrorPageExtension, &option, &output))
1179 KURL baseUrl(output.baseUrl);
1180 KURL failingUrl(option.url);
1182 WebCore::ResourceRequest request(baseUrl);
1183 WTF::RefPtr<WebCore::SharedBuffer> buffer = WebCore::SharedBuffer::create(output.content.constData(), output.content.length());
1184 WebCore::SubstituteData substituteData(buffer, output.contentType, output.encoding, failingUrl);
1185 m_frame->loader()->load(request, substituteData, false);
1189 void FrameLoaderClientQt::dispatchDidFailProvisionalLoad(const WebCore::ResourceError& error)
1191 if (dumpFrameLoaderCallbacks)
1192 printf("%s - didFailProvisionalLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
1194 if (!error.isNull() && !error.isCancellation()) {
1195 if (callErrorPageExtension(error))
1200 emitLoadFinished(false);
1203 void FrameLoaderClientQt::dispatchDidFailLoad(const WebCore::ResourceError& error)
1205 if (dumpFrameLoaderCallbacks)
1206 printf("%s - didFailLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
1208 if (!error.isNull() && !error.isCancellation()) {
1209 if (callErrorPageExtension(error))
1214 emitLoadFinished(false);
1217 WebCore::Frame* FrameLoaderClientQt::dispatchCreatePage(const WebCore::NavigationAction&)
1221 QWebPage *newPage = m_webFrame->page()->createWindow(QWebPage::WebBrowserWindow);
1224 return newPage->mainFrame()->d->frame;
1227 void FrameLoaderClientQt::dispatchDecidePolicyForResponse(FramePolicyFunction function, const WebCore::ResourceResponse& response, const WebCore::ResourceRequest&)
1229 // We need to call directly here.
1230 switch (response.httpStatusCode()) {
1231 case HTTPResetContent:
1232 // FIXME: a 205 response requires that the requester reset the document view.
1235 callPolicyFunction(function, PolicyIgnore);
1239 if (WebCore::contentDispositionType(response.httpHeaderField("Content-Disposition")) == WebCore::ContentDispositionAttachment)
1240 callPolicyFunction(function, PolicyDownload);
1241 else if (canShowMIMEType(response.mimeType()))
1242 callPolicyFunction(function, PolicyUse);
1244 callPolicyFunction(function, PolicyDownload);
1247 void FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>, const WTF::String&)
1249 Q_ASSERT(m_webFrame);
1250 QNetworkRequest r(request.toNetworkRequest(m_frame->loader()->networkingContext()));
1251 QWebPage* page = m_webFrame->page();
1253 if (!page->d->acceptNavigationRequest(0, r, QWebPage::NavigationType(action.type()))) {
1254 if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
1255 m_frame->loader()->resetMultipleFormSubmissionProtection();
1257 if (action.type() == NavigationTypeLinkClicked && r.url().hasFragment()) {
1258 ResourceRequest emptyRequest;
1259 m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest);
1262 callPolicyFunction(function, PolicyIgnore);
1265 callPolicyFunction(function, PolicyUse);
1268 void FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>)
1270 Q_ASSERT(m_webFrame);
1271 QNetworkRequest r(request.toNetworkRequest(m_frame->loader()->networkingContext()));
1272 QWebPage*page = m_webFrame->page();
1273 PolicyAction result;
1275 // Currently, this is only enabled by DRT.
1276 if (policyDelegateEnabled) {
1278 for (const Event* event = action.event(); event; event = event->underlyingEvent()) {
1279 if (event->isMouseEvent()) {
1280 const MouseEvent* mouseEvent = static_cast<const MouseEvent*>(event);
1281 node = QWebFramePrivate::core(m_webFrame)->eventHandler()->hitTestResultAtPoint(
1282 mouseEvent->absoluteLocation(), false).innerNonSharedNode();
1287 printf("Policy delegate: attempt to load %s with navigation type '%s'%s\n",
1288 qPrintable(drtDescriptionSuitableForTestResult(request.url())), navigationTypeToString(action.type()),
1289 (node) ? qPrintable(QString::fromLatin1(" originating from ") + drtDescriptionSuitableForTestResult(node, 0)) : "");
1291 if (policyDelegatePermissive)
1294 result = PolicyIgnore;
1296 page->d->acceptNavigationRequest(m_webFrame, r, QWebPage::NavigationType(action.type()));
1297 callPolicyFunction(function, result);
1301 if (!page->d->acceptNavigationRequest(m_webFrame, r, QWebPage::NavigationType(action.type()))) {
1302 if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
1303 m_frame->loader()->resetMultipleFormSubmissionProtection();
1305 if (action.type() == NavigationTypeLinkClicked && r.url().hasFragment()) {
1306 ResourceRequest emptyRequest;
1307 m_frame->loader()->activeDocumentLoader()->setLastCheckedRequest(emptyRequest);
1310 callPolicyFunction(function, PolicyIgnore);
1313 callPolicyFunction(function, PolicyUse);
1316 void FrameLoaderClientQt::dispatchUnableToImplementPolicy(const WebCore::ResourceError&)
1321 void FrameLoaderClientQt::startDownload(const WebCore::ResourceRequest& request, const String& /* suggestedName */)
1326 emit m_webFrame->page()->downloadRequested(request.toNetworkRequest(m_frame->loader()->networkingContext()));
1329 PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1330 const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1335 QWebFrameData frameData(m_frame->page(), m_frame, ownerElement, name);
1338 frameData.url = blankURL();
1340 frameData.url = url;
1342 frameData.referrer = referrer;
1343 frameData.allowsScrolling = allowsScrolling;
1344 frameData.marginWidth = marginWidth;
1345 frameData.marginHeight = marginHeight;
1347 QWeakPointer<QWebFrame> webFrame = new QWebFrame(m_webFrame, &frameData);
1348 // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1349 if (!webFrame.data()->d->frame->page()) {
1350 frameData.frame.release();
1351 ASSERT(webFrame.isNull());
1355 emit m_webFrame->page()->frameCreated(webFrame.data());
1357 // FIXME: Set override encoding if we have one.
1359 m_frame->loader()->loadURLIntoChildFrame(frameData.url, frameData.referrer, frameData.frame.get());
1361 // The frame's onload handler may have removed it from the document.
1362 if (!frameData.frame->tree()->parent())
1365 return frameData.frame.release();
1368 void FrameLoaderClientQt::didTransferChildFrameToNewDocument(Page*)
1370 ASSERT(m_frame->ownerElement());
1375 Frame* parentFrame = m_webFrame->d->frame->tree()->parent();
1376 ASSERT(parentFrame);
1378 if (QWebFrame* parent = QWebFramePrivate::kit(parentFrame)) {
1379 m_webFrame->d->setPage(parent->page());
1381 if (m_webFrame->parent() != qobject_cast<QObject*>(parent))
1382 m_webFrame->setParent(parent);
1386 void FrameLoaderClientQt::transferLoadingResourceFromPage(ResourceLoader*, const ResourceRequest&, Page*)
1390 ObjectContentType FrameLoaderClientQt::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
1392 // qDebug()<<" ++++++++++++++++ url is "<<url.string()<<", mime = "<<mimeTypeIn;
1393 QFileInfo fi(url.path());
1394 String extension = fi.suffix();
1395 if (mimeTypeIn == "application/x-qt-plugin" || mimeTypeIn == "application/x-qt-styled-widget")
1396 return ObjectContentOtherPlugin;
1398 if (url.isEmpty() && !mimeTypeIn.length())
1399 return ObjectContentNone;
1401 String mimeType = mimeTypeIn;
1402 if (!mimeType.length())
1403 mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
1405 if (!mimeType.length())
1406 mimeType = PluginDatabase::installedPlugins()->MIMETypeForExtension(extension);
1408 if (!mimeType.length())
1409 return ObjectContentFrame;
1411 ObjectContentType plugInType = ObjectContentNone;
1412 if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
1413 plugInType = ObjectContentNetscapePlugin;
1414 else if (m_frame->page() && m_frame->page()->pluginData() && m_frame->page()->pluginData()->supportsMimeType(mimeType))
1415 plugInType = ObjectContentOtherPlugin;
1417 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1418 return shouldPreferPlugInsForImages && plugInType != ObjectContentNone ? plugInType : ObjectContentImage;
1420 if (plugInType != ObjectContentNone)
1423 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1424 return ObjectContentFrame;
1426 if (url.protocol() == "about")
1427 return ObjectContentFrame;
1429 return ObjectContentNone;
1432 static const CSSPropertyID qstyleSheetProperties[] = {
1434 CSSPropertyFontFamily,
1435 CSSPropertyFontSize,
1436 CSSPropertyFontStyle,
1437 CSSPropertyFontWeight
1440 const unsigned numqStyleSheetProperties = sizeof(qstyleSheetProperties) / sizeof(qstyleSheetProperties[0]);
1442 class QtPluginWidget: public Widget
1445 QtPluginWidget(QWidget* w = 0): Widget(w) {}
1448 if (platformWidget())
1449 platformWidget()->deleteLater();
1451 virtual void invalidateRect(const IntRect& r)
1453 if (platformWidget())
1454 static_cast<QWidget*>(platformWidget())->update(r);
1456 virtual void frameRectsChanged()
1458 QWidget* widget = static_cast<QWidget*>(platformWidget());
1462 IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height()));
1463 widget->setGeometry(windowRect);
1465 ScrollView* parentScrollView = parent();
1466 if (!parentScrollView)
1469 ASSERT(parentScrollView->isFrameView());
1470 IntRect clipRect(static_cast<FrameView*>(parentScrollView)->windowClipRect());
1471 clipRect.move(-windowRect.x(), -windowRect.y());
1472 clipRect.intersect(widget->rect());
1474 QRegion clipRegion = QRegion(clipRect);
1475 widget->setMask(clipRegion);
1489 void handleVisibility()
1494 QWidget* widget = static_cast<QWidget*>(platformWidget());
1495 // If setMask is set with an empty QRegion, no clipping will
1496 // be performed, so in that case we hide the platformWidget.
1497 QRegion mask = widget->mask();
1498 widget->setVisible(!mask.isEmpty());
1502 #if !defined(QT_NO_GRAPHICSVIEW)
1503 class QtPluginGraphicsWidget: public Widget
1506 static RefPtr<QtPluginGraphicsWidget> create(QGraphicsWidget* w = 0)
1508 return adoptRef(new QtPluginGraphicsWidget(w));
1511 ~QtPluginGraphicsWidget()
1514 graphicsWidget->deleteLater();
1516 virtual void invalidateRect(const IntRect& r)
1518 QGraphicsScene* scene = graphicsWidget ? graphicsWidget->scene() : 0;
1520 scene->update(QRect(r));
1522 virtual void frameRectsChanged()
1524 if (!graphicsWidget)
1527 IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height()));
1528 graphicsWidget->setGeometry(QRect(windowRect));
1530 // FIXME: Make the code handle clipping of graphics widgets.
1535 graphicsWidget->show();
1540 graphicsWidget->hide();
1543 QtPluginGraphicsWidget(QGraphicsWidget* w = 0)
1547 setBindingObject(graphicsWidget);
1550 QGraphicsWidget* graphicsWidget;
1552 #endif // QT_NO_GRAPHICSVIEW
1554 PassRefPtr<Widget> FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames,
1555 const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1557 // qDebug()<<"------ Creating plugin in FrameLoaderClientQt::createPlugin for "<<url.string() << mimeType;
1558 // qDebug()<<"------\t url = "<<url.string();
1565 QString classid(element->getAttribute("classid"));
1567 for (unsigned i = 0; i < paramNames.size(); ++i) {
1568 params.append(paramNames[i]);
1569 if (paramNames[i] == "classid")
1570 classid = paramValues[i];
1572 for (unsigned i = 0; i < paramValues.size(); ++i)
1573 values.append(paramValues[i]);
1575 QString urlStr(url.string());
1578 QObject* object = 0;
1580 if (mimeType == "application/x-qt-plugin" || mimeType == "application/x-qt-styled-widget") {
1581 object = m_webFrame->page()->createPlugin(classid, qurl, params, values);
1582 #ifndef QT_NO_STYLE_STYLESHEET
1583 QWidget* widget = qobject_cast<QWidget*>(object);
1584 if (widget && mimeType == "application/x-qt-styled-widget") {
1586 QString styleSheet = element->getAttribute("style");
1587 if (!styleSheet.isEmpty())
1588 styleSheet += QLatin1Char(';');
1590 for (unsigned i = 0; i < numqStyleSheetProperties; ++i) {
1591 CSSPropertyID property = qstyleSheetProperties[i];
1593 styleSheet += QString::fromLatin1(getPropertyName(property));
1594 styleSheet += QLatin1Char(':');
1595 styleSheet += CSSComputedStyleDeclaration::create(element)->getPropertyValue(property);
1596 styleSheet += QLatin1Char(';');
1599 widget->setStyleSheet(styleSheet);
1601 #endif // QT_NO_STYLE_STYLESHEET
1605 QWebPluginFactory* factory = m_webFrame->page()->pluginFactory();
1607 object = factory->create(mimeType, qurl, params, values);
1611 QWidget* widget = qobject_cast<QWidget*>(object);
1613 QWidget* parentWidget = 0;
1614 if (m_webFrame->page()->d->client)
1615 parentWidget = qobject_cast<QWidget*>(m_webFrame->page()->d->client->pluginParent());
1616 if (parentWidget) // Don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose.
1617 widget->setParent(parentWidget);
1619 RefPtr<QtPluginWidget> w = adoptRef(new QtPluginWidget());
1620 w->setPlatformWidget(widget);
1621 // Make sure it's invisible until properly placed into the layout.
1622 w->setFrameRect(IntRect(0, 0, 0, 0));
1626 #if !defined(QT_NO_GRAPHICSVIEW)
1627 QGraphicsWidget* graphicsWidget = qobject_cast<QGraphicsWidget*>(object);
1628 if (graphicsWidget) {
1629 QGraphicsObject* parentWidget = 0;
1630 if (m_webFrame->page()->d->client)
1631 parentWidget = qobject_cast<QGraphicsObject*>(m_webFrame->page()->d->client->pluginParent());
1632 graphicsWidget->hide();
1633 if (parentWidget) // Don't reparent to nothing (i.e. keep whatever parent QWebPage::createPlugin() chose.
1634 graphicsWidget->setParentItem(parentWidget);
1635 RefPtr<QtPluginGraphicsWidget> w = QtPluginGraphicsWidget::create(graphicsWidget);
1636 // Make sure it's invisible until properly placed into the layout.
1637 w->setFrameRect(IntRect(0, 0, 0, 0));
1640 #endif // QT_NO_GRAPHICSVIEW
1642 // FIXME: Make things work for widgetless plugins as well.
1645 #if ENABLE(NETSCAPE_PLUGIN_API)
1646 else { // NPAPI Plugins
1647 Vector<String> params = paramNames;
1648 Vector<String> values = paramValues;
1649 if (mimeType == "application/x-shockwave-flash") {
1650 QWebPageClient* client = m_webFrame->page()->d->client.get();
1651 const bool isQWebView = client && qobject_cast<QWidget*>(client->pluginParent());
1653 // Inject wmode=opaque when there is no client or the client is not a QWebView.
1654 size_t wmodeIndex = params.find("wmode");
1655 if (wmodeIndex == WTF::notFound) {
1656 params.append("wmode");
1657 values.append("opaque");
1658 } else if (equalIgnoringCase(values[wmodeIndex], "window"))
1659 values[wmodeIndex] = "opaque";
1663 RefPtr<PluginView> pluginView = PluginView::create(m_frame, pluginSize, element, url,
1664 params, values, mimeType, loadManually);
1667 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1672 void FrameLoaderClientQt::redirectDataToPlugin(Widget* pluginWidget)
1674 ASSERT(!m_pluginView);
1675 m_pluginView = static_cast<PluginView*>(pluginWidget);
1676 m_hasSentResponseToPlugin = false;
1679 PassRefPtr<Widget> FrameLoaderClientQt::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const KURL& url,
1680 const Vector<String>& paramNames, const Vector<String>& paramValues)
1682 return createPlugin(pluginSize, element, url, paramNames, paramValues, "application/x-java-applet", true);
1685 String FrameLoaderClientQt::overrideMediaType() const
1690 QString FrameLoaderClientQt::chooseFile(const QString& oldFile)
1692 return m_webFrame->page()->chooseFile(m_webFrame, oldFile);
1695 PassRefPtr<FrameNetworkingContext> FrameLoaderClientQt::createNetworkingContext()
1697 QVariant value = m_webFrame->page()->property("_q_MIMESniffingDisabled");
1698 bool MIMESniffingDisabled = value.isValid() && value.toBool();
1700 return FrameNetworkingContextQt::create(m_frame, m_webFrame, !MIMESniffingDisabled, m_webFrame->page()->networkAccessManager());
1703 void FrameLoaderClientQt::emitLoadStarted()
1705 QWebPage* webPage = m_webFrame->page();
1706 if (m_isOriginatingLoad && webPage)
1707 emit webPage->loadStarted();
1708 emit m_webFrame->loadStarted();
1711 void FrameLoaderClientQt::emitLoadFinished(bool ok)
1713 // Signal handlers can lead to a new load, that will use the member again.
1714 const bool wasOriginatingLoad = m_isOriginatingLoad;
1715 m_isOriginatingLoad = false;
1717 QWebPage* webPage = m_webFrame->page();
1718 if (wasOriginatingLoad && webPage)
1719 emit webPage->loadFinished(ok);
1720 emit m_webFrame->loadFinished(ok);
1725 #include "moc_FrameLoaderClientQt.cpp"