initial import
[vuplus_webkit] / Source / WebKit / gtk / WebCoreSupport / FrameLoaderClientGtk.cpp
1 /*
2  *  Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com>
3  *  Copyright (C) 2007, 2008, 2009 Holger Hans Peter Freyther
4  *  Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
5  *  Copyright (C) 2008, 2009 Collabora Ltd.  All rights reserved.
6  *  Copyright (C) 2009, 2010 Gustavo Noronha Silva <gns@gnome.org>
7  *  Copyright (C) Research In Motion Limited 2009. All rights reserved.
8  *  Copyright (C) 2010 Igalia S.L.
9  *  Copyright (C) 2011 Apple Inc. All rights reserved.
10  *
11  *  This library is free software; you can redistribute it and/or
12  *  modify it under the terms of the GNU Lesser General Public
13  *  License as published by the Free Software Foundation; either
14  *  version 2 of the License, or (at your option) any later version.
15  *
16  *  This library is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  *  Lesser General Public License for more details.
20  *
21  *  You should have received a copy of the GNU Lesser General Public
22  *  License along with this library; if not, write to the Free Software
23  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24  */
25
26 #include "config.h"
27 #include "FrameLoaderClientGtk.h"
28
29 #include "AXObjectCache.h"
30 #include "AccessibilityObject.h"
31 #include "ArchiveResource.h"
32 #include "CachedFrame.h"
33 #include "Color.h"
34 #include "DOMObjectCache.h"
35 #include "DocumentLoader.h"
36 #include "DocumentLoaderGtk.h"
37 #include "FormState.h"
38 #include "FrameLoader.h"
39 #include "FrameNetworkingContextGtk.h"
40 #include "FrameTree.h"
41 #include "FrameView.h"
42 #include "GOwnPtr.h"
43 #include "GRefPtr.h"
44 #include "GtkPluginWidget.h"
45 #include "HTMLAppletElement.h"
46 #include "HTMLFormElement.h"
47 #include "HTMLFrameElement.h"
48 #include "HTMLFrameOwnerElement.h"
49 #include "HTMLNames.h"
50 #include "HTMLPlugInElement.h"
51 #include "JSDOMBinding.h"
52 #include "JSDOMWindow.h"
53 #include "Language.h"
54 #include "MIMETypeRegistry.h"
55 #include "MouseEvent.h"
56 #include "NotImplemented.h"
57 #include "Page.h"
58 #include "PluginDatabase.h"
59 #include "ProgressTracker.h"
60 #include "RenderPart.h"
61 #include "RenderView.h"
62 #include "ResourceHandle.h"
63 #include "ResourceLoader.h"
64 #include "ResourceRequest.h"
65 #include "ScriptController.h"
66 #include "Settings.h"
67 #include "webkiterror.h"
68 #include "webkitglobals.h"
69 #include "webkitglobalsprivate.h"
70 #include "webkiticondatabase.h"
71 #include "webkitnetworkrequest.h"
72 #include "webkitnetworkrequestprivate.h"
73 #include "webkitnetworkresponse.h"
74 #include "webkitnetworkresponseprivate.h"
75 #include "webkitviewportattributes.h"
76 #include "webkitviewportattributesprivate.h"
77 #include "webkitwebdatasourceprivate.h"
78 #include "webkitwebframe.h"
79 #include "webkitwebframeprivate.h"
80 #include "webkitwebnavigationaction.h"
81 #include "webkitwebnavigationactionprivate.h"
82 #include "webkitwebpolicydecision.h"
83 #include "webkitwebpolicydecisionprivate.h"
84 #include "webkitwebresource.h"
85 #include "webkitwebresourceprivate.h"
86 #include "webkitwebsettingsprivate.h"
87 #include "webkitwebview.h"
88 #include "webkitwebviewprivate.h"
89 #include <JavaScriptCore/APICast.h>
90 #include <gio/gio.h>
91 #include <glib.h>
92 #include <glib/gi18n-lib.h>
93 #include <stdio.h>
94 #include <wtf/text/CString.h>
95 #include <wtf/text/StringConcatenate.h>
96
97 using namespace WebCore;
98
99 namespace WebKit {
100
101 FrameLoaderClient::FrameLoaderClient(WebKitWebFrame* frame)
102     : m_frame(frame)
103     , m_policyDecision(0)
104     , m_loadingErrorPage(false)
105     , m_pluginView(0)
106     , m_hasSentResponseToPlugin(false)
107     , m_hasRepresentation(false)
108 {
109     ASSERT(m_frame);
110 }
111
112 FrameLoaderClient::~FrameLoaderClient()
113 {
114     if (m_policyDecision)
115         g_object_unref(m_policyDecision);
116 }
117
118
119 String FrameLoaderClient::userAgent(const KURL& url)
120 {
121     WebKitWebSettings* settings = webkit_web_view_get_settings(getViewFromFrame(m_frame));
122     GOwnPtr<gchar> userAgentString(webkitWebSettingsUserAgentForURI(settings, url.string().utf8().data()));
123     return String::fromUTF8(userAgentString.get());
124 }
125
126 static void notifyAccessibilityStatus(WebKitWebFrame* frame, WebKitLoadStatus loadStatus)
127 {
128     if (loadStatus != WEBKIT_LOAD_PROVISIONAL
129         && loadStatus != WEBKIT_LOAD_FAILED
130         && loadStatus != WEBKIT_LOAD_FINISHED)
131         return;
132
133     WebKitWebFramePrivate* priv = frame->priv;
134     if (!priv->coreFrame || !priv->coreFrame->document())
135         return;
136
137     RenderView* contentRenderer = priv->coreFrame->contentRenderer();
138     if (!contentRenderer)
139         return;
140
141     AXObjectCache* axObjectCache = priv->coreFrame->document()->axObjectCache();
142     if (!axObjectCache)
143         return;
144
145     AccessibilityObject* coreAxObject = axObjectCache->getOrCreate(contentRenderer);
146     if (!coreAxObject)
147         return;
148
149     AtkObject* axObject = coreAxObject->wrapper();
150     if (!axObject || !ATK_IS_DOCUMENT(axObject))
151         return;
152
153     switch (loadStatus) {
154     case WEBKIT_LOAD_PROVISIONAL:
155         g_signal_emit_by_name(axObject, "state-change", "busy", true);
156         if (core(frame)->loader()->loadType() == FrameLoadTypeReload)
157             g_signal_emit_by_name(axObject, "reload");
158         break;
159     case WEBKIT_LOAD_FAILED:
160         g_signal_emit_by_name(axObject, "load-stopped");
161         g_signal_emit_by_name(axObject, "state-change", "busy", false);
162         break;
163     case WEBKIT_LOAD_FINISHED:
164         g_signal_emit_by_name(axObject, "load-complete");
165         g_signal_emit_by_name(axObject, "state-change", "busy", false);
166     default:
167         break;
168     }
169 }
170
171 static void notifyStatus(WebKitWebFrame* frame, WebKitLoadStatus loadStatus)
172 {
173     frame->priv->loadStatus = loadStatus;
174     g_object_notify(G_OBJECT(frame), "load-status");
175
176     WebKitWebView* webView = getViewFromFrame(frame);
177     if (frame == webkit_web_view_get_main_frame(webView)) {
178         webView->priv->loadStatus = loadStatus;
179         g_object_notify(G_OBJECT(webView), "load-status");
180
181         if (AXObjectCache::accessibilityEnabled())
182             notifyAccessibilityStatus(frame, loadStatus);
183     }
184 }
185
186 static void loadDone(WebKitWebFrame* frame, bool didSucceed)
187 {
188     // FIXME: load-done is deprecated. Please remove when signal's been removed.
189     g_signal_emit_by_name(frame, "load-done", didSucceed);
190     notifyStatus(frame, WEBKIT_LOAD_FINISHED);
191 }
192
193 WTF::PassRefPtr<WebCore::DocumentLoader> FrameLoaderClient::createDocumentLoader(const WebCore::ResourceRequest& request, const SubstituteData& substituteData)
194 {
195     RefPtr<WebKit::DocumentLoader> loader = WebKit::DocumentLoader::create(request, substituteData);
196
197     GRefPtr<WebKitWebDataSource> webDataSource(adoptGRef(kitNew(loader.get())));
198     loader->setDataSource(webDataSource.get());
199
200     return loader.release();
201 }
202
203 void FrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction policyFunction, PassRefPtr<FormState>)
204 {
205     // FIXME: This is surely too simple
206     ASSERT(policyFunction);
207     if (!policyFunction)
208         return;
209     (core(m_frame)->loader()->policyChecker()->*policyFunction)(PolicyUse);
210 }
211
212 void FrameLoaderClient::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length)
213 {
214     if (!m_pluginView) {
215         ASSERT(loader->frame());
216         loader->commitData(data, length);
217
218         Frame* coreFrame = loader->frame();
219         if (coreFrame && coreFrame->document()->isMediaDocument())
220             loader->cancelMainResourceLoad(coreFrame->loader()->client()->pluginWillHandleLoadError(loader->response()));
221     }
222
223     if (m_pluginView) {
224         if (!m_hasSentResponseToPlugin) {
225             m_pluginView->didReceiveResponse(loader->response());
226             m_hasSentResponseToPlugin = true;
227         }
228
229         // FIXME: We may want to investigate refactoring our plugin loading
230         // code to be similar to mac's.
231         // Also, see http://trac.webkit.org/changeset/24118.
232         if (!m_pluginView)
233             return;
234
235         m_pluginView->didReceiveData(data, length);
236     }
237 }
238
239 bool
240 FrameLoaderClient::shouldUseCredentialStorage(WebCore::DocumentLoader*, unsigned long  identifier)
241 {
242     notImplemented();
243     return false;
244 }
245
246 void FrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long  identifier, const AuthenticationChallenge&)
247 {
248     notImplemented();
249 }
250
251 void FrameLoaderClient::dispatchDidCancelAuthenticationChallenge(WebCore::DocumentLoader*, unsigned long  identifier, const AuthenticationChallenge&)
252 {
253     notImplemented();
254 }
255
256 // We convert this to string because it's easier to use strings as
257 // keys in a GHashTable.
258 static char* toString(unsigned long identifier)
259 {
260     return g_strdup_printf("%ld", identifier);
261 }
262
263 void FrameLoaderClient::dispatchWillSendRequest(WebCore::DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
264 {
265     GRefPtr<WebKitNetworkResponse> networkResponse(0);
266
267     // We are adding one more resource to the load, or maybe we are
268     // just redirecting a load.
269     if (redirectResponse.isNull())
270         static_cast<WebKit::DocumentLoader*>(loader)->increaseLoadCount(identifier);
271     else
272         networkResponse = adoptGRef(kitNew(redirectResponse));
273
274     WebKitWebView* webView = getViewFromFrame(m_frame);
275     GOwnPtr<gchar> identifierString(toString(identifier));
276     WebKitWebResource* webResource = webkit_web_view_get_resource(webView, identifierString.get());
277     GRefPtr<WebKitNetworkRequest> networkRequest(adoptGRef(kitNew(request)));
278
279     if (!redirectResponse.isNull()) {
280         // This is a redirect, so we need to update the WebResource's knowledge
281         // of the URI.
282         g_free(webResource->priv->uri);
283         webResource->priv->uri = g_strdup(request.url().string().utf8().data());
284     }
285     
286     g_signal_emit_by_name(webView, "resource-request-starting", m_frame, webResource, networkRequest.get(), networkResponse.get());
287
288     // Feed any changes back into the ResourceRequest object.
289     SoupMessage* message = webkit_network_request_get_message(networkRequest.get());
290     if (!message) {
291         request.setURL(KURL(KURL(), String::fromUTF8(webkit_network_request_get_uri(networkRequest.get()))));
292         return;
293     }
294
295     request.updateFromSoupMessage(message);
296 }
297
298 void FrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, WebCore::DocumentLoader* loader, const ResourceRequest& request)
299 {
300     GOwnPtr<gchar> identifierString(toString(identifier));
301
302     WebKitWebResource* webResource = WEBKIT_WEB_RESOURCE(g_object_new(WEBKIT_TYPE_WEB_RESOURCE, "uri", request.url().string().utf8().data(), 0));
303
304     if (loader == loader->frameLoader()->provisionalDocumentLoader()
305         && loader->frameLoader()->isLoadingMainFrame()) {
306         webkit_web_view_add_main_resource(getViewFromFrame(m_frame), identifierString.get(), webResource);
307         return;
308     }
309
310     webkit_web_view_add_resource(getViewFromFrame(m_frame), identifierString.get(), webResource);
311 }
312
313 void FrameLoaderClient::postProgressStartedNotification()
314 {
315     WebKitWebView* webView = getViewFromFrame(m_frame);
316     g_signal_emit_by_name(webView, "load-started", m_frame);
317
318     g_object_notify(G_OBJECT(webView), "progress");
319 }
320
321 void FrameLoaderClient::postProgressEstimateChangedNotification()
322 {
323     WebKitWebView* webView = getViewFromFrame(m_frame);
324     Page* corePage = core(webView);
325
326     g_signal_emit_by_name(webView, "load-progress-changed", lround(corePage->progress()->estimatedProgress()*100));
327
328     g_object_notify(G_OBJECT(webView), "progress");
329 }
330
331 void FrameLoaderClient::postProgressFinishedNotification()
332 {
333     WebKitWebView* webView = getViewFromFrame(m_frame);
334     WebKitWebViewPrivate* privateData = webView->priv;
335
336     // We can get a stopLoad() from dispose when the object is being
337     // destroyed, don't emit the signal in that case.
338     if (!privateData->disposing)
339         g_signal_emit_by_name(webView, "load-finished", m_frame);
340 }
341
342 void FrameLoaderClient::frameLoaderDestroyed()
343 {
344     webkit_web_frame_core_frame_gone(m_frame);
345     g_object_unref(m_frame);
346     m_frame = 0;
347     delete this;
348 }
349
350 void FrameLoaderClient::dispatchDidReceiveResponse(WebCore::DocumentLoader* loader, unsigned long, const ResourceResponse& response)
351 {
352     // Update our knowledge of request soup flags - some are only set
353     // after the request is done.
354     loader->request().setSoupMessageFlags(response.soupMessageFlags());
355
356     m_response = response;
357 }
358
359 void FrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction policyFunction, const ResourceResponse& response, const ResourceRequest& resourceRequest)
360 {
361     ASSERT(policyFunction);
362     if (!policyFunction)
363         return;
364
365     if (resourceRequest.isNull()) {
366         (core(m_frame)->loader()->policyChecker()->*policyFunction)(PolicyIgnore);
367         return;
368     }
369
370     WebKitWebView* page = getViewFromFrame(m_frame);
371     GRefPtr<WebKitNetworkRequest> request(adoptGRef(kitNew(resourceRequest)));
372
373     WebKitWebPolicyDecision* policyDecision = webkit_web_policy_decision_new(m_frame, policyFunction);
374     if (m_policyDecision)
375         g_object_unref(m_policyDecision);
376     m_policyDecision = policyDecision;
377
378     String mimeType = response.mimeType();
379
380     gboolean isHandled = false;
381     g_signal_emit_by_name(page, "mime-type-policy-decision-requested", m_frame, request.get(), mimeType.utf8().data(), policyDecision, &isHandled);
382
383     if (isHandled)
384         return;
385
386     GRefPtr<WebKitNetworkResponse> networkResponse(adoptGRef(webkit_web_frame_get_network_response(m_frame)));
387     if (networkResponse) {
388         ResourceResponse response = core(networkResponse.get());
389         if (response.isAttachment()) {
390             webkit_web_policy_decision_download(policyDecision);
391             return;
392         }
393     }
394
395     if (canShowMIMEType(mimeType))
396         webkit_web_policy_decision_use(policyDecision);
397     else
398         webkit_web_policy_decision_ignore(policyDecision);
399 }
400
401 static WebKitWebNavigationAction* getNavigationAction(const NavigationAction& action, const char* targetFrame)
402 {
403     gint button = -1;
404
405     const Event* event = action.event();
406     if (event && event->isMouseEvent()) {
407         const MouseEvent* mouseEvent = static_cast<const MouseEvent*>(event);
408         // DOM button values are 0, 1 and 2 for left, middle and right buttons.
409         // GTK+ uses 1, 2 and 3, so let's add 1 to remain consistent.
410         button = mouseEvent->button() + 1;
411     }
412
413     gint modifierFlags = 0;
414     UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(event));
415     if (keyStateEvent) {
416         if (keyStateEvent->shiftKey())
417             modifierFlags |= GDK_SHIFT_MASK;
418         if (keyStateEvent->ctrlKey())
419             modifierFlags |= GDK_CONTROL_MASK;
420         if (keyStateEvent->altKey())
421             modifierFlags |= GDK_MOD1_MASK;
422         if (keyStateEvent->metaKey())
423             modifierFlags |= GDK_MOD2_MASK;
424     }
425
426     return WEBKIT_WEB_NAVIGATION_ACTION(g_object_new(WEBKIT_TYPE_WEB_NAVIGATION_ACTION,
427                                                      "reason", kit(action.type()),
428                                                      "original-uri", action.url().string().utf8().data(),
429                                                      "button", button,
430                                                      "modifier-state", modifierFlags,
431                                                      "target-frame", targetFrame,
432                                                      NULL));
433 }
434
435 void FrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction policyFunction, const NavigationAction& action, const ResourceRequest& resourceRequest, PassRefPtr<FormState>, const String& frameName)
436 {
437     ASSERT(policyFunction);
438     if (!policyFunction)
439         return;
440
441     if (resourceRequest.isNull()) {
442         (core(m_frame)->loader()->policyChecker()->*policyFunction)(PolicyIgnore);
443         return;
444     }
445
446     WebKitWebPolicyDecision* policyDecision = webkit_web_policy_decision_new(m_frame, policyFunction);
447
448     if (m_policyDecision)
449         g_object_unref(m_policyDecision);
450     m_policyDecision = policyDecision;
451
452     WebKitWebView* webView = getViewFromFrame(m_frame);
453     GRefPtr<WebKitNetworkRequest> request(adoptGRef(webkit_network_request_new(resourceRequest.url().string().utf8().data())));
454     GRefPtr<WebKitWebNavigationAction> navigationAction(adoptGRef(getNavigationAction(action, frameName.utf8().data())));
455     gboolean isHandled = false;
456
457     g_signal_emit_by_name(webView, "new-window-policy-decision-requested", m_frame, request.get(), navigationAction.get(), policyDecision, &isHandled);
458
459     // FIXME: I think Qt version marshals this to another thread so when we
460     // have multi-threaded download, we might need to do the same
461     if (!isHandled)
462         (core(m_frame)->loader()->policyChecker()->*policyFunction)(PolicyUse);
463 }
464
465 void FrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction policyFunction, const NavigationAction& action, const ResourceRequest& resourceRequest, PassRefPtr<FormState>)
466 {
467     ASSERT(policyFunction);
468     if (!policyFunction)
469         return;
470
471     if (resourceRequest.isNull()) {
472         (core(m_frame)->loader()->policyChecker()->*policyFunction)(PolicyIgnore);
473         return;
474     }
475
476     WebKitWebView* webView = getViewFromFrame(m_frame);
477     GRefPtr<WebKitNetworkRequest> request(adoptGRef(kitNew(resourceRequest)));
478     WebKitNavigationResponse response;
479     /*
480      * We still support the deprecated navigation-requested signal, if the
481      * application doesn't ignore the navigation then the new signal is
482      * emitted.
483      * navigation-policy-decision-requested must be emitted after
484      * navigation-requested as the policy decision can be async.
485      */
486     g_signal_emit_by_name(webView, "navigation-requested", m_frame, request.get(), &response);
487
488     if (response == WEBKIT_NAVIGATION_RESPONSE_IGNORE) {
489         (core(m_frame)->loader()->policyChecker()->*policyFunction)(PolicyIgnore);
490         return;
491     }
492
493     WebKitWebPolicyDecision* policyDecision = webkit_web_policy_decision_new(m_frame, policyFunction);
494     if (m_policyDecision)
495         g_object_unref(m_policyDecision);
496     m_policyDecision = policyDecision;
497
498     GRefPtr<WebKitWebNavigationAction> navigationAction(adoptGRef(getNavigationAction(action, 0)));
499     gboolean isHandled = false;
500     g_signal_emit_by_name(webView, "navigation-policy-decision-requested", m_frame, request.get(), navigationAction.get(), policyDecision, &isHandled);
501
502     // FIXME Implement default behavior when we can query the backend what protocols it supports
503     if (!isHandled)
504         webkit_web_policy_decision_use(m_policyDecision);
505 }
506
507 PassRefPtr<Widget> FrameLoaderClient::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
508 {
509     /* Check if we want to embed a GtkWidget, fallback to plugins later */
510     CString urlString = url.string().utf8();
511     CString mimeTypeString = mimeType.utf8();
512
513     ASSERT(paramNames.size() == paramValues.size());
514     GRefPtr<GHashTable> hash = adoptGRef(g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free));
515     for (unsigned i = 0; i < paramNames.size(); ++i) {
516         g_hash_table_insert(hash.get(),
517                             g_strdup(paramNames[i].utf8().data()),
518                             g_strdup(paramValues[i].utf8().data()));
519     }
520
521     GtkWidget* gtkWidget = 0;
522     g_signal_emit_by_name(getViewFromFrame(m_frame), "create-plugin-widget",
523                           mimeTypeString.data(), urlString.data(), hash.get(), &gtkWidget);
524     if (gtkWidget)
525         return adoptRef(new GtkPluginWidget(gtkWidget));
526
527     RefPtr<PluginView> pluginView = PluginView::create(core(m_frame), pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
528
529     if (pluginView->status() == PluginStatusLoadedSuccessfully)
530         return pluginView;
531
532     return 0;
533 }
534
535 PassRefPtr<Frame> FrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
536                                                  const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
537 {
538     ASSERT(m_frame);
539     Frame* parentFrame = core(m_frame);
540     WebKitWebView* webView = getViewFromFrame(m_frame);
541     WebCore::Page* page = core(webView);
542     ASSERT(page == parentFrame->page());
543
544     WebKitWebFrame* kitFrame = WEBKIT_WEB_FRAME(g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL));
545     WebKitWebFramePrivate* framePrivate = kitFrame->priv;
546     framePrivate->webView = webView;
547
548     RefPtr<Frame> childFrame = Frame::create(page, ownerElement, new FrameLoaderClient(kitFrame));
549     framePrivate->coreFrame = childFrame.get();
550
551     childFrame->tree()->setName(name);
552     parentFrame->tree()->appendChild(childFrame);
553     childFrame->init();
554
555     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
556     if (!childFrame->page())
557         return 0;
558
559     g_signal_emit_by_name(webView, "frame-created", kitFrame);
560
561     parentFrame->loader()->loadURLIntoChildFrame(url, referrer, childFrame.get());
562
563     // The frame's onload handler may have removed it from the document.
564     if (!childFrame->tree()->parent())
565         return 0;
566
567     return childFrame.release();
568 }
569
570 void FrameLoaderClient::didTransferChildFrameToNewDocument(WebCore::Page*)
571 {
572     ASSERT(m_frame);
573
574     // Update the frame's webview to the new parent's webview.
575     Frame* coreFrame = core(m_frame);
576     WebKitWebView* webView = getViewFromFrame(m_frame);
577
578     Frame* parentCoreFrame = coreFrame->tree()->parent();
579     WebKitWebFrame* parentKitFrame = kit(parentCoreFrame);
580     WebKitWebView* parentWebView = getViewFromFrame(parentKitFrame);
581     if (webView != parentWebView)
582         m_frame->priv->webView = parentWebView;
583
584     ASSERT(core(getViewFromFrame(m_frame)) == coreFrame->page());
585 }
586
587 void FrameLoaderClient::transferLoadingResourceFromPage(WebCore::ResourceLoader* loader, const WebCore::ResourceRequest& request, WebCore::Page* oldPage)
588 {
589     ASSERT(oldPage != core(m_frame)->page());
590
591     GOwnPtr<gchar> identifierString(toString(loader->identifier()));
592     ASSERT(!webkit_web_view_get_resource(getViewFromFrame(m_frame), identifierString.get()));
593
594     assignIdentifierToInitialRequest(loader->identifier(), loader->documentLoader(), request);
595
596     webkit_web_view_remove_resource(kit(oldPage), identifierString.get());
597 }
598
599 void FrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
600 {
601     ASSERT(!m_pluginView);
602     m_pluginView = static_cast<PluginView*>(pluginWidget);
603     m_hasSentResponseToPlugin = false;
604 }
605
606 PassRefPtr<Widget> FrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues)
607 {
608     return FrameLoaderClient::createPlugin(pluginSize, element, baseURL, paramNames, paramValues, "application/x-java-applet", false);
609 }
610
611 ObjectContentType FrameLoaderClient::objectContentType(const KURL& url, const String& mimeType, bool shouldPreferPlugInsForImages)
612 {
613     return FrameLoader::defaultObjectContentType(url, mimeType, shouldPreferPlugInsForImages);
614 }
615
616 String FrameLoaderClient::overrideMediaType() const
617 {
618     notImplemented();
619     return String();
620 }
621
622 void FrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
623 {
624     if (world != mainThreadNormalWorld())
625         return;
626
627     // Is this obsolete now?
628     g_signal_emit_by_name(m_frame, "cleared");
629
630     Frame* coreFrame = core(m_frame);
631     ASSERT(coreFrame);
632
633     Settings* settings = coreFrame->settings();
634     if (!settings || !settings->isJavaScriptEnabled())
635         return;
636
637     // TODO: Consider using g_signal_has_handler_pending() to avoid the overhead
638     // when there are no handlers.
639     JSGlobalContextRef context = toGlobalRef(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
640     JSObjectRef windowObject = toRef(coreFrame->script()->globalObject(mainThreadNormalWorld()));
641     ASSERT(windowObject);
642
643     WebKitWebView* webView = getViewFromFrame(m_frame);
644     g_signal_emit_by_name(webView, "window-object-cleared", m_frame, context, windowObject);
645
646     // TODO: Re-attach debug clients if present.
647     // The Win port has an example of how we might do this.
648 }
649
650 void FrameLoaderClient::documentElementAvailable()
651 {
652 }
653
654 void FrameLoaderClient::didPerformFirstNavigation() const
655 {
656     WebKitCacheModel cacheModel = webkit_get_cache_model();
657     // If user agents do not determine the cache model, we use WEBKIT_CACHE_MODEL_WEB_BROWSER by default.
658     if (cacheModel == WEBKIT_CACHE_MODEL_DEFAULT)
659         webkit_set_cache_model(WEBKIT_CACHE_MODEL_WEB_BROWSER);
660 }
661
662 void FrameLoaderClient::registerForIconNotification(bool shouldRegister)
663 {
664     notImplemented();
665 }
666
667 void FrameLoaderClient::setMainFrameDocumentReady(bool ready)
668 {
669     if (!ready)
670         DOMObjectCache::clearByFrame(core(m_frame));
671 }
672
673 bool FrameLoaderClient::hasWebView() const
674 {
675     return getViewFromFrame(m_frame);
676 }
677
678 void FrameLoaderClient::dispatchDidFinishLoad()
679 {
680     if (m_loadingErrorPage) {
681         m_loadingErrorPage = false;
682         return;
683     }
684
685     loadDone(m_frame, true);
686 }
687
688 void FrameLoaderClient::frameLoadCompleted()
689 {
690     notImplemented();
691 }
692
693 void FrameLoaderClient::saveViewStateToItem(HistoryItem*)
694 {
695     notImplemented();
696 }
697
698 void FrameLoaderClient::restoreViewState()
699 {
700     notImplemented();
701 }
702
703 bool FrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
704 {
705     // FIXME: This is a very simple implementation. More sophisticated
706     // implementation would delegate the decision to a PolicyDelegate.
707     // See mac implementation for example.
708     return item != 0;
709 }
710
711 bool FrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
712 {
713     return true;
714 }
715
716 void FrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
717 {
718 }
719
720 void FrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
721 {
722 }
723
724 void FrameLoaderClient::dispatchDidChangeBackForwardIndex() const
725 {
726 }
727
728 void FrameLoaderClient::didDisplayInsecureContent()
729 {
730     notImplemented();
731 }
732
733 void FrameLoaderClient::didRunInsecureContent(SecurityOrigin*, const KURL&)
734 {
735     notImplemented();
736 }
737
738 void FrameLoaderClient::makeRepresentation(WebCore::DocumentLoader*)
739 {
740     m_hasRepresentation = true;
741 }
742
743 void FrameLoaderClient::forceLayout()
744 {
745     FrameView* view = core(m_frame)->view();
746     if (view)
747         view->forceLayout(true);
748 }
749
750 void FrameLoaderClient::forceLayoutForNonHTML()
751 {
752     notImplemented();
753 }
754
755 void FrameLoaderClient::setCopiesOnScroll()
756 {
757     notImplemented();
758 }
759
760 void FrameLoaderClient::detachedFromParent2()
761 {
762     notImplemented();
763 }
764
765 void FrameLoaderClient::detachedFromParent3()
766 {
767     notImplemented();
768 }
769
770 void FrameLoaderClient::dispatchDidHandleOnloadEvents()
771 {
772     g_signal_emit_by_name(getViewFromFrame(m_frame), "onload-event", m_frame);
773 }
774
775 void FrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
776 {
777     notImplemented();
778 }
779
780 void FrameLoaderClient::dispatchDidCancelClientRedirect()
781 {
782     notImplemented();
783 }
784
785 void FrameLoaderClient::dispatchWillPerformClientRedirect(const KURL&, double, double)
786 {
787     notImplemented();
788 }
789
790 void FrameLoaderClient::dispatchDidChangeLocationWithinPage()
791 {
792     WebKitWebFramePrivate* priv = m_frame->priv;
793     g_free(priv->uri);
794     priv->uri = g_strdup(core(m_frame)->document()->url().string().utf8().data());
795     g_object_notify(G_OBJECT(m_frame), "uri");
796     WebKitWebView* webView = getViewFromFrame(m_frame);
797     if (m_frame == webkit_web_view_get_main_frame(webView))
798         g_object_notify(G_OBJECT(webView), "uri");
799 }
800
801 void FrameLoaderClient::dispatchDidPushStateWithinPage()
802 {
803     notImplemented();
804 }
805
806 void FrameLoaderClient::dispatchDidReplaceStateWithinPage()
807 {
808     notImplemented();
809 }
810
811 void FrameLoaderClient::dispatchDidPopStateWithinPage()
812 {
813     notImplemented();
814 }
815
816 void FrameLoaderClient::dispatchWillClose()
817 {
818     notImplemented();
819 }
820
821 void FrameLoaderClient::dispatchDidReceiveIcon()
822 {
823     if (m_loadingErrorPage)
824         return;
825
826     const gchar* frameURI = webkit_web_frame_get_uri(m_frame);
827     WebKitIconDatabase* database = webkit_get_icon_database();
828     g_signal_emit_by_name(database, "icon-loaded", m_frame, frameURI);
829
830     WebKitWebView* webView = getViewFromFrame(m_frame);
831
832     // Avoid reporting favicons for non-main frames.
833     if (m_frame != webkit_web_view_get_main_frame(webView))
834         return;
835
836     g_object_notify(G_OBJECT(webView), "icon-uri");
837     g_signal_emit_by_name(webView, "icon-loaded", webkit_web_view_get_icon_uri(webView));
838 }
839
840 void FrameLoaderClient::dispatchDidStartProvisionalLoad()
841 {
842     if (m_loadingErrorPage)
843         return;
844
845     notifyStatus(m_frame, WEBKIT_LOAD_PROVISIONAL);
846 }
847
848 void FrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
849 {
850     if (m_loadingErrorPage)
851         return;
852
853     WebKitWebFramePrivate* priv = m_frame->priv;
854     g_free(priv->title);
855     // FIXME: use direction of title.
856     priv->title = g_strdup(title.string().utf8().data());
857
858     g_signal_emit_by_name(m_frame, "title-changed", priv->title);
859     g_object_notify(G_OBJECT(m_frame), "title");
860
861     WebKitWebView* webView = getViewFromFrame(m_frame);
862     if (m_frame == webkit_web_view_get_main_frame(webView)) {
863         g_signal_emit_by_name(webView, "title-changed", m_frame, title.string().utf8().data());
864         g_object_notify(G_OBJECT(webView), "title");
865     }
866 }
867
868 void FrameLoaderClient::dispatchDidChangeIcons(WebCore::IconType)
869 {
870     notImplemented();
871 }
872
873 void FrameLoaderClient::dispatchDidCommitLoad()
874 {
875     if (m_loadingErrorPage)
876         return;
877
878     /* Update the URI once first data has been received.
879      * This means the URI is valid and successfully identify the page that's going to be loaded.
880      */
881     g_object_freeze_notify(G_OBJECT(m_frame));
882
883     WebKitWebFramePrivate* priv = m_frame->priv;
884     g_free(priv->uri);
885     priv->uri = g_strdup(core(m_frame)->loader()->activeDocumentLoader()->url().string().utf8().data());
886     g_free(priv->title);
887     priv->title = NULL;
888     g_object_notify(G_OBJECT(m_frame), "uri");
889     g_object_notify(G_OBJECT(m_frame), "title");
890
891     g_signal_emit_by_name(m_frame, "load-committed");
892     notifyStatus(m_frame, WEBKIT_LOAD_COMMITTED);
893
894     WebKitWebView* webView = getViewFromFrame(m_frame);
895     if (m_frame == webkit_web_view_get_main_frame(webView)) {
896         g_object_freeze_notify(G_OBJECT(webView));
897         g_object_notify(G_OBJECT(webView), "uri");
898         g_object_notify(G_OBJECT(webView), "title");
899         g_object_thaw_notify(G_OBJECT(webView));
900         g_signal_emit_by_name(webView, "load-committed", m_frame);
901     }
902
903     g_object_thaw_notify(G_OBJECT(m_frame));
904 }
905
906 void FrameLoaderClient::dispatchDidFinishDocumentLoad()
907 {
908     WebKitWebView* webView = getViewFromFrame(m_frame);
909     g_signal_emit_by_name(webView, "document-load-finished", m_frame);
910 }
911
912 void FrameLoaderClient::dispatchDidFirstLayout()
913 {
914     notImplemented();
915 }
916
917 void FrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
918 {
919     if (m_loadingErrorPage)
920         return;
921
922     notifyStatus(m_frame, WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT);
923 }
924
925 void FrameLoaderClient::dispatchShow()
926 {
927     WebKitWebView* webView = getViewFromFrame(m_frame);
928     webkit_web_view_notify_ready(webView);
929 }
930
931 void FrameLoaderClient::cancelPolicyCheck()
932 {
933     //FIXME Add support for more than one policy decision at once
934     if (m_policyDecision)
935         webkit_web_policy_decision_cancel(m_policyDecision);
936 }
937
938 void FrameLoaderClient::dispatchDidLoadMainResource(WebCore::DocumentLoader*)
939 {
940     notImplemented();
941 }
942
943 void FrameLoaderClient::revertToProvisionalState(WebCore::DocumentLoader*)
944 {
945     m_hasRepresentation = true;
946 }
947
948 void FrameLoaderClient::willChangeTitle(WebCore::DocumentLoader*)
949 {
950     notImplemented();
951 }
952
953 void FrameLoaderClient::didChangeTitle(WebCore::DocumentLoader *l)
954 {
955     setTitle(l->title(), l->url());
956 }
957
958 bool FrameLoaderClient::canHandleRequest(const ResourceRequest&) const
959 {
960     notImplemented();
961     return true;
962 }
963
964 bool FrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
965 {
966     notImplemented();
967     return false;
968 }
969
970 bool FrameLoaderClient::canShowMIMEType(const String& type) const
971 {
972     return (MIMETypeRegistry::isSupportedImageMIMEType(type)
973             || MIMETypeRegistry::isSupportedNonImageMIMEType(type)
974             || MIMETypeRegistry::isSupportedMediaMIMEType(type)
975             || PluginDatabase::installedPlugins()->isMIMETypeRegistered(type));
976 }
977
978 bool FrameLoaderClient::representationExistsForURLScheme(const String&) const
979 {
980     notImplemented();
981     return false;
982 }
983
984 String FrameLoaderClient::generatedMIMETypeForURLScheme(const String&) const
985 {
986     notImplemented();
987     return String();
988 }
989
990 void FrameLoaderClient::finishedLoading(WebCore::DocumentLoader* documentLoader)
991 {
992     if (!m_pluginView) {
993         // This is necessary to create an empty document,
994         // but it has to be skipped in the provisional phase.
995         if (m_hasRepresentation)
996             documentLoader->writer()->setEncoding("", false);
997     } else {
998         m_pluginView->didFinishLoading();
999         m_pluginView = 0;
1000         m_hasSentResponseToPlugin = false;
1001     }
1002 }
1003
1004
1005 void FrameLoaderClient::provisionalLoadStarted()
1006 {
1007     notImplemented();
1008 }
1009
1010 void FrameLoaderClient::didFinishLoad() {
1011     notImplemented();
1012 }
1013
1014 void FrameLoaderClient::prepareForDataSourceReplacement() 
1015 {
1016     notImplemented();
1017 }
1018
1019 void FrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
1020 {
1021     WebKitWebFramePrivate* frameData = m_frame->priv;
1022     g_free(frameData->title);
1023     // FIXME: use direction of title.
1024     frameData->title = g_strdup(title.string().utf8().data());
1025 }
1026
1027 void FrameLoaderClient::dispatchDidReceiveContentLength(WebCore::DocumentLoader*, unsigned long identifier, int dataLength)
1028 {
1029     notImplemented();
1030 }
1031
1032 void FrameLoaderClient::dispatchDidFinishLoading(WebCore::DocumentLoader* loader, unsigned long identifier)
1033 {
1034     static_cast<WebKit::DocumentLoader*>(loader)->decreaseLoadCount(identifier);
1035
1036     WebKitWebView* webView = getViewFromFrame(m_frame);
1037     GOwnPtr<gchar> identifierString(toString(identifier));
1038     WebKitWebResource* webResource = webkit_web_view_get_resource(webView, identifierString.get());
1039
1040     // A NULL WebResource means the load has been interrupted, and
1041     // replaced by another one while this resource was being loaded.
1042     if (!webResource)
1043         return;
1044
1045     const char* uri = webkit_web_resource_get_uri(webResource);
1046     RefPtr<ArchiveResource> coreResource(loader->subresource(KURL(KURL(), uri)));
1047
1048     // If coreResource is NULL here, the resource failed to load,
1049     // unless it's the main resource.
1050     if (!coreResource && webResource != webkit_web_view_get_main_resource(webView))
1051         return;
1052
1053     if (!coreResource)
1054         coreResource = loader->mainResource();
1055
1056     webkit_web_resource_init_with_core_resource(webResource, coreResource.get());
1057
1058     // FIXME: This function should notify the application that the resource
1059     // finished loading, maybe using a load-status property in the
1060     // WebKitWebResource object, similar to what we do for WebKitWebFrame'
1061     // signal.
1062     notImplemented();
1063 }
1064
1065 void FrameLoaderClient::dispatchDidFailLoading(WebCore::DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
1066 {
1067     static_cast<WebKit::DocumentLoader*>(loader)->decreaseLoadCount(identifier);
1068
1069     // FIXME: This function should notify the application that the resource failed
1070     // loading, maybe a 'load-error' signal in the WebKitWebResource object.
1071     notImplemented();
1072 }
1073
1074 bool FrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length)
1075 {
1076     notImplemented();
1077     return false;
1078 }
1079
1080 void FrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
1081 {
1082     dispatchDidFailLoad(error);
1083 }
1084
1085 void FrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
1086 {
1087     if (m_loadingErrorPage)
1088         return;
1089
1090     notifyStatus(m_frame, WEBKIT_LOAD_FAILED);
1091
1092     WebKitWebView* webView = getViewFromFrame(m_frame);
1093     GError* webError = g_error_new_literal(g_quark_from_string(error.domain().utf8().data()),
1094                                            error.errorCode(),
1095                                            error.localizedDescription().utf8().data());
1096     gboolean isHandled = false;
1097     g_signal_emit_by_name(webView, "load-error", m_frame, error.failingURL().utf8().data(), webError, &isHandled);
1098
1099     if (isHandled) {
1100         g_error_free(webError);
1101         return;
1102     }
1103
1104     if (!shouldFallBack(error)) {
1105         g_error_free(webError);
1106         return;
1107     }
1108
1109     m_loadingErrorPage = true;
1110
1111     String content;
1112     gchar* fileContent = 0;
1113     gchar* errorURI = g_filename_to_uri(DATA_DIR"/webkit-1.0/resources/error.html", NULL, NULL);
1114     GFile* errorFile = g_file_new_for_uri(errorURI);
1115     g_free(errorURI);
1116
1117     if (!errorFile)
1118         content = makeString("<html><body>", webError->message, "</body></html>");
1119     else {
1120         gboolean loaded = g_file_load_contents(errorFile, 0, &fileContent, 0, 0, 0);
1121         if (!loaded)
1122             content = makeString("<html><body>", webError->message, "</body></html>");
1123         else
1124             content = String::format(fileContent, error.failingURL().utf8().data(), webError->message);
1125     }
1126
1127     webkit_web_frame_load_alternate_string(m_frame, content.utf8().data(), 0, error.failingURL().utf8().data());
1128
1129     g_free(fileContent);
1130
1131     if (errorFile)
1132         g_object_unref(errorFile);
1133
1134     g_error_free(webError);
1135 }
1136
1137 void FrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest&, const ResourceResponse& response)
1138 {
1139     GRefPtr<WebKitNetworkRequest> networkRequest(adoptGRef(kitNew(request)));
1140     WebKitWebView* view = getViewFromFrame(m_frame);
1141
1142     webkit_web_view_request_download(view, networkRequest.get(), response, handle);
1143 }
1144
1145 ResourceError FrameLoaderClient::cancelledError(const ResourceRequest& request)
1146 {
1147     return ResourceError(g_quark_to_string(WEBKIT_NETWORK_ERROR), WEBKIT_NETWORK_ERROR_CANCELLED,
1148                          request.url().string(), _("Load request cancelled"));
1149 }
1150
1151 ResourceError FrameLoaderClient::blockedError(const ResourceRequest& request)
1152 {
1153     return ResourceError(g_quark_to_string(WEBKIT_POLICY_ERROR), WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT,
1154                          request.url().string(), _("Not allowed to use restricted network port"));
1155 }
1156
1157 ResourceError FrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
1158 {
1159     return ResourceError(g_quark_to_string(WEBKIT_POLICY_ERROR), WEBKIT_POLICY_ERROR_CANNOT_SHOW_URL,
1160                          request.url().string(), _("URL cannot be shown"));
1161 }
1162
1163 ResourceError FrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request)
1164 {
1165     return ResourceError(g_quark_to_string(WEBKIT_POLICY_ERROR), WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE,
1166                          request.url().string(), _("Frame load was interrupted"));
1167 }
1168
1169 ResourceError FrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
1170 {
1171     return ResourceError(g_quark_to_string(WEBKIT_POLICY_ERROR), WEBKIT_POLICY_ERROR_CANNOT_SHOW_MIME_TYPE,
1172                          response.url().string(), _("Content with the specified MIME type cannot be shown"));
1173 }
1174
1175 ResourceError FrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
1176 {
1177     return ResourceError(g_quark_to_string(WEBKIT_NETWORK_ERROR), WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST,
1178                          response.url().string(), _("File does not exist"));
1179 }
1180
1181 ResourceError FrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
1182 {
1183     return ResourceError(g_quark_to_string(WEBKIT_PLUGIN_ERROR), WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD,
1184                          response.url().string(), _("Plugin will handle load"));
1185 }
1186
1187 bool FrameLoaderClient::shouldFallBack(const ResourceError& error)
1188 {
1189     return !(error.isCancellation() || error.errorCode() == WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE || error.errorCode() == WEBKIT_PLUGIN_ERROR_WILL_HANDLE_LOAD);
1190 }
1191
1192 bool FrameLoaderClient::canCachePage() const
1193 {
1194     return true;
1195 }
1196
1197 Frame* FrameLoaderClient::dispatchCreatePage(const NavigationAction&)
1198 {
1199     WebKitWebView* webView = getViewFromFrame(m_frame);
1200     WebKitWebView* newWebView = 0;
1201
1202     g_signal_emit_by_name(webView, "create-web-view", m_frame, &newWebView);
1203
1204     if (!newWebView)
1205         return 0;
1206
1207     WebKitWebViewPrivate* privateData = newWebView->priv;
1208     return core(privateData->mainFrame);
1209 }
1210
1211 void FrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError&)
1212 {
1213     notImplemented();
1214 }
1215
1216 void FrameLoaderClient::setMainDocumentError(WebCore::DocumentLoader*, const ResourceError& error)
1217 {
1218     if (m_pluginView) {
1219         m_pluginView->didFail(error);
1220         m_pluginView = 0;
1221         m_hasSentResponseToPlugin = false;
1222     }
1223 }
1224
1225 void FrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
1226 {
1227     GRefPtr<WebKitNetworkRequest> networkRequest(adoptGRef(kitNew(request)));
1228     WebKitWebView* view = getViewFromFrame(m_frame);
1229
1230     webkit_web_view_request_download(view, networkRequest.get());
1231 }
1232
1233 void FrameLoaderClient::updateGlobalHistory()
1234 {
1235     notImplemented();
1236 }
1237
1238 void FrameLoaderClient::updateGlobalHistoryRedirectLinks()
1239 {
1240     notImplemented();
1241 }
1242
1243 void FrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
1244 {
1245 }
1246
1247 static void postCommitFrameViewSetup(WebKitWebFrame *frame)
1248 {
1249     WebKitWebView* containingWindow = getViewFromFrame(frame);
1250     webkit_web_view_clear_resources(containingWindow);
1251
1252     // Invalidate the viewport attributes - they will only be valid
1253     // again if the page we're beginning to load now has an
1254     // appropriate viewport meta tag.
1255     WebKitWebViewPrivate* priv = containingWindow->priv;
1256     priv->viewportAttributes->priv->isValid = FALSE;
1257     g_object_notify(G_OBJECT(priv->viewportAttributes.get()), "valid");
1258
1259     if (priv->currentMenu) {
1260         gtk_widget_destroy(GTK_WIDGET(priv->currentMenu));
1261         priv->currentMenu = 0;
1262     }
1263
1264     // Do not allow click counting between main frame loads.
1265     priv->clickCounter.reset();
1266 }
1267
1268 void FrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame* cachedFrame)
1269 {
1270     ASSERT(cachedFrame->view());
1271
1272     Frame* frame = core(m_frame);
1273     if (frame != frame->page()->mainFrame())
1274         return;
1275
1276     postCommitFrameViewSetup(m_frame);
1277 }
1278
1279 void FrameLoaderClient::transitionToCommittedForNewPage()
1280 {
1281     WebKitWebView* containingWindow = getViewFromFrame(m_frame);
1282     GtkAllocation allocation;
1283 #if GTK_CHECK_VERSION(2, 18, 0)
1284     gtk_widget_get_allocation(GTK_WIDGET(containingWindow), &allocation);
1285 #else
1286     allocation = GTK_WIDGET(containingWindow)->allocation;
1287 #endif
1288     IntSize size = IntSize(allocation.width, allocation.height);
1289     bool transparent = webkit_web_view_get_transparent(containingWindow);
1290     Color backgroundColor = transparent ? WebCore::Color::transparent : WebCore::Color::white;
1291     Frame* frame = core(m_frame);
1292     ASSERT(frame);
1293
1294     frame->createView(size, backgroundColor, transparent, IntSize(), false);
1295
1296     // We need to do further manipulation on the FrameView if it was the mainFrame
1297     if (frame != frame->page()->mainFrame())
1298         return;
1299
1300     postCommitFrameViewSetup(m_frame);
1301 }
1302
1303 void FrameLoaderClient::didSaveToPageCache()
1304 {
1305 }
1306
1307 void FrameLoaderClient::didRestoreFromPageCache()
1308 {
1309 }
1310
1311 void FrameLoaderClient::dispatchDidBecomeFrameset(bool)
1312 {
1313 }
1314
1315 PassRefPtr<FrameNetworkingContext> FrameLoaderClient::createNetworkingContext()
1316 {
1317     return FrameNetworkingContextGtk::create(core(m_frame));
1318 }
1319
1320 }