summaryrefslogtreecommitdiffstats
path: root/WebKit/win/WebFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/win/WebFrame.cpp')
-rw-r--r--WebKit/win/WebFrame.cpp968
1 files changed, 951 insertions, 17 deletions
diff --git a/WebKit/win/WebFrame.cpp b/WebKit/win/WebFrame.cpp
index 0a87263..ebaa7b3 100644
--- a/WebKit/win/WebFrame.cpp
+++ b/WebKit/win/WebFrame.cpp
@@ -31,9 +31,16 @@
#include "COMPtr.h"
#include "DefaultPolicyDelegate.h"
#include "DOMCoreClasses.h"
-#include "FormValuesPropertyBag.h"
+#include "IWebError.h"
+#include "IWebErrorPrivate.h"
+#include "IWebHistory.h"
+#include "IWebHistoryItemPrivate.h"
+#include "IWebFrameLoadDelegatePrivate.h"
+#include "IWebFormDelegate.h"
+#include "IWebUIDelegatePrivate.h"
#include "MarshallingHelpers.h"
#include "WebActionPropertyBag.h"
+#include "WebCachedPagePlatformData.h"
#include "WebChromeClient.h"
#include "WebDocumentLoader.h"
#include "WebDownload.h"
@@ -50,8 +57,10 @@
#include "WebHistoryItem.h"
#include "WebScriptDebugger.h"
#include "WebScriptDebugServer.h"
+#include "WebURLAuthenticationChallenge.h"
#include "WebURLResponse.h"
#pragma warning( push, 0 )
+#include <WebCore/AuthenticationChallenge.h>
#include <WebCore/BString.h>
#include <WebCore/Cache.h>
#include <WebCore/Document.h>
@@ -122,6 +131,12 @@ const float PrintingMinimumShrinkFactor = 1.25f;
// behavior matches MacIE and Mozilla, at least)
const float PrintingMaximumShrinkFactor = 2.0f;
+
+// {A3676398-4485-4a9d-87DC-CB5A40E6351D}
+const GUID IID_WebFrame =
+{ 0xa3676398, 0x4485, 0x4a9d, { 0x87, 0xdc, 0xcb, 0x5a, 0x40, 0xe6, 0x35, 0x1d } };
+
+
//-----------------------------------------------------------------------------
// Helpers to convert from WebCore to WebKit type
WebFrame* kit(Frame* frame)
@@ -150,6 +165,202 @@ Frame* core(const WebFrame* webFrame)
return const_cast<WebFrame*>(webFrame)->impl();
}
+WebView* kit(Page* page)
+{
+ return page ? static_cast<WebChromeClient*>(page->chrome()->client())->webView() : 0;
+}
+
+//-----------------------------------------------------------------------------
+
+class FormValuesPropertyBag : public IPropertyBag, public IPropertyBag2
+{
+public:
+ FormValuesPropertyBag(HashMap<String, String>* formValues) : m_formValues(formValues) {}
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IPropertyBag
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE Read(
+ /* [in] */ LPCOLESTR pszPropName,
+ /* [out][in] */ VARIANT* pVar,
+ /* [in] */ IErrorLog* pErrorLog);
+
+ virtual HRESULT STDMETHODCALLTYPE Write(
+ /* [in] */ LPCOLESTR pszPropName,
+ /* [in] */ VARIANT* pVar);
+
+ // IPropertyBag2
+ virtual HRESULT STDMETHODCALLTYPE Read(
+ /* [in] */ ULONG cProperties,
+ /* [in] */ PROPBAG2 *pPropBag,
+ /* [in] */ IErrorLog *pErrLog,
+ /* [out] */ VARIANT *pvarValue,
+ /* [out] */ HRESULT *phrError);
+
+ virtual HRESULT STDMETHODCALLTYPE Write(
+ /* [in] */ ULONG cProperties,
+ /* [in] */ PROPBAG2 *pPropBag,
+ /* [in] */ VARIANT *pvarValue);
+
+ virtual HRESULT STDMETHODCALLTYPE CountProperties(
+ /* [out] */ ULONG *pcProperties);
+
+ virtual HRESULT STDMETHODCALLTYPE GetPropertyInfo(
+ /* [in] */ ULONG iProperty,
+ /* [in] */ ULONG cProperties,
+ /* [out] */ PROPBAG2 *pPropBag,
+ /* [out] */ ULONG *pcProperties);
+
+ virtual HRESULT STDMETHODCALLTYPE LoadObject(
+ /* [in] */ LPCOLESTR pstrName,
+ /* [in] */ DWORD dwHint,
+ /* [in] */ IUnknown *pUnkObject,
+ /* [in] */ IErrorLog *pErrLog);
+
+protected:
+ HashMap<String, String>* m_formValues;
+};
+
+HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::QueryInterface(REFIID riid, void** ppvObject)
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = this;
+ else if (IsEqualGUID(riid, IID_IPropertyBag))
+ *ppvObject = static_cast<IPropertyBag*>(this);
+ else if (IsEqualGUID(riid, IID_IPropertyBag2))
+ *ppvObject = static_cast<IPropertyBag2*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE FormValuesPropertyBag::AddRef(void)
+{
+ return 1;
+}
+
+ULONG STDMETHODCALLTYPE FormValuesPropertyBag::Release(void)
+{
+ return 0;
+}
+
+HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* /*pErrorLog*/)
+{
+ HRESULT hr = S_OK;
+
+ if (!pszPropName || !pVar)
+ return E_POINTER;
+
+ String key(pszPropName);
+ if (!m_formValues->contains(key))
+ return E_INVALIDARG;
+
+ String value = m_formValues->get(key);
+
+ VARTYPE requestedType = V_VT(pVar);
+ VariantClear(pVar);
+ V_VT(pVar) = VT_BSTR;
+ V_BSTR(pVar) = SysAllocStringLen(value.characters(), value.length());
+ if (value.length() && !V_BSTR(pVar))
+ return E_OUTOFMEMORY;
+
+ if (requestedType != VT_BSTR && requestedType != VT_EMPTY)
+ hr = VariantChangeType(pVar, pVar, VARIANT_NOUSEROVERRIDE | VARIANT_ALPHABOOL, requestedType);
+
+ return hr;
+}
+
+HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar)
+{
+ if (!pszPropName || !pVar)
+ return E_POINTER;
+ VariantClear(pVar);
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Read(
+ /* [in] */ ULONG cProperties,
+ /* [in] */ PROPBAG2* pPropBag,
+ /* [in] */ IErrorLog* pErrLog,
+ /* [out] */ VARIANT* pvarValue,
+ /* [out] */ HRESULT* phrError)
+{
+ if (cProperties > (size_t)m_formValues->size())
+ return E_INVALIDARG;
+ if (!pPropBag || !pvarValue || !phrError)
+ return E_POINTER;
+
+ for (ULONG i=0; i<cProperties; i++) {
+ VariantInit(&pvarValue[i]);
+ phrError[i] = Read(pPropBag->pstrName, &pvarValue[i], pErrLog);
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Write(
+ /* [in] */ ULONG /*cProperties*/,
+ /* [in] */ PROPBAG2* pPropBag,
+ /* [in] */ VARIANT* pvarValue)
+{
+ if (!pPropBag || !pvarValue)
+ return E_POINTER;
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::CountProperties(
+ /* [out] */ ULONG* pcProperties)
+{
+ *pcProperties = m_formValues->size();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::GetPropertyInfo(
+ /* [in] */ ULONG iProperty,
+ /* [in] */ ULONG cProperties,
+ /* [out] */ PROPBAG2* pPropBag,
+ /* [out] */ ULONG* pcProperties)
+{
+ if (iProperty > (size_t)m_formValues->size() || iProperty+cProperties > (size_t)m_formValues->size())
+ return E_INVALIDARG;
+ if (!pPropBag || !pcProperties)
+ return E_POINTER;
+
+ *pcProperties = 0;
+ ULONG i = 0;
+ ULONG endProperty = iProperty + cProperties;
+ for (HashMap<String, String>::iterator it = m_formValues->begin(); i<endProperty; i++) {
+ if (i >= iProperty) {
+ int storeIndex = (*pcProperties)++;
+ pPropBag[storeIndex].dwType = PROPBAG2_TYPE_DATA;
+ pPropBag[storeIndex].vt = VT_BSTR;
+ pPropBag[storeIndex].cfType = CF_TEXT;
+ pPropBag[storeIndex].dwHint = 0;
+ pPropBag[storeIndex].pstrName = const_cast<LPOLESTR>(it->first.charactersWithNullTermination());
+ }
+ ++it;
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::LoadObject(
+ /* [in] */ LPCOLESTR pstrName,
+ /* [in] */ DWORD /*dwHint*/,
+ /* [in] */ IUnknown* pUnkObject,
+ /* [in] */ IErrorLog* /*pErrLog*/)
+{
+ if (!pstrName || !pUnkObject)
+ return E_POINTER;
+ return E_FAIL;
+}
+
//-----------------------------------------------------------------------------
static Element *elementFromDOMElement(IDOMElement *element)
@@ -210,6 +421,8 @@ public:
: frame(0)
, webView(0)
, m_policyFunction(0)
+ , m_pluginView(0)
+ , m_hasSentResponseToPlugin(false)
{
}
@@ -220,13 +433,16 @@ public:
WebView* webView;
FramePolicyFunction m_policyFunction;
COMPtr<WebFramePolicyListener> m_policyListener;
+
+ // Points to the plugin view that data should be redirected to.
+ PluginView* m_pluginView;
+ bool m_hasSentResponseToPlugin;
};
// WebFrame ----------------------------------------------------------------
WebFrame::WebFrame()
- : WebFrameLoaderClient(this)
- , m_refCount(0)
+ : m_refCount(0)
, d(new WebFrame::WebFramePrivate)
, m_quickRedirectComing(false)
, m_inPrintingMode(false)
@@ -278,7 +494,7 @@ HRESULT STDMETHODCALLTYPE WebFrame::allowsScrolling(
HRESULT STDMETHODCALLTYPE WebFrame::QueryInterface(REFIID riid, void** ppvObject)
{
*ppvObject = 0;
- if (IsEqualGUID(riid, __uuidof(WebFrame)))
+ if (IsEqualGUID(riid, IID_WebFrame))
*ppvObject = this;
else if (IsEqualGUID(riid, IID_IUnknown))
*ppvObject = static_cast<IWebFrame*>(this);
@@ -421,8 +637,8 @@ void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, B
mimeTypeString = "text/html";
String encodingString(textEncodingName, SysStringLen(textEncodingName));
- KURL baseKURL(String(baseURL ? baseURL : L"", SysStringLen(baseURL)));
- KURL failingKURL(String(failingURL, SysStringLen(failingURL)));
+ KURL baseKURL = DeprecatedString((DeprecatedChar*)baseURL, SysStringLen(baseURL));
+ KURL failingKURL = DeprecatedString((DeprecatedChar*)failingURL, SysStringLen(failingURL));
ResourceRequest request(baseKURL);
SubstituteData substituteData(data, mimeTypeString, encodingString, failingKURL);
@@ -716,14 +932,21 @@ HRESULT STDMETHODCALLTYPE WebFrame::childFrames(
HRESULT STDMETHODCALLTYPE WebFrame::renderTreeAsExternalRepresentation(
/* [retval][out] */ BSTR *result)
{
- if (!result)
+ if (!result) {
+ ASSERT_NOT_REACHED();
return E_POINTER;
+ }
+
+ *result = 0;
Frame* coreFrame = core(this);
if (!coreFrame)
return E_FAIL;
- *result = BString(externalRepresentation(coreFrame->renderer())).release();
+ DeprecatedString representation = externalRepresentation(coreFrame->renderer());
+
+ *result = SysAllocStringLen((LPCOLESTR)representation.unicode(), representation.length());
+
return S_OK;
}
@@ -1079,6 +1302,18 @@ HRESULT WebFrame::canProvideDocumentSource(bool* result)
return hr;
}
+// FrameWinClient
+
+void WebFrame::ref()
+{
+ this->AddRef();
+}
+
+void WebFrame::deref()
+{
+ this->Release();
+}
+
void WebFrame::frameLoaderDestroyed()
{
// The FrameLoader going away is equivalent to the Frame going away,
@@ -1088,11 +1323,180 @@ void WebFrame::frameLoaderDestroyed()
this->Release();
}
+PassRefPtr<Frame> WebFrame::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
+{
+ Frame* coreFrame = core(this);
+ ASSERT(coreFrame);
+
+ COMPtr<WebFrame> webFrame;
+ webFrame.adoptRef(WebFrame::createInstance());
+
+ webFrame->initWithWebFrameView(0, d->webView, coreFrame->page(), ownerElement);
+
+ RefPtr<Frame> childFrame(adoptRef(core(webFrame.get()))); // We have to adopt, because Frames start out with a refcount of 1.
+ ASSERT(childFrame);
+
+ coreFrame->tree()->appendChild(childFrame);
+ childFrame->tree()->setName(name);
+ childFrame->init();
+
+ loadURLIntoChild(URL, referrer, webFrame.get());
+
+ // The frame's onload handler may have removed it from the document.
+ if (!childFrame->tree()->parent())
+ return 0;
+
+ return childFrame.release();
+}
+
+void WebFrame::loadURLIntoChild(const KURL& originalURL, const String& referrer, WebFrame* childFrame)
+{
+ ASSERT(childFrame);
+ ASSERT(core(childFrame));
+
+ Frame* coreFrame = core(this);
+ ASSERT(coreFrame);
+
+ HistoryItem* parentItem = coreFrame->loader()->currentHistoryItem();
+ FrameLoadType loadType = coreFrame->loader()->loadType();
+ FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
+
+ KURL url = originalURL;
+
+ // If we're moving in the backforward list, we might want to replace the content
+ // of this child frame with whatever was there at that point.
+ // Reload will maintain the frame contents, LoadSame will not.
+ if (parentItem && parentItem->children().size() &&
+ (isBackForwardLoadType(loadType)
+ || loadType == FrameLoadTypeReload
+ || loadType == FrameLoadTypeReloadAllowingStaleData))
+ {
+ if (HistoryItem* childItem = parentItem->childItemWithName(core(childFrame)->tree()->name())) {
+ // Use the original URL to ensure we get all the side-effects, such as
+ // onLoad handlers, of any redirects that happened. An example of where
+ // this is needed is Radar 3213556.
+ url = childItem->originalURLString().deprecatedString();
+ // These behaviors implied by these loadTypes should apply to the child frames
+ childLoadType = loadType;
+
+ if (isBackForwardLoadType(loadType))
+ // For back/forward, remember this item so we can traverse any child items as child frames load
+ core(childFrame)->loader()->setProvisionalHistoryItem(childItem);
+ else
+ // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item
+ core(childFrame)->loader()->setCurrentHistoryItem(childItem);
+ }
+ }
+
+ // FIXME: Handle loading WebArchives here
+
+ core(childFrame)->loader()->load(url, referrer, childLoadType, String(), 0, 0);
+}
+
+void WebFrame::openURL(const String& URL, const Event* triggeringEvent, bool newWindow, bool lockHistory)
+{
+ bool ctrlPressed = false;
+ bool shiftPressed = false;
+ if (triggeringEvent) {
+ if (triggeringEvent->isMouseEvent()) {
+ const MouseRelatedEvent* mouseEvent = static_cast<const MouseRelatedEvent*>(triggeringEvent);
+ ctrlPressed = mouseEvent->ctrlKey();
+ shiftPressed = mouseEvent->shiftKey();
+ } else if (triggeringEvent->isKeyboardEvent()) {
+ const KeyboardEvent* keyEvent = static_cast<const KeyboardEvent*>(triggeringEvent);
+ ctrlPressed = keyEvent->ctrlKey();
+ shiftPressed = keyEvent->shiftKey();
+ }
+ }
+
+ if (ctrlPressed)
+ newWindow = true;
+
+ BString urlBStr = URL;
+
+ IWebMutableURLRequest* request = WebMutableURLRequest::createInstance();
+ if (FAILED(request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 0)))
+ goto exit;
+
+ if (newWindow) {
+ // new tab/window
+ IWebUIDelegate* ui;
+ IWebView* newWebView;
+ if (SUCCEEDED(d->webView->uiDelegate(&ui)) && ui) {
+ if (SUCCEEDED(ui->createWebViewWithRequest(d->webView, request, &newWebView))) {
+ if (shiftPressed) {
+ // Ctrl-Option-Shift-click: Opens a link in a new window and selects it.
+ // Ctrl-Shift-click: Opens a link in a new tab and selects it.
+ ui->webViewShow(d->webView);
+ }
+ newWebView->Release();
+ newWebView = 0;
+ }
+ ui->Release();
+ }
+ } else {
+ m_quickRedirectComing = lockHistory;
+ loadRequest(request);
+ }
+
+exit:
+ request->Release();
+}
+
+void WebFrame::dispatchDidHandleOnloadEvents()
+{
+ IWebFrameLoadDelegatePrivate* frameLoadDelegatePriv;
+ if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv) {
+ frameLoadDelegatePriv->didHandleOnloadEventsForFrame(d->webView, this);
+ frameLoadDelegatePriv->Release();
+ }
+}
+
+void WebFrame::windowScriptObjectAvailable(JSContextRef context, JSObjectRef windowObject)
+{
+ IWebFrameLoadDelegate* frameLoadDelegate;
+ if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)) && frameLoadDelegate) {
+ frameLoadDelegate->windowScriptObjectAvailable(d->webView, context, windowObject);
+ frameLoadDelegate->Release();
+ }
+}
+
+WebHistory* WebFrame::webHistory()
+{
+ if (this != d->webView->topLevelFrame())
+ return 0;
+
+ IWebHistoryPrivate* historyInternal = WebHistory::optionalSharedHistoryInternal(); // does not add a ref
+ if (!historyInternal)
+ return 0;
+
+ WebHistory* webHistory;
+ if (FAILED(historyInternal->QueryInterface(&webHistory)))
+ return 0;
+
+ return webHistory;
+}
+
+bool WebFrame::hasWebView() const
+{
+ return !!d->webView;
+}
+
+bool WebFrame::hasFrameView() const
+{
+ return !!d->frameView();
+}
+
void WebFrame::makeRepresentation(DocumentLoader*)
{
notImplemented();
}
+void WebFrame::forceLayout()
+{
+ core(this)->forceLayout(true);
+}
+
void WebFrame::forceLayoutForNonHTML()
{
notImplemented();
@@ -1103,6 +1507,11 @@ void WebFrame::setCopiesOnScroll()
notImplemented();
}
+void WebFrame::detachedFromParent1()
+{
+ notImplemented();
+}
+
void WebFrame::detachedFromParent2()
{
notImplemented();
@@ -1118,6 +1527,96 @@ void WebFrame::detachedFromParent4()
notImplemented();
}
+void WebFrame::dispatchDidReceiveServerRedirectForProvisionalLoad()
+{
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(d->webView, this);
+}
+
+void WebFrame::dispatchDidCancelClientRedirect()
+{
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didCancelClientRedirectForFrame(d->webView, this);
+}
+
+void WebFrame::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
+{
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->willPerformClientRedirectToURL(d->webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), this);
+}
+
+void WebFrame::dispatchDidChangeLocationWithinPage()
+{
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didChangeLocationWithinPageForFrame(d->webView, this);
+}
+
+void WebFrame::dispatchWillClose()
+{
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->willCloseFrame(d->webView, this);
+}
+
+void WebFrame::dispatchDidReceiveIcon()
+{
+ d->webView->dispatchDidReceiveIconFromWebFrame(this);
+}
+
+void WebFrame::dispatchDidStartProvisionalLoad()
+{
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didStartProvisionalLoadForFrame(d->webView, this);
+}
+
+void WebFrame::dispatchDidReceiveTitle(const String& title)
+{
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didReceiveTitle(d->webView, BString(title), this);
+}
+
+void WebFrame::dispatchDidCommitLoad()
+{
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didCommitLoadForFrame(d->webView, this);
+}
+
+void WebFrame::dispatchDidFinishDocumentLoad()
+{
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
+ frameLoadDelegatePriv->didFinishDocumentLoadForFrame(d->webView, this);
+}
+
+void WebFrame::dispatchDidFinishLoad()
+{
+ COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
+ if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
+ frameLoadDelegate->didFinishLoadForFrame(d->webView, this);
+}
+
+void WebFrame::dispatchDidFirstLayout()
+{
+ COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
+ if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
+ frameLoadDelegatePriv->didFirstLayoutInFrame(d->webView, this);
+}
+
+void WebFrame::dispatchShow()
+{
+ COMPtr<IWebUIDelegate> ui;
+
+ if (SUCCEEDED(d->webView->uiDelegate(&ui)))
+ ui->webViewShow(d->webView);
+}
+
void WebFrame::cancelPolicyCheck()
{
if (d->m_policyListener) {
@@ -1153,6 +1652,19 @@ void WebFrame::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<F
(coreFrame->loader()->*function)(PolicyUse);
}
+void WebFrame::dispatchDidLoadMainResource(DocumentLoader* loader)
+{
+ if (WebScriptDebugServer::listenerCount() > 0) {
+ Frame* coreFrame = core(this);
+ if (!coreFrame)
+ return;
+
+ WebScriptDebugServer::sharedWebScriptDebugServer()->didLoadMainResourceForDataSource(
+ kit(coreFrame->page()),
+ loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0);
+ }
+}
+
void WebFrame::revertToProvisionalState(DocumentLoader*)
{
notImplemented();
@@ -1178,6 +1690,21 @@ void WebFrame::didChangeTitle(DocumentLoader*)
notImplemented();
}
+void WebFrame::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)
+ if (!d->m_pluginView)
+ committedLoad(loader, 0, 0);
+ else {
+ if (d->m_pluginView->status() == PluginStatusLoadedSuccessfully)
+ d->m_pluginView->didFinishLoading();
+ d->m_pluginView = 0;
+ d->m_hasSentResponseToPlugin = false;
+ }
+}
+
void WebFrame::finalSetupForReplace(DocumentLoader*)
{
notImplemented();
@@ -1264,19 +1791,159 @@ void WebFrame::prepareForDataSourceReplacement()
notImplemented();
}
+void WebFrame::setTitle(const String& title, const KURL& url)
+{
+ BOOL privateBrowsingEnabled = FALSE;
+ COMPtr<IWebPreferences> preferences;
+ if (SUCCEEDED(d->webView->preferences(&preferences)))
+ preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
+ if (!privateBrowsingEnabled) {
+ // update title in global history
+ COMPtr<WebHistory> history;
+ history.adoptRef(webHistory());
+ if (history) {
+ COMPtr<IWebHistoryItem> item;
+ if (SUCCEEDED(history->itemForURL(BString(url.string()), &item))) {
+ COMPtr<IWebHistoryItemPrivate> itemPrivate;
+ if (SUCCEEDED(item->QueryInterface(IID_IWebHistoryItemPrivate, (void**)&itemPrivate)))
+ itemPrivate->setTitle(BString(title));
+ }
+ }
+ }
+}
+
String WebFrame::userAgent(const KURL& url)
{
return d->webView->userAgentForKURL(url);
}
+void WebFrame::savePlatformDataToCachedPage(CachedPage* cachedPage)
+{
+ Frame* coreFrame = core(this);
+ if (!coreFrame)
+ return;
+
+ ASSERT(coreFrame->loader()->documentLoader() == cachedPage->documentLoader());
+
+ WebCachedPagePlatformData* webPlatformData = new WebCachedPagePlatformData(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader()->documentLoader())));
+ cachedPage->setCachedPagePlatformData(webPlatformData);
+}
+
void WebFrame::transitionToCommittedFromCachedPage(CachedPage*)
{
}
+void WebFrame::transitionToCommittedForNewPage()
+{
+ Frame* frame = core(this);
+ ASSERT(frame);
+
+ Page* page = frame->page();
+ ASSERT(page);
+
+ bool isMainFrame = frame == page->mainFrame();
+
+ if (isMainFrame && frame->view())
+ frame->view()->detachFromWindow();
+
+ frame->setView(0);
+
+ FrameView* frameView;
+ if (isMainFrame) {
+ RECT rect;
+ d->webView->frameRect(&rect);
+ frameView = new FrameView(frame, IntRect(rect).size());
+ } else
+ frameView = new FrameView(frame);
+
+ frame->setView(frameView);
+ frameView->deref(); // FrameViews are created with a ref count of 1. Release this ref since we've assigned it to frame.
+
+ HWND viewWindow;
+ if (SUCCEEDED(d->webView->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
+ frameView->setContainingWindow(viewWindow);
+
+ if (isMainFrame)
+ frameView->attachToWindow();
+
+ if (frame->ownerRenderer())
+ frame->ownerRenderer()->setWidget(frameView);
+
+ if (HTMLFrameOwnerElement* owner = frame->ownerElement())
+ frame->view()->setScrollbarsMode(owner->scrollingMode());
+}
+
+void WebFrame::updateGlobalHistoryForStandardLoad(const KURL& url)
+{
+ COMPtr<WebHistory> history;
+ history.adoptRef(webHistory());
+
+ if (!history)
+ return;
+
+ history->addItemForURL(BString(url.string()), 0);
+}
+
+void WebFrame::updateGlobalHistoryForReload(const KURL& url)
+{
+ BString urlBStr(url.string());
+
+ COMPtr<WebHistory> history;
+ history.adoptRef(webHistory());
+
+ if (!history)
+ return;
+
+ COMPtr<IWebHistoryItem> item;
+ if (SUCCEEDED(history->itemForURL(urlBStr, &item))) {
+ COMPtr<IWebHistoryItemPrivate> itemPrivate;
+ if (SUCCEEDED(item->QueryInterface(IID_IWebHistoryItemPrivate, (void**)&itemPrivate))) {
+ SYSTEMTIME currentTime;
+ GetSystemTime(&currentTime);
+ DATE visitedTime = 0;
+ SystemTimeToVariantTime(&currentTime, &visitedTime);
+
+ // FIXME - bumping the last visited time doesn't mark the history as changed
+ itemPrivate->setLastVisitedTimeInterval(visitedTime);
+ }
+ }
+}
+
+bool WebFrame::shouldGoToHistoryItem(HistoryItem*) const
+{
+ return true;
+}
+
void WebFrame::saveViewStateToItem(HistoryItem*)
{
}
+bool WebFrame::canCachePage() const
+{
+ return true;
+}
+
+PassRefPtr<DocumentLoader> WebFrame::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
+{
+ RefPtr<WebDocumentLoader> loader = new WebDocumentLoader(request, substituteData);
+
+ COMPtr<WebDataSource> dataSource;
+ dataSource.adoptRef(WebDataSource::createInstance(loader.get()));
+
+ loader->setDataSource(dataSource.get());
+ return loader.release();
+}
+
+void WebFrame::setMainDocumentError(DocumentLoader*, const ResourceError& error)
+{
+ if (d->m_pluginView) {
+ if (d->m_pluginView->status() == PluginStatusLoadedSuccessfully)
+ d->m_pluginView->didFail(error);
+ d->m_pluginView = 0;
+ d->m_hasSentResponseToPlugin = false;
+ }
+}
+
ResourceError WebFrame::cancelledError(const ResourceRequest& request)
{
// FIXME: Need ChickenCat to include CFNetwork/CFURLError.h to get these values
@@ -1319,6 +1986,22 @@ bool WebFrame::shouldFallBack(const ResourceError& error)
return error.errorCode() != WebURLErrorCancelled;
}
+void WebFrame::receivedData(const char* data, int length, const String& textEncoding)
+{
+ Frame* coreFrame = core(this);
+ if (!coreFrame)
+ return;
+
+ // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
+ String encoding = coreFrame->loader()->documentLoader()->overrideEncoding();
+ bool userChosen = !encoding.isNull();
+ if (encoding.isNull())
+ encoding = textEncoding;
+ coreFrame->loader()->setEncoding(encoding, userChosen);
+
+ coreFrame->loader()->addData(data, length);
+}
+
COMPtr<WebFramePolicyListener> WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction function)
{
// FIXME: <rdar://5634381> We need to support multiple active policy listeners.
@@ -1351,6 +2034,28 @@ void WebFrame::receivedPolicyDecision(PolicyAction action)
(coreFrame->loader()->*function)(action);
}
+void WebFrame::committedLoad(DocumentLoader* loader, const char* data, int length)
+{
+ // FIXME: This should probably go through the data source.
+ const String& textEncoding = loader->response().textEncodingName();
+
+ if (!d->m_pluginView)
+ receivedData(data, length, textEncoding);
+
+ if (d->m_pluginView && d->m_pluginView->status() == PluginStatusLoadedSuccessfully) {
+ if (!d->m_hasSentResponseToPlugin) {
+ d->m_pluginView->didReceiveResponse(d->frame->loader()->documentLoader()->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_pluginView
+ // to null
+ if (!d->m_pluginView)
+ return;
+ d->m_hasSentResponseToPlugin = true;
+ }
+ d->m_pluginView->didReceiveData(data, length);
+ }
+}
+
void WebFrame::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const String& mimeType, const ResourceRequest& request)
{
Frame* coreFrame = core(this);
@@ -1439,6 +2144,76 @@ bool WebFrame::willUseArchive(ResourceLoader*, const ResourceRequest&, const KUR
return false;
}
+void WebFrame::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
+{
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
+ COMPtr<IWebURLRequest> webURLRequest;
+ webURLRequest.adoptRef(WebMutableURLRequest::createInstance(request));
+
+ resourceLoadDelegate->identifierForInitialRequest(d->webView, webURLRequest.get(), getWebDataSource(loader), identifier);
+ }
+}
+
+void WebFrame::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
+{
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
+ COMPtr<IWebURLRequest> webURLRequest;
+ webURLRequest.adoptRef(WebMutableURLRequest::createInstance(request));
+ COMPtr<IWebURLResponse> webURLRedirectResponse;
+ webURLRedirectResponse.adoptRef(WebURLResponse::createInstance(redirectResponse));
+ COMPtr<IWebURLRequest> newWebURLRequest;
+
+ if (FAILED(resourceLoadDelegate->willSendRequest(d->webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest)))
+ return;
+
+ if (webURLRequest == newWebURLRequest)
+ return;
+
+ COMPtr<WebMutableURLRequest> newWebURLRequestImpl;
+ if (FAILED(newWebURLRequest->QueryInterface(&newWebURLRequestImpl)))
+ return;
+
+ request = newWebURLRequestImpl->resourceRequest();
+ }
+}
+
+void WebFrame::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
+{
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
+ COMPtr<IWebURLResponse> webURLResponse;
+ webURLResponse.adoptRef(WebURLResponse::createInstance(response));
+
+ resourceLoadDelegate->didReceiveResponse(d->webView, identifier, webURLResponse.get(), getWebDataSource(loader));
+ }
+}
+
+void WebFrame::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
+{
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ resourceLoadDelegate->didReceiveContentLength(d->webView, identifier, length, getWebDataSource(loader));
+}
+
+void WebFrame::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
+{
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ resourceLoadDelegate->didFinishLoadingFromDataSource(d->webView, identifier, getWebDataSource(loader));
+}
+
+void WebFrame::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
+{
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
+ COMPtr<IWebError> webError;
+ webError.adoptRef(WebError::createInstance(error));
+ resourceLoadDelegate->didFailLoadingWithError(d->webView, identifier, webError.get(), getWebDataSource(loader));
+ }
+}
+
bool WebFrame::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
{
notImplemented();
@@ -1465,14 +2240,178 @@ void WebFrame::dispatchDidFailLoad(const ResourceError& error)
}
}
+Frame* WebFrame::dispatchCreatePage()
+{
+ COMPtr<IWebUIDelegate> ui;
+
+ if (SUCCEEDED(d->webView->uiDelegate(&ui))) {
+ COMPtr<IWebView> newWebView;
+
+ if (SUCCEEDED(ui->createWebViewWithRequest(d->webView, 0, &newWebView))) {
+ COMPtr<IWebFrame> mainFrame;
+
+ if (SUCCEEDED(newWebView->mainFrame(&mainFrame))) {
+ COMPtr<WebFrame> mainFrameImpl;
+
+ if (SUCCEEDED(mainFrame->QueryInterface(IID_WebFrame, (void**)&mainFrameImpl)))
+ return core(mainFrameImpl.get());
+ }
+ }
+ }
+ return 0;
+}
+
+void WebFrame::postProgressStartedNotification()
+{
+ static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
+ IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+ notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(d->webView), 0);
+}
+
+void WebFrame::postProgressEstimateChangedNotification()
+{
+ static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
+ IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+ notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(d->webView), 0);
+}
+
+void WebFrame::postProgressFinishedNotification()
+{
+ static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
+ IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
+ notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(d->webView), 0);
+}
+
void WebFrame::startDownload(const ResourceRequest&)
{
notImplemented();
}
+void WebFrame::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
+{
+ ASSERT(challenge.sourceHandle());
+
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
+ COMPtr<IWebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
+
+ if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(d->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.sourceHandle()->receivedRequestToContinueWithoutCredential(challenge);
+}
+
+void WebFrame::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
+{
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+ if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
+ COMPtr<IWebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
+
+ if (SUCCEEDED(resourceLoadDelegate->didCancelAuthenticationChallenge(d->webView, identifier, webChallenge.get(), getWebDataSource(loader))))
+ return;
+ }
+}
+
+PassRefPtr<Frame> WebFrame::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;
+
+ // Propagate the marginwidth/height and scrolling modes to the view.
+ if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag)) {
+ HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement);
+ if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
+ result->view()->setScrollbarsMode(ScrollbarAlwaysOff);
+ int marginWidth = frameElt->getMarginWidth();
+ int marginHeight = frameElt->getMarginHeight();
+ if (marginWidth != -1)
+ result->view()->setMarginWidth(marginWidth);
+ if (marginHeight != -1)
+ result->view()->setMarginHeight(marginHeight);
+ }
+
+ return result.release();
+}
+
+Widget* WebFrame::createPlugin(const IntSize& pluginSize, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
+{
+ PluginView* pluginView = PluginDatabase::installedPlugins()->createPluginView(core(this), pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
+
+ if (pluginView->status() == PluginStatusLoadedSuccessfully)
+ return pluginView;
+
+ COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
+
+ if (FAILED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
+ return pluginView;
+
+ RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ unsigned count = (unsigned)paramNames.size();
+ for (unsigned i = 0; i < count; i++) {
+ if (paramNames[i] == "pluginspage") {
+ static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
+ RetainPtr<CFStringRef> str(AdoptCF, paramValues[i].createCFString());
+ CFDictionarySetValue(userInfo.get(), key, str.get());
+ break;
+ }
+ }
+
+ if (!mimeType.isNull()) {
+ static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
+
+ RetainPtr<CFStringRef> str(AdoptCF, mimeType.createCFString());
+ CFDictionarySetValue(userInfo.get(), key, str.get());
+ }
+
+ String pluginName;
+ if (pluginView->plugin())
+ 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(AdoptCOM, 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, url.string(), String());
+ COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
+
+ resourceLoadDelegate->plugInFailedWithError(d->webView, error.get(), getWebDataSource(d->frame->loader()->documentLoader()));
+
+ return pluginView;
+}
+
+void WebFrame::redirectDataToPlugin(Widget* pluginWidget)
+{
+ // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
+
+ d->m_pluginView = static_cast<PluginView*>(pluginWidget);
+}
+
Widget* WebFrame::createJavaAppletWidget(const IntSize& pluginSize, Element* element, const KURL& /*baseURL*/, const Vector<String>& paramNames, const Vector<String>& paramValues)
{
- PluginView* pluginView = PluginView::create(core(this), pluginSize, element, KURL(), paramNames, paramValues, "application/x-java-applet", false);
+ PluginView* pluginView = PluginDatabase::installedPlugins()->
+ createPluginView(core(this), pluginSize, element, KURL(), paramNames, paramValues, "application/x-java-applet", false);
// Check if the plugin can be loaded successfully
if (pluginView->plugin() && pluginView->plugin()->load())
@@ -1496,7 +2435,7 @@ ObjectContentType WebFrame::objectContentType(const KURL& url, const String& mim
{
String mimeType = mimeTypeIn;
if (mimeType.isEmpty())
- mimeType = MIMETypeRegistry::getMIMETypeForExtension(url.path().substring(url.path().reverseFind('.') + 1));
+ mimeType = MIMETypeRegistry::getMIMETypeForExtension(url.path().mid(url.path().findRev('.')+1));
if (mimeType.isEmpty())
return ObjectContentFrame; // Go ahead and hope that we can display the content.
@@ -1931,8 +2870,8 @@ HRESULT STDMETHODCALLTYPE WebFrame::isDescendantOfFrame(
*result = FALSE;
Frame* coreFrame = core(this);
- COMPtr<WebFrame> ancestorWebFrame(Query, ancestor);
- if (!ancestorWebFrame)
+ COMPtr<WebFrame> ancestorWebFrame;
+ if (!ancestor || FAILED(ancestor->QueryInterface(IID_WebFrame, (void**)&ancestorWebFrame)))
return S_OK;
*result = (coreFrame && coreFrame->tree()->isDescendantOf(core(ancestorWebFrame.get()))) ? TRUE : FALSE;
@@ -1962,8 +2901,3 @@ void WebFrame::unmarkAllBadGrammar()
doc->removeMarkers(DocumentMarker::Grammar);
}
}
-
-WebView* WebFrame::webView() const
-{
- return d->webView;
-}