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 #pragma warning(push, 0)
     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/HTMLPlugInElement.h>
     63 #include <WebCore/HistoryItem.h>
     64 #include <WebCore/Page.h>
     65 #include <WebCore/PluginPackage.h>
     66 #include <WebCore/PluginView.h>
     67 #include <WebCore/RenderPart.h>
     68 #include <WebCore/ResourceHandle.h>
     69 #include <WebCore/ScriptString.h>
     70 #pragma warning(pop)
     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 void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(unsigned long, const ScriptString&)
    247 {
    248 }
    249 
    250 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const unsigned char* data, const unsigned long long length)
    251 {
    252     WebView* webView = m_webFrame->webView();
    253     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    254     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    255         return true;
    256 
    257     COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate(Query, resourceLoadDelegate);
    258     if (!resourceLoadDelegatePrivate)
    259         return true;
    260 
    261     COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(response));
    262     BOOL shouldCache;
    263     if (SUCCEEDED(resourceLoadDelegatePrivate->shouldCacheResponse(webView, identifier, urlResponse.get(), data, length, getWebDataSource(loader), &shouldCache)))
    264         return shouldCache;
    265 
    266     return true;
    267 }
    268 
    269 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
    270 {
    271     WebView* webView = m_webFrame->webView();
    272     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    273     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
    274         frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame);
    275 }
    276 
    277 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
    278 {
    279     WebView* webView = m_webFrame->webView();
    280     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    281     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    282         frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame);
    283 }
    284 
    285 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
    286 {
    287     WebView* webView = m_webFrame->webView();
    288     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    289     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    290         frameLoadDelegate->didCancelClientRedirectForFrame(webView, m_webFrame);
    291 }
    292 
    293 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
    294 {
    295     WebView* webView = m_webFrame->webView();
    296     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    297     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    298         frameLoadDelegate->willPerformClientRedirectToURL(webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), m_webFrame);
    299 }
    300 
    301 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
    302 {
    303     WebView* webView = m_webFrame->webView();
    304     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    305     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    306         frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame);
    307 }
    308 
    309 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
    310 {
    311     WebView* webView = m_webFrame->webView();
    312     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    313     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
    314         return;
    315 
    316     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
    317     if (!frameLoadDelegatePriv2)
    318         return;
    319 
    320     frameLoadDelegatePriv2->didPushStateWithinPageForFrame(webView, m_webFrame);
    321 }
    322 
    323 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
    324 {
    325     WebView* webView = m_webFrame->webView();
    326     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    327     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
    328         return;
    329 
    330     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
    331     if (!frameLoadDelegatePriv2)
    332         return;
    333 
    334     frameLoadDelegatePriv2->didReplaceStateWithinPageForFrame(webView, m_webFrame);
    335 }
    336 
    337 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
    338 {
    339     WebView* webView = m_webFrame->webView();
    340     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    341     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
    342         return;
    343 
    344     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
    345     if (!frameLoadDelegatePriv2)
    346         return;
    347 
    348     frameLoadDelegatePriv2->didPopStateWithinPageForFrame(webView, m_webFrame);
    349 }
    350 void WebFrameLoaderClient::dispatchWillClose()
    351 {
    352     WebView* webView = m_webFrame->webView();
    353     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    354     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    355         frameLoadDelegate->willCloseFrame(webView, m_webFrame);
    356 }
    357 
    358 void WebFrameLoaderClient::dispatchDidReceiveIcon()
    359 {
    360     m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame);
    361 }
    362 
    363 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
    364 {
    365     WebView* webView = m_webFrame->webView();
    366     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    367     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    368         frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame);
    369 }
    370 
    371 void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title)
    372 {
    373     WebView* webView = m_webFrame->webView();
    374     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    375     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    376         frameLoadDelegate->didReceiveTitle(webView, BString(title), m_webFrame);
    377 }
    378 
    379 void WebFrameLoaderClient::dispatchDidCommitLoad()
    380 {
    381     WebView* webView = m_webFrame->webView();
    382     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    383     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    384         frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame);
    385 }
    386 
    387 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
    388 {
    389     WebView* webView = m_webFrame->webView();
    390     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    391     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
    392         frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame);
    393 }
    394 
    395 void WebFrameLoaderClient::dispatchDidFinishLoad()
    396 {
    397     WebView* webView = m_webFrame->webView();
    398     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
    399     if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
    400         frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame);
    401 }
    402 
    403 void WebFrameLoaderClient::dispatchDidFirstLayout()
    404 {
    405     WebView* webView = m_webFrame->webView();
    406     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    407     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
    408         frameLoadDelegatePriv->didFirstLayoutInFrame(webView, m_webFrame);
    409 }
    410 
    411 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
    412 {
    413     WebView* webView = m_webFrame->webView();
    414     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
    415     if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate)
    416         frameLoadDelegatePrivate->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame);
    417 }
    418 
    419 Frame* WebFrameLoaderClient::dispatchCreatePage()
    420 {
    421     WebView* webView = m_webFrame->webView();
    422 
    423     COMPtr<IWebUIDelegate> ui;
    424     if (FAILED(webView->uiDelegate(&ui)))
    425         return 0;
    426 
    427     COMPtr<IWebView> newWebView;
    428     if (FAILED(ui->createWebViewWithRequest(webView, 0, &newWebView)))
    429         return 0;
    430 
    431     COMPtr<IWebFrame> mainFrame;
    432     if (FAILED(newWebView->mainFrame(&mainFrame)))
    433         return 0;
    434 
    435     COMPtr<WebFrame> mainFrameImpl(Query, mainFrame);
    436     return core(mainFrameImpl.get());
    437 }
    438 
    439 void WebFrameLoaderClient::dispatchShow()
    440 {
    441     WebView* webView = m_webFrame->webView();
    442     COMPtr<IWebUIDelegate> ui;
    443     if (SUCCEEDED(webView->uiDelegate(&ui)))
    444         ui->webViewShow(webView);
    445 }
    446 
    447 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
    448 {
    449 }
    450 
    451 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
    452 {
    453     if (!m_manualLoader)
    454         return;
    455 
    456     m_manualLoader->didFail(error);
    457     m_manualLoader = 0;
    458     m_hasSentResponseToPlugin = false;
    459 }
    460 
    461 void WebFrameLoaderClient::postProgressStartedNotification()
    462 {
    463     static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
    464     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
    465     notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
    466 }
    467 
    468 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
    469 {
    470     static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
    471     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
    472     notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
    473 }
    474 
    475 void WebFrameLoaderClient::postProgressFinishedNotification()
    476 {
    477     static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
    478     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
    479     notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
    480 }
    481 
    482 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
    483 {
    484     // FIXME: This should probably go through the data source.
    485     const String& textEncoding = loader->response().textEncodingName();
    486 
    487     if (!m_manualLoader)
    488         receivedData(data, length, textEncoding);
    489 
    490     if (!m_manualLoader)
    491         return;
    492 
    493     if (!m_hasSentResponseToPlugin) {
    494         m_manualLoader->didReceiveResponse(core(m_webFrame)->loader()->documentLoader()->response());
    495         // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
    496         // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader
    497         // to null
    498         if (!m_manualLoader)
    499             return;
    500         m_hasSentResponseToPlugin = true;
    501     }
    502     m_manualLoader->didReceiveData(data, length);
    503 }
    504 
    505 void WebFrameLoaderClient::receivedData(const char* data, int length, const String& textEncoding)
    506 {
    507     Frame* coreFrame = core(m_webFrame);
    508     if (!coreFrame)
    509         return;
    510 
    511     // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
    512     String encoding = coreFrame->loader()->documentLoader()->overrideEncoding();
    513     bool userChosen = !encoding.isNull();
    514     if (encoding.isNull())
    515         encoding = textEncoding;
    516     coreFrame->loader()->setEncoding(encoding, userChosen);
    517 
    518     coreFrame->loader()->addData(data, length);
    519 }
    520 
    521 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
    522 {
    523     // Telling the frame we received some data and passing 0 as the data is our
    524     // way to get work done that is normally done when the first bit of data is
    525     // received, even for the case of a document with no data (like about:blank)
    526     if (!m_manualLoader) {
    527         committedLoad(loader, 0, 0);
    528         return;
    529     }
    530 
    531     m_manualLoader->didFinishLoading();
    532     m_manualLoader = 0;
    533     m_hasSentResponseToPlugin = false;
    534 }
    535 
    536 void WebFrameLoaderClient::updateGlobalHistory()
    537 {
    538     DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
    539     WebView* webView = m_webFrame->webView();
    540     COMPtr<IWebHistoryDelegate> historyDelegate;
    541     webView->historyDelegate(&historyDelegate);
    542 
    543     if (historyDelegate) {
    544         COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(loader->response()));
    545         COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(loader->originalRequestCopy()));
    546 
    547         COMPtr<IWebNavigationData> navigationData(AdoptCOM, WebNavigationData::createInstance(
    548             loader->urlForHistory(), loader->title(), urlRequest.get(), urlResponse.get(), loader->substituteData().isValid(), loader->clientRedirectSourceForHistory()));
    549 
    550         historyDelegate->didNavigateWithNavigationData(webView, navigationData.get(), m_webFrame);
    551         return;
    552     }
    553 
    554     WebHistory* history = WebHistory::sharedHistory();
    555     if (!history)
    556         return;
    557 
    558     history->visitedURL(loader->urlForHistory(), loader->title(), loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure(), !loader->clientRedirectSourceForHistory());
    559 }
    560 
    561 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
    562 {
    563     WebView* webView = m_webFrame->webView();
    564     COMPtr<IWebHistoryDelegate> historyDelegate;
    565     webView->historyDelegate(&historyDelegate);
    566 
    567     WebHistory* history = WebHistory::sharedHistory();
    568 
    569     DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
    570     ASSERT(loader->unreachableURL().isEmpty());
    571 
    572     if (!loader->clientRedirectSourceForHistory().isNull()) {
    573         if (historyDelegate) {
    574             BString sourceURL(loader->clientRedirectSourceForHistory());
    575             BString destURL(loader->clientRedirectDestinationForHistory());
    576             historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
    577         } else {
    578             if (history) {
    579                 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) {
    580                     COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
    581                     webHistoryItem->historyItem()->addRedirectURL(loader->clientRedirectDestinationForHistory());
    582                 }
    583             }
    584         }
    585     }
    586 
    587     if (!loader->serverRedirectSourceForHistory().isNull()) {
    588         if (historyDelegate) {
    589             BString sourceURL(loader->serverRedirectSourceForHistory());
    590             BString destURL(loader->serverRedirectDestinationForHistory());
    591             historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL, destURL, m_webFrame);
    592         } else {
    593             if (history) {
    594                 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) {
    595                     COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
    596                     webHistoryItem->historyItem()->addRedirectURL(loader->serverRedirectDestinationForHistory());
    597                 }
    598             }
    599         }
    600     }
    601 }
    602 
    603 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const
    604 {
    605     return true;
    606 }
    607 
    608 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
    609 {
    610 }
    611 
    612 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
    613 {
    614 }
    615 
    616 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
    617 {
    618 }
    619 
    620 void WebFrameLoaderClient::didDisplayInsecureContent()
    621 {
    622     WebView* webView = m_webFrame->webView();
    623     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
    624     if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
    625         return;
    626 
    627     COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
    628     if (!frameLoadDelegatePriv2)
    629         return;
    630 
    631     frameLoadDelegatePriv2->didDisplayInsecureContent(webView);
    632 }
    633 
    634 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin)
    635 {
    636     COMPtr<IWebSecurityOrigin> webSecurityOrigin = WebSecurityOrigin::createInstance(origin);
    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->didRunInsecureContent(webView, webSecurityOrigin.get());
    648 }
    649 
    650 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
    651 {
    652     RefPtr<WebDocumentLoader> loader = WebDocumentLoader::create(request, substituteData);
    653 
    654     COMPtr<WebDataSource> dataSource(AdoptCOM, WebDataSource::createInstance(loader.get()));
    655 
    656     loader->setDataSource(dataSource.get());
    657     return loader.release();
    658 }
    659 
    660 void WebFrameLoaderClient::setTitle(const String& title, const KURL& url)
    661 {
    662     WebView* webView = m_webFrame->webView();
    663     COMPtr<IWebHistoryDelegate> historyDelegate;
    664     webView->historyDelegate(&historyDelegate);
    665     if (historyDelegate) {
    666         BString titleBSTR(title);
    667         BString urlBSTR(url.string());
    668         historyDelegate->updateHistoryTitle(webView, titleBSTR, urlBSTR);
    669         return;
    670     }
    671 
    672     BOOL privateBrowsingEnabled = FALSE;
    673     COMPtr<IWebPreferences> preferences;
    674     if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences)))
    675         preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
    676     if (privateBrowsingEnabled)
    677         return;
    678 
    679     // update title in global history
    680     COMPtr<WebHistory> history = webHistory();
    681     if (!history)
    682         return;
    683 
    684     COMPtr<IWebHistoryItem> item;
    685     if (FAILED(history->itemForURL(BString(url.string()), &item)))
    686         return;
    687 
    688     COMPtr<IWebHistoryItemPrivate> itemPrivate(Query, item);
    689     if (!itemPrivate)
    690         return;
    691 
    692     itemPrivate->setTitle(BString(title));
    693 }
    694 
    695 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
    696 {
    697 #if USE(CFNETWORK)
    698     Frame* coreFrame = core(m_webFrame);
    699     if (!coreFrame)
    700         return;
    701 
    702     ASSERT(coreFrame->loader()->documentLoader() == cachedFrame->documentLoader());
    703 
    704     WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader()->documentLoader())));
    705     cachedFrame->setCachedFramePlatformData(webPlatformData);
    706 #else
    707     notImplemented();
    708 #endif
    709 }
    710 
    711 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
    712 {
    713 }
    714 
    715 void WebFrameLoaderClient::transitionToCommittedForNewPage()
    716 {
    717     WebView* view = m_webFrame->webView();
    718 
    719     RECT rect;
    720     view->frameRect(&rect);
    721     bool transparent = view->transparent();
    722     Color backgroundColor = transparent ? Color::transparent : Color::white;
    723     core(m_webFrame)->createView(IntRect(rect).size(), backgroundColor, transparent, IntSize(), false);
    724 }
    725 
    726 bool WebFrameLoaderClient::canCachePage() const
    727 {
    728     return true;
    729 }
    730 
    731 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
    732                             const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
    733 {
    734     RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
    735     if (!result)
    736         return 0;
    737     return result.release();
    738 }
    739 
    740 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
    741 {
    742     Frame* coreFrame = core(m_webFrame);
    743     ASSERT(coreFrame);
    744 
    745     COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance());
    746 
    747     RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement);
    748 
    749     coreFrame->tree()->appendChild(childFrame);
    750     childFrame->tree()->setName(name);
    751     childFrame->init();
    752 
    753     coreFrame->loader()->loadURLIntoChildFrame(URL, referrer, childFrame.get());
    754 
    755     // The frame's onload handler may have removed it from the document.
    756     if (!childFrame->tree()->parent())
    757         return 0;
    758 
    759     return childFrame.release();
    760 }
    761 
    762 void WebFrameLoaderClient::dispatchDidFailToStartPlugin(const PluginView* pluginView) const
    763 {
    764     WebView* webView = m_webFrame->webView();
    765 
    766     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
    767     if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
    768         return;
    769 
    770     RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
    771 
    772     Frame* frame = core(m_webFrame);
    773     ASSERT(frame == pluginView->parentFrame());
    774 
    775     if (!pluginView->pluginsPage().isNull()) {
    776         KURL pluginPageURL = frame->document()->completeURL(deprecatedParseURL(pluginView->pluginsPage()));
    777         if (pluginPageURL.protocolInHTTPFamily()) {
    778             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
    779             RetainPtr<CFStringRef> str(AdoptCF, pluginPageURL.string().createCFString());
    780             CFDictionarySetValue(userInfo.get(), key, str.get());
    781         }
    782     }
    783 
    784     if (!pluginView->mimeType().isNull()) {
    785         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
    786 
    787         RetainPtr<CFStringRef> str(AdoptCF, pluginView->mimeType().createCFString());
    788         CFDictionarySetValue(userInfo.get(), key, str.get());
    789     }
    790 
    791     if (pluginView->plugin()) {
    792         String pluginName = pluginView->plugin()->name();
    793         if (!pluginName.isNull()) {
    794             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
    795             RetainPtr<CFStringRef> str(AdoptCF, pluginName.createCFString());
    796             CFDictionarySetValue(userInfo.get(), key, str.get());
    797         }
    798     }
    799 
    800     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
    801     userInfoBag->setDictionary(userInfo.get());
    802 
    803     int errorCode = 0;
    804     switch (pluginView->status()) {
    805         case PluginStatusCanNotFindPlugin:
    806             errorCode = WebKitErrorCannotFindPlugIn;
    807             break;
    808         case PluginStatusCanNotLoadPlugin:
    809             errorCode = WebKitErrorCannotLoadPlugIn;
    810             break;
    811         default:
    812             ASSERT_NOT_REACHED();
    813     }
    814 
    815     ResourceError resourceError(String(WebKitErrorDomain), errorCode, pluginView->url().string(), String());
    816     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
    817 
    818     resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader()));
    819 }
    820 
    821 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)
    822 {
    823     WebView* webView = m_webFrame->webView();
    824 
    825     COMPtr<IWebUIDelegate> ui;
    826     if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
    827         COMPtr<IWebUIDelegatePrivate> uiPrivate(Query, ui);
    828 
    829         if (uiPrivate) {
    830             // Assemble the view arguments in a property bag.
    831             HashMap<String, String> viewArguments;
    832             for (unsigned i = 0; i < paramNames.size(); i++)
    833                 viewArguments.set(paramNames[i], paramValues[i]);
    834             COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
    835             COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(element));
    836 
    837             HashMap<String, COMVariant> arguments;
    838 
    839             arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag);
    840             arguments.set(WebEmbeddedViewBaseURLKey, url.string());
    841             arguments.set(WebEmbeddedViewContainingElementKey, containingElement);
    842             arguments.set(WebEmbeddedViewMIMETypeKey, mimeType);
    843 
    844             COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments));
    845 
    846             COMPtr<IWebEmbeddedView> view;
    847             HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view);
    848             if (SUCCEEDED(result)) {
    849                 HWND parentWindow;
    850                 HRESULT hr = webView->viewWindow((OLE_HANDLE*)&parentWindow);
    851                 ASSERT(SUCCEEDED(hr));
    852 
    853                 return EmbeddedWidget::create(view.get(), element, parentWindow, pluginSize);
    854             }
    855         }
    856     }
    857 
    858     Frame* frame = core(m_webFrame);
    859     RefPtr<PluginView> pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
    860 
    861     if (pluginView->status() == PluginStatusLoadedSuccessfully)
    862         return pluginView;
    863 
    864     dispatchDidFailToStartPlugin(pluginView.get());
    865 
    866     return pluginView;
    867 }
    868 
    869 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
    870 {
    871     // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
    872 
    873     if (pluginWidget->isPluginView())
    874         m_manualLoader = static_cast<PluginView*>(pluginWidget);
    875     else
    876         m_manualLoader = static_cast<EmbeddedWidget*>(pluginWidget);
    877 }
    878 
    879 WebHistory* WebFrameLoaderClient::webHistory() const
    880 {
    881     if (m_webFrame != m_webFrame->webView()->topLevelFrame())
    882         return 0;
    883 
    884     return WebHistory::sharedHistory();
    885 }
    886 
    887 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& mimeType) const
    888 {
    889     WebView* webView = m_webFrame->webView();
    890     if (!webView)
    891         return false;
    892 
    893     return webView->shouldUseEmbeddedView(mimeType);
    894 }
    895