Home | History | Annotate | Download | only in WebCoreSupport
      1 /*
      2  * Copyright (C) 2006, 2007, 2008, 2009 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  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
     14  *     its contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include "config.h"
     30 #include "WebFrameLoaderClient.h"
     31 
     32 #include "CFDictionaryPropertyBag.h"
     33 #include "COMPropertyBag.h"
     34 #include "DOMHTMLClasses.h"
     35 #include "EmbeddedWidget.h"
     36 #include "MarshallingHelpers.h"
     37 #include "NotImplemented.h"
     38 #include "WebCachedFramePlatformData.h"
     39 #include "WebChromeClient.h"
     40 #include "WebDocumentLoader.h"
     41 #include "WebError.h"
     42 #include "WebFrame.h"
     43 #include "WebHistory.h"
     44 #include "WebHistoryItem.h"
     45 #include "WebMutableURLRequest.h"
     46 #include "WebNavigationData.h"
     47 #include "WebNotificationCenter.h"
     48 #include "WebSecurityOrigin.h"
     49 #include "WebURLAuthenticationChallenge.h"
     50 #include "WebURLResponse.h"
     51 #include "WebView.h"
     52 #include <WebCore/BackForwardController.h>
     53 #include <WebCore/CachedFrame.h>
     54 #include <WebCore/DocumentLoader.h>
     55 #include <WebCore/FrameLoader.h>
     56 #include <WebCore/FrameTree.h>
     57 #include <WebCore/FrameView.h>
     58 #include <WebCore/HTMLAppletElement.h>
     59 #include <WebCore/HTMLFrameElement.h>
     60 #include <WebCore/HTMLFrameOwnerElement.h>
     61 #include <WebCore/HTMLNames.h>
     62 #include <WebCore/HTMLParserIdioms.h>
     63 #include <WebCore/HTMLPlugInElement.h>
     64 #include <WebCore/HistoryItem.h>
     65 #include <WebCore/Page.h>
     66 #include <WebCore/PluginPackage.h>
     67 #include <WebCore/PluginView.h>
     68 #include <WebCore/RenderPart.h>
     69 #include <WebCore/ResourceHandle.h>
     70 #include <WebCore/Settings.h>
     71 
     72 using namespace WebCore;
     73 using namespace HTMLNames;
     74 
     75 static WebDataSource* getWebDataSource(DocumentLoader* loader)
     76 {
     77     return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
     78 }
     79 
     80 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* webFrame)
     81     : m_webFrame(webFrame)
     82     , m_manualLoader(0)
     83     , m_hasSentResponseToPlugin(false)
     84 {
     85     ASSERT_ARG(webFrame, webFrame);
     86 }
     87 
     88 WebFrameLoaderClient::~WebFrameLoaderClient()
     89 {
     90 }
     91 
     92 bool WebFrameLoaderClient::hasWebView() const
     93 {
     94     return m_webFrame->webView();
     95 }
     96 
     97 void WebFrameLoaderClient::forceLayout()
     98 {
     99     Frame* frame = core(m_webFrame);
    100     if (!frame)
    101         return;
    102 
    103     if (frame->document() && frame->document()->inPageCache())
    104         return;
    105 
    106     FrameView* view = frame->view();
    107     if (!view)
    108         return;
    109 
    110     view->setNeedsLayout();
    111     view->forceLayout(true);
    112 }
    113 
    114 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
    115 {
    116     WebView* webView = m_webFrame->webView();
    117     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    118     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    119         return;
    120 
    121     COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
    122     resourceLoadDelegate->identifierForInitialRequest(webView, webURLRequest.get(), getWebDataSource(loader), identifier);
    123 }
    124 
    125 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier)
    126 {
    127     WebView* webView = m_webFrame->webView();
    128     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    129     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    130         return true;
    131 
    132     COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate;
    133     if (FAILED(resourceLoadDelegate->QueryInterface(IID_IWebResourceLoadDelegatePrivate, reinterpret_cast<void**>(&resourceLoadDelegatePrivate))))
    134         return true;
    135 
    136     BOOL shouldUse;
    137     if (SUCCEEDED(resourceLoadDelegatePrivate->shouldUseCredentialStorage(webView, identifier, getWebDataSource(loader), &shouldUse)))
    138         return shouldUse;
    139 
    140     return true;
    141 }
    142 
    143 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
    144 {
    145 #if USE(CFNETWORK)
    146     ASSERT(challenge.authenticationClient());
    147 
    148     WebView* webView = m_webFrame->webView();
    149     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    150     if (SUCCEEDED(webView->resourceLoadDelegate(&resourceLoadDelegate))) {
    151         COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
    152         if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader))))
    153             return;
    154     }
    155 
    156     // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle
    157     // to continue without credential - this is the best approximation of Mac behavior
    158     challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge);
    159 #else
    160    notImplemented();
    161 #endif
    162 }
    163 
    164 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
    165 {
    166     WebView* webView = m_webFrame->webView();
    167     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    168     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    169         return;
    170 
    171     COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
    172     resourceLoadDelegate->didCancelAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader));
    173 }
    174 
    175 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
    176 {
    177     WebView* webView = m_webFrame->webView();
    178     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    179     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    180         return;
    181 
    182     COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
    183     COMPtr<WebURLResponse> webURLRedirectResponse(AdoptCOM, WebURLResponse::createInstance(redirectResponse));
    184 
    185     COMPtr<IWebURLRequest> newWebURLRequest;
    186     if (FAILED(resourceLoadDelegate->willSendRequest(webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest)))
    187         return;
    188 
    189     if (webURLRequest == newWebURLRequest)
    190         return;
    191 
    192     if (!newWebURLRequest) {
    193         request = ResourceRequest();
    194         return;
    195     }
    196 
    197     COMPtr<WebMutableURLRequest> newWebURLRequestImpl(Query, newWebURLRequest);
    198     if (!newWebURLRequestImpl)
    199         return;
    200 
    201     request = newWebURLRequestImpl->resourceRequest();
    202 }
    203 
    204 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
    205 {
    206     WebView* webView = m_webFrame->webView();
    207     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    208     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    209         return;
    210 
    211     COMPtr<WebURLResponse> webURLResponse(AdoptCOM, WebURLResponse::createInstance(response));
    212     resourceLoadDelegate->didReceiveResponse(webView, identifier, webURLResponse.get(), getWebDataSource(loader));
    213 }
    214 
    215 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
    216 {
    217     WebView* webView = m_webFrame->webView();
    218     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    219     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    220         return;
    221 
    222     resourceLoadDelegate->didReceiveContentLength(webView, identifier, length, getWebDataSource(loader));
    223 }
    224 
    225 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
    226 {
    227     WebView* webView = m_webFrame->webView();
    228     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    229     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    230         return;
    231 
    232     resourceLoadDelegate->didFinishLoadingFromDataSource(webView, identifier, getWebDataSource(loader));
    233 }
    234 
    235 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
    236 {
    237     WebView* webView = m_webFrame->webView();
    238     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    239     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    240         return;
    241 
    242     COMPtr<WebError> webError(AdoptCOM, WebError::createInstance(error));
    243     resourceLoadDelegate->didFailLoadingWithError(webView, identifier, webError.get(), getWebDataSource(loader));
    244 }
    245 
    246 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const unsigned char* data, const unsigned long long length)
    247 {
    248     WebView* webView = m_webFrame->webView();
    249     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    250     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    251         return true;
    252 
    253     COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate(Query, resourceLoadDelegate);
    254     if (!resourceLoadDelegatePrivate)
    255         return true;
    256 
    257     COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(response));
    258     BOOL shouldCache;
    259     if (SUCCEEDED(resourceLoadDelegatePrivate->shouldCacheResponse(webView, identifier, urlResponse.get(), data, length, getWebDataSource(loader), &shouldCache)))
    260         return shouldCache;
    261 
    262     return true;
    263 }
    264 
    265 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
    266 {
    267     WebView* webView = m_webFrame->webView();
    268     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    269     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
    270         frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame);
    271 }
    272 
    273 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
    274 {
    275     WebView* webView = m_webFrame->webView();
    276     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    277     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    278         frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame);
    279 }
    280 
    281 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
    282 {
    283     WebView* webView = m_webFrame->webView();
    284     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    285     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    286         frameLoadDelegate->didCancelClientRedirectForFrame(webView, m_webFrame);
    287 }
    288 
    289 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
    290 {
    291     WebView* webView = m_webFrame->webView();
    292     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    293     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    294         frameLoadDelegate->willPerformClientRedirectToURL(webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), m_webFrame);
    295 }
    296 
    297 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
    298 {
    299     WebView* webView = m_webFrame->webView();
    300     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    301     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    302         frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame);
    303 }
    304 
    305 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
    306 {
    307     WebView* webView = m_webFrame->webView();
    308     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    309     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
    310         return;
    311 
    312     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
    313     if (!frameLoadDelegatePriv2)
    314         return;
    315 
    316     frameLoadDelegatePriv2->didPushStateWithinPageForFrame(webView, m_webFrame);
    317 }
    318 
    319 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
    320 {
    321     WebView* webView = m_webFrame->webView();
    322     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    323     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
    324         return;
    325 
    326     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
    327     if (!frameLoadDelegatePriv2)
    328         return;
    329 
    330     frameLoadDelegatePriv2->didReplaceStateWithinPageForFrame(webView, m_webFrame);
    331 }
    332 
    333 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
    334 {
    335     WebView* webView = m_webFrame->webView();
    336     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    337     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
    338         return;
    339 
    340     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
    341     if (!frameLoadDelegatePriv2)
    342         return;
    343 
    344     frameLoadDelegatePriv2->didPopStateWithinPageForFrame(webView, m_webFrame);
    345 }
    346 void WebFrameLoaderClient::dispatchWillClose()
    347 {
    348     WebView* webView = m_webFrame->webView();
    349     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    350     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    351         frameLoadDelegate->willCloseFrame(webView, m_webFrame);
    352 }
    353 
    354 void WebFrameLoaderClient::dispatchDidReceiveIcon()
    355 {
    356     m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame);
    357 }
    358 
    359 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
    360 {
    361     WebView* webView = m_webFrame->webView();
    362     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    363     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    364         frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame);
    365 }
    366 
    367 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
    368 {
    369     WebView* webView = m_webFrame->webView();
    370     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    371     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    372         // FIXME: use direction of title.
    373         frameLoadDelegate->didReceiveTitle(webView, BString(title.string()), m_webFrame);
    374 }
    375 
    376 void WebFrameLoaderClient::dispatchDidChangeIcons()
    377 {
    378     WebView* webView = m_webFrame->webView();
    379     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    380     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
    381         return;
    382 
    383     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
    384     if (!frameLoadDelegatePriv2)
    385         return;
    386 
    387     frameLoadDelegatePriv2->didChangeIcons(webView, m_webFrame);
    388 }
    389 
    390 void WebFrameLoaderClient::dispatchDidCommitLoad()
    391 {
    392     WebView* webView = m_webFrame->webView();
    393     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    394     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    395         frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame);
    396 }
    397 
    398 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
    399 {
    400     WebView* webView = m_webFrame->webView();
    401     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    402     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
    403         frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame);
    404 }
    405 
    406 void WebFrameLoaderClient::dispatchDidFinishLoad()
    407 {
    408     WebView* webView = m_webFrame->webView();
    409     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    410     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    411         frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame);
    412 }
    413 
    414 void WebFrameLoaderClient::dispatchDidFirstLayout()
    415 {
    416     WebView* webView = m_webFrame->webView();
    417     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    418     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
    419         frameLoadDelegatePriv->didFirstLayoutInFrame(webView, m_webFrame);
    420 }
    421 
    422 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
    423 {
    424     WebView* webView = m_webFrame->webView();
    425     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
    426     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate)
    427         frameLoadDelegatePrivate->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame);
    428 }
    429 
    430 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&)
    431 {
    432     WebView* webView = m_webFrame->webView();
    433 
    434     COMPtr<IWebUIDelegate> ui;
    435     if (FAILED(webView->uiDelegate(&ui)))
    436         return 0;
    437 
    438     COMPtr<IWebView> newWebView;
    439     if (FAILED(ui->createWebViewWithRequest(webView, 0, &newWebView)))
    440         return 0;
    441 
    442     COMPtr<IWebFrame> mainFrame;
    443     if (FAILED(newWebView->mainFrame(&mainFrame)))
    444         return 0;
    445 
    446     COMPtr<WebFrame> mainFrameImpl(Query, mainFrame);
    447     return core(mainFrameImpl.get());
    448 }
    449 
    450 void WebFrameLoaderClient::dispatchShow()
    451 {
    452     WebView* webView = m_webFrame->webView();
    453     COMPtr<IWebUIDelegate> ui;
    454     if (SUCCEEDED(webView->uiDelegate(&ui)))
    455         ui->webViewShow(webView);
    456 }
    457 
    458 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
    459 {
    460 }
    461 
    462 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
    463 {
    464     if (!m_manualLoader)
    465         return;
    466 
    467     m_manualLoader->didFail(error);
    468     m_manualLoader = 0;
    469     m_hasSentResponseToPlugin = false;
    470 }
    471 
    472 void WebFrameLoaderClient::postProgressStartedNotification()
    473 {
    474     static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
    475     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
    476     notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
    477 }
    478 
    479 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
    480 {
    481     static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
    482     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
    483     notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
    484 }
    485 
    486 void WebFrameLoaderClient::postProgressFinishedNotification()
    487 {
    488     static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
    489     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
    490     notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
    491 }
    492 
    493 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
    494 {
    495     if (!m_manualLoader)
    496         loader->commitData(data, length);
    497 
    498     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
    499     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
    500     Frame* coreFrame = core(m_webFrame);
    501     if (coreFrame->document()->isMediaDocument())
    502         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
    503 
    504     if (!m_manualLoader)
    505         return;
    506 
    507     if (!m_hasSentResponseToPlugin) {
    508         m_manualLoader->didReceiveResponse(loader->response());
    509         // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
    510         // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader
    511         // to null
    512         if (!m_manualLoader)
    513             return;
    514         m_hasSentResponseToPlugin = true;
    515     }
    516     m_manualLoader->didReceiveData(data, length);
    517 }
    518 
    519 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
    520 {
    521     // Telling the frame we received some data and passing 0 as the data is our
    522     // way to get work done that is normally done when the first bit of data is
    523     // received, even for the case of a document with no data (like about:blank)
    524     committedLoad(loader, 0, 0);
    525 
    526     if (!m_manualLoader)
    527         return;
    528 
    529     m_manualLoader->didFinishLoading();
    530     m_manualLoader = 0;
    531     m_hasSentResponseToPlugin = false;
    532 }
    533 
    534 void WebFrameLoaderClient::updateGlobalHistory()
    535 {
    536     DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
    537     WebView* webView = m_webFrame->webView();
    538     COMPtr<IWebHistoryDelegate> historyDelegate;
    539     webView->historyDelegate(&historyDelegate);
    540 
    541     if (historyDelegate) {
    542         COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(loader->response()));
    543         COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(loader->originalRequestCopy()));
    544 
    545         COMPtr<IWebNavigationData> navigationData(AdoptCOM, WebNavigationData::createInstance(
    546             loader->urlForHistory(), loader->title().string(), urlRequest.get(), urlResponse.get(), loader->substituteData().isValid(), loader->clientRedirectSourceForHistory()));
    547 
    548         historyDelegate->didNavigateWithNavigationData(webView, navigationData.get(), m_webFrame);
    549         return;
    550     }
    551 
    552     WebHistory* history = WebHistory::sharedHistory();
    553     if (!history)
    554         return;
    555 
    556     history->visitedURL(loader->urlForHistory(), loader->title().string(), loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure(), !loader->clientRedirectSourceForHistory());
    557 }
    558 
    559 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
    560 {
    561     WebView* webView = m_webFrame->webView();
    562     COMPtr<IWebHistoryDelegate> historyDelegate;
    563     webView->historyDelegate(&historyDelegate);
    564 
    565     WebHistory* history = WebHistory::sharedHistory();
    566 
    567     DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
    568     ASSERT(loader->unreachableURL().isEmpty());
    569 
    570     if (!loader->clientRedirectSourceForHistory().isNull()) {
    571         if (historyDelegate) {
    572             BString sourceURL(loader->clientRedirectSourceForHistory());
    573             BString destURL(loader->clientRedirectDestinationForHistory());
    574             historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
    575         } else {
    576             if (history) {
    577                 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) {
    578                     COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
    579                     webHistoryItem->historyItem()->addRedirectURL(loader->clientRedirectDestinationForHistory());
    580                 }
    581             }
    582         }
    583     }
    584 
    585     if (!loader->serverRedirectSourceForHistory().isNull()) {
    586         if (historyDelegate) {
    587             BString sourceURL(loader->serverRedirectSourceForHistory());
    588             BString destURL(loader->serverRedirectDestinationForHistory());
    589             historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
    590         } else {
    591             if (history) {
    592                 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) {
    593                     COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
    594                     webHistoryItem->historyItem()->addRedirectURL(loader->serverRedirectDestinationForHistory());
    595                 }
    596             }
    597         }
    598     }
    599 }
    600 
    601 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const
    602 {
    603     return true;
    604 }
    605 
    606 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem*) const
    607 {
    608     return true;
    609 }
    610 
    611 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
    612 {
    613 }
    614 
    615 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
    616 {
    617 }
    618 
    619 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
    620 {
    621 }
    622 
    623 void WebFrameLoaderClient::updateGlobalHistoryItemForPage()
    624 {
    625     HistoryItem* historyItem = 0;
    626     WebView* webView = m_webFrame->webView();
    627 
    628     if (Page* page = webView->page()) {
    629         if (!page->settings()->privateBrowsingEnabled())
    630             historyItem = page->backForward()->currentItem();
    631     }
    632 
    633     webView->setGlobalHistoryItem(historyItem);
    634 }
    635 
    636 void WebFrameLoaderClient::didDisplayInsecureContent()
    637 {
    638     WebView* webView = m_webFrame->webView();
    639     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    640     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
    641         return;
    642 
    643     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
    644     if (!frameLoadDelegatePriv2)
    645         return;
    646 
    647     frameLoadDelegatePriv2->didDisplayInsecureContent(webView);
    648 }
    649 
    650 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL)
    651 {
    652     COMPtr<IWebSecurityOrigin> webSecurityOrigin = WebSecurityOrigin::createInstance(origin);
    653 
    654     WebView* webView = m_webFrame->webView();
    655     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    656     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
    657         return;
    658 
    659     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
    660     if (!frameLoadDelegatePriv2)
    661         return;
    662 
    663     frameLoadDelegatePriv2->didRunInsecureContent(webView, webSecurityOrigin.get());
    664 }
    665 
    666 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
    667 {
    668     RefPtr<WebDocumentLoader> loader = WebDocumentLoader::create(request, substituteData);
    669 
    670     COMPtr<WebDataSource> dataSource(AdoptCOM, WebDataSource::createInstance(loader.get()));
    671 
    672     loader->setDataSource(dataSource.get());
    673     return loader.release();
    674 }
    675 
    676 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
    677 {
    678     WebView* webView = m_webFrame->webView();
    679     COMPtr<IWebHistoryDelegate> historyDelegate;
    680     webView->historyDelegate(&historyDelegate);
    681     if (historyDelegate) {
    682         BString titleBSTR(title.string());
    683         BString urlBSTR(url.string());
    684         historyDelegate->updateHistoryTitle(webView, titleBSTR, urlBSTR);
    685         return;
    686     }
    687 
    688     BOOL privateBrowsingEnabled = FALSE;
    689     COMPtr<IWebPreferences> preferences;
    690     if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences)))
    691         preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
    692     if (privateBrowsingEnabled)
    693         return;
    694 
    695     // update title in global history
    696     COMPtr<WebHistory> history = webHistory();
    697     if (!history)
    698         return;
    699 
    700     COMPtr<IWebHistoryItem> item;
    701     if (FAILED(history->itemForURL(BString(url.string()), &item)))
    702         return;
    703 
    704     COMPtr<IWebHistoryItemPrivate> itemPrivate(Query, item);
    705     if (!itemPrivate)
    706         return;
    707 
    708     itemPrivate->setTitle(BString(title.string()));
    709 }
    710 
    711 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
    712 {
    713 #if USE(CFNETWORK)
    714     Frame* coreFrame = core(m_webFrame);
    715     if (!coreFrame)
    716         return;
    717 
    718     ASSERT(coreFrame->loader()->documentLoader() == cachedFrame->documentLoader());
    719 
    720     WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader()->documentLoader())));
    721     cachedFrame->setCachedFramePlatformData(webPlatformData);
    722 #else
    723     notImplemented();
    724 #endif
    725 }
    726 
    727 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
    728 {
    729 }
    730 
    731 void WebFrameLoaderClient::transitionToCommittedForNewPage()
    732 {
    733     WebView* view = m_webFrame->webView();
    734 
    735     RECT rect;
    736     view->frameRect(&rect);
    737     bool transparent = view->transparent();
    738     Color backgroundColor = transparent ? Color::transparent : Color::white;
    739     core(m_webFrame)->createView(IntRect(rect).size(), backgroundColor, transparent, IntSize(), false);
    740 }
    741 
    742 void WebFrameLoaderClient::didSaveToPageCache()
    743 {
    744 }
    745 
    746 void WebFrameLoaderClient::didRestoreFromPageCache()
    747 {
    748 }
    749 
    750 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool)
    751 {
    752 }
    753 
    754 bool WebFrameLoaderClient::canCachePage() const
    755 {
    756     return true;
    757 }
    758 
    759 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
    760                             const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
    761 {
    762     RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
    763     if (!result)
    764         return 0;
    765     return result.release();
    766 }
    767 
    768 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*)
    769 {
    770     Frame* coreFrame = core(m_webFrame);
    771     ASSERT(coreFrame);
    772     WebView* webView = kit(coreFrame->page());
    773     if (m_webFrame->webView() != webView)
    774         m_webFrame->setWebView(webView);
    775 }
    776 
    777 void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request, Page* oldPage)
    778 {
    779     assignIdentifierToInitialRequest(identifier, loader, request);
    780 
    781     WebView* oldWebView = kit(oldPage);
    782     if (!oldWebView)
    783         return;
    784 
    785     COMPtr<IWebResourceLoadDelegate> oldResourceLoadDelegate;
    786     if (FAILED(oldWebView->resourceLoadDelegate(&oldResourceLoadDelegate)))
    787         return;
    788 
    789     COMPtr<IWebResourceLoadDelegatePrivate2> oldResourceLoadDelegatePrivate2(Query, oldResourceLoadDelegate);
    790     if (!oldResourceLoadDelegatePrivate2)
    791         return;
    792     oldResourceLoadDelegatePrivate2->removeIdentifierForRequest(oldWebView, identifier);
    793 }
    794 
    795 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
    796 {
    797     Frame* coreFrame = core(m_webFrame);
    798     ASSERT(coreFrame);
    799 
    800     COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance());
    801 
    802     RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement);
    803 
    804     childFrame->tree()->setName(name);
    805     coreFrame->tree()->appendChild(childFrame);
    806     childFrame->init();
    807 
    808     coreFrame->loader()->loadURLIntoChildFrame(URL, referrer, childFrame.get());
    809 
    810     // The frame's onload handler may have removed it from the document.
    811     if (!childFrame->tree()->parent())
    812         return 0;
    813 
    814     return childFrame.release();
    815 }
    816 
    817 void WebFrameLoaderClient::dispatchDidFailToStartPlugin(const PluginView* pluginView) const
    818 {
    819     WebView* webView = m_webFrame->webView();
    820 
    821     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    822     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    823         return;
    824 
    825     RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
    826 
    827     Frame* frame = core(m_webFrame);
    828     ASSERT(frame == pluginView->parentFrame());
    829 
    830     if (!pluginView->pluginsPage().isNull()) {
    831         KURL pluginPageURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(pluginView->pluginsPage()));
    832         if (pluginPageURL.protocolInHTTPFamily()) {
    833             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
    834             RetainPtr<CFStringRef> str(AdoptCF, pluginPageURL.string().createCFString());
    835             CFDictionarySetValue(userInfo.get(), key, str.get());
    836         }
    837     }
    838 
    839     if (!pluginView->mimeType().isNull()) {
    840         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
    841 
    842         RetainPtr<CFStringRef> str(AdoptCF, pluginView->mimeType().createCFString());
    843         CFDictionarySetValue(userInfo.get(), key, str.get());
    844     }
    845 
    846     if (pluginView->plugin()) {
    847         String pluginName = pluginView->plugin()->name();
    848         if (!pluginName.isNull()) {
    849             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
    850             RetainPtr<CFStringRef> str(AdoptCF, pluginName.createCFString());
    851             CFDictionarySetValue(userInfo.get(), key, str.get());
    852         }
    853     }
    854 
    855     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
    856     userInfoBag->setDictionary(userInfo.get());
    857 
    858     int errorCode = 0;
    859     switch (pluginView->status()) {
    860         case PluginStatusCanNotFindPlugin:
    861             errorCode = WebKitErrorCannotFindPlugIn;
    862             break;
    863         case PluginStatusCanNotLoadPlugin:
    864             errorCode = WebKitErrorCannotLoadPlugIn;
    865             break;
    866         default:
    867             ASSERT_NOT_REACHED();
    868     }
    869 
    870     ResourceError resourceError(String(WebKitErrorDomain), errorCode, pluginView->url().string(), String());
    871     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
    872 
    873     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader()));
    874 }
    875 
    876 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
    877 {
    878     WebView* webView = m_webFrame->webView();
    879 
    880     COMPtr<IWebUIDelegate> ui;
    881     if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
    882         COMPtr<IWebUIDelegatePrivate> uiPrivate(Query, ui);
    883 
    884         if (uiPrivate) {
    885             // Assemble the view arguments in a property bag.
    886             HashMap<String, String> viewArguments;
    887             for (unsigned i = 0; i < paramNames.size(); i++)
    888                 viewArguments.set(paramNames[i], paramValues[i]);
    889             COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
    890             COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(element));
    891 
    892             HashMap<String, COMVariant> arguments;
    893 
    894             arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag);
    895             arguments.set(WebEmbeddedViewBaseURLKey, url.string());
    896             arguments.set(WebEmbeddedViewContainingElementKey, containingElement);
    897             arguments.set(WebEmbeddedViewMIMETypeKey, mimeType);
    898 
    899             COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments));
    900 
    901             COMPtr<IWebEmbeddedView> view;
    902             HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view);
    903             if (SUCCEEDED(result)) {
    904                 HWND parentWindow;
    905                 HRESULT hr = webView->viewWindow((OLE_HANDLE*)&parentWindow);
    906                 ASSERT(SUCCEEDED(hr));
    907 
    908                 return EmbeddedWidget::create(view.get(), element, parentWindow, pluginSize);
    909             }
    910         }
    911     }
    912 
    913     Frame* frame = core(m_webFrame);
    914     RefPtr<PluginView> pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
    915 
    916     if (pluginView->status() == PluginStatusLoadedSuccessfully)
    917         return pluginView;
    918 
    919     dispatchDidFailToStartPlugin(pluginView.get());
    920 
    921     return 0;
    922 }
    923 
    924 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
    925 {
    926     // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
    927 
    928     if (pluginWidget->isPluginView())
    929         m_manualLoader = static_cast<PluginView*>(pluginWidget);
    930     else
    931         m_manualLoader = static_cast<EmbeddedWidget*>(pluginWidget);
    932 }
    933 
    934 WebHistory* WebFrameLoaderClient::webHistory() const
    935 {
    936     if (m_webFrame != m_webFrame->webView()->topLevelFrame())
    937         return 0;
    938 
    939     return WebHistory::sharedHistory();
    940 }
    941 
    942 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& mimeType) const
    943 {
    944     WebView* webView = m_webFrame->webView();
    945     if (!webView)
    946         return false;
    947 
    948     return webView->shouldUseEmbeddedView(mimeType);
    949 }
    950