4044090ef337fcbe53d86dd4f3b817b516a5bd4b
[WebKit-https.git] / WebKit / gtk / WebCoreSupport / FrameLoaderClientGtk.cpp
1 /*
2  *  Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com>
3  *  Copyright (C) 2007, 2008 Holger Hans Peter Freyther
4  *  Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
5  *  Copyright (C) 2008 Collabora Ltd.  All rights reserved.
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #include "config.h"
23 #include "FrameLoaderClientGtk.h"
24
25 #include "Color.h"
26 #include "DocumentLoader.h"
27 #include "FormState.h"
28 #include "FrameLoader.h"
29 #include "FrameView.h"
30 #include "FrameTree.h"
31 #include "HTMLAppletElement.h"
32 #include "HTMLFormElement.h"
33 #include "HTMLFrameElement.h"
34 #include "HTMLFrameOwnerElement.h"
35 #include "HTMLNames.h"
36 #include "HTMLPlugInElement.h"
37 #include "JSDOMWindow.h"
38 #include "Language.h"
39 #include "MIMETypeRegistry.h"
40 #include "MouseEvent.h"
41 #include "NotImplemented.h"
42 #include "PlatformString.h"
43 #include "PluginDatabase.h"
44 #include "RenderPart.h"
45 #include "ResourceRequest.h"
46 #include "CString.h"
47 #include "ProgressTracker.h"
48 #include "JSDOMBinding.h"
49 #include "ScriptController.h"
50 #include "webkitwebview.h"
51 #include "webkitnetworkrequest.h"
52 #include "webkitwebframe.h"
53 #include "webkitwebnavigationaction.h"
54 #include "webkitwebpolicydecision.h"
55 #include "webkitprivate.h"
56
57 #include <JavaScriptCore/APICast.h>
58 #include <stdio.h>
59 #if PLATFORM(UNIX)
60 #include <sys/utsname.h>
61 #endif
62
63 using namespace WebCore;
64
65 namespace WebKit {
66
67 FrameLoaderClient::FrameLoaderClient(WebKitWebFrame* frame)
68     : m_frame(frame)
69     , m_userAgent("")
70     , m_policyDecision(0)
71     , m_pluginView(0)
72     , m_hasSentResponseToPlugin(false)
73 {
74     ASSERT(m_frame);
75 }
76
77 FrameLoaderClient::~FrameLoaderClient()
78 {
79     if (m_policyDecision)
80         g_object_unref(m_policyDecision);
81 }
82
83 static String agentPlatform()
84 {
85 #ifdef GDK_WINDOWING_X11
86     return "X11";
87 #elif defined(GDK_WINDOWING_WIN32)
88     return "Windows";
89 #elif defined(GDK_WINDOWING_QUARTZ)
90     return "Macintosh";
91 #elif defined(GDK_WINDOWING_DIRECTFB)
92     return "DirectFB";
93 #else
94     notImplemented();
95     return "Unknown";
96 #endif
97 }
98
99 static String agentOS()
100 {
101 #if PLATFORM(DARWIN)
102 #if PLATFORM(X86)
103     return "Intel Mac OS X";
104 #else
105     return "PPC Mac OS X";
106 #endif
107 #elif PLATFORM(UNIX)
108     struct utsname name;
109     if (uname(&name) != -1)
110         return String::format("%s %s", name.sysname, name.machine);
111     else
112         return "Unknown";
113 #elif PLATFORM(WIN_OS)
114     // FIXME: Compute the Windows version
115     return "Windows";
116 #else
117     notImplemented();
118     return "Unknown";
119 #endif
120 }
121
122 static String composeUserAgent()
123 {
124     // This is a liberal interpretation of http://www.mozilla.org/build/revised-user-agent-strings.html
125     // See also http://developer.apple.com/internet/safari/faq.html#anchor2
126
127     String ua;
128
129     // Product
130     ua += "Mozilla/5.0";
131
132     // Comment
133     ua += " (";
134     ua += agentPlatform(); // Platform
135     ua += "; U; "; // Security
136     ua += agentOS(); // OS-or-CPU
137     ua += "; ";
138     ua += defaultLanguage(); // Localization information
139     ua += ") ";
140
141     // WebKit Product
142     // FIXME: The WebKit version is hardcoded
143     static const String webKitVersion = "528.5+";
144     ua += "AppleWebKit/" + webKitVersion;
145     ua += " (KHTML, like Gecko, ";
146     // We mention Safari since many broken sites check for it (OmniWeb does this too)
147     // We re-use the WebKit version, though it doesn't seem to matter much in practice
148     ua += "Safari/" + webKitVersion;
149     ua += ") ";
150
151     // Vendor Product
152     ua += g_get_prgname();
153
154     return ua;
155 }
156
157 String FrameLoaderClient::userAgent(const KURL&)
158 {
159     if (m_userAgent.isEmpty())
160         m_userAgent = composeUserAgent();
161
162     return m_userAgent;
163 }
164
165 WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClient::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData)
166 {
167     return DocumentLoader::create(request, substituteData);
168 }
169
170 void FrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction policyFunction, PassRefPtr<FormState>)
171 {
172     // FIXME: This is surely too simple
173     ASSERT(policyFunction);
174     if (!policyFunction)
175         return;
176     (core(m_frame)->loader()->*policyFunction)(PolicyUse);
177 }
178
179
180 void FrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
181 {
182     if (!m_pluginView) {
183         ASSERT(loader->frame());
184         // Setting the encoding on the frame loader is our way to get work done that is normally done
185         // when the first bit of data is received, even for the case of a document with no data (like about:blank).
186         String encoding = loader->overrideEncoding();
187         bool userChosen = !encoding.isNull();
188         if (!userChosen)
189             encoding = loader->response().textEncodingName();
190
191         FrameLoader* frameLoader = loader->frameLoader();
192         frameLoader->setEncoding(encoding, userChosen);
193         if (data)
194             frameLoader->addData(data, length);
195     }
196
197     if (m_pluginView) {
198         if (!m_hasSentResponseToPlugin) {
199             m_pluginView->didReceiveResponse(loader->response());
200             m_hasSentResponseToPlugin = true;
201         }
202         m_pluginView->didReceiveData(data, length);
203     }
204 }
205
206 bool
207 FrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long  identifier)
208 {
209     notImplemented();
210     return false;
211 }
212
213 void FrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long  identifier, const AuthenticationChallenge&)
214 {
215     notImplemented();
216 }
217
218 void FrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long  identifier, const AuthenticationChallenge&)
219 {
220     notImplemented();
221 }
222
223 void FrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long, ResourceRequest&, const ResourceResponse&)
224 {
225     notImplemented();
226 }
227
228 void FrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&)
229 {
230     notImplemented();
231 }
232
233 void FrameLoaderClient::postProgressStartedNotification()
234 {
235     WebKitWebView* webView = getViewFromFrame(m_frame);
236     g_signal_emit_by_name(webView, "load-started", m_frame);
237 }
238
239 void FrameLoaderClient::postProgressEstimateChangedNotification()
240 {
241     WebKitWebView* webView = getViewFromFrame(m_frame);
242     Page* corePage = core(webView);
243
244     g_signal_emit_by_name(webView, "load-progress-changed", lround(corePage->progress()->estimatedProgress()*100));
245 }
246
247 void FrameLoaderClient::postProgressFinishedNotification()
248 {
249     WebKitWebView* webView = getViewFromFrame(m_frame);
250     WebKitWebViewPrivate* privateData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
251
252     // We can get a stopLoad() from dispose when the object is being
253     // destroyed, don't emit the signal in that case.
254     if (!privateData->disposing)
255         g_signal_emit_by_name(webView, "load-finished", m_frame);
256 }
257
258 void FrameLoaderClient::frameLoaderDestroyed()
259 {
260     webkit_web_frame_core_frame_gone(m_frame);
261     g_object_unref(m_frame);
262     m_frame = 0;
263     delete this;
264 }
265
266 void FrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long, const ResourceResponse& response)
267 {
268     m_response = response;
269 }
270
271 void FrameLoaderClient::dispatchDecidePolicyForMIMEType(FramePolicyFunction policyFunction, const String& mimeType, const ResourceRequest& resourceRequest)
272 {
273     ASSERT(policyFunction);
274     if (!policyFunction)
275         return;
276
277     if (resourceRequest.isNull()) {
278         (core(m_frame)->loader()->*policyFunction)(PolicyIgnore);
279         return;
280     }
281
282     WebKitWebView* page = getViewFromFrame(m_frame);
283     WebKitNetworkRequest* request = webkit_network_request_new(resourceRequest.url().string().utf8().data());
284
285     WebKitWebPolicyDecision* policyDecision = webkit_web_policy_decision_new(m_frame, policyFunction);
286     if (m_policyDecision)
287         g_object_unref(m_policyDecision);
288     m_policyDecision = policyDecision;
289
290     gboolean isHandled = false;
291     g_signal_emit_by_name(page, "mime-type-policy-decision-requested", m_frame, request, mimeType.utf8().data(), policyDecision, &isHandled);
292
293     g_object_unref(request);
294
295     if (isHandled)
296         return;
297
298     if (canShowMIMEType(mimeType))
299         webkit_web_policy_decision_use (policyDecision);
300     else
301         webkit_web_policy_decision_download (policyDecision);
302 }
303
304 void FrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction policyFunction, const NavigationAction& action, const ResourceRequest& resourceRequest, PassRefPtr<FormState>, const String& s)
305 {
306     ASSERT(policyFunction);
307     if (!policyFunction)
308         return;
309
310     if (resourceRequest.isNull()) {
311         (core(m_frame)->loader()->*policyFunction)(PolicyIgnore);
312         return;
313     }
314
315     // FIXME: I think Qt version marshals this to another thread so when we
316     // have multi-threaded download, we might need to do the same
317     (core(m_frame)->loader()->*policyFunction)(PolicyUse);
318 }
319
320 void FrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction policyFunction, const NavigationAction& action, const ResourceRequest& resourceRequest, PassRefPtr<FormState>)
321 {
322     ASSERT(policyFunction);
323     if (!policyFunction)
324         return;
325
326     if (resourceRequest.isNull()) {
327         (core(m_frame)->loader()->*policyFunction)(PolicyIgnore);
328         return;
329     }
330
331     WebKitWebView* webView = getViewFromFrame(m_frame);
332     WebKitNetworkRequest* request = webkit_network_request_new(resourceRequest.url().string().utf8().data());
333     WebKitNavigationResponse response;
334     /*
335      * We still support the deprecated navigation-requested signal, if the
336      * application doesn't ignore the navigation then the new signal is
337      * emitted.
338      * navigation-policy-decision-requested must be emitted after
339      * navigation-requested as the policy decision can be async.
340      */
341     g_signal_emit_by_name(webView, "navigation-requested", m_frame, request, &response);
342
343     if (response == WEBKIT_NAVIGATION_RESPONSE_IGNORE) {
344         (core(m_frame)->loader()->*policyFunction)(PolicyIgnore);
345         g_object_unref(request);
346         return;
347     }
348
349     WebKitWebPolicyDecision* policyDecision = webkit_web_policy_decision_new(m_frame, policyFunction);
350     if (m_policyDecision)
351         g_object_unref(m_policyDecision);
352     m_policyDecision = policyDecision;
353
354     gint button = -1;
355     gint modifierFlags = 0;
356
357     const Event* event = action.event();
358     if (event && event->isMouseEvent()) {
359         const MouseEvent* mouseEvent = static_cast<const MouseEvent*>(event);
360         // DOM button values are 0, 1 and 2 for left, middle and right buttons.
361         // GTK+ uses 1, 2 and 3, so let's add 1 to remain consistent.
362         button = mouseEvent->button() + 1;
363     }
364
365     UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event));
366     if (keyStateEvent) {
367         if (keyStateEvent->shiftKey())
368             modifierFlags |= GDK_SHIFT_MASK;
369         if (keyStateEvent->ctrlKey())
370             modifierFlags |= GDK_CONTROL_MASK;
371         if (keyStateEvent->altKey())
372             modifierFlags |= GDK_MOD1_MASK;
373         if (keyStateEvent->metaKey())
374             modifierFlags |= GDK_MOD2_MASK;
375     }
376
377     GObject* navigationAction = G_OBJECT(g_object_new(WEBKIT_TYPE_WEB_NAVIGATION_ACTION,
378                                                      "reason", kit(action.type()),
379                                                       "original-uri", action.url().string().utf8().data(),
380                                                       "button", button,
381                                                       "modifier-state", modifierFlags,
382                                                       NULL));
383
384     gboolean isHandled = false;
385     g_signal_emit_by_name(webView, "navigation-policy-decision-requested", m_frame, request, navigationAction, policyDecision, &isHandled);
386
387     g_object_unref(navigationAction);
388     g_object_unref(request);
389
390     // FIXME Implement default behavior when we can query the backend what protocols it supports
391     if (!isHandled)
392         webkit_web_policy_decision_use(m_policyDecision);
393 }
394
395 Widget* FrameLoaderClient::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
396 {
397     PluginView* pluginView = PluginView::create(core(m_frame), pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
398
399     if (pluginView->status() == PluginStatusLoadedSuccessfully)
400         return pluginView;
401
402     return 0;
403 }
404
405 PassRefPtr<Frame> FrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
406                                                  const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
407 {
408     Frame* coreFrame = core(webFrame());
409
410     ASSERT(core(getViewFromFrame(webFrame())) == coreFrame->page());
411
412     RefPtr<Frame> childFrame = webkit_web_frame_init_with_web_view(getViewFromFrame(webFrame()), ownerElement);
413
414     coreFrame->tree()->appendChild(childFrame);
415
416     childFrame->tree()->setName(name);
417     childFrame->init();
418     childFrame->loader()->loadURL(url, referrer, String(), false, FrameLoadTypeRedirectWithLockedBackForwardList, 0, 0);
419
420     // The frame's onload handler may have removed it from the document.
421     if (!childFrame->tree()->parent())
422         return 0;
423
424     return childFrame.release();
425 }
426
427 void FrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
428 {
429     ASSERT(!m_pluginView);
430     m_pluginView = static_cast<PluginView*>(pluginWidget);
431     m_hasSentResponseToPlugin = false;
432 }
433
434 Widget* FrameLoaderClient::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL,
435                                                   const Vector<String>& paramNames, const Vector<String>& paramValues)
436 {
437     notImplemented();
438     return 0;
439 }
440
441 ObjectContentType FrameLoaderClient::objectContentType(const KURL& url, const String& mimeType)
442 {
443     String type = mimeType;
444     // We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns "application/octet-stream" upon failure
445     if (type.isEmpty())
446         type = MIMETypeRegistry::getMIMETypeForExtension(url.path().substring(url.path().reverseFind('.') + 1));
447
448     if (type.isEmpty())
449         return WebCore::ObjectContentFrame;
450
451     if (MIMETypeRegistry::isSupportedImageMIMEType(type))
452         return WebCore::ObjectContentImage;
453
454     if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
455         return WebCore::ObjectContentNetscapePlugin;
456
457     if (MIMETypeRegistry::isSupportedNonImageMIMEType(type))
458         return WebCore::ObjectContentFrame;
459
460     return WebCore::ObjectContentNone;
461 }
462
463 String FrameLoaderClient::overrideMediaType() const
464 {
465     notImplemented();
466     return String();
467 }
468
469 void FrameLoaderClient::windowObjectCleared()
470 {
471     // Is this obsolete now?
472     g_signal_emit_by_name(m_frame, "cleared");
473
474     Frame* coreFrame = core(webFrame());
475     ASSERT(coreFrame);
476
477     Settings* settings = coreFrame->settings();
478     if (!settings || !settings->isJavaScriptEnabled())
479         return;
480
481     // TODO: Consider using g_signal_has_handler_pending() to avoid the overhead
482     // when there are no handlers.
483     JSGlobalContextRef context = toGlobalRef(coreFrame->script()->globalObject()->globalExec());
484     JSObjectRef windowObject = toRef(coreFrame->script()->globalObject());
485     ASSERT(windowObject);
486
487     WebKitWebView* webView = getViewFromFrame(m_frame);
488     g_signal_emit_by_name(webView, "window-object-cleared", m_frame, context, windowObject);
489
490     // TODO: Re-attach debug clients if present.
491     // The Win port has an example of how we might do this.
492 }
493
494 void FrameLoaderClient::documentElementAvailable()
495 {
496 }
497
498 void FrameLoaderClient::didPerformFirstNavigation() const
499 {
500 }
501
502 void FrameLoaderClient::registerForIconNotification(bool)
503 {
504     notImplemented();
505 }
506
507 void FrameLoaderClient::setMainFrameDocumentReady(bool)
508 {
509     // this is only interesting once we provide an external API for the DOM
510 }
511
512 bool FrameLoaderClient::hasWebView() const
513 {
514     notImplemented();
515     return true;
516 }
517
518 void FrameLoaderClient::dispatchDidFinishLoad()
519 {
520     g_signal_emit_by_name(m_frame, "load-done", true);
521 }
522
523 void FrameLoaderClient::frameLoadCompleted()
524 {
525     notImplemented();
526 }
527
528 void FrameLoaderClient::saveViewStateToItem(HistoryItem*)
529 {
530     notImplemented();
531 }
532
533 void FrameLoaderClient::restoreViewState()
534 {
535     notImplemented();
536 }
537
538 bool FrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
539 {
540     // FIXME: This is a very simple implementation. More sophisticated
541     // implementation would delegate the decision to a PolicyDelegate.
542     // See mac implementation for example.
543     return item != 0;
544 }
545
546 void FrameLoaderClient::makeRepresentation(DocumentLoader*)
547 {
548     notImplemented();
549 }
550
551 void FrameLoaderClient::forceLayout()
552 {
553     FrameView* view = core(m_frame)->view();
554     if (view)
555         view->forceLayout(true);
556 }
557
558 void FrameLoaderClient::forceLayoutForNonHTML()
559 {
560     notImplemented();
561 }
562
563 void FrameLoaderClient::setCopiesOnScroll()
564 {
565     notImplemented();
566 }
567
568 void FrameLoaderClient::detachedFromParent2()
569 {
570     notImplemented();
571 }
572
573 void FrameLoaderClient::detachedFromParent3()
574 {
575     notImplemented();
576 }
577
578 void FrameLoaderClient::dispatchDidHandleOnloadEvents()
579 {
580     notImplemented();
581 }
582
583 void FrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
584 {
585     notImplemented();
586 }
587
588 void FrameLoaderClient::dispatchDidCancelClientRedirect()
589 {
590     notImplemented();
591 }
592
593 void FrameLoaderClient::dispatchWillPerformClientRedirect(const KURL&, double, double)
594 {
595     notImplemented();
596 }
597
598 void FrameLoaderClient::dispatchDidChangeLocationWithinPage()
599 {
600     notImplemented();
601 }
602
603 void FrameLoaderClient::dispatchWillClose()
604 {
605     notImplemented();
606 }
607
608 void FrameLoaderClient::dispatchDidReceiveIcon()
609 {
610     WebKitWebView* webView = getViewFromFrame(m_frame);
611
612     g_signal_emit_by_name(webView, "icon-loaded", m_frame);
613 }
614
615 void FrameLoaderClient::dispatchDidStartProvisionalLoad()
616 {
617 }
618
619 void FrameLoaderClient::dispatchDidReceiveTitle(const String& title)
620 {
621     g_signal_emit_by_name(m_frame, "title-changed", title.utf8().data());
622
623     WebKitWebView* webView = getViewFromFrame(m_frame);
624     if (m_frame == webkit_web_view_get_main_frame(webView))
625         g_signal_emit_by_name(webView, "title-changed", m_frame, title.utf8().data());
626 }
627
628 void FrameLoaderClient::dispatchDidCommitLoad()
629 {
630     /* Update the URI once first data has been received.
631      * This means the URI is valid and successfully identify the page that's going to be loaded.
632      */
633     WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(m_frame);
634     g_free(frameData->uri);
635     frameData->uri = g_strdup(core(m_frame)->loader()->url().prettyURL().utf8().data());
636
637     g_signal_emit_by_name(m_frame, "load-committed");
638
639     WebKitWebView* webView = getViewFromFrame(m_frame);
640     if (m_frame == webkit_web_view_get_main_frame(webView))
641         g_signal_emit_by_name(webView, "load-committed", m_frame);
642 }
643
644 void FrameLoaderClient::dispatchDidFinishDocumentLoad()
645 {
646     notImplemented();
647 }
648
649 void FrameLoaderClient::dispatchDidFirstLayout()
650 {
651     notImplemented();
652 }
653
654 void FrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
655 {
656     notImplemented();
657 }
658
659 void FrameLoaderClient::dispatchShow()
660 {
661     WebKitWebView* webView = getViewFromFrame(m_frame);
662     webkit_web_view_notify_ready(webView);
663 }
664
665 void FrameLoaderClient::cancelPolicyCheck()
666 {
667     //FIXME Add support for more than one policy decision at once
668     if (m_policyDecision)
669         webkit_web_policy_decision_cancel(m_policyDecision);
670 }
671
672 void FrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
673 {
674     notImplemented();
675 }
676
677 void FrameLoaderClient::revertToProvisionalState(DocumentLoader*)
678 {
679     notImplemented();
680 }
681
682 void FrameLoaderClient::willChangeTitle(DocumentLoader*)
683 {
684     notImplemented();
685 }
686
687 void FrameLoaderClient::didChangeTitle(DocumentLoader *l)
688 {
689     setTitle(l->title(), l->url());
690 }
691
692 bool FrameLoaderClient::canHandleRequest(const ResourceRequest&) const
693 {
694     notImplemented();
695     return true;
696 }
697
698 bool FrameLoaderClient::canShowMIMEType(const String& type) const
699 {
700     return MIMETypeRegistry::isSupportedImageMIMEType(type) || MIMETypeRegistry::isSupportedNonImageMIMEType(type) ||
701         PluginDatabase::installedPlugins()->isMIMETypeRegistered(type);
702 }
703
704 bool FrameLoaderClient::representationExistsForURLScheme(const String&) const
705 {
706     notImplemented();
707     return false;
708 }
709
710 String FrameLoaderClient::generatedMIMETypeForURLScheme(const String&) const
711 {
712     notImplemented();
713     return String();
714 }
715
716 void FrameLoaderClient::finishedLoading(DocumentLoader* documentLoader)
717 {
718     if (!m_pluginView)
719         committedLoad(documentLoader, 0, 0);
720     else {
721         m_pluginView->didFinishLoading();
722         m_pluginView = 0;
723         m_hasSentResponseToPlugin = false;
724     }
725 }
726
727
728 void FrameLoaderClient::provisionalLoadStarted()
729 {
730     notImplemented();
731 }
732
733 void FrameLoaderClient::didFinishLoad() {
734     notImplemented();
735 }
736
737 void FrameLoaderClient::prepareForDataSourceReplacement() { notImplemented(); }
738
739 void FrameLoaderClient::setTitle(const String& title, const KURL& url)
740 {
741     WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(m_frame);
742     g_free(frameData->title);
743     frameData->title = g_strdup(title.utf8().data());
744 }
745
746 void FrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived)
747 {
748     notImplemented();
749 }
750
751 void FrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
752 {
753     notImplemented();
754 }
755
756 void FrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError&)
757 {
758     notImplemented();
759 }
760
761 bool FrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length)
762 {
763     notImplemented();
764     return false;
765 }
766
767 void FrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError&)
768 {
769     g_signal_emit_by_name(m_frame, "load-done", false);
770 }
771
772 void FrameLoaderClient::dispatchDidFailLoad(const ResourceError&)
773 {
774     g_signal_emit_by_name(m_frame, "load-done", false);
775 }
776
777 void FrameLoaderClient::download(ResourceHandle*, const ResourceRequest&, const ResourceRequest&, const ResourceResponse&)
778 {
779     notImplemented();
780 }
781
782 ResourceError FrameLoaderClient::cancelledError(const ResourceRequest&)
783 {
784     notImplemented();
785     ResourceError error("", 0, "", "");
786     error.setIsCancellation(true);
787     return error;
788 }
789
790 ResourceError FrameLoaderClient::blockedError(const ResourceRequest&)
791 {
792     notImplemented();
793     return ResourceError("", 0, "", "");
794 }
795
796 ResourceError FrameLoaderClient::cannotShowURLError(const ResourceRequest&)
797 {
798     notImplemented();
799     return ResourceError("", 0, "", "");
800 }
801
802 ResourceError FrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest&)
803 {
804     notImplemented();
805     return ResourceError("", 0, "", "");
806 }
807
808 ResourceError FrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse&)
809 {
810     notImplemented();
811     return ResourceError("", 0, "", "");
812 }
813
814 ResourceError FrameLoaderClient::fileDoesNotExistError(const ResourceResponse&)
815 {
816     notImplemented();
817     return ResourceError("", 0, "", "");
818 }
819
820 ResourceError FrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse&)
821 {
822     notImplemented();
823     return ResourceError("", 0, "", "");
824 }
825
826 bool FrameLoaderClient::shouldFallBack(const ResourceError&)
827 {
828     notImplemented();
829     return false;
830 }
831
832 bool FrameLoaderClient::canCachePage() const
833 {
834     return true;
835 }
836
837 Frame* FrameLoaderClient::dispatchCreatePage()
838 {
839     WebKitWebView* webView = getViewFromFrame(m_frame);
840     WebKitWebView* newWebView = 0;
841
842     g_signal_emit_by_name(webView, "create-web-view", m_frame, &newWebView);
843
844     if (!newWebView)
845         return 0;
846
847     WebKitWebViewPrivate* privateData = WEBKIT_WEB_VIEW_GET_PRIVATE(newWebView);
848     return core(privateData->mainFrame);
849 }
850
851 void FrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError&)
852 {
853     notImplemented();
854 }
855
856 void FrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
857 {
858     if (m_pluginView) {
859         m_pluginView->didFail(error);
860         m_pluginView = 0;
861         m_hasSentResponseToPlugin = false;
862     }
863 }
864
865 void FrameLoaderClient::startDownload(const ResourceRequest&)
866 {
867     notImplemented();
868 }
869
870 void FrameLoaderClient::updateGlobalHistory()
871 {
872     notImplemented();
873 }
874
875 void FrameLoaderClient::updateGlobalHistoryRedirectLinks()
876 {
877     notImplemented();
878 }
879
880 void FrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*)
881 {
882 }
883
884 void FrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
885 {
886 }
887
888 void FrameLoaderClient::transitionToCommittedForNewPage()
889 {
890     WebKitWebView* containingWindow = getViewFromFrame(m_frame);
891     IntSize size = IntSize(GTK_WIDGET(containingWindow)->allocation.width,
892                            GTK_WIDGET(containingWindow)->allocation.height);
893     bool transparent = webkit_web_view_get_transparent(containingWindow);
894     Color backgroundColor = transparent ? WebCore::Color::transparent : WebCore::Color::white;
895     Frame* frame = core(m_frame);
896     ASSERT(frame);
897
898     frame->createView(size, backgroundColor, transparent, IntSize(), false);
899
900     // We need to do further manipulation on the FrameView if it was the mainFrame
901     if (frame != frame->page()->mainFrame())
902         return;
903
904     WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(containingWindow);
905     frame->view()->setGtkAdjustments(priv->horizontalAdjustment, priv->verticalAdjustment);
906 }
907
908 }