OSDN Git Service

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