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