Add a mechanism to store and retrieve preferences for the Web Inspector.
[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) 2008 Nokia Corporation and/or its subsidiary(-ies)
5  * Copyright (C) 2008 Collabora Ltd. All rights reserved.
6  *
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #include "CSSComputedStyleDeclaration.h"
33 #include "CSSPropertyNames.h"
34 #include "FrameLoaderClientQt.h"
35 #include "FrameTree.h"
36 #include "FrameView.h"
37 #include "DocumentLoader.h"
38 #include "MIMETypeRegistry.h"
39 #include "ResourceResponse.h"
40 #include "Page.h"
41 #include "PluginData.h"
42 #include "PluginDatabase.h"
43 #include "ProgressTracker.h"
44 #include "RenderPart.h"
45 #include "ResourceRequest.h"
46 #include "HistoryItem.h"
47 #include "HTMLFormElement.h"
48 #include "NotImplemented.h"
49 #include "QNetworkReplyHandler.h"
50 #include "ResourceHandleInternal.h"
51 #include "ResourceHandle.h"
52
53 #include "qwebpage.h"
54 #include "qwebframe.h"
55 #include "qwebframe_p.h"
56 #include "qwebhistoryinterface.h"
57 #include "qwebpluginfactory.h"
58
59 #include <qfileinfo.h>
60
61 #include <QCoreApplication>
62 #include <QDebug>
63 #if QT_VERSION >= 0x040400
64 #include <QNetworkRequest>
65 #include <QNetworkReply>
66 #else
67 #include "qwebnetworkinterface_p.h"
68 #endif
69
70 static bool dumpFrameLoaderCallbacks = false;
71 static bool dumpResourceLoadCallbacks = false;
72
73 static QMap<unsigned long, QString> dumpAssignedUrls;
74
75 void QWEBKIT_EXPORT qt_dump_frame_loader(bool b)
76 {
77     dumpFrameLoaderCallbacks = b;
78 }
79
80 void QWEBKIT_EXPORT qt_dump_resource_load_callbacks(bool b)
81 {
82     dumpResourceLoadCallbacks = b;
83 }
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     QUrl url = _url;
106     return url.toString();
107 }
108
109 static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceError& error)
110 {
111     QString failingURL = error.failingURL();
112     return QString::fromLatin1("<NSError domain NSURLErrorDomain, code %1, failing URL \"%2\">").arg(error.errorCode()).arg(failingURL);
113 }
114
115 static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceRequest& request)
116 {
117     QString url = request.url().string();
118     return QString::fromLatin1("<NSURLRequest %1>").arg(url);
119 }
120
121 static QString drtDescriptionSuitableForTestResult(const WebCore::ResourceResponse& response)
122 {
123     QString text = response.httpStatusText();
124     if (text.isEmpty())
125         return QLatin1String("(null)");
126
127     return text;
128 }
129
130
131 namespace WebCore
132 {
133
134 FrameLoaderClientQt::FrameLoaderClientQt()
135     : m_frame(0)
136     , m_webFrame(0)
137     , m_pluginView(0)
138     , m_hasSentResponseToPlugin(false)
139     , m_firstData(false)
140     , m_policyFunction(0)
141     , m_loadSucceeded(false)
142 {
143     connect(this, SIGNAL(sigCallPolicyFunction(int)), this, SLOT(slotCallPolicyFunction(int)), Qt::QueuedConnection);
144 }
145
146
147 FrameLoaderClientQt::~FrameLoaderClientQt()
148 {
149 }
150
151 void FrameLoaderClientQt::setFrame(QWebFrame* webFrame, Frame* frame)
152 {
153     m_webFrame = webFrame;
154     m_frame = frame;
155     if (!m_webFrame || !m_webFrame->page()) {
156         qWarning("FrameLoaderClientQt::setFrame frame without Page!");
157         return;
158     }
159
160     connect(this, SIGNAL(loadStarted()),
161             m_webFrame->page(), SIGNAL(loadStarted()));
162     connect(this, SIGNAL(loadProgress(int)),
163             m_webFrame->page(), SIGNAL(loadProgress(int)));
164     connect(this, SIGNAL(loadFinished(bool)),
165             m_webFrame->page(), SIGNAL(loadFinished(bool)));
166     connect(this, SIGNAL(titleChanged(const QString&)),
167             m_webFrame, SIGNAL(titleChanged(const QString&)));
168 }
169
170 QWebFrame* FrameLoaderClientQt::webFrame() const
171 {
172     return m_webFrame;
173 }
174
175 void FrameLoaderClientQt::callPolicyFunction(FramePolicyFunction function, PolicyAction action)
176 {
177     ASSERT(!m_policyFunction);
178     ASSERT(function);
179
180     m_policyFunction = function;
181     emit sigCallPolicyFunction(action);
182 }
183
184 void FrameLoaderClientQt::slotCallPolicyFunction(int action)
185 {
186     if (!m_frame || !m_policyFunction)
187         return;
188     FramePolicyFunction function = m_policyFunction;
189     m_policyFunction = 0;
190     (m_frame->loader()->*function)(WebCore::PolicyAction(action));
191 }
192
193 bool FrameLoaderClientQt::hasWebView() const
194 {
195     //notImplemented();
196     return true;
197 }
198
199 void FrameLoaderClientQt::savePlatformDataToCachedPage(CachedPage*) 
200 {
201     notImplemented();
202 }
203
204 void FrameLoaderClientQt::transitionToCommittedFromCachedPage(CachedPage*)
205 {
206 }
207
208 void FrameLoaderClientQt::transitionToCommittedForNewPage()
209 {
210     ASSERT(m_frame);
211     ASSERT(m_webFrame);
212
213     Page* page = m_frame->page();
214     ASSERT(page);
215
216     bool isMainFrame = m_frame == page->mainFrame();
217
218     m_frame->setView(0);
219
220     FrameView* frameView;
221     if (isMainFrame)
222         frameView = new FrameView(m_frame, m_webFrame->page()->viewportSize());
223     else
224         frameView = new FrameView(m_frame);
225
226     m_frame->setView(frameView);
227     // FrameViews are created with a ref count of 1. Release this ref since we've assigned it to frame.
228     frameView->deref();
229
230     if (m_webFrame && m_webFrame->page())
231         m_webFrame->d->updateBackground();
232
233     if (m_frame->ownerRenderer())
234         m_frame->ownerRenderer()->setWidget(frameView);
235 }
236
237
238 void FrameLoaderClientQt::makeRepresentation(DocumentLoader*)
239 {
240     // don't need this for now I think.
241 }
242
243
244 void FrameLoaderClientQt::forceLayout()
245 {
246     m_frame->forceLayout(true);
247 }
248
249
250 void FrameLoaderClientQt::forceLayoutForNonHTML()
251 {
252 }
253
254
255 void FrameLoaderClientQt::setCopiesOnScroll()
256 {
257     // apparently mac specific
258 }
259
260
261 void FrameLoaderClientQt::detachedFromParent2()
262 {
263 }
264
265
266 void FrameLoaderClientQt::detachedFromParent3()
267 {
268 }
269
270 void FrameLoaderClientQt::dispatchDidHandleOnloadEvents()
271 {
272     // don't need this one
273     if (dumpFrameLoaderCallbacks)
274         printf("%s - didHandleOnloadEventsForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
275
276 }
277
278
279 void FrameLoaderClientQt::dispatchDidReceiveServerRedirectForProvisionalLoad()
280 {
281     if (dumpFrameLoaderCallbacks)
282         printf("%s - didReceiveServerRedirectForProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
283
284     notImplemented();
285 }
286
287
288 void FrameLoaderClientQt::dispatchDidCancelClientRedirect()
289 {
290     if (dumpFrameLoaderCallbacks)
291         printf("%s - didCancelClientRedirectForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
292
293     notImplemented();
294 }
295
296
297 void FrameLoaderClientQt::dispatchWillPerformClientRedirect(const KURL& url,
298                                                             double interval,
299                                                             double fireDate)
300 {
301     if (dumpFrameLoaderCallbacks)
302         printf("%s - willPerformClientRedirectToURL: %s \n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(drtDescriptionSuitableForTestResult(url)));
303
304     notImplemented();
305 }
306
307
308 void FrameLoaderClientQt::dispatchDidChangeLocationWithinPage()
309 {
310     if (dumpFrameLoaderCallbacks)
311         printf("%s - didChangeLocationWithinPageForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
312
313     notImplemented();
314 }
315
316
317 void FrameLoaderClientQt::dispatchWillClose()
318 {
319     if (dumpFrameLoaderCallbacks)
320         printf("%s - willCloseFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
321 }
322
323
324 void FrameLoaderClientQt::dispatchDidStartProvisionalLoad()
325 {
326     if (dumpFrameLoaderCallbacks)
327         printf("%s - didStartProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
328
329     if (m_webFrame)
330         emit m_webFrame->provisionalLoad();
331 }
332
333
334 void FrameLoaderClientQt::dispatchDidReceiveTitle(const String& title)
335 {
336     if (dumpFrameLoaderCallbacks)
337         printf("%s - didReceiveTitle: %s\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(QString(title)));
338
339     if (!m_webFrame)
340         return;
341
342
343
344     // ### hack
345     emit m_webFrame->urlChanged(m_webFrame->url());
346     emit titleChanged(title);
347 }
348
349
350 void FrameLoaderClientQt::dispatchDidCommitLoad()
351 {
352     if (dumpFrameLoaderCallbacks)
353         printf("%s - didCommitLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
354
355     if (m_frame->tree()->parent() || !m_webFrame)
356         return;
357
358     m_webFrame->page()->d->updateNavigationActions();
359
360     // We should assume first the frame has no title. If it has, then the above dispatchDidReceiveTitle()
361     // will be called very soon with the correct title.
362     // This properly resets the title when we navigate to a URI without a title.
363     emit titleChanged(String());
364 }
365
366
367 void FrameLoaderClientQt::dispatchDidFinishDocumentLoad()
368 {
369     if (dumpFrameLoaderCallbacks)
370         printf("%s - didFinishDocumentLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
371
372     if (m_frame->tree()->parent() || !m_webFrame)
373         return;
374
375     m_webFrame->page()->d->updateNavigationActions();
376 }
377
378
379 void FrameLoaderClientQt::dispatchDidFinishLoad()
380 {
381     if (dumpFrameLoaderCallbacks)
382         printf("%s - didFinishLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
383
384     m_loadSucceeded = true;
385
386     if (m_frame->tree()->parent() || !m_webFrame)
387         return;
388     m_webFrame->page()->d->updateNavigationActions();
389 }
390
391
392 void FrameLoaderClientQt::dispatchDidFirstLayout()
393 {
394     if (m_webFrame)
395         emit m_webFrame->initialLayoutCompleted();
396 }
397
398
399 void FrameLoaderClientQt::dispatchShow()
400 {
401     notImplemented();
402 }
403
404
405 void FrameLoaderClientQt::cancelPolicyCheck()
406 {
407 //    qDebug() << "FrameLoaderClientQt::cancelPolicyCheck";
408     m_policyFunction = 0;
409 }
410
411
412 void FrameLoaderClientQt::dispatchWillSubmitForm(FramePolicyFunction function,
413                                                  PassRefPtr<FormState>)
414 {
415     notImplemented();
416     Q_ASSERT(!m_policyFunction);
417     // FIXME: This is surely too simple
418     callPolicyFunction(function, PolicyUse);
419 }
420
421
422 void FrameLoaderClientQt::dispatchDidLoadMainResource(DocumentLoader*)
423 {
424 }
425
426
427 void FrameLoaderClientQt::revertToProvisionalState(DocumentLoader*)
428 {
429     notImplemented();
430 }
431
432
433 void FrameLoaderClientQt::postProgressStartedNotification()
434 {
435     if (m_webFrame && m_frame->page()) {
436         emit loadStarted();
437         postProgressEstimateChangedNotification();
438     }
439     if (m_frame->tree()->parent() || !m_webFrame)
440         return;
441     m_webFrame->page()->d->updateNavigationActions();
442 }
443
444 void FrameLoaderClientQt::postProgressEstimateChangedNotification()
445 {
446     if (m_webFrame && m_frame->page())
447         emit loadProgress(qRound(m_frame->page()->progress()->estimatedProgress() * 100));
448 }
449
450 void FrameLoaderClientQt::postProgressFinishedNotification()
451 {
452     // send a mousemove event to
453     // (1) update the cursor to change according to whatever is underneath the mouse cursor right now
454     // (2) display the tool tip if the mouse hovers a node which has a tool tip
455     if (m_frame && m_frame->eventHandler() && m_webFrame->page()) {
456         QWidget* view = m_webFrame->page()->view();
457         if (view && view->hasFocus()) {
458             QPoint localPos = view->mapFromGlobal(QCursor::pos());
459             if (view->rect().contains(localPos)) {
460                 QMouseEvent event(QEvent::MouseMove, localPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
461                 m_frame->eventHandler()->mouseMoved(PlatformMouseEvent(&event, 0));
462             }
463         }
464     }
465
466     if (m_webFrame && m_frame->page())
467         emit loadFinished(m_loadSucceeded);
468 }
469
470 void FrameLoaderClientQt::setMainFrameDocumentReady(bool b)
471 {
472     // this is only interesting once we provide an external API for the DOM
473 }
474
475
476 void FrameLoaderClientQt::willChangeTitle(DocumentLoader*)
477 {
478     // no need for, dispatchDidReceiveTitle is the right callback
479 }
480
481
482 void FrameLoaderClientQt::didChangeTitle(DocumentLoader *)
483 {
484     // no need for, dispatchDidReceiveTitle is the right callback
485 }
486
487
488 void FrameLoaderClientQt::finishedLoading(DocumentLoader* loader)
489 {
490     if (!m_pluginView) {
491         if(m_firstData) {
492             FrameLoader *fl = loader->frameLoader();
493             fl->setEncoding(m_response.textEncodingName(), false);
494             m_firstData = false; 
495         }
496     }
497     else {
498         m_pluginView->didFinishLoading();
499         m_pluginView = 0;
500         m_hasSentResponseToPlugin = false;
501     }
502 }
503
504
505 bool FrameLoaderClientQt::canShowMIMEType(const String& MIMEType) const
506 {
507     if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType))
508         return true;
509
510     if (MIMETypeRegistry::isSupportedNonImageMIMEType(MIMEType))
511         return true;
512
513     if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(MIMEType))
514         return true;
515
516     return false;
517 }
518
519 bool FrameLoaderClientQt::representationExistsForURLScheme(const String& URLScheme) const
520 {
521     return false;
522 }
523
524
525 String FrameLoaderClientQt::generatedMIMETypeForURLScheme(const String& URLScheme) const
526 {
527     notImplemented();
528     return String();
529 }
530
531
532 void FrameLoaderClientQt::frameLoadCompleted()
533 {
534     // Note: Can be called multiple times.
535     // Even if already complete, we might have set a previous item on a frame that
536     // didn't do any data loading on the past transaction. Make sure to clear these out.
537     m_frame->loader()->setPreviousHistoryItem(0);
538 }
539
540
541 void FrameLoaderClientQt::restoreViewState()
542 {
543     notImplemented();
544 }
545
546
547 void FrameLoaderClientQt::provisionalLoadStarted()
548 {
549     // don't need to do anything here
550 }
551
552
553 void FrameLoaderClientQt::didFinishLoad()
554 {
555 //     notImplemented();
556 }
557
558
559 void FrameLoaderClientQt::prepareForDataSourceReplacement()
560 {
561     m_frame->loader()->detachChildren();
562 }
563
564 void FrameLoaderClientQt::setTitle(const String&, const KURL&)
565 {
566     // no need for, dispatchDidReceiveTitle is the right callback
567 }
568
569
570 String FrameLoaderClientQt::userAgent(const KURL& url)
571 {
572     if (m_webFrame) {
573         return m_webFrame->page()->userAgentForUrl(url);
574     }
575     return String();
576 }
577
578 void FrameLoaderClientQt::dispatchDidReceiveIcon()
579 {
580     if (dumpFrameLoaderCallbacks)
581         printf("%s - didReceiveIconForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
582
583     if (m_webFrame) {
584         emit m_webFrame->iconChanged();
585     }
586 }
587
588 void FrameLoaderClientQt::frameLoaderDestroyed()
589 {
590     delete m_webFrame;
591     m_frame = 0;
592     m_webFrame = 0;
593
594     delete this;
595 }
596
597 bool FrameLoaderClientQt::canHandleRequest(const WebCore::ResourceRequest&) const
598 {
599     return true;
600 }
601
602 void FrameLoaderClientQt::windowObjectCleared()
603 {
604     if (dumpFrameLoaderCallbacks)
605         printf("%s - didClearWindowObjectForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
606
607     if (m_webFrame)
608         emit m_webFrame->javaScriptWindowObjectCleared();
609 }
610
611 void FrameLoaderClientQt::didPerformFirstNavigation() const
612 {
613     if (m_frame->tree()->parent() || !m_webFrame)
614         return;
615     m_webFrame->page()->d->updateNavigationActions();
616 }
617
618 void FrameLoaderClientQt::registerForIconNotification(bool)
619 {
620     notImplemented();
621 }
622
623 void FrameLoaderClientQt::updateGlobalHistory(const WebCore::KURL& url)
624 {
625     QWebHistoryInterface *history = QWebHistoryInterface::defaultInterface();
626     if (history)
627         history->addHistoryEntry(url.prettyURL());
628 }
629
630 bool FrameLoaderClientQt::shouldGoToHistoryItem(WebCore::HistoryItem *item) const
631 {
632     return true;
633 }
634
635 void FrameLoaderClientQt::saveViewStateToItem(WebCore::HistoryItem*)
636 {
637 }
638
639 bool FrameLoaderClientQt::canCachePage() const
640 {
641     return true;
642 }
643
644 void FrameLoaderClientQt::setMainDocumentError(WebCore::DocumentLoader* loader, const WebCore::ResourceError& error)
645 {
646     if (!m_pluginView) {
647         if (m_firstData) {
648             loader->frameLoader()->setEncoding(m_response.textEncodingName(), false);
649             m_firstData = false;
650         }
651     } else {
652         m_pluginView->didFail(error);
653         m_pluginView = 0;
654         m_hasSentResponseToPlugin = false;
655     }
656 }
657
658 void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length)
659 {
660     if (!m_pluginView) {
661         if (!m_frame)
662             return;
663         FrameLoader *fl = loader->frameLoader();
664         if (m_firstData) {
665             fl->setEncoding(m_response.textEncodingName(), false);
666             m_firstData = false;
667         }
668         fl->addData(data, length);
669     }
670     
671     // We re-check here as the plugin can have been created
672     if (m_pluginView) {
673         if (!m_hasSentResponseToPlugin) {
674             m_pluginView->didReceiveResponse(loader->response());
675             m_hasSentResponseToPlugin = true;
676         }
677         m_pluginView->didReceiveData(data, length);
678     }
679 }
680
681 WebCore::ResourceError FrameLoaderClientQt::cancelledError(const WebCore::ResourceRequest& request)
682 {
683     return ResourceError("Error", -999, request.url().prettyURL(),
684             QCoreApplication::translate("QWebFrame", "Request cancelled", 0, QCoreApplication::UnicodeUTF8));
685 }
686
687 // copied from WebKit/Misc/WebKitErrors[Private].h
688 enum {
689     WebKitErrorCannotShowMIMEType =                             100,
690     WebKitErrorCannotShowURL =                                  101,
691     WebKitErrorFrameLoadInterruptedByPolicyChange =             102,
692     WebKitErrorCannotUseRestrictedPort = 103,
693     WebKitErrorCannotFindPlugIn =                               200,
694     WebKitErrorCannotLoadPlugIn =                               201,
695     WebKitErrorJavaUnavailable =                                202,
696 };
697
698 WebCore::ResourceError FrameLoaderClientQt::blockedError(const WebCore::ResourceRequest& request)
699 {
700     return ResourceError("Error", WebKitErrorCannotUseRestrictedPort, request.url().prettyURL(),
701             QCoreApplication::translate("QWebFrame", "Request blocked", 0, QCoreApplication::UnicodeUTF8));
702 }
703
704
705 WebCore::ResourceError FrameLoaderClientQt::cannotShowURLError(const WebCore::ResourceRequest& request)
706 {
707     return ResourceError("Error", WebKitErrorCannotShowURL, request.url().string(),
708             QCoreApplication::translate("QWebFrame", "Cannot show URL", 0, QCoreApplication::UnicodeUTF8));
709 }
710
711 WebCore::ResourceError FrameLoaderClientQt::interruptForPolicyChangeError(const WebCore::ResourceRequest& request)
712 {
713     return ResourceError("Error", WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(),
714             QCoreApplication::translate("QWebFrame", "Frame load interruped by policy change", 0, QCoreApplication::UnicodeUTF8));
715 }
716
717 WebCore::ResourceError FrameLoaderClientQt::cannotShowMIMETypeError(const WebCore::ResourceResponse& response)
718 {
719     return ResourceError("Error", WebKitErrorCannotShowMIMEType, response.url().string(),
720             QCoreApplication::translate("QWebFrame", "Cannot show mimetype", 0, QCoreApplication::UnicodeUTF8));
721 }
722
723 WebCore::ResourceError FrameLoaderClientQt::fileDoesNotExistError(const WebCore::ResourceResponse& response)
724 {
725     return ResourceError("Error", -998 /* ### */, response.url().string(),
726             QCoreApplication::translate("QWebFrame", "File does not exist", 0, QCoreApplication::UnicodeUTF8));
727 }
728
729 WebCore::ResourceError FrameLoaderClientQt::pluginWillHandleLoadError(const WebCore::ResourceResponse& response)
730 {
731     notImplemented();
732     return ResourceError();
733 }
734
735 bool FrameLoaderClientQt::shouldFallBack(const WebCore::ResourceError&)
736 {
737     notImplemented();
738     return false;
739 }
740
741 WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClientQt::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData)
742 {
743     RefPtr<DocumentLoader> loader = DocumentLoader::create(request, substituteData);
744     if (substituteData.isValid())
745         loader->setDeferMainResourceDataLoad(false);
746     return loader.release();
747 }
748
749 void FrameLoaderClientQt::download(WebCore::ResourceHandle* handle, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&)
750 {
751 #if QT_VERSION >= 0x040400
752     if (!m_webFrame)
753         return;
754
755     QNetworkReplyHandler* handler = handle->getInternal()->m_job;
756     QNetworkReply* reply = handler->release();
757     if (reply) {
758         QWebPage *page = m_webFrame->page();
759         if (page->forwardUnsupportedContent())
760             emit m_webFrame->page()->unsupportedContent(reply);
761         else
762             reply->abort();
763     }
764 #endif
765 }
766
767 void FrameLoaderClientQt::assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader* loader, const WebCore::ResourceRequest& request)
768 {
769     if (dumpResourceLoadCallbacks)
770         dumpAssignedUrls[identifier] = drtDescriptionSuitableForTestResult(request.url());
771 }
772
773 void FrameLoaderClientQt::dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest& newRequest, const WebCore::ResourceResponse& redirectResponse)
774 {
775     if (dumpResourceLoadCallbacks)
776         printf("%s - willSendRequest %s redirectResponse %s\n",
777                qPrintable(dumpAssignedUrls[identifier]),
778                qPrintable(drtDescriptionSuitableForTestResult(newRequest)),
779                qPrintable(drtDescriptionSuitableForTestResult(redirectResponse)));
780
781     // seems like the Mac code doesn't do anything here by default neither
782     //qDebug() << "FrameLoaderClientQt::dispatchWillSendRequest" << request.isNull() << request.url().string`();
783 }
784
785 void FrameLoaderClientQt::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
786 {
787     notImplemented();
788 }
789
790 void FrameLoaderClientQt::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
791 {
792     notImplemented();
793 }
794
795 void FrameLoaderClientQt::dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long, const WebCore::ResourceResponse& response)
796 {
797
798     m_response = response;
799     m_firstData = true;
800     //qDebug() << "    got response from" << response.url().string();
801 }
802
803 void FrameLoaderClientQt::dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long, int)
804 {
805 }
806
807 void FrameLoaderClientQt::dispatchDidFinishLoading(WebCore::DocumentLoader* loader, unsigned long)
808 {
809 }
810
811 void FrameLoaderClientQt::dispatchDidFailLoading(WebCore::DocumentLoader* loader, unsigned long identifier, const WebCore::ResourceError& error)
812 {
813     if (dumpResourceLoadCallbacks)
814         printf("%s - didFailLoadingWithError: %s\n", qPrintable(dumpAssignedUrls[identifier]), qPrintable(drtDescriptionSuitableForTestResult(error)));
815
816     if (m_firstData) {
817         FrameLoader *fl = loader->frameLoader();
818         fl->setEncoding(m_response.textEncodingName(), false);
819         m_firstData = false;
820     }
821 }
822
823 bool FrameLoaderClientQt::dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int)
824 {
825     notImplemented();
826     return false;
827 }
828
829 void FrameLoaderClientQt::dispatchDidFailProvisionalLoad(const WebCore::ResourceError&)
830 {
831     if (dumpFrameLoaderCallbacks)
832         printf("%s - didFailProvisionalLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
833
834     m_loadSucceeded = false;
835 }
836
837 void FrameLoaderClientQt::dispatchDidFailLoad(const WebCore::ResourceError&)
838 {
839     if (dumpFrameLoaderCallbacks)
840         printf("%s - didFailLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
841
842     m_loadSucceeded = false;
843 }
844
845 WebCore::Frame* FrameLoaderClientQt::dispatchCreatePage()
846 {
847     if (!m_webFrame)
848         return 0;
849     QWebPage *newPage = m_webFrame->page()->createWindow(QWebPage::WebBrowserWindow);
850     if (!newPage)
851         return 0;
852     return newPage->mainFrame()->d->frame;
853 }
854
855 void FrameLoaderClientQt::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const WebCore::String& MIMEType, const WebCore::ResourceRequest&)
856 {
857     // we need to call directly here
858     Q_ASSERT(!m_policyFunction);
859     m_policyFunction = function;
860     if (canShowMIMEType(MIMEType))
861         slotCallPolicyFunction(PolicyUse);
862     else
863         slotCallPolicyFunction(PolicyDownload);
864 }
865
866 void FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>, const WebCore::String&)
867 {
868     Q_ASSERT(!m_policyFunction);
869     Q_ASSERT(m_webFrame);
870     m_policyFunction = function;
871 #if QT_VERSION < 0x040400
872     QWebNetworkRequest r(request);
873 #else
874     QNetworkRequest r(request.toNetworkRequest());
875 #endif
876     QWebPage* page = m_webFrame->page();
877
878     if (!page->d->acceptNavigationRequest(0, r, QWebPage::NavigationType(action.type()))) {
879         if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
880             m_frame->loader()->resetMultipleFormSubmissionProtection();
881         slotCallPolicyFunction(PolicyIgnore);
882         return;
883     }
884     slotCallPolicyFunction(PolicyUse);
885 }
886
887 void FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>)
888 {
889     Q_ASSERT(!m_policyFunction);
890     Q_ASSERT(m_webFrame);
891     m_policyFunction = function;
892 #if QT_VERSION < 0x040400
893     QWebNetworkRequest r(request);
894 #else
895     QNetworkRequest r(request.toNetworkRequest());
896 #endif
897     QWebPage*page = m_webFrame->page();
898
899     if (!page->d->acceptNavigationRequest(m_webFrame, r, QWebPage::NavigationType(action.type()))) {
900         if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
901             m_frame->loader()->resetMultipleFormSubmissionProtection();
902         slotCallPolicyFunction(PolicyIgnore);
903         return;
904     }
905     slotCallPolicyFunction(PolicyUse);
906 }
907
908 void FrameLoaderClientQt::dispatchUnableToImplementPolicy(const WebCore::ResourceError&)
909 {
910     notImplemented();
911 }
912
913 void FrameLoaderClientQt::startDownload(const WebCore::ResourceRequest& request)
914 {
915 #if QT_VERSION >= 0x040400
916     if (!m_webFrame)
917         return;
918
919     QWebPage *page = m_webFrame->page();
920     emit m_webFrame->page()->downloadRequested(request.toNetworkRequest());
921 #endif
922 }
923
924 PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
925                                         const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
926 {
927     if (!m_webFrame)
928         return 0;
929
930     QWebFrameData frameData;
931     frameData.url = url;
932     frameData.name = name;
933     frameData.ownerElement = ownerElement;
934     frameData.referrer = referrer;
935     frameData.allowsScrolling = allowsScrolling;
936     frameData.marginWidth = marginWidth;
937     frameData.marginHeight = marginHeight;
938
939     QWebFrame* webFrame = new QWebFrame(m_webFrame, &frameData);
940     emit m_webFrame->page()->frameCreated(webFrame);
941
942     RefPtr<Frame> childFrame = adoptRef(webFrame->d->frame);
943
944     // FIXME: All of the below should probably be moved over into WebCore
945     childFrame->tree()->setName(name);
946     m_frame->tree()->appendChild(childFrame);
947     // ### set override encoding if we have one
948
949     FrameLoadType loadType = m_frame->loader()->loadType();
950     FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
951
952     childFrame->loader()->loadURL(frameData.url, frameData.referrer, String(), childLoadType, 0, 0);
953
954     // The frame's onload handler may have removed it from the document.
955     if (!childFrame->tree()->parent())
956         return 0;
957
958     return childFrame.release();
959 }
960
961 ObjectContentType FrameLoaderClientQt::objectContentType(const KURL& url, const String& _mimeType)
962 {
963 //    qDebug()<<" ++++++++++++++++ url is "<<url.prettyURL()<<", mime = "<<_mimeType;
964     if (_mimeType == "application/x-qt-plugin" || _mimeType == "application/x-qt-styled-widget")
965         return ObjectContentOtherPlugin;
966
967     if (url.isEmpty() && !_mimeType.length())
968         return ObjectContentNone;
969
970     String mimeType = _mimeType;
971     if (!mimeType.length()) {
972         QFileInfo fi(url.path());
973         mimeType = MIMETypeRegistry::getMIMETypeForExtension(fi.suffix());
974     }
975
976     if (!mimeType.length())
977         return ObjectContentFrame;
978
979     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
980         return ObjectContentImage;
981
982     if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
983         return ObjectContentNetscapePlugin;
984
985     if (m_frame->page() && m_frame->page()->pluginData()->supportsMimeType(mimeType))
986         return ObjectContentOtherPlugin;
987
988     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
989         return ObjectContentFrame;
990
991     if (url.protocol() == "about")
992         return ObjectContentFrame;
993
994     return ObjectContentNone;
995 }
996
997 static const CSSPropertyID qstyleSheetProperties[] = {
998     CSSPropertyColor,
999     CSSPropertyFontFamily,
1000     CSSPropertyFontSize,
1001     CSSPropertyFontStyle,
1002     CSSPropertyFontWeight
1003 };
1004
1005 const unsigned numqStyleSheetProperties = sizeof(qstyleSheetProperties) / sizeof(qstyleSheetProperties[0]);
1006
1007 class QtPluginWidget: public Widget
1008 {
1009 public:
1010     QtPluginWidget(QWidget* w = 0): Widget(w) {}
1011     virtual void invalidateRect(const IntRect& r)
1012     { 
1013         if (platformWidget())
1014             platformWidget()->update(r);
1015     }
1016 };
1017
1018 Widget* FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, Element* element, const KURL& url, const Vector<String>& paramNames,
1019                                           const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1020 {
1021 //     qDebug()<<"------ Creating plugin in FrameLoaderClientQt::createPlugin for "<<url.prettyURL() << mimeType;
1022 //     qDebug()<<"------\t url = "<<url.prettyURL();
1023
1024     if (!m_webFrame)
1025         return 0;
1026
1027     QStringList params;
1028     QStringList values;
1029     QString classid(element->getAttribute("classid"));
1030
1031     for (int i = 0; i < paramNames.size(); ++i) {
1032         params.append(paramNames[i]);
1033         if (paramNames[i] == "classid")
1034             classid = paramValues[i];
1035     }
1036     for (int i = 0; i < paramValues.size(); ++i)
1037         values.append(paramValues[i]);
1038
1039     QString urlStr(url.string());
1040     QUrl qurl = urlStr;
1041
1042     QObject *object = 0;
1043
1044     if (mimeType == "application/x-qt-plugin" || mimeType == "application/x-qt-styled-widget") {
1045         object = m_webFrame->page()->createPlugin(classid, qurl, params, values);
1046 #ifndef QT_NO_STYLE_STYLESHEET
1047         QWidget *widget = qobject_cast<QWidget *>(object);
1048         if (widget && mimeType == "application/x-qt-styled-widget") {
1049
1050             QString styleSheet = element->getAttribute("style");
1051             if (!styleSheet.isEmpty())
1052                 styleSheet += QLatin1Char(';');
1053
1054             for (int i = 0; i < numqStyleSheetProperties; ++i) {
1055                 CSSPropertyID property = qstyleSheetProperties[i];
1056
1057                 styleSheet += QString::fromLatin1(::getPropertyName(property));
1058                 styleSheet += QLatin1Char(':');
1059                 styleSheet += computedStyle(element)->getPropertyValue(property);
1060                 styleSheet += QLatin1Char(';');
1061             }
1062
1063             widget->setStyleSheet(styleSheet);
1064         }
1065 #endif // QT_NO_STYLE_STYLESHEET
1066     }
1067
1068 #if QT_VERSION >= 0x040400
1069         if (!object) {
1070             QWebPluginFactory* factory = m_webFrame->page()->pluginFactory();
1071             if (factory)
1072                 object = factory->create(mimeType, qurl, params, values);
1073         }
1074 #endif
1075
1076         if (object) {
1077             QWidget *widget = qobject_cast<QWidget *>(object);
1078             QWidget *view = m_webFrame->page()->view();
1079             if (widget && view) {
1080                 widget->setParent(view);
1081                 QtPluginWidget* w= new QtPluginWidget();
1082                 w->setPlatformWidget(widget);
1083                 return w;
1084             }
1085             // FIXME: make things work for widgetless plugins as well
1086             delete object;
1087     } else { // NPAPI Plugins
1088         PluginView* pluginView = PluginView::create(m_frame, pluginSize, element, url,
1089             paramNames, paramValues, mimeType, loadManually);
1090         return pluginView;
1091     }
1092
1093     return 0;
1094 }
1095
1096 void FrameLoaderClientQt::redirectDataToPlugin(Widget* pluginWidget)
1097 {
1098     ASSERT(!m_pluginView);
1099     m_pluginView = static_cast<PluginView*>(pluginWidget);
1100     m_hasSentResponseToPlugin = false;
1101 }
1102
1103 Widget* FrameLoaderClientQt::createJavaAppletWidget(const IntSize&, Element*, const KURL& baseURL,
1104                                                     const Vector<String>& paramNames, const Vector<String>& paramValues)
1105 {
1106     notImplemented();
1107     return 0;
1108 }
1109
1110 String FrameLoaderClientQt::overrideMediaType() const
1111 {
1112     return String();
1113 }
1114
1115 QString FrameLoaderClientQt::chooseFile(const QString& oldFile)
1116 {
1117     return webFrame()->page()->chooseFile(webFrame(), oldFile);
1118 }
1119
1120 }
1121
1122 #include "moc_FrameLoaderClientQt.cpp"