summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp')
-rw-r--r--Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp930
1 files changed, 930 insertions, 0 deletions
diff --git a/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp b/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp
new file mode 100644
index 0000000..7fd2b98
--- /dev/null
+++ b/Source/WebKit/win/WebCoreSupport/WebFrameLoaderClient.cpp
@@ -0,0 +1,930 @@
+/*
+ * 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 <WebCore/CachedFrame.h>
+#include <WebCore/DocumentLoader.h>
+#include <WebCore/FrameLoader.h>
+#include <WebCore/FrameTree.h>
+#include <WebCore/FrameView.h>
+#include <WebCore/HTMLAppletElement.h>
+#include <WebCore/HTMLFrameElement.h>
+#include <WebCore/HTMLFrameOwnerElement.h>
+#include <WebCore/HTMLNames.h>
+#include <WebCore/HTMLParserIdioms.h>
+#include <WebCore/HTMLPlugInElement.h>
+#include <WebCore/HistoryItem.h>
+#include <WebCore/Page.h>
+#include <WebCore/PluginPackage.h>
+#include <WebCore/PluginView.h>
+#include <WebCore/RenderPart.h>
+#include <WebCore/ResourceHandle.h>
+#pragma warning(pop)
+
+using namespace WebCore;
+using namespace HTMLNames;
+
+static WebDataSource* getWebDataSource(DocumentLoader* loader)
+{
+ return loader ? static_cast<WebDocumentLoader*>(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<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ COMPtr<WebMutableURLRequest> 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<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return true;
+
+ COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate;
+ if (FAILED(resourceLoadDelegate->QueryInterface(IID_IWebResourceLoadDelegatePrivate, reinterpret_cast<void**>(&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<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (SUCCEEDED(webView->resourceLoadDelegate(&resourceLoadDelegate))) {
+ COMPtr<WebURLAuthenticationChallenge> 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<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ COMPtr<WebURLAuthenticationChallenge> 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<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
+ COMPtr<WebURLResponse> webURLRedirectResponse(AdoptCOM, WebURLResponse::createInstance(redirectResponse));
+
+ COMPtr<IWebURLRequest> 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<WebMutableURLRequest> 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<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ COMPtr<WebURLResponse> 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<IWebResourceLoadDelegate> 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<IWebResourceLoadDelegate> 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<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ COMPtr<WebError> 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<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return true;
+
+ COMPtr<IWebResourceLoadDelegatePrivate> resourceLoadDelegatePrivate(Query, resourceLoadDelegate);
+ if (!resourceLoadDelegatePrivate)
+ return true;
+
+ COMPtr<IWebURLResponse> 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<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
+ frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> 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<IWebFrameLoadDelegate> 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<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
+ return;
+
+ COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
+ if (!frameLoadDelegatePriv2)
+ return;
+
+ frameLoadDelegatePriv2->didPushStateWithinPageForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
+ return;
+
+ COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
+ if (!frameLoadDelegatePriv2)
+ return;
+
+ frameLoadDelegatePriv2->didReplaceStateWithinPageForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
+ return;
+
+ COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
+ if (!frameLoadDelegatePriv2)
+ return;
+
+ frameLoadDelegatePriv2->didPopStateWithinPageForFrame(webView, m_webFrame);
+}
+void WebFrameLoaderClient::dispatchWillClose()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> 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<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title)
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didReceiveTitle(webView, BString(title), m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidChangeIcons()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
+ return;
+
+ COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
+ if (!frameLoadDelegatePriv2)
+ return;
+
+ frameLoadDelegatePriv2->didChangeIcons(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidCommitLoad()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
+ frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidFinishLoad()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidFirstLayout()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
+ frameLoadDelegatePriv->didFirstLayoutInFrame(webView, m_webFrame);
+}
+
+void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
+ if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate)
+ frameLoadDelegatePrivate->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame);
+}
+
+Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction&)
+{
+ WebView* webView = m_webFrame->webView();
+
+ COMPtr<IWebUIDelegate> ui;
+ if (FAILED(webView->uiDelegate(&ui)))
+ return 0;
+
+ COMPtr<IWebView> newWebView;
+ if (FAILED(ui->createWebViewWithRequest(webView, 0, &newWebView)))
+ return 0;
+
+ COMPtr<IWebFrame> mainFrame;
+ if (FAILED(newWebView->mainFrame(&mainFrame)))
+ return 0;
+
+ COMPtr<WebFrame> mainFrameImpl(Query, mainFrame);
+ return core(mainFrameImpl.get());
+}
+
+void WebFrameLoaderClient::dispatchShow()
+{
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebUIDelegate> 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<IWebView*>(m_webFrame->webView()), 0);
+}
+
+void WebFrameLoaderClient::postProgressEstimateChangedNotification()
+{
+ static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
+ IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+ notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
+}
+
+void WebFrameLoaderClient::postProgressFinishedNotification()
+{
+ static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
+ IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+ notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(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. <http://webkit.org/b/48762>.
+ 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<IWebHistoryDelegate> historyDelegate;
+ webView->historyDelegate(&historyDelegate);
+
+ if (historyDelegate) {
+ COMPtr<IWebURLResponse> urlResponse(AdoptCOM, WebURLResponse::createInstance(loader->response()));
+ COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(loader->originalRequestCopy()));
+
+ COMPtr<IWebNavigationData> 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<IWebHistoryDelegate> 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> iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) {
+ COMPtr<WebHistoryItem> 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> iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) {
+ COMPtr<WebHistoryItem> 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<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
+ return;
+
+ COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
+ if (!frameLoadDelegatePriv2)
+ return;
+
+ frameLoadDelegatePriv2->didDisplayInsecureContent(webView);
+}
+
+void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin)
+{
+ COMPtr<IWebSecurityOrigin> webSecurityOrigin = WebSecurityOrigin::createInstance(origin);
+
+ WebView* webView = m_webFrame->webView();
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (FAILED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) || !frameLoadDelegatePriv)
+ return;
+
+ COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePriv2(Query, frameLoadDelegatePriv);
+ if (!frameLoadDelegatePriv2)
+ return;
+
+ frameLoadDelegatePriv2->didRunInsecureContent(webView, webSecurityOrigin.get());
+}
+
+PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
+{
+ RefPtr<WebDocumentLoader> loader = WebDocumentLoader::create(request, substituteData);
+
+ COMPtr<WebDataSource> 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<IWebHistoryDelegate> historyDelegate;
+ webView->historyDelegate(&historyDelegate);
+ if (historyDelegate) {
+ BString titleBSTR(title);
+ BString urlBSTR(url.string());
+ historyDelegate->updateHistoryTitle(webView, titleBSTR, urlBSTR);
+ return;
+ }
+
+ BOOL privateBrowsingEnabled = FALSE;
+ COMPtr<IWebPreferences> preferences;
+ if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences)))
+ preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
+ if (privateBrowsingEnabled)
+ return;
+
+ // update title in global history
+ COMPtr<WebHistory> history = webHistory();
+ if (!history)
+ return;
+
+ COMPtr<IWebHistoryItem> item;
+ if (FAILED(history->itemForURL(BString(url.string()), &item)))
+ return;
+
+ COMPtr<IWebHistoryItemPrivate> 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<IWebDataSource*>(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<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
+ const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
+{
+ RefPtr<Frame> 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<IWebResourceLoadDelegate> oldResourceLoadDelegate;
+ if (FAILED(oldWebView->resourceLoadDelegate(&oldResourceLoadDelegate)))
+ return;
+
+ COMPtr<IWebResourceLoadDelegatePrivate2> oldResourceLoadDelegatePrivate2(Query, oldResourceLoadDelegate);
+ if (!oldResourceLoadDelegatePrivate2)
+ return;
+ oldResourceLoadDelegatePrivate2->removeIdentifierForRequest(oldWebView, identifier);
+}
+
+PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
+{
+ Frame* coreFrame = core(m_webFrame);
+ ASSERT(coreFrame);
+
+ COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance());
+
+ RefPtr<Frame> 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<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return;
+
+ RetainPtr<CFMutableDictionaryRef> 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<CFStringRef> str(AdoptCF, pluginPageURL.string().createCFString());
+ CFDictionarySetValue(userInfo.get(), key, str.get());
+ }
+ }
+
+ if (!pluginView->mimeType().isNull()) {
+ static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
+
+ RetainPtr<CFStringRef> 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<CFStringRef> str(AdoptCF, pluginName.createCFString());
+ CFDictionarySetValue(userInfo.get(), key, str.get());
+ }
+ }
+
+ COMPtr<CFDictionaryPropertyBag> 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<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
+
+ resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader()));
+}
+
+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)
+{
+ WebView* webView = m_webFrame->webView();
+
+ COMPtr<IWebUIDelegate> ui;
+ if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
+ COMPtr<IWebUIDelegatePrivate> uiPrivate(Query, ui);
+
+ if (uiPrivate) {
+ // Assemble the view arguments in a property bag.
+ HashMap<String, String> viewArguments;
+ for (unsigned i = 0; i < paramNames.size(); i++)
+ viewArguments.set(paramNames[i], paramValues[i]);
+ COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
+ COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(element));
+
+ HashMap<String, COMVariant> arguments;
+
+ arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag);
+ arguments.set(WebEmbeddedViewBaseURLKey, url.string());
+ arguments.set(WebEmbeddedViewContainingElementKey, containingElement);
+ arguments.set(WebEmbeddedViewMIMETypeKey, mimeType);
+
+ COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments));
+
+ COMPtr<IWebEmbeddedView> 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 = 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 <rdar://problem/4852889>
+
+ if (pluginWidget->isPluginView())
+ m_manualLoader = static_cast<PluginView*>(pluginWidget);
+ else
+ m_manualLoader = static_cast<EmbeddedWidget*>(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);
+}