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