/* * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "WebFrameLoaderClient.h" #include "CFDictionaryPropertyBag.h" #include "COMPropertyBag.h" #include "DOMHTMLClasses.h" #include "EmbeddedWidget.h" #include "MarshallingHelpers.h" #include "NotImplemented.h" #include "WebCachedFramePlatformData.h" #include "WebChromeClient.h" #include "WebDocumentLoader.h" #include "WebError.h" #include "WebFrame.h" #include "WebHistory.h" #include "WebHistoryItem.h" #include "WebMutableURLRequest.h" #include "WebNavigationData.h" #include "WebNotificationCenter.h" #include "WebSecurityOrigin.h" #include "WebURLAuthenticationChallenge.h" #include "WebURLResponse.h" #include "WebView.h" #pragma warning(push, 0) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #pragma warning(pop) using namespace WebCore; using namespace HTMLNames; static WebDataSource* getWebDataSource(DocumentLoader* loader) { return loader ? static_cast(loader)->dataSource() : 0; } WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* webFrame) : m_webFrame(webFrame) , m_manualLoader(0) , m_hasSentResponseToPlugin(false) { ASSERT_ARG(webFrame, webFrame); } WebFrameLoaderClient::~WebFrameLoaderClient() { } bool WebFrameLoaderClient::hasWebView() const { return m_webFrame->webView(); } void WebFrameLoaderClient::forceLayout() { Frame* frame = core(m_webFrame); if (!frame) return; if (frame->document() && frame->document()->inPageCache()) return; FrameView* view = frame->view(); if (!view) return; view->setNeedsLayout(); view->forceLayout(true); } void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) { WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return; COMPtr webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request)); resourceLoadDelegate->identifierForInitialRequest(webView, webURLRequest.get(), getWebDataSource(loader), identifier); } bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier) { WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return true; COMPtr resourceLoadDelegatePrivate; if (FAILED(resourceLoadDelegate->QueryInterface(IID_IWebResourceLoadDelegatePrivate, reinterpret_cast(&resourceLoadDelegatePrivate)))) return true; BOOL shouldUse; if (SUCCEEDED(resourceLoadDelegatePrivate->shouldUseCredentialStorage(webView, identifier, getWebDataSource(loader), &shouldUse))) return shouldUse; return true; } void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge) { #if USE(CFNETWORK) ASSERT(challenge.authenticationClient()); WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (SUCCEEDED(webView->resourceLoadDelegate(&resourceLoadDelegate))) { COMPtr webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge)); if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader)))) return; } // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle // to continue without credential - this is the best approximation of Mac behavior challenge.authenticationClient()->receivedRequestToContinueWithoutCredential(challenge); #else notImplemented(); #endif } void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge) { WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return; COMPtr webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge)); resourceLoadDelegate->didCancelAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader)); } void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) { WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return; COMPtr webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request)); COMPtr webURLRedirectResponse(AdoptCOM, WebURLResponse::createInstance(redirectResponse)); COMPtr newWebURLRequest; if (FAILED(resourceLoadDelegate->willSendRequest(webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest))) return; if (webURLRequest == newWebURLRequest) return; if (!newWebURLRequest) { request = ResourceRequest(); return; } COMPtr newWebURLRequestImpl(Query, newWebURLRequest); if (!newWebURLRequestImpl) return; request = newWebURLRequestImpl->resourceRequest(); } void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response) { WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return; COMPtr webURLResponse(AdoptCOM, WebURLResponse::createInstance(response)); resourceLoadDelegate->didReceiveResponse(webView, identifier, webURLResponse.get(), getWebDataSource(loader)); } void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length) { WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return; resourceLoadDelegate->didReceiveContentLength(webView, identifier, length, getWebDataSource(loader)); } void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier) { WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return; resourceLoadDelegate->didFinishLoadingFromDataSource(webView, identifier, getWebDataSource(loader)); } void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error) { WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return; COMPtr webError(AdoptCOM, WebError::createInstance(error)); resourceLoadDelegate->didFailLoadingWithError(webView, identifier, webError.get(), getWebDataSource(loader)); } bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const unsigned char* data, const unsigned long long length) { WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return true; COMPtr resourceLoadDelegatePrivate(Query, resourceLoadDelegate); if (!resourceLoadDelegatePrivate) return true; COMPtr urlResponse(AdoptCOM, WebURLResponse::createInstance(response)); BOOL shouldCache; if (SUCCEEDED(resourceLoadDelegatePrivate->shouldCacheResponse(webView, identifier, urlResponse.get(), data, length, getWebDataSource(loader), &shouldCache))) return shouldCache; return true; } void WebFrameLoaderClient::dispatchDidHandleOnloadEvents() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegatePriv; if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv) frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegate; if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidCancelClientRedirect() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegate; if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) frameLoadDelegate->didCancelClientRedirectForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate) { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegate; if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) frameLoadDelegate->willPerformClientRedirectToURL(webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), m_webFrame); } void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegate; if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidPushStateWithinPage() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegatePriv; if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) return; COMPtr frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); if (!frameLoadDelegatePriv2) return; frameLoadDelegatePriv2->didPushStateWithinPageForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegatePriv; if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) return; COMPtr frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); if (!frameLoadDelegatePriv2) return; frameLoadDelegatePriv2->didReplaceStateWithinPageForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidPopStateWithinPage() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegatePriv; if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) return; COMPtr frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); if (!frameLoadDelegatePriv2) return; frameLoadDelegatePriv2->didPopStateWithinPageForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchWillClose() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegate; if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) frameLoadDelegate->willCloseFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidReceiveIcon() { m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame); } void WebFrameLoaderClient::dispatchDidStartProvisionalLoad() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegate; if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title) { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegate; if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) frameLoadDelegate->didReceiveTitle(webView, BString(title), m_webFrame); } void WebFrameLoaderClient::dispatchDidChangeIcons() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegatePriv; if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) return; COMPtr frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); if (!frameLoadDelegatePriv2) return; frameLoadDelegatePriv2->didChangeIcons(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidCommitLoad() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegate; if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidFinishDocumentLoad() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegatePriv; if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv) frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidFinishLoad() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegate; if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate))) frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidFirstLayout() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegatePriv; if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv) frameLoadDelegatePriv->didFirstLayoutInFrame(webView, m_webFrame); } void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegatePrivate; if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate) frameLoadDelegatePrivate->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame); } Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&) { WebView* webView = m_webFrame->webView(); COMPtr ui; if (FAILED(webView->uiDelegate(&ui))) return 0; COMPtr newWebView; if (FAILED(ui->createWebViewWithRequest(webView, 0, &newWebView))) return 0; COMPtr mainFrame; if (FAILED(newWebView->mainFrame(&mainFrame))) return 0; COMPtr mainFrameImpl(Query, mainFrame); return core(mainFrameImpl.get()); } void WebFrameLoaderClient::dispatchShow() { WebView* webView = m_webFrame->webView(); COMPtr ui; if (SUCCEEDED(webView->uiDelegate(&ui))) ui->webViewShow(webView); } void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*) { } void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error) { if (!m_manualLoader) return; m_manualLoader->didFail(error); m_manualLoader = 0; m_hasSentResponseToPlugin = false; } void WebFrameLoaderClient::postProgressStartedNotification() { static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification); IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal(); notifyCenter->postNotificationName(progressStartedName, static_cast(m_webFrame->webView()), 0); } void WebFrameLoaderClient::postProgressEstimateChangedNotification() { static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification); IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal(); notifyCenter->postNotificationName(progressEstimateChangedName, static_cast(m_webFrame->webView()), 0); } void WebFrameLoaderClient::postProgressFinishedNotification() { static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification); IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal(); notifyCenter->postNotificationName(progressFinishedName, static_cast(m_webFrame->webView()), 0); } void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length) { if (!m_manualLoader) loader->commitData(data, length); // If the document is a stand-alone media document, now is the right time to cancel the WebKit load. // FIXME: This code should be shared across all ports. . Frame* coreFrame = core(m_webFrame); if (coreFrame->document()->isMediaDocument()) loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response())); if (!m_manualLoader) return; if (!m_hasSentResponseToPlugin) { m_manualLoader->didReceiveResponse(loader->response()); // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader // to null if (!m_manualLoader) return; m_hasSentResponseToPlugin = true; } m_manualLoader->didReceiveData(data, length); } void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader) { // Telling the frame we received some data and passing 0 as the data is our // way to get work done that is normally done when the first bit of data is // received, even for the case of a document with no data (like about:blank) committedLoad(loader, 0, 0); if (!m_manualLoader) return; m_manualLoader->didFinishLoading(); m_manualLoader = 0; m_hasSentResponseToPlugin = false; } void WebFrameLoaderClient::updateGlobalHistory() { DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader(); WebView* webView = m_webFrame->webView(); COMPtr historyDelegate; webView->historyDelegate(&historyDelegate); if (historyDelegate) { COMPtr urlResponse(AdoptCOM, WebURLResponse::createInstance(loader->response())); COMPtr urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(loader->originalRequestCopy())); COMPtr navigationData(AdoptCOM, WebNavigationData::createInstance( loader->urlForHistory(), loader->title(), urlRequest.get(), urlResponse.get(), loader->substituteData().isValid(), loader->clientRedirectSourceForHistory())); historyDelegate->didNavigateWithNavigationData(webView, navigationData.get(), m_webFrame); return; } WebHistory* history = WebHistory::sharedHistory(); if (!history) return; history->visitedURL(loader->urlForHistory(), loader->title(), loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure(), !loader->clientRedirectSourceForHistory()); } void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks() { WebView* webView = m_webFrame->webView(); COMPtr historyDelegate; webView->historyDelegate(&historyDelegate); WebHistory* history = WebHistory::sharedHistory(); DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader(); ASSERT(loader->unreachableURL().isEmpty()); if (!loader->clientRedirectSourceForHistory().isNull()) { if (historyDelegate) { BString sourceURL(loader->clientRedirectSourceForHistory()); BString destURL(loader->clientRedirectDestinationForHistory()); historyDelegate->didPerformClientRedirectFromURL(webView, sourceURL, destURL, m_webFrame); } else { if (history) { if (COMPtr iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) { COMPtr webHistoryItem(Query, iWebHistoryItem); webHistoryItem->historyItem()->addRedirectURL(loader->clientRedirectDestinationForHistory()); } } } } if (!loader->serverRedirectSourceForHistory().isNull()) { if (historyDelegate) { BString sourceURL(loader->serverRedirectSourceForHistory()); BString destURL(loader->serverRedirectDestinationForHistory()); historyDelegate->didPerformServerRedirectFromURL(webView, sourceURL, destURL, m_webFrame); } else { if (history) { if (COMPtr iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) { COMPtr webHistoryItem(Query, iWebHistoryItem); webHistoryItem->historyItem()->addRedirectURL(loader->serverRedirectDestinationForHistory()); } } } } } bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const { return true; } void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const { } void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const { } void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const { } void WebFrameLoaderClient::didDisplayInsecureContent() { WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegatePriv; if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) return; COMPtr frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); if (!frameLoadDelegatePriv2) return; frameLoadDelegatePriv2->didDisplayInsecureContent(webView); } void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin, const KURL& insecureURL) { COMPtr webSecurityOrigin = WebSecurityOrigin::createInstance(origin); WebView* webView = m_webFrame->webView(); COMPtr frameLoadDelegatePriv; if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv) return; COMPtr frameLoadDelegatePriv2(Query, frameLoadDelegatePriv); if (!frameLoadDelegatePriv2) return; frameLoadDelegatePriv2->didRunInsecureContent(webView, webSecurityOrigin.get()); } PassRefPtr WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData) { RefPtr loader = WebDocumentLoader::create(request, substituteData); COMPtr dataSource(AdoptCOM, WebDataSource::createInstance(loader.get())); loader->setDataSource(dataSource.get()); return loader.release(); } void WebFrameLoaderClient::setTitle(const String& title, const KURL& url) { WebView* webView = m_webFrame->webView(); COMPtr historyDelegate; webView->historyDelegate(&historyDelegate); if (historyDelegate) { BString titleBSTR(title); BString urlBSTR(url.string()); historyDelegate->updateHistoryTitle(webView, titleBSTR, urlBSTR); return; } BOOL privateBrowsingEnabled = FALSE; COMPtr preferences; if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences))) preferences->privateBrowsingEnabled(&privateBrowsingEnabled); if (privateBrowsingEnabled) return; // update title in global history COMPtr history = webHistory(); if (!history) return; COMPtr item; if (FAILED(history->itemForURL(BString(url.string()), &item))) return; COMPtr itemPrivate(Query, item); if (!itemPrivate) return; itemPrivate->setTitle(BString(title)); } void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame) { #if USE(CFNETWORK) Frame* coreFrame = core(m_webFrame); if (!coreFrame) return; ASSERT(coreFrame->loader()->documentLoader() == cachedFrame->documentLoader()); WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData(static_cast(getWebDataSource(coreFrame->loader()->documentLoader()))); cachedFrame->setCachedFramePlatformData(webPlatformData); #else notImplemented(); #endif } void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*) { } void WebFrameLoaderClient::transitionToCommittedForNewPage() { WebView* view = m_webFrame->webView(); RECT rect; view->frameRect(&rect); bool transparent = view->transparent(); Color backgroundColor = transparent ? Color::transparent : Color::white; core(m_webFrame)->createView(IntRect(rect).size(), backgroundColor, transparent, IntSize(), false); } void WebFrameLoaderClient::didSaveToPageCache() { } void WebFrameLoaderClient::didRestoreFromPageCache() { } void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool) { } bool WebFrameLoaderClient::canCachePage() const { return true; } PassRefPtr WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/) { RefPtr result = createFrame(url, name, ownerElement, referrer); if (!result) return 0; return result.release(); } void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*) { Frame* coreFrame = core(m_webFrame); ASSERT(coreFrame); WebView* webView = kit(coreFrame->page()); if (m_webFrame->webView() != webView) m_webFrame->setWebView(webView); } void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request, Page* oldPage) { assignIdentifierToInitialRequest(identifier, loader, request); WebView* oldWebView = kit(oldPage); if (!oldWebView) return; COMPtr oldResourceLoadDelegate; if (FAILED(oldWebView->resourceLoadDelegate(&oldResourceLoadDelegate))) return; COMPtr oldResourceLoadDelegatePrivate2(Query, oldResourceLoadDelegate); if (!oldResourceLoadDelegatePrivate2) return; oldResourceLoadDelegatePrivate2->removeIdentifierForRequest(oldWebView, identifier); } PassRefPtr WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer) { Frame* coreFrame = core(m_webFrame); ASSERT(coreFrame); COMPtr webFrame(AdoptCOM, WebFrame::createInstance()); RefPtr childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement); childFrame->tree()->setName(name); coreFrame->tree()->appendChild(childFrame); childFrame->init(); coreFrame->loader()->loadURLIntoChildFrame(URL, referrer, childFrame.get()); // The frame's onload handler may have removed it from the document. if (!childFrame->tree()->parent()) return 0; return childFrame.release(); } void WebFrameLoaderClient::dispatchDidFailToStartPlugin(const PluginView* pluginView) const { WebView* webView = m_webFrame->webView(); COMPtr resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return; RetainPtr userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); Frame* frame = core(m_webFrame); ASSERT(frame == pluginView->parentFrame()); if (!pluginView->pluginsPage().isNull()) { KURL pluginPageURL = frame->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(pluginView->pluginsPage())); if (pluginPageURL.protocolInHTTPFamily()) { static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey); RetainPtr str(AdoptCF, pluginPageURL.string().createCFString()); CFDictionarySetValue(userInfo.get(), key, str.get()); } } if (!pluginView->mimeType().isNull()) { static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey); RetainPtr str(AdoptCF, pluginView->mimeType().createCFString()); CFDictionarySetValue(userInfo.get(), key, str.get()); } if (pluginView->plugin()) { String pluginName = pluginView->plugin()->name(); if (!pluginName.isNull()) { static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey); RetainPtr str(AdoptCF, pluginName.createCFString()); CFDictionarySetValue(userInfo.get(), key, str.get()); } } COMPtr userInfoBag = CFDictionaryPropertyBag::createInstance(); userInfoBag->setDictionary(userInfo.get()); int errorCode = 0; switch (pluginView->status()) { case PluginStatusCanNotFindPlugin: errorCode = WebKitErrorCannotFindPlugIn; break; case PluginStatusCanNotLoadPlugin: errorCode = WebKitErrorCannotLoadPlugIn; break; default: ASSERT_NOT_REACHED(); } ResourceError resourceError(String(WebKitErrorDomain), errorCode, pluginView->url().string(), String()); COMPtr error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get())); resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader())); } PassRefPtr WebFrameLoaderClient::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector& paramNames, const Vector& paramValues, const String& mimeType, bool loadManually) { WebView* webView = m_webFrame->webView(); COMPtr ui; if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) { COMPtr uiPrivate(Query, ui); if (uiPrivate) { // Assemble the view arguments in a property bag. HashMap viewArguments; for (unsigned i = 0; i < paramNames.size(); i++) viewArguments.set(paramNames[i], paramValues[i]); COMPtr viewArgumentsBag(AdoptCOM, COMPropertyBag::adopt(viewArguments)); COMPtr containingElement(AdoptCOM, DOMElement::createInstance(element)); HashMap arguments; arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag); arguments.set(WebEmbeddedViewBaseURLKey, url.string()); arguments.set(WebEmbeddedViewContainingElementKey, containingElement); arguments.set(WebEmbeddedViewMIMETypeKey, mimeType); COMPtr argumentsBag(AdoptCOM, COMPropertyBag::adopt(arguments)); COMPtr view; HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view); if (SUCCEEDED(result)) { HWND parentWindow; HRESULT hr = webView->viewWindow((OLE_HANDLE*)&parentWindow); ASSERT(SUCCEEDED(hr)); return EmbeddedWidget::create(view.get(), element, parentWindow, pluginSize); } } } Frame* frame = core(m_webFrame); RefPtr pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually); if (pluginView->status() == PluginStatusLoadedSuccessfully) return pluginView; dispatchDidFailToStartPlugin(pluginView.get()); return 0; } void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget) { // Ideally, this function shouldn't be necessary, see if (pluginWidget->isPluginView()) m_manualLoader = static_cast(pluginWidget); else m_manualLoader = static_cast(pluginWidget); } WebHistory* WebFrameLoaderClient::webHistory() const { if (m_webFrame != m_webFrame->webView()->topLevelFrame()) return 0; return WebHistory::sharedHistory(); } bool WebFrameLoaderClient::shouldUsePluginDocument(const String& mimeType) const { WebView* webView = m_webFrame->webView(); if (!webView) return false; return webView->shouldUseEmbeddedView(mimeType); }