Home | History | Annotate | Download | only in WebCoreSupport
      1 /*
      2  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  * THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "WebFrameLoaderClient.h"
     28 
     29 #include "AuthenticationManager.h"
     30 #include "DataReference.h"
     31 #include "InjectedBundleNavigationAction.h"
     32 #include "InjectedBundleUserMessageCoders.h"
     33 #include "PlatformCertificateInfo.h"
     34 #include "PluginView.h"
     35 #include "StringPairVector.h"
     36 #include "WebBackForwardListProxy.h"
     37 #include "WebContextMessages.h"
     38 #include "WebCoreArgumentCoders.h"
     39 #include "WebErrors.h"
     40 #include "WebEvent.h"
     41 #include "WebFrame.h"
     42 #include "WebFrameNetworkingContext.h"
     43 #include "WebNavigationDataStore.h"
     44 #include "WebPage.h"
     45 #include "WebPageProxyMessages.h"
     46 #include "WebProcess.h"
     47 #include "WebProcessProxyMessages.h"
     48 #include <JavaScriptCore/APICast.h>
     49 #include <JavaScriptCore/JSObject.h>
     50 #include <WebCore/Chrome.h>
     51 #include <WebCore/DOMWrapperWorld.h>
     52 #include <WebCore/DocumentLoader.h>
     53 #include <WebCore/FormState.h>
     54 #include <WebCore/Frame.h>
     55 #include <WebCore/FrameLoadRequest.h>
     56 #include <WebCore/FrameView.h>
     57 #include <WebCore/HTMLAppletElement.h>
     58 #include <WebCore/HTMLFormElement.h>
     59 #include <WebCore/HistoryItem.h>
     60 #include <WebCore/MIMETypeRegistry.h>
     61 #include <WebCore/MouseEvent.h>
     62 #include <WebCore/NotImplemented.h>
     63 #include <WebCore/Page.h>
     64 #include <WebCore/PluginData.h>
     65 #include <WebCore/ProgressTracker.h>
     66 #include <WebCore/ResourceError.h>
     67 #include <WebCore/UIEventWithKeyState.h>
     68 #include <WebCore/Widget.h>
     69 #include <WebCore/WindowFeatures.h>
     70 
     71 using namespace WebCore;
     72 
     73 namespace WebKit {
     74 
     75 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* frame)
     76     : m_frame(frame)
     77     , m_hasSentResponseToPluginView(false)
     78     , m_frameHasCustomRepresentation(false)
     79 {
     80 }
     81 
     82 WebFrameLoaderClient::~WebFrameLoaderClient()
     83 {
     84 }
     85 
     86 void WebFrameLoaderClient::frameLoaderDestroyed()
     87 {
     88     m_frame->invalidate();
     89 
     90     // Balances explicit ref() in WebFrame::createMainFrame and WebFrame::createSubframe.
     91     m_frame->deref();
     92 }
     93 
     94 bool WebFrameLoaderClient::hasHTMLView() const
     95 {
     96     return !m_frameHasCustomRepresentation;
     97 }
     98 
     99 bool WebFrameLoaderClient::hasWebView() const
    100 {
    101     return m_frame->page();
    102 }
    103 
    104 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
    105 {
    106     notImplemented();
    107 }
    108 
    109 void WebFrameLoaderClient::forceLayout()
    110 {
    111     notImplemented();
    112 }
    113 
    114 void WebFrameLoaderClient::forceLayoutForNonHTML()
    115 {
    116     notImplemented();
    117 }
    118 
    119 void WebFrameLoaderClient::setCopiesOnScroll()
    120 {
    121     notImplemented();
    122 }
    123 
    124 void WebFrameLoaderClient::detachedFromParent2()
    125 {
    126     WebPage* webPage = m_frame->page();
    127     if (!webPage)
    128         return;
    129 
    130     RefPtr<APIObject> userData;
    131 
    132     // Notify the bundle client.
    133     webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData);
    134 
    135     // Notify the UIProcess.
    136     webPage->send(Messages::WebPageProxy::DidRemoveFrameFromHierarchy(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
    137 
    138 }
    139 
    140 void WebFrameLoaderClient::detachedFromParent3()
    141 {
    142     notImplemented();
    143 }
    144 
    145 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
    146 {
    147     WebPage* webPage = m_frame->page();
    148     if (!webPage)
    149         return;
    150 
    151     bool pageIsProvisionallyLoading = false;
    152     if (FrameLoader* frameLoader = loader->frameLoader())
    153         pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader;
    154 
    155     webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(webPage, m_frame, identifier, request, pageIsProvisionallyLoading);
    156     webPage->send(Messages::WebPageProxy::DidInitiateLoadForResource(m_frame->frameID(), identifier, request, pageIsProvisionallyLoading));
    157 }
    158 
    159 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
    160 {
    161     WebPage* webPage = m_frame->page();
    162     if (!webPage)
    163         return;
    164 
    165     webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(webPage, m_frame, identifier, request, redirectResponse);
    166 
    167     if (request.isNull()) {
    168         // FIXME: We should probably send a message saying we cancelled the request for the resource.
    169         return;
    170     }
    171 
    172     webPage->send(Messages::WebPageProxy::DidSendRequestForResource(m_frame->frameID(), identifier, request, redirectResponse));
    173 }
    174 
    175 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier)
    176 {
    177     return true;
    178 }
    179 
    180 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge)
    181 {
    182     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
    183     // Once we do, we might need to make sure authentication fits with our solution.
    184 
    185     WebPage* webPage = m_frame->page();
    186     if (!webPage)
    187         return;
    188 
    189     AuthenticationManager::shared().didReceiveAuthenticationChallenge(m_frame, challenge);
    190 }
    191 
    192 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)
    193 {
    194     notImplemented();
    195 }
    196 
    197 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
    198 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace)
    199 {
    200     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
    201     // Once we do, we might need to make sure authentication fits with our solution.
    202 
    203     WebPage* webPage = m_frame->page();
    204     if (!webPage)
    205         return false;
    206 
    207     bool canAuthenticate;
    208     if (!webPage->sendSync(Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame(m_frame->frameID(), protectionSpace), Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame::Reply(canAuthenticate)))
    209         return false;
    210 
    211     return canAuthenticate;
    212 }
    213 #endif
    214 
    215 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response)
    216 {
    217     WebPage* webPage = m_frame->page();
    218     if (!webPage)
    219         return;
    220 
    221     webPage->injectedBundleResourceLoadClient().didReceiveResponseForResource(webPage, m_frame, identifier, response);
    222     webPage->send(Messages::WebPageProxy::DidReceiveResponseForResource(m_frame->frameID(), identifier, response));
    223 }
    224 
    225 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength)
    226 {
    227     WebPage* webPage = m_frame->page();
    228     if (!webPage)
    229         return;
    230 
    231     webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength);
    232     webPage->send(Messages::WebPageProxy::DidReceiveContentLengthForResource(m_frame->frameID(), identifier, dataLength));
    233 }
    234 
    235 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
    236 {
    237     WebPage* webPage = m_frame->page();
    238     if (!webPage)
    239         return;
    240 
    241     webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(webPage, m_frame, identifier);
    242     webPage->send(Messages::WebPageProxy::DidFinishLoadForResource(m_frame->frameID(), identifier));
    243 }
    244 
    245 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error)
    246 {
    247     WebPage* webPage = m_frame->page();
    248     if (!webPage)
    249         return;
    250 
    251     webPage->injectedBundleResourceLoadClient().didFailLoadForResource(webPage, m_frame, identifier, error);
    252     webPage->send(Messages::WebPageProxy::DidFailLoadForResource(m_frame->frameID(), identifier, error));
    253 }
    254 
    255 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length)
    256 {
    257     notImplemented();
    258     return false;
    259 }
    260 
    261 void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const String&)
    262 {
    263     notImplemented();
    264 }
    265 
    266 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
    267 {
    268     WebPage* webPage = m_frame->page();
    269     if (!webPage)
    270         return;
    271 
    272     // Notify the bundle client.
    273     webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(webPage, m_frame);
    274 }
    275 
    276 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
    277 {
    278     WebPage* webPage = m_frame->page();
    279     if (!webPage)
    280         return;
    281 
    282     DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader();
    283     const String& url = provisionalLoader->url().string();
    284     RefPtr<APIObject> userData;
    285 
    286     // Notify the bundle client.
    287     webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(webPage, m_frame, userData);
    288 
    289     // Notify the UIProcess.
    290     webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), url, InjectedBundleUserMessageEncoder(userData.get())));
    291 }
    292 
    293 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
    294 {
    295     WebPage* webPage = m_frame->page();
    296     if (!webPage)
    297         return;
    298 
    299     // Notify the bundle client.
    300     webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(webPage, m_frame);
    301 }
    302 
    303 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double interval, double fireDate)
    304 {
    305     WebPage* webPage = m_frame->page();
    306     if (!webPage)
    307         return;
    308 
    309     // Notify the bundle client.
    310     webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(webPage, m_frame, url.string(), interval, fireDate);
    311 }
    312 
    313 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
    314 {
    315     WebPage* webPage = m_frame->page();
    316     if (!webPage)
    317         return;
    318 
    319     RefPtr<APIObject> userData;
    320 
    321     // Notify the bundle client.
    322     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationAnchorNavigation, userData);
    323 
    324     // Notify the UIProcess.
    325     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
    326 }
    327 
    328 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
    329 {
    330     WebPage* webPage = m_frame->page();
    331     if (!webPage)
    332         return;
    333 
    334     RefPtr<APIObject> userData;
    335 
    336     // Notify the bundle client.
    337     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePush, userData);
    338 
    339     // Notify the UIProcess.
    340     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
    341 }
    342 
    343 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
    344 {
    345     WebPage* webPage = m_frame->page();
    346     if (!webPage)
    347         return;
    348 
    349     RefPtr<APIObject> userData;
    350 
    351     // Notify the bundle client.
    352     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStateReplace, userData);
    353 
    354     // Notify the UIProcess.
    355     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
    356 }
    357 
    358 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
    359 {
    360     WebPage* webPage = m_frame->page();
    361     if (!webPage)
    362         return;
    363 
    364     RefPtr<APIObject> userData;
    365 
    366     // Notify the bundle client.
    367     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePop, userData);
    368 
    369     // Notify the UIProcess.
    370     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
    371 }
    372 
    373 void WebFrameLoaderClient::dispatchWillClose()
    374 {
    375     notImplemented();
    376 }
    377 
    378 void WebFrameLoaderClient::dispatchDidReceiveIcon()
    379 {
    380     notImplemented();
    381 }
    382 
    383 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
    384 {
    385     WebPage* webPage = m_frame->page();
    386     if (!webPage)
    387         return;
    388 
    389     webPage->findController().hideFindUI();
    390     webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame);
    391 
    392     DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader();
    393     const String& url = provisionalLoader->url().string();
    394     RefPtr<APIObject> userData;
    395 
    396     // Notify the bundle client.
    397     webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData);
    398 
    399     String unreachableURL = provisionalLoader->unreachableURL().string();
    400 
    401     // Notify the UIProcess.
    402     webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), url, unreachableURL, InjectedBundleUserMessageEncoder(userData.get())));
    403 }
    404 
    405 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
    406 {
    407     WebPage* webPage = m_frame->page();
    408     if (!webPage)
    409         return;
    410 
    411     RefPtr<APIObject> userData;
    412 
    413     // Notify the bundle client.
    414     // FIXME: use direction of title.
    415     webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title.string(), m_frame, userData);
    416 
    417     // Notify the UIProcess.
    418     webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title.string(), InjectedBundleUserMessageEncoder(userData.get())));
    419 }
    420 
    421 void WebFrameLoaderClient::dispatchDidChangeIcons()
    422 {
    423     notImplemented();
    424 }
    425 
    426 void WebFrameLoaderClient::dispatchDidCommitLoad()
    427 {
    428     WebPage* webPage = m_frame->page();
    429     if (!webPage)
    430         return;
    431 
    432     const ResourceResponse& response = m_frame->coreFrame()->loader()->documentLoader()->response();
    433     RefPtr<APIObject> userData;
    434 
    435     // Notify the bundle client.
    436     webPage->injectedBundleLoaderClient().didCommitLoadForFrame(webPage, m_frame, userData);
    437 
    438     webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame);
    439 
    440     // Notify the UIProcess.
    441 
    442     webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), response.mimeType(), m_frameHasCustomRepresentation, PlatformCertificateInfo(response), InjectedBundleUserMessageEncoder(userData.get())));
    443 
    444     // Only restore the scale factor for standard frame loads (of the main frame).
    445     if (m_frame->isMainFrame() && m_frame->coreFrame()->loader()->loadType() == FrameLoadTypeStandard) {
    446         if (m_frame->coreFrame()->pageScaleFactor() != 1)
    447             webPage->scaleWebView(1, IntPoint());
    448     }
    449 }
    450 
    451 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
    452 {
    453     WebPage* webPage = m_frame->page();
    454     if (!webPage)
    455         return;
    456 
    457     RefPtr<APIObject> userData;
    458 
    459     // Notify the bundle client.
    460     webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(webPage, m_frame, error, userData);
    461 
    462     webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame);
    463 
    464     // Notify the UIProcess.
    465     webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
    466 
    467     // If we have a load listener, notify it.
    468     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
    469         loadListener->didFailLoad(m_frame, error.isCancellation());
    470 }
    471 
    472 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
    473 {
    474     WebPage* webPage = m_frame->page();
    475     if (!webPage)
    476         return;
    477 
    478     RefPtr<APIObject> userData;
    479 
    480     // Notify the bundle client.
    481     webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(webPage, m_frame, error, userData);
    482 
    483     // Notify the UIProcess.
    484     webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
    485 
    486     // If we have a load listener, notify it.
    487     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
    488         loadListener->didFailLoad(m_frame, error.isCancellation());
    489 }
    490 
    491 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
    492 {
    493     WebPage* webPage = m_frame->page();
    494     if (!webPage)
    495         return;
    496 
    497     RefPtr<APIObject> userData;
    498 
    499     // Notify the bundle client.
    500     webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(webPage, m_frame, userData);
    501 
    502     // Notify the UIProcess.
    503     webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
    504 }
    505 
    506 void WebFrameLoaderClient::dispatchDidFinishLoad()
    507 {
    508     WebPage* webPage = m_frame->page();
    509     if (!webPage)
    510         return;
    511 
    512     RefPtr<APIObject> userData;
    513 
    514     // Notify the bundle client.
    515     webPage->injectedBundleLoaderClient().didFinishLoadForFrame(webPage, m_frame, userData);
    516 
    517     // Notify the UIProcess.
    518     webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
    519 
    520     // If we have a load listener, notify it.
    521     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
    522         loadListener->didFinishLoad(m_frame);
    523 }
    524 
    525 void WebFrameLoaderClient::dispatchDidFirstLayout()
    526 {
    527     WebPage* webPage = m_frame->page();
    528     if (!webPage)
    529         return;
    530 
    531     RefPtr<APIObject> userData;
    532 
    533     // Notify the bundle client.
    534     webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData);
    535 
    536     // Notify the UIProcess.
    537     webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
    538 }
    539 
    540 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
    541 {
    542     WebPage* webPage = m_frame->page();
    543     if (!webPage)
    544         return;
    545 
    546     RefPtr<APIObject> userData;
    547 
    548     // Notify the bundle client.
    549     webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData);
    550 
    551     // Notify the UIProcess.
    552     webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
    553 }
    554 
    555 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
    556 {
    557     WebPage* webPage = m_frame->page();
    558     if (!webPage)
    559         return 0;
    560 
    561     // Just call through to the chrome client.
    562     Page* newPage = webPage->corePage()->chrome()->createWindow(m_frame->coreFrame(), FrameLoadRequest(m_frame->coreFrame()->document()->securityOrigin()), WindowFeatures(), navigationAction);
    563     if (!newPage)
    564         return 0;
    565 
    566     return newPage->mainFrame();
    567 }
    568 
    569 void WebFrameLoaderClient::dispatchShow()
    570 {
    571     WebPage* webPage = m_frame->page();
    572     if (!webPage)
    573         return;
    574 
    575     webPage->show();
    576 }
    577 
    578 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function, const ResourceResponse& response, const ResourceRequest& request)
    579 {
    580     WebPage* webPage = m_frame->page();
    581     if (!webPage)
    582         return;
    583 
    584     if (!request.url().string())
    585         return;
    586 
    587     RefPtr<APIObject> userData;
    588 
    589     // Notify the bundle client.
    590     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData);
    591     if (policy == WKBundlePagePolicyActionUse) {
    592         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
    593         return;
    594     }
    595 
    596     uint64_t listenerID = m_frame->setUpPolicyListener(function);
    597     bool receivedPolicyAction;
    598     uint64_t policyAction;
    599     uint64_t downloadID;
    600 
    601     // Notify the UIProcess.
    602     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), response, request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForResponse::Reply(receivedPolicyAction, policyAction, downloadID)))
    603         return;
    604 
    605     // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
    606     if (receivedPolicyAction)
    607         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
    608 }
    609 
    610 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
    611 {
    612     WebPage* webPage = m_frame->page();
    613     if (!webPage)
    614         return;
    615 
    616     RefPtr<APIObject> userData;
    617 
    618     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
    619 
    620     // Notify the bundle client.
    621     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.get(), request, frameName, userData);
    622     if (policy == WKBundlePagePolicyActionUse) {
    623         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
    624         return;
    625     }
    626 
    627 
    628     uint64_t listenerID = m_frame->setUpPolicyListener(function);
    629 
    630     // Notify the UIProcess.
    631     webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, frameName, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
    632 }
    633 
    634 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState)
    635 {
    636     WebPage* webPage = m_frame->page();
    637     if (!webPage)
    638         return;
    639 
    640     // Always ignore requests with empty URLs.
    641     if (request.isEmpty()) {
    642         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyIgnore);
    643         return;
    644     }
    645 
    646     RefPtr<APIObject> userData;
    647 
    648     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
    649 
    650     // Notify the bundle client.
    651     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData);
    652     if (policy == WKBundlePagePolicyActionUse) {
    653         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
    654         return;
    655     }
    656 
    657     uint64_t listenerID = m_frame->setUpPolicyListener(function);
    658     bool receivedPolicyAction;
    659     uint64_t policyAction;
    660     uint64_t downloadID;
    661 
    662     // Notify the UIProcess.
    663     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, policyAction, downloadID)))
    664         return;
    665 
    666     // We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply.
    667     if (receivedPolicyAction)
    668         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
    669 }
    670 
    671 void WebFrameLoaderClient::cancelPolicyCheck()
    672 {
    673     m_frame->invalidatePolicyListener();
    674 }
    675 
    676 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
    677 {
    678     WebPage* webPage = m_frame->page();
    679     if (!webPage)
    680         return;
    681 
    682     RefPtr<APIObject> userData;
    683 
    684     // Notify the bundle client.
    685     webPage->injectedBundlePolicyClient().unableToImplementPolicy(webPage, m_frame, error, userData);
    686 
    687     // Notify the UIProcess.
    688     webPage->send(Messages::WebPageProxy::UnableToImplementPolicy(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
    689 }
    690 
    691 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> prpFormState)
    692 {
    693     WebPage* webPage = m_frame->page();
    694     if (!webPage)
    695         return;
    696 
    697     // FIXME: Pass more of the form state.
    698     RefPtr<FormState> formState = prpFormState;
    699 
    700     HTMLFormElement* form = formState->form();
    701     WebFrame* sourceFrame = static_cast<WebFrameLoaderClient*>(formState->sourceFrame()->loader()->client())->webFrame();
    702     const Vector<std::pair<String, String> >& values = formState->textFieldValues();
    703 
    704     RefPtr<APIObject> userData;
    705     webPage->injectedBundleFormClient().willSubmitForm(webPage, form, m_frame, sourceFrame, values, userData);
    706 
    707 
    708     uint64_t listenerID = m_frame->setUpPolicyListener(function);
    709     StringPairVector valuesVector(values);
    710 
    711     webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), valuesVector, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
    712 }
    713 
    714 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
    715 {
    716     notImplemented();
    717 }
    718 
    719 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
    720 {
    721     notImplemented();
    722 }
    723 
    724 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
    725 {
    726     if (!m_pluginView)
    727         return;
    728 
    729     m_pluginView->manualLoadDidFail(error);
    730     m_pluginView = 0;
    731     m_hasSentResponseToPluginView = false;
    732 }
    733 
    734 void WebFrameLoaderClient::willChangeEstimatedProgress()
    735 {
    736     notImplemented();
    737 }
    738 
    739 void WebFrameLoaderClient::didChangeEstimatedProgress()
    740 {
    741     notImplemented();
    742 }
    743 
    744 void WebFrameLoaderClient::postProgressStartedNotification()
    745 {
    746     if (WebPage* webPage = m_frame->page())
    747         webPage->send(Messages::WebPageProxy::DidStartProgress());
    748 }
    749 
    750 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
    751 {
    752     if (WebPage* webPage = m_frame->page()) {
    753         double progress = webPage->corePage()->progress()->estimatedProgress();
    754         webPage->send(Messages::WebPageProxy::DidChangeProgress(progress));
    755 
    756     }
    757 }
    758 
    759 void WebFrameLoaderClient::postProgressFinishedNotification()
    760 {
    761     if (WebPage* webPage = m_frame->page())
    762         webPage->send(Messages::WebPageProxy::DidFinishProgress());
    763 }
    764 
    765 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
    766 {
    767     notImplemented();
    768 }
    769 
    770 void WebFrameLoaderClient::startDownload(const ResourceRequest& request)
    771 {
    772     m_frame->startDownload(request);
    773 }
    774 
    775 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*)
    776 {
    777     notImplemented();
    778 }
    779 
    780 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*)
    781 {
    782     notImplemented();
    783 }
    784 
    785 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
    786 {
    787     // If we're loading a custom representation, we don't want to hand off the data to WebCore.
    788     if (m_frameHasCustomRepresentation)
    789         return;
    790 
    791     if (!m_pluginView)
    792         loader->commitData(data, length);
    793 
    794     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
    795     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
    796     if (m_frame->coreFrame()->document()->isMediaDocument())
    797         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
    798 
    799     // Calling commitData did not create the plug-in view.
    800     if (!m_pluginView)
    801         return;
    802 
    803     if (!m_hasSentResponseToPluginView) {
    804         m_pluginView->manualLoadDidReceiveResponse(loader->response());
    805         // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
    806         // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
    807         // to null
    808         if (!m_pluginView)
    809             return;
    810         m_hasSentResponseToPluginView = true;
    811     }
    812     m_pluginView->manualLoadDidReceiveData(data, length);
    813 }
    814 
    815 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
    816 {
    817     if (!m_pluginView) {
    818         committedLoad(loader, 0, 0);
    819 
    820         if (m_frameHasCustomRepresentation) {
    821             WebPage* webPage = m_frame->page();
    822             if (!webPage)
    823                 return;
    824 
    825             RefPtr<SharedBuffer> mainResourceData = loader->mainResourceData();
    826             CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(mainResourceData ? mainResourceData->data() : 0), mainResourceData ? mainResourceData->size() : 0);
    827 
    828             webPage->send(Messages::WebPageProxy::DidFinishLoadingDataForCustomRepresentation(loader->response().suggestedFilename(), dataReference));
    829         }
    830 
    831         return;
    832     }
    833 
    834     m_pluginView->manualLoadDidFinishLoading();
    835     m_pluginView = 0;
    836     m_hasSentResponseToPluginView = false;
    837 }
    838 
    839 void WebFrameLoaderClient::updateGlobalHistory()
    840 {
    841     WebPage* webPage = m_frame->page();
    842     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
    843         return;
    844 
    845     DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
    846 
    847     WebNavigationDataStore data;
    848     data.url = loader->urlForHistory().string();
    849     // FIXME: use direction of title.
    850     data.title = loader->title().string();
    851 
    852     WebProcess::shared().connection()->send(Messages::WebContext::DidNavigateWithNavigationData(webPage->pageID(), data, m_frame->frameID()), 0);
    853 }
    854 
    855 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
    856 {
    857     WebPage* webPage = m_frame->page();
    858     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
    859         return;
    860 
    861     DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
    862     ASSERT(loader->unreachableURL().isEmpty());
    863 
    864     // Client redirect
    865     if (!loader->clientRedirectSourceForHistory().isNull()) {
    866         WebProcess::shared().connection()->send(Messages::WebContext::DidPerformClientRedirect(webPage->pageID(),
    867             loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()), 0);
    868     }
    869 
    870     // Server redirect
    871     if (!loader->serverRedirectSourceForHistory().isNull()) {
    872         WebProcess::shared().connection()->send(Messages::WebContext::DidPerformServerRedirect(webPage->pageID(),
    873             loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()), 0);
    874     }
    875 }
    876 
    877 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
    878 {
    879     WebPage* webPage = m_frame->page();
    880     if (!webPage)
    881         return false;
    882 
    883     uint64_t itemID = WebBackForwardListProxy::idForItem(item);
    884     if (!itemID) {
    885         // We should never be considering navigating to an item that is not actually in the back/forward list.
    886         ASSERT_NOT_REACHED();
    887         return false;
    888     }
    889 
    890     bool shouldGoToBackForwardListItem;
    891     if (!webPage->sendSync(Messages::WebPageProxy::ShouldGoToBackForwardListItem(itemID), Messages::WebPageProxy::ShouldGoToBackForwardListItem::Reply(shouldGoToBackForwardListItem)))
    892         return false;
    893 
    894     return shouldGoToBackForwardListItem;
    895 }
    896 
    897 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
    898 {
    899     return true;
    900 }
    901 
    902 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
    903 {
    904     notImplemented();
    905 }
    906 
    907 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
    908 {
    909     notImplemented();
    910 }
    911 
    912 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
    913 {
    914     notImplemented();
    915 }
    916 
    917 void WebFrameLoaderClient::didDisplayInsecureContent()
    918 {
    919     WebPage* webPage = m_frame->page();
    920     if (!webPage)
    921         return;
    922 
    923     RefPtr<APIObject> userData;
    924 
    925     webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(webPage, m_frame, userData);
    926 
    927     webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
    928 }
    929 
    930 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin*, const KURL&)
    931 {
    932     WebPage* webPage = m_frame->page();
    933     if (!webPage)
    934         return;
    935 
    936     RefPtr<APIObject> userData;
    937 
    938     webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(webPage, m_frame, userData);
    939 
    940     webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
    941 }
    942 
    943 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
    944 {
    945     return WebKit::cancelledError(request);
    946 }
    947 
    948 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
    949 {
    950     return WebKit::blockedError(request);
    951 }
    952 
    953 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
    954 {
    955     return WebKit::cannotShowURLError(request);
    956 }
    957 
    958 ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest& request)
    959 {
    960     return WebKit::interruptForPolicyChangeError(request);
    961 }
    962 
    963 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
    964 {
    965     return WebKit::cannotShowMIMETypeError(response);
    966 }
    967 
    968 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
    969 {
    970     return WebKit::fileDoesNotExistError(response);
    971 }
    972 
    973 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
    974 {
    975     return WebKit::pluginWillHandleLoadError(response);
    976 }
    977 
    978 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
    979 {
    980     DEFINE_STATIC_LOCAL(const ResourceError, cancelledError, (this->cancelledError(ResourceRequest())));
    981     DEFINE_STATIC_LOCAL(const ResourceError, pluginWillHandleLoadError, (this->pluginWillHandleLoadError(ResourceResponse())));
    982 
    983     if (error.errorCode() == cancelledError.errorCode() && error.domain() == cancelledError.domain())
    984         return false;
    985 
    986     if (error.errorCode() == pluginWillHandleLoadError.errorCode() && error.domain() == pluginWillHandleLoadError.domain())
    987         return false;
    988 
    989     return true;
    990 }
    991 
    992 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const
    993 {
    994     notImplemented();
    995     return true;
    996 }
    997 
    998 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
    999 {
   1000     notImplemented();
   1001     return true;
   1002 }
   1003 
   1004 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
   1005 {
   1006     return true;
   1007 }
   1008 
   1009 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
   1010 {
   1011     notImplemented();
   1012     return false;
   1013 }
   1014 
   1015 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
   1016 {
   1017     notImplemented();
   1018     return String();
   1019 }
   1020 
   1021 void WebFrameLoaderClient::frameLoadCompleted()
   1022 {
   1023     notImplemented();
   1024 }
   1025 
   1026 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*)
   1027 {
   1028     notImplemented();
   1029 }
   1030 
   1031 void WebFrameLoaderClient::restoreViewState()
   1032 {
   1033     // Inform the UI process of the scale factor.
   1034     double scaleFactor = m_frame->coreFrame()->loader()->history()->currentItem()->pageScaleFactor();
   1035     m_frame->page()->send(Messages::WebPageProxy::ViewScaleFactorDidChange(scaleFactor));
   1036 
   1037     // FIXME: This should not be necessary. WebCore should be correctly invalidating
   1038     // the view on restores from the back/forward cache.
   1039     if (m_frame == m_frame->page()->mainFrame())
   1040         m_frame->page()->drawingArea()->setNeedsDisplay(m_frame->page()->bounds());
   1041 }
   1042 
   1043 void WebFrameLoaderClient::provisionalLoadStarted()
   1044 {
   1045     notImplemented();
   1046 }
   1047 
   1048 void WebFrameLoaderClient::didFinishLoad()
   1049 {
   1050     // If we have a load listener, notify it.
   1051     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
   1052         loadListener->didFinishLoad(m_frame);
   1053 }
   1054 
   1055 void WebFrameLoaderClient::prepareForDataSourceReplacement()
   1056 {
   1057     notImplemented();
   1058 }
   1059 
   1060 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& data)
   1061 {
   1062     return DocumentLoader::create(request, data);
   1063 }
   1064 
   1065 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
   1066 {
   1067     WebPage* webPage = m_frame->page();
   1068     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
   1069         return;
   1070 
   1071     // FIXME: use direction of title.
   1072     WebProcess::shared().connection()->send(Messages::WebContext::DidUpdateHistoryTitle(webPage->pageID(),
   1073         title.string(), url.string(), m_frame->frameID()), 0);
   1074 }
   1075 
   1076 String WebFrameLoaderClient::userAgent(const KURL&)
   1077 {
   1078     WebPage* webPage = m_frame->page();
   1079     if (!webPage)
   1080         return String();
   1081 
   1082     return webPage->userAgent();
   1083 }
   1084 
   1085 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*)
   1086 {
   1087 }
   1088 
   1089 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
   1090 {
   1091     WebPage* webPage = m_frame->page();
   1092     bool isMainFrame = webPage->mainFrame() == m_frame;
   1093 
   1094     const String& mimeType = m_frame->coreFrame()->loader()->documentLoader()->response().mimeType();
   1095     m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForMIMEType(mimeType);
   1096 }
   1097 
   1098 void WebFrameLoaderClient::transitionToCommittedForNewPage()
   1099 {
   1100     WebPage* webPage = m_frame->page();
   1101     Color backgroundColor = webPage->drawsTransparentBackground() ? Color::transparent : Color::white;
   1102 
   1103     bool isMainFrame = webPage->mainFrame() == m_frame;
   1104 
   1105 #if ENABLE(TILED_BACKING_STORE)
   1106     IntSize currentVisibleContentSize = m_frame->coreFrame()->view() ? m_frame->coreFrame()->view()->actualVisibleContentRect().size() : IntSize();
   1107     m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, webPage->resizesToContentsLayoutSize(), isMainFrame && webPage->resizesToContentsEnabled());
   1108 
   1109     if (isMainFrame && webPage->resizesToContentsEnabled()) {
   1110         m_frame->coreFrame()->view()->setDelegatesScrolling(true);
   1111         m_frame->coreFrame()->view()->setPaintsEntireContents(true);
   1112     }
   1113 
   1114     // The HistoryController will update the scroll position later if needed.
   1115     m_frame->coreFrame()->view()->setActualVisibleContentRect(IntRect(IntPoint::zero(), currentVisibleContentSize));
   1116 #else
   1117     const String& mimeType = m_frame->coreFrame()->loader()->documentLoader()->response().mimeType();
   1118     m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForMIMEType(mimeType);
   1119 
   1120     m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, IntSize(), false);
   1121 #endif
   1122 
   1123     m_frame->coreFrame()->view()->setTransparent(!webPage->drawsBackground());
   1124 }
   1125 
   1126 void WebFrameLoaderClient::didSaveToPageCache()
   1127 {
   1128     WebPage* webPage = m_frame->page();
   1129     if (!webPage)
   1130         return;
   1131 
   1132     if (m_frame->isMainFrame())
   1133         return;
   1134 
   1135     webPage->send(Messages::WebPageProxy::DidSaveFrameToPageCache(m_frame->frameID()));
   1136 }
   1137 
   1138 void WebFrameLoaderClient::didRestoreFromPageCache()
   1139 {
   1140     WebPage* webPage = m_frame->page();
   1141     if (!webPage)
   1142         return;
   1143 
   1144     if (m_frame->isMainFrame())
   1145         return;
   1146 
   1147     WebFrame* parentFrame = static_cast<WebFrameLoaderClient*>(m_frame->coreFrame()->tree()->parent()->loader()->client())->webFrame();
   1148     webPage->send(Messages::WebPageProxy::DidRestoreFrameFromPageCache(m_frame->frameID(), parentFrame->frameID()));
   1149 }
   1150 
   1151 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value)
   1152 {
   1153     WebPage* webPage = m_frame->page();
   1154     if (!webPage)
   1155         return;
   1156 
   1157     webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value));
   1158 }
   1159 
   1160 bool WebFrameLoaderClient::canCachePage() const
   1161 {
   1162     // We cannot cache frames that have custom representations because they are
   1163     // rendered in the UIProcess.
   1164     return !m_frameHasCustomRepresentation;
   1165 }
   1166 
   1167 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response)
   1168 {
   1169     m_frame->convertHandleToDownload(handle, request, initialRequest, response);
   1170 }
   1171 
   1172 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
   1173                                                     const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
   1174 {
   1175     WebPage* webPage = m_frame->page();
   1176 
   1177     RefPtr<WebFrame> subframe = WebFrame::createSubframe(webPage, name, ownerElement);
   1178 
   1179     Frame* coreSubframe = subframe->coreFrame();
   1180 
   1181      // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
   1182     m_frame->coreFrame()->loader()->loadURLIntoChildFrame(url, referrer, coreSubframe);
   1183 
   1184     // The frame's onload handler may have removed it from the document.
   1185     if (!coreSubframe->tree()->parent())
   1186         return 0;
   1187 
   1188     return coreSubframe;
   1189 }
   1190 
   1191 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*)
   1192 {
   1193     notImplemented();
   1194 }
   1195 
   1196 void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*)
   1197 {
   1198     notImplemented();
   1199 }
   1200 
   1201 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement* pluginElement, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
   1202 {
   1203     ASSERT(paramNames.size() == paramValues.size());
   1204 
   1205     WebPage* webPage = m_frame->page();
   1206     ASSERT(webPage);
   1207 
   1208     Plugin::Parameters parameters;
   1209     parameters.url = url;
   1210     parameters.names = paramNames;
   1211     parameters.values = paramValues;
   1212     parameters.mimeType = mimeType;
   1213     parameters.loadManually = loadManually;
   1214 
   1215     // <rdar://problem/8440903>: AppleConnect has a bug where it does not
   1216     // understand the parameter names specified in the <object> element that
   1217     // embeds its plug-in. This hack works around the issue by converting the
   1218     // parameter names to lowercase before passing them to the plug-in.
   1219     // FIXME: This workaround should be dependent on site-specific quirks being
   1220     // enabled. This requires adding this setting to WebKit2's WebPreferences
   1221     // implementation. See <https://bugs.webkit.org/show_bug.cgi?id=46076>.
   1222     if (equalIgnoringCase(mimeType, "application/x-snkp")) {
   1223         for (size_t i = 0; i < paramNames.size(); ++i)
   1224             parameters.names[i] = paramNames[i].lower();
   1225     }
   1226 
   1227 #if PLUGIN_ARCHITECTURE(X11)
   1228     if (equalIgnoringCase(mimeType, "application/x-shockwave-flash")) {
   1229         // Currently we don't support transparency and windowed mode.
   1230         // Inject wmode=opaque to make Flash work in these conditions.
   1231         size_t wmodeIndex = parameters.names.find("wmode");
   1232         if (wmodeIndex == -1) {
   1233             parameters.names.append("wmode");
   1234             parameters.values.append("opaque");
   1235         } else if (equalIgnoringCase(parameters.values[wmodeIndex], "window"))
   1236             parameters.values[wmodeIndex] = "opaque";
   1237     }
   1238 #endif
   1239 
   1240     RefPtr<Plugin> plugin = webPage->createPlugin(parameters);
   1241     if (!plugin)
   1242         return 0;
   1243 
   1244     return PluginView::create(pluginElement, plugin.release(), parameters);
   1245 }
   1246 
   1247 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
   1248 {
   1249     ASSERT(!m_pluginView);
   1250     ASSERT(pluginWidget);
   1251 
   1252     m_pluginView = static_cast<PluginView*>(pluginWidget);
   1253 }
   1254 
   1255 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues)
   1256 {
   1257     return createPlugin(pluginSize, appletElement, KURL(), paramNames, paramValues, "application/x-java-applet", false);
   1258 }
   1259 
   1260 static bool pluginSupportsExtension(PluginData* pluginData, const String& extension)
   1261 {
   1262     ASSERT(extension.lower() == extension);
   1263 
   1264     for (size_t i = 0; i < pluginData->mimes().size(); ++i) {
   1265         const MimeClassInfo& mimeClassInfo = pluginData->mimes()[i];
   1266 
   1267         if (mimeClassInfo.extensions.contains(extension))
   1268             return true;
   1269     }
   1270     return false;
   1271 }
   1272 
   1273 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
   1274 {
   1275     // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code
   1276     // is consolidated.
   1277 
   1278     String mimeType = mimeTypeIn;
   1279     if (mimeType.isEmpty()) {
   1280         String extension = url.path().substring(url.path().reverseFind('.') + 1).lower();
   1281 
   1282         // Try to guess the MIME type from the extension.
   1283         mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
   1284 
   1285         if (mimeType.isEmpty()) {
   1286             // Check if there's a plug-in around that can handle the extension.
   1287             if (WebPage* webPage = m_frame->page()) {
   1288                 if (PluginData* pluginData = webPage->corePage()->pluginData()) {
   1289                     if (pluginSupportsExtension(pluginData, extension))
   1290                         return ObjectContentNetscapePlugin;
   1291                 }
   1292             }
   1293         }
   1294     }
   1295 
   1296     if (mimeType.isEmpty())
   1297         return ObjectContentFrame;
   1298 
   1299     bool plugInSupportsMIMEType = false;
   1300     if (WebPage* webPage = m_frame->page()) {
   1301         if (PluginData* pluginData = webPage->corePage()->pluginData()) {
   1302             if (pluginData->supportsMimeType(mimeType))
   1303                 plugInSupportsMIMEType = true;
   1304         }
   1305     }
   1306 
   1307     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
   1308         return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? ObjectContentNetscapePlugin : ObjectContentImage;
   1309 
   1310     if (plugInSupportsMIMEType)
   1311         return ObjectContentNetscapePlugin;
   1312 
   1313     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
   1314         return ObjectContentFrame;
   1315 
   1316     return ObjectContentNone;
   1317 }
   1318 
   1319 String WebFrameLoaderClient::overrideMediaType() const
   1320 {
   1321     notImplemented();
   1322     return String();
   1323 }
   1324 
   1325 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
   1326 {
   1327     WebPage* webPage = m_frame->page();
   1328     if (!webPage)
   1329         return;
   1330 
   1331     webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world);
   1332 }
   1333 
   1334 void WebFrameLoaderClient::documentElementAvailable()
   1335 {
   1336     notImplemented();
   1337 }
   1338 
   1339 void WebFrameLoaderClient::didPerformFirstNavigation() const
   1340 {
   1341     notImplemented();
   1342 }
   1343 
   1344 void WebFrameLoaderClient::registerForIconNotification(bool listen)
   1345 {
   1346     notImplemented();
   1347 }
   1348 
   1349 #if PLATFORM(MAC)
   1350 
   1351 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject()
   1352 {
   1353     return m_frame->page()->accessibilityRemoteObject();
   1354 }
   1355 
   1356 #if ENABLE(MAC_JAVA_BRIDGE)
   1357 jobject WebFrameLoaderClient::javaApplet(NSView*) { return 0; }
   1358 #endif
   1359 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const
   1360 {
   1361     return response;
   1362 }
   1363 
   1364 #endif
   1365 #if USE(CFNETWORK)
   1366 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, const unsigned char* data, unsigned long long length)
   1367 {
   1368     return true;
   1369 }
   1370 
   1371 #endif
   1372 
   1373 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& /*mimeType*/) const
   1374 {
   1375     notImplemented();
   1376     return false;
   1377 }
   1378 
   1379 void WebFrameLoaderClient::didChangeScrollOffset()
   1380 {
   1381     WebPage* webPage = m_frame->page();
   1382     if (!webPage)
   1383         return;
   1384 
   1385     if (!m_frame->isMainFrame())
   1386         return;
   1387 
   1388     // If this is called when tearing down a FrameView, the WebCore::Frame's
   1389     // current FrameView will be null.
   1390     if (!m_frame->coreFrame()->view())
   1391         return;
   1392 
   1393     webPage->didChangeScrollOffsetForMainFrame();
   1394 }
   1395 
   1396 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
   1397 {
   1398     return WebFrameNetworkingContext::create(m_frame->coreFrame());
   1399 }
   1400 
   1401 } // namespace WebKit
   1402