Fixes QWebFrame::setScrollBarPolicy(..) to actually work. Also happens
[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                                                                 (ScrollbarMode)m_webFrame->scrollBarPolicy(Qt::Horizontal),
222                                                                 (ScrollbarMode)m_webFrame->scrollBarPolicy(Qt::Vertical));
223 }
224
225
226 void FrameLoaderClientQt::makeRepresentation(DocumentLoader*)
227 {
228     // don't need this for now I think.
229 }
230
231
232 void FrameLoaderClientQt::forceLayout()
233 {
234     m_frame->forceLayout(true);
235 }
236
237
238 void FrameLoaderClientQt::forceLayoutForNonHTML()
239 {
240 }
241
242
243 void FrameLoaderClientQt::setCopiesOnScroll()
244 {
245     // apparently mac specific
246 }
247
248
249 void FrameLoaderClientQt::detachedFromParent2()
250 {
251 }
252
253
254 void FrameLoaderClientQt::detachedFromParent3()
255 {
256 }
257
258 void FrameLoaderClientQt::dispatchDidHandleOnloadEvents()
259 {
260     // don't need this one
261     if (dumpFrameLoaderCallbacks)
262         printf("%s - didHandleOnloadEventsForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
263
264 }
265
266
267 void FrameLoaderClientQt::dispatchDidReceiveServerRedirectForProvisionalLoad()
268 {
269     if (dumpFrameLoaderCallbacks)
270         printf("%s - didReceiveServerRedirectForProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
271
272     notImplemented();
273 }
274
275
276 void FrameLoaderClientQt::dispatchDidCancelClientRedirect()
277 {
278     if (dumpFrameLoaderCallbacks)
279         printf("%s - didCancelClientRedirectForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
280
281     notImplemented();
282 }
283
284
285 void FrameLoaderClientQt::dispatchWillPerformClientRedirect(const KURL& url,
286                                                             double interval,
287                                                             double fireDate)
288 {
289     if (dumpFrameLoaderCallbacks)
290         printf("%s - willPerformClientRedirectToURL: %s \n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(drtDescriptionSuitableForTestResult(url)));
291
292     notImplemented();
293 }
294
295
296 void FrameLoaderClientQt::dispatchDidChangeLocationWithinPage()
297 {
298     if (dumpFrameLoaderCallbacks)
299         printf("%s - didChangeLocationWithinPageForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
300
301     notImplemented();
302 }
303
304
305 void FrameLoaderClientQt::dispatchWillClose()
306 {
307     if (dumpFrameLoaderCallbacks)
308         printf("%s - willCloseFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
309 }
310
311
312 void FrameLoaderClientQt::dispatchDidStartProvisionalLoad()
313 {
314     if (dumpFrameLoaderCallbacks)
315         printf("%s - didStartProvisionalLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
316
317     if (m_webFrame)
318         emit m_webFrame->provisionalLoad();
319 }
320
321
322 void FrameLoaderClientQt::dispatchDidReceiveTitle(const String& title)
323 {
324     if (dumpFrameLoaderCallbacks)
325         printf("%s - didReceiveTitle: %s\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), qPrintable(QString(title)));
326
327     if (!m_webFrame)
328         return;
329
330
331
332     // ### hack
333     emit m_webFrame->urlChanged(m_webFrame->url());
334     emit titleChanged(title);
335 }
336
337
338 void FrameLoaderClientQt::dispatchDidCommitLoad()
339 {
340     if (dumpFrameLoaderCallbacks)
341         printf("%s - didCommitLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
342
343     if (m_frame->tree()->parent() || !m_webFrame)
344         return;
345
346     m_webFrame->page()->d->updateNavigationActions();
347
348     // We should assume first the frame has no title. If it has, then the above dispatchDidReceiveTitle()
349     // will be called very soon with the correct title.
350     // This properly resets the title when we navigate to a URI without a title.
351     emit titleChanged(String());
352 }
353
354
355 void FrameLoaderClientQt::dispatchDidFinishDocumentLoad()
356 {
357     if (dumpFrameLoaderCallbacks)
358         printf("%s - didFinishDocumentLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
359
360     if (QWebPagePrivate::drtRun) {
361         int unloadEventCount = m_frame->eventHandler()->pendingFrameUnloadEventCount();
362         if (unloadEventCount)
363             printf("%s - has %u onunload handler(s)\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)), unloadEventCount);
364     }
365
366     if (m_frame->tree()->parent() || !m_webFrame)
367         return;
368
369     m_webFrame->page()->d->updateNavigationActions();
370 }
371
372
373 void FrameLoaderClientQt::dispatchDidFinishLoad()
374 {
375     if (dumpFrameLoaderCallbacks)
376         printf("%s - didFinishLoadForFrame\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
377
378     m_loadSucceeded = true;
379
380     if (m_frame->tree()->parent() || !m_webFrame)
381         return;
382     m_webFrame->page()->d->updateNavigationActions();
383 }
384
385
386 void FrameLoaderClientQt::dispatchDidFirstLayout()
387 {
388     if (m_webFrame)
389         emit m_webFrame->initialLayoutCompleted();
390 }
391
392 void FrameLoaderClientQt::dispatchDidFirstVisuallyNonEmptyLayout()
393 {
394     notImplemented();
395 }
396
397 void FrameLoaderClientQt::dispatchShow()
398 {
399     notImplemented();
400 }
401
402
403 void FrameLoaderClientQt::cancelPolicyCheck()
404 {
405 //    qDebug() << "FrameLoaderClientQt::cancelPolicyCheck";
406     m_policyFunction = 0;
407 }
408
409
410 void FrameLoaderClientQt::dispatchWillSubmitForm(FramePolicyFunction function,
411                                                  PassRefPtr<FormState>)
412 {
413     notImplemented();
414     Q_ASSERT(!m_policyFunction);
415     // FIXME: This is surely too simple
416     callPolicyFunction(function, PolicyUse);
417 }
418
419
420 void FrameLoaderClientQt::dispatchDidLoadMainResource(DocumentLoader*)
421 {
422 }
423
424
425 void FrameLoaderClientQt::revertToProvisionalState(DocumentLoader*)
426 {
427     notImplemented();
428 }
429
430
431 void FrameLoaderClientQt::postProgressStartedNotification()
432 {
433     if (m_webFrame && m_frame->page()) {
434         emit loadStarted();
435         postProgressEstimateChangedNotification();
436     }
437     if (m_frame->tree()->parent() || !m_webFrame)
438         return;
439     m_webFrame->page()->d->updateNavigationActions();
440 }
441
442 void FrameLoaderClientQt::postProgressEstimateChangedNotification()
443 {
444     if (m_webFrame && m_frame->page())
445         emit loadProgress(qRound(m_frame->page()->progress()->estimatedProgress() * 100));
446 }
447
448 void FrameLoaderClientQt::postProgressFinishedNotification()
449 {
450     // send a mousemove event to
451     // (1) update the cursor to change according to whatever is underneath the mouse cursor right now
452     // (2) display the tool tip if the mouse hovers a node which has a tool tip
453     if (m_frame && m_frame->eventHandler() && m_webFrame->page()) {
454         QWidget* view = m_webFrame->page()->view();
455         if (view && view->hasFocus()) {
456             QPoint localPos = view->mapFromGlobal(QCursor::pos());
457             if (view->rect().contains(localPos)) {
458                 QMouseEvent event(QEvent::MouseMove, localPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier);
459                 m_frame->eventHandler()->mouseMoved(PlatformMouseEvent(&event, 0));
460             }
461         }
462     }
463
464     if (m_webFrame && m_frame->page())
465         emit loadFinished(m_loadSucceeded);
466 }
467
468 void FrameLoaderClientQt::setMainFrameDocumentReady(bool b)
469 {
470     // this is only interesting once we provide an external API for the DOM
471 }
472
473
474 void FrameLoaderClientQt::willChangeTitle(DocumentLoader*)
475 {
476     // no need for, dispatchDidReceiveTitle is the right callback
477 }
478
479
480 void FrameLoaderClientQt::didChangeTitle(DocumentLoader *)
481 {
482     // no need for, dispatchDidReceiveTitle is the right callback
483 }
484
485
486 void FrameLoaderClientQt::finishedLoading(DocumentLoader* loader)
487 {
488     if (!m_pluginView) {
489         if(m_firstData) {
490             FrameLoader *fl = loader->frameLoader();
491             fl->setEncoding(m_response.textEncodingName(), false);
492             m_firstData = false; 
493         }
494     }
495     else {
496         m_pluginView->didFinishLoading();
497         m_pluginView = 0;
498         m_hasSentResponseToPlugin = false;
499     }
500 }
501
502
503 bool FrameLoaderClientQt::canShowMIMEType(const String& MIMEType) const
504 {
505     if (MIMETypeRegistry::isSupportedImageMIMEType(MIMEType))
506         return true;
507
508     if (MIMETypeRegistry::isSupportedNonImageMIMEType(MIMEType))
509         return true;
510
511     if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(MIMEType))
512         return true;
513
514     return false;
515 }
516
517 bool FrameLoaderClientQt::representationExistsForURLScheme(const String& URLScheme) const
518 {
519     return false;
520 }
521
522
523 String FrameLoaderClientQt::generatedMIMETypeForURLScheme(const String& URLScheme) const
524 {
525     notImplemented();
526     return String();
527 }
528
529
530 void FrameLoaderClientQt::frameLoadCompleted()
531 {
532     // Note: Can be called multiple times.
533     // Even if already complete, we might have set a previous item on a frame that
534     // didn't do any data loading on the past transaction. Make sure to clear these out.
535     m_frame->loader()->setPreviousHistoryItem(0);
536 }
537
538
539 void FrameLoaderClientQt::restoreViewState()
540 {
541     if (!m_webFrame)
542         return;
543     emit m_webFrame->page()->restoreFrameStateRequested(m_webFrame);
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()
624 {
625     QWebHistoryInterface *history = QWebHistoryInterface::defaultInterface();
626     if (history)
627         history->addHistoryEntry(m_frame->loader()->documentLoader()->urlForHistory().prettyURL());
628 }
629
630 bool FrameLoaderClientQt::shouldGoToHistoryItem(WebCore::HistoryItem *item) const
631 {
632     return true;
633 }
634
635 void FrameLoaderClientQt::saveViewStateToItem(WebCore::HistoryItem* item)
636 {
637     QWebHistoryItem historyItem(new QWebHistoryItemPrivate(item));
638     emit m_webFrame->page()->saveFrameStateRequested(m_webFrame, &historyItem);
639 }
640
641 bool FrameLoaderClientQt::canCachePage() const
642 {
643     return true;
644 }
645
646 void FrameLoaderClientQt::setMainDocumentError(WebCore::DocumentLoader* loader, const WebCore::ResourceError& error)
647 {
648     if (!m_pluginView) {
649         if (m_firstData) {
650             loader->frameLoader()->setEncoding(m_response.textEncodingName(), false);
651             m_firstData = false;
652         }
653     } else {
654         m_pluginView->didFail(error);
655         m_pluginView = 0;
656         m_hasSentResponseToPlugin = false;
657     }
658 }
659
660 void FrameLoaderClientQt::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length)
661 {
662     if (!m_pluginView) {
663         if (!m_frame)
664             return;
665         FrameLoader *fl = loader->frameLoader();
666         if (m_firstData) {
667             fl->setEncoding(m_response.textEncodingName(), false);
668             m_firstData = false;
669         }
670         fl->addData(data, length);
671     }
672     
673     // We re-check here as the plugin can have been created
674     if (m_pluginView) {
675         if (!m_hasSentResponseToPlugin) {
676             m_pluginView->didReceiveResponse(loader->response());
677             m_hasSentResponseToPlugin = true;
678         }
679         m_pluginView->didReceiveData(data, length);
680     }
681 }
682
683 WebCore::ResourceError FrameLoaderClientQt::cancelledError(const WebCore::ResourceRequest& request)
684 {
685     return ResourceError("Error", -999, request.url().prettyURL(),
686             QCoreApplication::translate("QWebFrame", "Request cancelled", 0, QCoreApplication::UnicodeUTF8));
687 }
688
689 // copied from WebKit/Misc/WebKitErrors[Private].h
690 enum {
691     WebKitErrorCannotShowMIMEType =                             100,
692     WebKitErrorCannotShowURL =                                  101,
693     WebKitErrorFrameLoadInterruptedByPolicyChange =             102,
694     WebKitErrorCannotUseRestrictedPort = 103,
695     WebKitErrorCannotFindPlugIn =                               200,
696     WebKitErrorCannotLoadPlugIn =                               201,
697     WebKitErrorJavaUnavailable =                                202,
698 };
699
700 WebCore::ResourceError FrameLoaderClientQt::blockedError(const WebCore::ResourceRequest& request)
701 {
702     return ResourceError("Error", WebKitErrorCannotUseRestrictedPort, request.url().prettyURL(),
703             QCoreApplication::translate("QWebFrame", "Request blocked", 0, QCoreApplication::UnicodeUTF8));
704 }
705
706
707 WebCore::ResourceError FrameLoaderClientQt::cannotShowURLError(const WebCore::ResourceRequest& request)
708 {
709     return ResourceError("Error", WebKitErrorCannotShowURL, request.url().string(),
710             QCoreApplication::translate("QWebFrame", "Cannot show URL", 0, QCoreApplication::UnicodeUTF8));
711 }
712
713 WebCore::ResourceError FrameLoaderClientQt::interruptForPolicyChangeError(const WebCore::ResourceRequest& request)
714 {
715     return ResourceError("Error", WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(),
716             QCoreApplication::translate("QWebFrame", "Frame load interruped by policy change", 0, QCoreApplication::UnicodeUTF8));
717 }
718
719 WebCore::ResourceError FrameLoaderClientQt::cannotShowMIMETypeError(const WebCore::ResourceResponse& response)
720 {
721     return ResourceError("Error", WebKitErrorCannotShowMIMEType, response.url().string(),
722             QCoreApplication::translate("QWebFrame", "Cannot show mimetype", 0, QCoreApplication::UnicodeUTF8));
723 }
724
725 WebCore::ResourceError FrameLoaderClientQt::fileDoesNotExistError(const WebCore::ResourceResponse& response)
726 {
727     return ResourceError("Error", -998 /* ### */, response.url().string(),
728             QCoreApplication::translate("QWebFrame", "File does not exist", 0, QCoreApplication::UnicodeUTF8));
729 }
730
731 WebCore::ResourceError FrameLoaderClientQt::pluginWillHandleLoadError(const WebCore::ResourceResponse& response)
732 {
733     notImplemented();
734     return ResourceError();
735 }
736
737 bool FrameLoaderClientQt::shouldFallBack(const WebCore::ResourceError&)
738 {
739     notImplemented();
740     return false;
741 }
742
743 WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClientQt::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData)
744 {
745     RefPtr<DocumentLoader> loader = DocumentLoader::create(request, substituteData);
746     if (substituteData.isValid())
747         loader->setDeferMainResourceDataLoad(false);
748     return loader.release();
749 }
750
751 void FrameLoaderClientQt::download(WebCore::ResourceHandle* handle, const WebCore::ResourceRequest&, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&)
752 {
753 #if QT_VERSION >= 0x040400
754     if (!m_webFrame)
755         return;
756
757     QNetworkReplyHandler* handler = handle->getInternal()->m_job;
758     QNetworkReply* reply = handler->release();
759     if (reply) {
760         QWebPage *page = m_webFrame->page();
761         if (page->forwardUnsupportedContent())
762             emit m_webFrame->page()->unsupportedContent(reply);
763         else
764             reply->abort();
765     }
766 #endif
767 }
768
769 void FrameLoaderClientQt::assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader* loader, const WebCore::ResourceRequest& request)
770 {
771     if (dumpResourceLoadCallbacks)
772         dumpAssignedUrls[identifier] = drtDescriptionSuitableForTestResult(request.url());
773 }
774
775 void FrameLoaderClientQt::dispatchWillSendRequest(WebCore::DocumentLoader*, unsigned long identifier, WebCore::ResourceRequest& newRequest, const WebCore::ResourceResponse& redirectResponse)
776 {
777     if (dumpResourceLoadCallbacks)
778         printf("%s - willSendRequest %s redirectResponse %s\n",
779                qPrintable(dumpAssignedUrls[identifier]),
780                qPrintable(drtDescriptionSuitableForTestResult(newRequest)),
781                qPrintable(drtDescriptionSuitableForTestResult(redirectResponse)));
782
783     // seems like the Mac code doesn't do anything here by default neither
784     //qDebug() << "FrameLoaderClientQt::dispatchWillSendRequest" << request.isNull() << request.url().string`();
785 }
786
787 bool
788 FrameLoaderClientQt::shouldUseCredentialStorage(DocumentLoader*, unsigned long)
789 {
790     notImplemented();
791     return false;
792 }
793
794 void FrameLoaderClientQt::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
795 {
796     notImplemented();
797 }
798
799 void FrameLoaderClientQt::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&)
800 {
801     notImplemented();
802 }
803
804 void FrameLoaderClientQt::dispatchDidReceiveResponse(WebCore::DocumentLoader*, unsigned long, const WebCore::ResourceResponse& response)
805 {
806
807     m_response = response;
808     m_firstData = true;
809     //qDebug() << "    got response from" << response.url().string();
810 }
811
812 void FrameLoaderClientQt::dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long, int)
813 {
814 }
815
816 void FrameLoaderClientQt::dispatchDidFinishLoading(WebCore::DocumentLoader* loader, unsigned long)
817 {
818 }
819
820 void FrameLoaderClientQt::dispatchDidFailLoading(WebCore::DocumentLoader* loader, unsigned long identifier, const WebCore::ResourceError& error)
821 {
822     if (dumpResourceLoadCallbacks)
823         printf("%s - didFailLoadingWithError: %s\n", qPrintable(dumpAssignedUrls[identifier]), qPrintable(drtDescriptionSuitableForTestResult(error)));
824
825     if (m_firstData) {
826         FrameLoader *fl = loader->frameLoader();
827         fl->setEncoding(m_response.textEncodingName(), false);
828         m_firstData = false;
829     }
830 }
831
832 bool FrameLoaderClientQt::dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int)
833 {
834     notImplemented();
835     return false;
836 }
837
838 void FrameLoaderClientQt::dispatchDidFailProvisionalLoad(const WebCore::ResourceError&)
839 {
840     if (dumpFrameLoaderCallbacks)
841         printf("%s - didFailProvisionalLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
842
843     m_loadSucceeded = false;
844 }
845
846 void FrameLoaderClientQt::dispatchDidFailLoad(const WebCore::ResourceError&)
847 {
848     if (dumpFrameLoaderCallbacks)
849         printf("%s - didFailLoadWithError\n", qPrintable(drtDescriptionSuitableForTestResult(m_frame)));
850
851     m_loadSucceeded = false;
852 }
853
854 WebCore::Frame* FrameLoaderClientQt::dispatchCreatePage()
855 {
856     if (!m_webFrame)
857         return 0;
858     QWebPage *newPage = m_webFrame->page()->createWindow(QWebPage::WebBrowserWindow);
859     if (!newPage)
860         return 0;
861     return newPage->mainFrame()->d->frame;
862 }
863
864 void FrameLoaderClientQt::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const WebCore::String& MIMEType, const WebCore::ResourceRequest&)
865 {
866     // we need to call directly here
867     Q_ASSERT(!m_policyFunction);
868     m_policyFunction = function;
869     if (canShowMIMEType(MIMEType))
870         slotCallPolicyFunction(PolicyUse);
871     else
872         slotCallPolicyFunction(PolicyDownload);
873 }
874
875 void FrameLoaderClientQt::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>, const WebCore::String&)
876 {
877     Q_ASSERT(!m_policyFunction);
878     Q_ASSERT(m_webFrame);
879     m_policyFunction = function;
880 #if QT_VERSION < 0x040400
881     QWebNetworkRequest r(request);
882 #else
883     QNetworkRequest r(request.toNetworkRequest());
884 #endif
885     QWebPage* page = m_webFrame->page();
886
887     if (!page->d->acceptNavigationRequest(0, r, QWebPage::NavigationType(action.type()))) {
888         if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
889             m_frame->loader()->resetMultipleFormSubmissionProtection();
890         slotCallPolicyFunction(PolicyIgnore);
891         return;
892     }
893     slotCallPolicyFunction(PolicyUse);
894 }
895
896 void FrameLoaderClientQt::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const WebCore::NavigationAction& action, const WebCore::ResourceRequest& request, PassRefPtr<WebCore::FormState>)
897 {
898     Q_ASSERT(!m_policyFunction);
899     Q_ASSERT(m_webFrame);
900     m_policyFunction = function;
901 #if QT_VERSION < 0x040400
902     QWebNetworkRequest r(request);
903 #else
904     QNetworkRequest r(request.toNetworkRequest());
905 #endif
906     QWebPage*page = m_webFrame->page();
907
908     if (!page->d->acceptNavigationRequest(m_webFrame, r, QWebPage::NavigationType(action.type()))) {
909         if (action.type() == NavigationTypeFormSubmitted || action.type() == NavigationTypeFormResubmitted)
910             m_frame->loader()->resetMultipleFormSubmissionProtection();
911         slotCallPolicyFunction(PolicyIgnore);
912         return;
913     }
914     slotCallPolicyFunction(PolicyUse);
915 }
916
917 void FrameLoaderClientQt::dispatchUnableToImplementPolicy(const WebCore::ResourceError&)
918 {
919     notImplemented();
920 }
921
922 void FrameLoaderClientQt::startDownload(const WebCore::ResourceRequest& request)
923 {
924 #if QT_VERSION >= 0x040400
925     if (!m_webFrame)
926         return;
927
928     QWebPage *page = m_webFrame->page();
929     emit m_webFrame->page()->downloadRequested(request.toNetworkRequest());
930 #endif
931 }
932
933 PassRefPtr<Frame> FrameLoaderClientQt::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
934                                         const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
935 {
936     if (!m_webFrame)
937         return 0;
938
939     QWebFrameData frameData;
940     frameData.url = url;
941     frameData.name = name;
942     frameData.ownerElement = ownerElement;
943     frameData.referrer = referrer;
944     frameData.allowsScrolling = allowsScrolling;
945     frameData.marginWidth = marginWidth;
946     frameData.marginHeight = marginHeight;
947
948     QWebFrame* webFrame = new QWebFrame(m_webFrame, &frameData);
949     emit m_webFrame->page()->frameCreated(webFrame);
950
951     RefPtr<Frame> childFrame = adoptRef(webFrame->d->frame);
952
953     // ### set override encoding if we have one
954
955     FrameLoadType loadType = m_frame->loader()->loadType();
956     FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
957
958     childFrame->loader()->loadURL(frameData.url, frameData.referrer, String(), childLoadType, 0, 0);
959
960     // The frame's onload handler may have removed it from the document.
961     if (!childFrame->tree()->parent())
962         return 0;
963
964     return childFrame.release();
965 }
966
967 ObjectContentType FrameLoaderClientQt::objectContentType(const KURL& url, const String& _mimeType)
968 {
969 //    qDebug()<<" ++++++++++++++++ url is "<<url.prettyURL()<<", mime = "<<_mimeType;
970     if (_mimeType == "application/x-qt-plugin" || _mimeType == "application/x-qt-styled-widget")
971         return ObjectContentOtherPlugin;
972
973     if (url.isEmpty() && !_mimeType.length())
974         return ObjectContentNone;
975
976     String mimeType = _mimeType;
977     if (!mimeType.length()) {
978         QFileInfo fi(url.path());
979         mimeType = MIMETypeRegistry::getMIMETypeForExtension(fi.suffix());
980     }
981
982     if (!mimeType.length())
983         return ObjectContentFrame;
984
985     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
986         return ObjectContentImage;
987
988     if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
989         return ObjectContentNetscapePlugin;
990
991     if (m_frame->page() && m_frame->page()->pluginData()->supportsMimeType(mimeType))
992         return ObjectContentOtherPlugin;
993
994     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
995         return ObjectContentFrame;
996
997     if (url.protocol() == "about")
998         return ObjectContentFrame;
999
1000     return ObjectContentNone;
1001 }
1002
1003 static const CSSPropertyID qstyleSheetProperties[] = {
1004     CSSPropertyColor,
1005     CSSPropertyFontFamily,
1006     CSSPropertyFontSize,
1007     CSSPropertyFontStyle,
1008     CSSPropertyFontWeight
1009 };
1010
1011 const unsigned numqStyleSheetProperties = sizeof(qstyleSheetProperties) / sizeof(qstyleSheetProperties[0]);
1012
1013 class QtPluginWidget: public Widget
1014 {
1015 public:
1016     QtPluginWidget(QWidget* w = 0): Widget(w) {}
1017     ~QtPluginWidget()
1018     {
1019         if (platformWidget())
1020             platformWidget()->deleteLater();
1021     }
1022     virtual void invalidateRect(const IntRect& r)
1023     { 
1024         if (platformWidget())
1025             platformWidget()->update(r);
1026     }
1027     virtual void frameRectsChanged()
1028     {
1029         if (!platformWidget())
1030             return;
1031
1032         IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height()));
1033         platformWidget()->setGeometry(windowRect);
1034
1035         ScrollView* parentScrollView = parent();
1036         if (!parentScrollView)
1037             return;
1038
1039         ASSERT(parentScrollView->isFrameView());
1040         IntRect clipRect(static_cast<FrameView*>(parentScrollView)->windowClipRect());
1041         clipRect.move(-windowRect.x(), -windowRect.y());
1042         clipRect.intersect(platformWidget()->rect());
1043         platformWidget()->setMask(QRegion(clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()));
1044     }
1045 };
1046
1047 Widget* FrameLoaderClientQt::createPlugin(const IntSize& pluginSize, Element* element, const KURL& url, const Vector<String>& paramNames,
1048                                           const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1049 {
1050 //     qDebug()<<"------ Creating plugin in FrameLoaderClientQt::createPlugin for "<<url.prettyURL() << mimeType;
1051 //     qDebug()<<"------\t url = "<<url.prettyURL();
1052
1053     if (!m_webFrame)
1054         return 0;
1055
1056     QStringList params;
1057     QStringList values;
1058     QString classid(element->getAttribute("classid"));
1059
1060     for (int i = 0; i < paramNames.size(); ++i) {
1061         params.append(paramNames[i]);
1062         if (paramNames[i] == "classid")
1063             classid = paramValues[i];
1064     }
1065     for (int i = 0; i < paramValues.size(); ++i)
1066         values.append(paramValues[i]);
1067
1068     QString urlStr(url.string());
1069     QUrl qurl = urlStr;
1070
1071     QObject* object = 0;
1072
1073     if (mimeType == "application/x-qt-plugin" || mimeType == "application/x-qt-styled-widget") {
1074         object = m_webFrame->page()->createPlugin(classid, qurl, params, values);
1075 #ifndef QT_NO_STYLE_STYLESHEET
1076         QWidget* widget = qobject_cast<QWidget*>(object);
1077         if (widget && mimeType == "application/x-qt-styled-widget") {
1078
1079             QString styleSheet = element->getAttribute("style");
1080             if (!styleSheet.isEmpty())
1081                 styleSheet += QLatin1Char(';');
1082
1083             for (int i = 0; i < numqStyleSheetProperties; ++i) {
1084                 CSSPropertyID property = qstyleSheetProperties[i];
1085
1086                 styleSheet += QString::fromLatin1(::getPropertyName(property));
1087                 styleSheet += QLatin1Char(':');
1088                 styleSheet += computedStyle(element)->getPropertyValue(property);
1089                 styleSheet += QLatin1Char(';');
1090             }
1091
1092             widget->setStyleSheet(styleSheet);
1093         }
1094 #endif // QT_NO_STYLE_STYLESHEET
1095     }
1096
1097 #if QT_VERSION >= 0x040400
1098         if (!object) {
1099             QWebPluginFactory* factory = m_webFrame->page()->pluginFactory();
1100             if (factory)
1101                 object = factory->create(mimeType, qurl, params, values);
1102         }
1103 #endif
1104
1105         if (object) {
1106             QWidget* widget = qobject_cast<QWidget*>(object);
1107             if (widget) {
1108                 QWidget* view = m_webFrame->page()->view();
1109                 if (view)
1110                     widget->setParent(view);
1111                 QtPluginWidget* w = new QtPluginWidget();
1112                 w->setPlatformWidget(widget);
1113                 // Make sure it's invisible until properly placed into the layout
1114                 w->setFrameRect(IntRect(0, 0, 0, 0));
1115                 return w;
1116             }
1117             // FIXME: make things work for widgetless plugins as well
1118             delete object;
1119     } else { // NPAPI Plugins
1120         PluginView* pluginView = PluginView::create(m_frame, pluginSize, element, url,
1121             paramNames, paramValues, mimeType, loadManually);
1122         return pluginView;
1123     }
1124
1125     return 0;
1126 }
1127
1128 void FrameLoaderClientQt::redirectDataToPlugin(Widget* pluginWidget)
1129 {
1130     ASSERT(!m_pluginView);
1131     m_pluginView = static_cast<PluginView*>(pluginWidget);
1132     m_hasSentResponseToPlugin = false;
1133 }
1134
1135 Widget* FrameLoaderClientQt::createJavaAppletWidget(const IntSize&, Element*, const KURL& baseURL,
1136                                                     const Vector<String>& paramNames, const Vector<String>& paramValues)
1137 {
1138     notImplemented();
1139     return 0;
1140 }
1141
1142 String FrameLoaderClientQt::overrideMediaType() const
1143 {
1144     return String();
1145 }
1146
1147 QString FrameLoaderClientQt::chooseFile(const QString& oldFile)
1148 {
1149     return webFrame()->page()->chooseFile(webFrame(), oldFile);
1150 }
1151
1152 }
1153
1154 #include "moc_FrameLoaderClientQt.cpp"