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