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