2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "WebKitDLL.h"
30 #include "CFDictionaryPropertyBag.h"
32 #include "DefaultPolicyDelegate.h"
33 #include "DOMCoreClasses.h"
34 #include "IWebError.h"
35 #include "IWebErrorPrivate.h"
36 #include "IWebHistory.h"
37 #include "IWebHistoryItemPrivate.h"
38 #include "IWebFrameLoadDelegatePrivate.h"
39 #include "IWebFormDelegate.h"
40 #include "IWebUIDelegatePrivate.h"
41 #include "MarshallingHelpers.h"
42 #include "WebActionPropertyBag.h"
43 #include "WebChromeClient.h"
44 #include "WebDocumentLoader.h"
45 #include "WebDownload.h"
47 #include "WebMutableURLRequest.h"
48 #include "WebEditorClient.h"
49 #include "WebFramePolicyListener.h"
50 #include "WebHistory.h"
52 #include "WebKitStatisticsPrivate.h"
53 #include "WebNotificationCenter.h"
55 #include "WebDataSource.h"
56 #include "WebHistoryItem.h"
57 #include "WebScriptDebugger.h"
58 #include "WebScriptDebugServer.h"
59 #include "WebURLAuthenticationChallenge.h"
60 #include "WebURLResponse.h"
61 #pragma warning( push, 0 )
62 #include <WebCore/AuthenticationChallenge.h>
63 #include <WebCore/BString.h>
64 #include <WebCore/Cache.h>
65 #include <WebCore/Document.h>
66 #include <WebCore/DocumentLoader.h>
67 #include <WebCore/DOMImplementation.h>
68 #include <WebCore/DOMWindow.h>
69 #include <WebCore/Event.h>
70 #include <WebCore/FormState.h>
71 #include <WebCore/FrameLoader.h>
72 #include <WebCore/FrameLoadRequest.h>
73 #include <WebCore/FrameTree.h>
74 #include <WebCore/FrameView.h>
75 #include <WebCore/FrameWin.h>
76 #include <WebCore/GDIObjectCounter.h>
77 #include <WebCore/GraphicsContext.h>
78 #include <WebCore/HistoryItem.h>
79 #include <WebCore/HTMLFormElement.h>
80 #include <WebCore/HTMLGenericFormElement.h>
81 #include <WebCore/HTMLInputElement.h>
82 #include <WebCore/HTMLNames.h>
83 #include <WebCore/KeyboardEvent.h>
84 #include <WebCore/MIMETypeRegistry.h>
85 #include <WebCore/MouseRelatedEvent.h>
86 #include <WebCore/NotImplemented.h>
87 #include <WebCore/Page.h>
88 #include <WebCore/PlatformKeyboardEvent.h>
89 #include <WebCore/PlugInInfoStore.h>
90 #include <WebCore/PluginDatabaseWin.h>
91 #include <WebCore/PluginViewWin.h>
92 #include <WebCore/ResourceHandle.h>
93 #include <WebCore/ResourceHandleWin.h>
94 #include <WebCore/ResourceRequest.h>
95 #include <WebCore/RenderFrame.h>
96 #include <WebCore/RenderTreeAsText.h>
97 #include <WebCore/Settings.h>
98 #include <WebCore/TextIterator.h>
99 #include <WebCore/kjs_binding.h>
100 #include <WebCore/kjs_proxy.h>
101 #include <WebCore/kjs_window.h>
102 #include <JavaScriptCore/APICast.h>
103 #include <wtf/MathExtras.h>
106 #include <CoreGraphics/CoreGraphics.h>
108 // CG SPI used for printing
110 CGAffineTransform CGContextGetBaseCTM(CGContextRef c);
111 void CGContextSetBaseCTM(CGContextRef c, CGAffineTransform m);
114 using namespace WebCore;
115 using namespace HTMLNames;
117 #define FLASH_REDRAW 0
120 // By imaging to a width a little wider than the available pixels,
121 // thin pages will be scaled down a little, matching the way they
122 // print in IE and Camino. This lets them use fewer sheets than they
123 // would otherwise, which is presumably why other browsers do this.
124 // Wide pages will be scaled down more than this.
125 const float PrintingMinimumShrinkFactor = 1.25f;
127 // This number determines how small we are willing to reduce the page content
128 // in order to accommodate the widest line. If the page would have to be
129 // reduced smaller to make the widest line fit, we just clip instead (this
130 // behavior matches MacIE and Mozilla, at least)
131 const float PrintingMaximumShrinkFactor = 2.0f;
134 // {A3676398-4485-4a9d-87DC-CB5A40E6351D}
135 const GUID IID_WebFrame =
136 { 0xa3676398, 0x4485, 0x4a9d, { 0x87, 0xdc, 0xcb, 0x5a, 0x40, 0xe6, 0x35, 0x1d } };
139 //-----------------------------------------------------------------------------
140 // Helpers to convert from WebCore to WebKit type
141 WebFrame* kit(Frame* frame)
146 FrameLoaderClient* frameLoaderClient = frame->loader()->client();
147 if (frameLoaderClient)
148 return static_cast<WebFrame*>(frameLoaderClient); // eek, is there a better way than static cast?
152 Frame* core(WebFrame* webFrame)
156 return webFrame->impl();
159 // This function is not in WebFrame.h because we don't want to advertise the ability to get a non-const Frame from a const WebFrame
160 Frame* core(const WebFrame* webFrame)
164 return const_cast<WebFrame*>(webFrame)->impl();
167 WebView* kit(Page* page)
169 return page ? static_cast<WebChromeClient*>(page->chrome()->client())->webView() : 0;
172 //-----------------------------------------------------------------------------
174 class FormValuesPropertyBag : public IPropertyBag, public IPropertyBag2
177 FormValuesPropertyBag(HashMap<String, String>* formValues) : m_formValues(formValues) {}
180 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
181 virtual ULONG STDMETHODCALLTYPE AddRef(void);
182 virtual ULONG STDMETHODCALLTYPE Release(void);
185 virtual /* [local] */ HRESULT STDMETHODCALLTYPE Read(
186 /* [in] */ LPCOLESTR pszPropName,
187 /* [out][in] */ VARIANT* pVar,
188 /* [in] */ IErrorLog* pErrorLog);
190 virtual HRESULT STDMETHODCALLTYPE Write(
191 /* [in] */ LPCOLESTR pszPropName,
192 /* [in] */ VARIANT* pVar);
195 virtual HRESULT STDMETHODCALLTYPE Read(
196 /* [in] */ ULONG cProperties,
197 /* [in] */ PROPBAG2 *pPropBag,
198 /* [in] */ IErrorLog *pErrLog,
199 /* [out] */ VARIANT *pvarValue,
200 /* [out] */ HRESULT *phrError);
202 virtual HRESULT STDMETHODCALLTYPE Write(
203 /* [in] */ ULONG cProperties,
204 /* [in] */ PROPBAG2 *pPropBag,
205 /* [in] */ VARIANT *pvarValue);
207 virtual HRESULT STDMETHODCALLTYPE CountProperties(
208 /* [out] */ ULONG *pcProperties);
210 virtual HRESULT STDMETHODCALLTYPE GetPropertyInfo(
211 /* [in] */ ULONG iProperty,
212 /* [in] */ ULONG cProperties,
213 /* [out] */ PROPBAG2 *pPropBag,
214 /* [out] */ ULONG *pcProperties);
216 virtual HRESULT STDMETHODCALLTYPE LoadObject(
217 /* [in] */ LPCOLESTR pstrName,
218 /* [in] */ DWORD dwHint,
219 /* [in] */ IUnknown *pUnkObject,
220 /* [in] */ IErrorLog *pErrLog);
223 HashMap<String, String>* m_formValues;
226 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::QueryInterface(REFIID riid, void** ppvObject)
229 if (IsEqualGUID(riid, IID_IUnknown))
231 else if (IsEqualGUID(riid, IID_IPropertyBag))
232 *ppvObject = static_cast<IPropertyBag*>(this);
233 else if (IsEqualGUID(riid, IID_IPropertyBag2))
234 *ppvObject = static_cast<IPropertyBag2*>(this);
236 return E_NOINTERFACE;
242 ULONG STDMETHODCALLTYPE FormValuesPropertyBag::AddRef(void)
247 ULONG STDMETHODCALLTYPE FormValuesPropertyBag::Release(void)
252 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* /*pErrorLog*/)
256 if (!pszPropName || !pVar)
259 String key(pszPropName);
260 if (!m_formValues->contains(key))
263 String value = m_formValues->get(key);
265 VARTYPE requestedType = V_VT(pVar);
267 V_VT(pVar) = VT_BSTR;
268 V_BSTR(pVar) = SysAllocStringLen(value.characters(), value.length());
269 if (value.length() && !V_BSTR(pVar))
270 return E_OUTOFMEMORY;
272 if (requestedType != VT_BSTR && requestedType != VT_EMPTY)
273 hr = VariantChangeType(pVar, pVar, VARIANT_NOUSEROVERRIDE | VARIANT_ALPHABOOL, requestedType);
278 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar)
280 if (!pszPropName || !pVar)
286 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Read(
287 /* [in] */ ULONG cProperties,
288 /* [in] */ PROPBAG2* pPropBag,
289 /* [in] */ IErrorLog* pErrLog,
290 /* [out] */ VARIANT* pvarValue,
291 /* [out] */ HRESULT* phrError)
293 if (cProperties > (size_t)m_formValues->size())
295 if (!pPropBag || !pvarValue || !phrError)
298 for (ULONG i=0; i<cProperties; i++) {
299 VariantInit(&pvarValue[i]);
300 phrError[i] = Read(pPropBag->pstrName, &pvarValue[i], pErrLog);
306 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Write(
307 /* [in] */ ULONG /*cProperties*/,
308 /* [in] */ PROPBAG2* pPropBag,
309 /* [in] */ VARIANT* pvarValue)
311 if (!pPropBag || !pvarValue)
316 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::CountProperties(
317 /* [out] */ ULONG* pcProperties)
319 *pcProperties = m_formValues->size();
323 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::GetPropertyInfo(
324 /* [in] */ ULONG iProperty,
325 /* [in] */ ULONG cProperties,
326 /* [out] */ PROPBAG2* pPropBag,
327 /* [out] */ ULONG* pcProperties)
329 if (iProperty > (size_t)m_formValues->size() || iProperty+cProperties > (size_t)m_formValues->size())
331 if (!pPropBag || !pcProperties)
336 ULONG endProperty = iProperty + cProperties;
337 for (HashMap<String, String>::iterator it = m_formValues->begin(); i<endProperty; i++) {
338 if (i >= iProperty) {
339 int storeIndex = (*pcProperties)++;
340 pPropBag[storeIndex].dwType = PROPBAG2_TYPE_DATA;
341 pPropBag[storeIndex].vt = VT_BSTR;
342 pPropBag[storeIndex].cfType = CF_TEXT;
343 pPropBag[storeIndex].dwHint = 0;
344 pPropBag[storeIndex].pstrName = const_cast<LPOLESTR>(it->first.charactersWithNullTermination());
352 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::LoadObject(
353 /* [in] */ LPCOLESTR pstrName,
354 /* [in] */ DWORD /*dwHint*/,
355 /* [in] */ IUnknown* pUnkObject,
356 /* [in] */ IErrorLog* /*pErrLog*/)
358 if (!pstrName || !pUnkObject)
363 //-----------------------------------------------------------------------------
365 static Element *elementFromDOMElement(IDOMElement *element)
370 COMPtr<IDOMElementPrivate> elePriv;
371 HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
374 hr = elePriv->coreElement((void**)&ele);
381 static HTMLFormElement *formElementFromDOMElement(IDOMElement *element)
386 IDOMElementPrivate* elePriv;
387 HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
390 hr = elePriv->coreElement((void**)&ele);
392 if (SUCCEEDED(hr) && ele && ele->hasTagName(formTag))
393 return static_cast<HTMLFormElement*>(ele);
398 static HTMLInputElement* inputElementFromDOMElement(IDOMElement* element)
403 IDOMElementPrivate* elePriv;
404 HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
407 hr = elePriv->coreElement((void**)&ele);
409 if (SUCCEEDED(hr) && ele && ele->hasTagName(inputTag))
410 return static_cast<HTMLInputElement*>(ele);
415 // WebFramePrivate ------------------------------------------------------------
417 class WebFrame::WebFramePrivate {
422 , m_policyFunction(0)
424 , m_hasSentResponseToPlugin(false)
428 ~WebFramePrivate() { }
429 FrameView* frameView() { return frame ? frame->view() : 0; }
433 FramePolicyFunction m_policyFunction;
434 COMPtr<WebFramePolicyListener> m_policyListener;
436 // Points to the plugin view that data should be redirected to.
437 PluginViewWin* m_pluginView;
438 bool m_hasSentResponseToPlugin;
441 // WebFrame ----------------------------------------------------------------
445 , d(new WebFrame::WebFramePrivate)
446 , m_quickRedirectComing(false)
447 , m_inPrintingMode(false)
449 , m_scriptDebugger(0)
455 WebFrame::~WebFrame()
462 WebFrame* WebFrame::createInstance()
464 WebFrame* instance = new WebFrame();
469 HRESULT STDMETHODCALLTYPE WebFrame::setAllowsScrolling(
470 /* [in] */ BOOL flag)
472 if (Frame* frame = core(this))
473 if (FrameView* view = frame->view())
474 view->setAllowsScrolling(!!flag);
479 HRESULT STDMETHODCALLTYPE WebFrame::allowsScrolling(
480 /* [retval][out] */ BOOL *flag)
483 if (Frame* frame = core(this))
484 if (FrameView* view = frame->view())
485 *flag = view->allowsScrolling();
491 // IUnknown -------------------------------------------------------------------
493 HRESULT STDMETHODCALLTYPE WebFrame::QueryInterface(REFIID riid, void** ppvObject)
496 if (IsEqualGUID(riid, IID_WebFrame))
498 else if (IsEqualGUID(riid, IID_IUnknown))
499 *ppvObject = static_cast<IWebFrame*>(this);
500 else if (IsEqualGUID(riid, IID_IWebFrame))
501 *ppvObject = static_cast<IWebFrame*>(this);
502 else if (IsEqualGUID(riid, IID_IWebFramePrivate))
503 *ppvObject = static_cast<IWebFramePrivate*>(this);
504 else if (IsEqualGUID(riid, IID_IWebDocumentText))
505 *ppvObject = static_cast<IWebDocumentText*>(this);
507 return E_NOINTERFACE;
513 ULONG STDMETHODCALLTYPE WebFrame::AddRef(void)
518 ULONG STDMETHODCALLTYPE WebFrame::Release(void)
520 ULONG newRef = --m_refCount;
527 // IWebFrame -------------------------------------------------------------------
529 HRESULT STDMETHODCALLTYPE WebFrame::name(
530 /* [retval][out] */ BSTR* frameName)
533 ASSERT_NOT_REACHED();
539 Frame* coreFrame = core(this);
543 *frameName = BString(coreFrame->tree()->name()).release();
547 HRESULT STDMETHODCALLTYPE WebFrame::webView(
548 /* [retval][out] */ IWebView** view)
558 HRESULT STDMETHODCALLTYPE WebFrame::frameView(
559 /* [retval][out] */ IWebFrameView** /*view*/)
561 ASSERT_NOT_REACHED();
565 HRESULT STDMETHODCALLTYPE WebFrame::DOMDocument(
566 /* [retval][out] */ IDOMDocument** result)
569 ASSERT_NOT_REACHED();
575 if (Frame* coreFrame = core(this))
576 if (Document* document = coreFrame->document())
577 *result = DOMDocument::createInstance(document);
579 return *result ? S_OK : E_FAIL;
582 HRESULT STDMETHODCALLTYPE WebFrame::frameElement(
583 /* [retval][out] */ IDOMHTMLElement** /*frameElement*/)
585 ASSERT_NOT_REACHED();
589 HRESULT STDMETHODCALLTYPE WebFrame::currentForm(
590 /* [retval][out] */ IDOMElement **currentForm)
593 ASSERT_NOT_REACHED();
599 if (Frame* coreFrame = core(this))
600 if (HTMLFormElement* formElement = coreFrame->currentForm())
601 *currentForm = DOMElement::createInstance(formElement);
603 return *currentForm ? S_OK : E_FAIL;
606 JSGlobalContextRef STDMETHODCALLTYPE WebFrame::globalContext()
608 Frame* coreFrame = core(this);
612 return toGlobalRef(coreFrame->scriptProxy()->interpreter()->globalExec());
615 HRESULT STDMETHODCALLTYPE WebFrame::loadRequest(
616 /* [in] */ IWebURLRequest* request)
618 COMPtr<WebMutableURLRequest> requestImpl;
620 HRESULT hr = request->QueryInterface(CLSID_WebMutableURLRequest, (void**)&requestImpl);
624 Frame* coreFrame = core(this);
628 coreFrame->loader()->load(requestImpl->resourceRequest());
632 void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL)
634 String mimeTypeString(mimeType, SysStringLen(mimeType));
636 mimeTypeString = "text/html";
638 String encodingString(textEncodingName, SysStringLen(textEncodingName));
639 KURL baseKURL = DeprecatedString((DeprecatedChar*)baseURL, SysStringLen(baseURL));
640 KURL failingKURL = DeprecatedString((DeprecatedChar*)failingURL, SysStringLen(failingURL));
642 ResourceRequest request(baseKURL);
643 SubstituteData substituteData(data, mimeTypeString, encodingString, failingKURL);
645 // This method is only called from IWebFrame methods, so don't ASSERT that the Frame pointer isn't null.
646 if (Frame* coreFrame = core(this))
647 coreFrame->loader()->load(request, substituteData);
651 HRESULT STDMETHODCALLTYPE WebFrame::loadData(
652 /* [in] */ IStream* data,
653 /* [in] */ BSTR mimeType,
654 /* [in] */ BSTR textEncodingName,
657 RefPtr<SharedBuffer> sharedBuffer = new SharedBuffer();
660 if (SUCCEEDED(data->Stat(&stat, STATFLAG_NONAME))) {
661 if (!stat.cbSize.HighPart && stat.cbSize.LowPart) {
662 Vector<char> dataBuffer(stat.cbSize.LowPart);
664 // FIXME: this does a needless copy, would be better to read right into the SharedBuffer
665 // or adopt the Vector or something.
666 if (SUCCEEDED(data->Read(dataBuffer.data(), static_cast<ULONG>(dataBuffer.size()), &read)))
667 sharedBuffer->append(dataBuffer.data(), static_cast<int>(dataBuffer.size()));
671 loadData(sharedBuffer, mimeType, textEncodingName, url, 0);
675 void WebFrame::loadHTMLString(BSTR string, BSTR baseURL, BSTR unreachableURL)
677 RefPtr<SharedBuffer> sharedBuffer = new SharedBuffer(reinterpret_cast<char*>(string), sizeof(UChar) * SysStringLen(string));
678 BString utf16Encoding(TEXT("utf-16"), 6);
679 loadData(sharedBuffer.release(), 0, utf16Encoding, baseURL, unreachableURL);
682 HRESULT STDMETHODCALLTYPE WebFrame::loadHTMLString(
683 /* [in] */ BSTR string,
684 /* [in] */ BSTR baseURL)
686 loadHTMLString(string, baseURL, 0);
690 HRESULT STDMETHODCALLTYPE WebFrame::loadAlternateHTMLString(
692 /* [in] */ BSTR baseURL,
693 /* [in] */ BSTR unreachableURL)
695 loadHTMLString(str, baseURL, unreachableURL);
699 HRESULT STDMETHODCALLTYPE WebFrame::loadArchive(
700 /* [in] */ IWebArchive* /*archive*/)
702 ASSERT_NOT_REACHED();
706 static inline WebDataSource *getWebDataSource(DocumentLoader* loader)
708 return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
711 HRESULT STDMETHODCALLTYPE WebFrame::dataSource(
712 /* [retval][out] */ IWebDataSource** source)
715 ASSERT_NOT_REACHED();
721 Frame* coreFrame = core(this);
725 WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->documentLoader());
727 *source = webDataSource;
730 webDataSource->AddRef();
732 return *source ? S_OK : E_FAIL;
735 HRESULT STDMETHODCALLTYPE WebFrame::provisionalDataSource(
736 /* [retval][out] */ IWebDataSource** source)
739 ASSERT_NOT_REACHED();
745 Frame* coreFrame = core(this);
749 WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->provisionalDocumentLoader());
751 *source = webDataSource;
754 webDataSource->AddRef();
756 return *source ? S_OK : E_FAIL;
759 KURL WebFrame::url() const
761 Frame* coreFrame = core(this);
765 return coreFrame->loader()->URL();
768 void WebFrame::attachScriptDebugger()
770 if (!m_scriptDebugger && core(this)->scriptProxy()->haveInterpreter())
771 m_scriptDebugger.set(new WebScriptDebugger(this));
774 void WebFrame::detachScriptDebugger()
776 m_scriptDebugger.clear();
779 HRESULT STDMETHODCALLTYPE WebFrame::stopLoading( void)
781 if (Frame* coreFrame = core(this))
782 coreFrame->loader()->stopAllLoaders();
786 HRESULT STDMETHODCALLTYPE WebFrame::reload( void)
788 Frame* coreFrame = core(this);
792 coreFrame->loader()->reload();
796 HRESULT STDMETHODCALLTYPE WebFrame::findFrameNamed(
797 /* [in] */ BSTR name,
798 /* [retval][out] */ IWebFrame** frame)
801 ASSERT_NOT_REACHED();
807 Frame* coreFrame = core(this);
811 Frame* foundFrame = coreFrame->tree()->find(AtomicString(name, SysStringLen(name)));
815 WebFrame* foundWebFrame = kit(foundFrame);
819 return foundWebFrame->QueryInterface(IID_IWebFrame, (void**)frame);
822 HRESULT STDMETHODCALLTYPE WebFrame::parentFrame(
823 /* [retval][out] */ IWebFrame** frame)
827 if (Frame* coreFrame = core(this))
828 if (WebFrame* webFrame = kit(coreFrame->tree()->parent()))
829 hr = webFrame->QueryInterface(IID_IWebFrame, (void**) frame);
834 class EnumChildFrames : public IEnumVARIANT
837 EnumChildFrames(Frame* f) : m_refCount(1), m_frame(f), m_curChild(f ? f->tree()->firstChild() : 0) { }
839 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject)
842 if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IEnumVARIANT))
845 return E_NOINTERFACE;
851 virtual ULONG STDMETHODCALLTYPE AddRef(void)
856 virtual ULONG STDMETHODCALLTYPE Release(void)
858 ULONG newRef = --m_refCount;
864 virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
871 if (!celt || celt > 1)
873 if (!m_frame || !m_curChild)
876 WebFrame* webFrame = kit(m_curChild);
878 HRESULT hr = webFrame->QueryInterface(IID_IUnknown, (void**)&unknown);
882 V_VT(rgVar) = VT_UNKNOWN;
883 V_UNKNOWN(rgVar) = unknown;
885 m_curChild = m_curChild->tree()->nextSibling();
891 virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
895 for (unsigned i = 0; i < celt && m_curChild; i++)
896 m_curChild = m_curChild->tree()->nextSibling();
897 return m_curChild ? S_OK : S_FALSE;
900 virtual HRESULT STDMETHODCALLTYPE Reset(void)
904 m_curChild = m_frame->tree()->firstChild();
908 virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT**)
919 HRESULT STDMETHODCALLTYPE WebFrame::childFrames(
920 /* [retval][out] */ IEnumVARIANT **enumFrames)
925 *enumFrames = new EnumChildFrames(core(this));
929 // IWebFramePrivate ------------------------------------------------------
931 HRESULT STDMETHODCALLTYPE WebFrame::renderTreeAsExternalRepresentation(
932 /* [retval][out] */ BSTR *result)
935 ASSERT_NOT_REACHED();
941 Frame* coreFrame = core(this);
945 DeprecatedString representation = externalRepresentation(coreFrame->renderer());
947 *result = SysAllocStringLen((LPCOLESTR)representation.unicode(), representation.length());
952 HRESULT STDMETHODCALLTYPE WebFrame::scrollOffset(
953 /* [retval][out] */ SIZE* offset)
956 ASSERT_NOT_REACHED();
960 Frame* coreFrame = core(this);
964 FrameView* view = coreFrame->view();
968 *offset = view->scrollOffset();
972 HRESULT STDMETHODCALLTYPE WebFrame::layout()
974 Frame* coreFrame = core(this);
978 FrameView* view = coreFrame->view();
986 HRESULT STDMETHODCALLTYPE WebFrame::firstLayoutDone(
987 /* [retval][out] */ BOOL* result)
990 ASSERT_NOT_REACHED();
996 Frame* coreFrame = core(this);
1000 *result = coreFrame->loader()->firstLayoutDone();
1004 HRESULT STDMETHODCALLTYPE WebFrame::loadType(
1005 /* [retval][out] */ WebFrameLoadType* type)
1008 ASSERT_NOT_REACHED();
1012 *type = (WebFrameLoadType)0;
1014 Frame* coreFrame = core(this);
1018 *type = (WebFrameLoadType)coreFrame->loader()->loadType();
1022 // IWebDocumentText -----------------------------------------------------------
1024 HRESULT STDMETHODCALLTYPE WebFrame::supportsTextEncoding(
1025 /* [retval][out] */ BOOL* result)
1031 HRESULT STDMETHODCALLTYPE WebFrame::selectedString(
1032 /* [retval][out] */ BSTR* result)
1036 Frame* coreFrame = core(this);
1040 String text = coreFrame->selectedText();
1041 text.replace('\\', coreFrame->backslashAsCurrencySymbol());
1043 *result = BString(text).release();
1047 HRESULT STDMETHODCALLTYPE WebFrame::selectAll()
1052 HRESULT STDMETHODCALLTYPE WebFrame::deselectAll()
1057 // WebFrame ---------------------------------------------------------------
1059 void WebFrame::initWithWebFrameView(IWebFrameView* /*view*/, IWebView* webView, Page* page, HTMLFrameOwnerElement* ownerElement)
1061 if (FAILED(webView->QueryInterface(CLSID_WebView, (void**)&d->webView)))
1063 d->webView->Release(); // don't hold the extra ref
1066 d->webView->viewWindow((OLE_HANDLE*)&viewWindow);
1068 this->AddRef(); // We release this ref in frameLoaderDestroyed()
1069 Frame* frame = new Frame(page, ownerElement, this);
1072 FrameView* frameView = new FrameView(frame);
1074 frame->setView(frameView);
1075 frameView->deref(); // FrameViews are created with a ref count of 1. Release this ref since we've assigned it to frame.
1077 frameView->setContainingWindow(viewWindow);
1080 Frame* WebFrame::impl()
1085 void WebFrame::invalidate()
1087 Frame* coreFrame = core(this);
1090 if (Document* document = coreFrame->document())
1091 document->recalcStyle(Node::Force);
1094 void WebFrame::setTextSizeMultiplier(float multiplier)
1096 int newZoomFactor = (int)round(multiplier * 100);
1097 Frame* coreFrame = core(this);
1100 if (coreFrame->zoomFactor() == newZoomFactor)
1103 coreFrame->setZoomFactor(newZoomFactor);
1106 HRESULT WebFrame::inViewSourceMode(BOOL* flag)
1109 ASSERT_NOT_REACHED();
1115 Frame* coreFrame = core(this);
1119 *flag = coreFrame->inViewSourceMode() ? TRUE : FALSE;
1123 HRESULT WebFrame::setInViewSourceMode(BOOL flag)
1125 Frame* coreFrame = core(this);
1129 coreFrame->setInViewSourceMode(!!flag);
1133 HRESULT WebFrame::elementWithName(BSTR name, IDOMElement* form, IDOMElement** element)
1136 return E_INVALIDARG;
1138 HTMLFormElement *formElement = formElementFromDOMElement(form);
1140 Vector<HTMLGenericFormElement*>& elements = formElement->formElements;
1141 AtomicString targetName((UChar*)name, SysStringLen(name));
1142 for (unsigned int i = 0; i < elements.size(); i++) {
1143 HTMLGenericFormElement *elt = elements[i];
1144 // Skip option elements, other duds
1145 if (elt->name() == targetName) {
1146 *element = DOMElement::createInstance(elt);
1154 HRESULT WebFrame::formForElement(IDOMElement* element, IDOMElement** form)
1157 return E_INVALIDARG;
1159 HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1163 HTMLFormElement *formElement = inputElement->form();
1167 *form = DOMElement::createInstance(formElement);
1171 HRESULT WebFrame::elementDoesAutoComplete(IDOMElement *element, bool *result)
1175 return E_INVALIDARG;
1177 HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1181 *result = (inputElement->inputType() == HTMLInputElement::TEXT && inputElement->autoComplete());
1186 HRESULT WebFrame::controlsInForm(IDOMElement* form, IDOMElement** controls, int* cControls)
1189 return E_INVALIDARG;
1191 HTMLFormElement *formElement = formElementFromDOMElement(form);
1195 int inCount = *cControls;
1196 int count = (int) formElement->formElements.size();
1200 if (inCount < count)
1204 Vector<HTMLGenericFormElement*>& elements = formElement->formElements;
1205 for (int i = 0; i < count; i++) {
1206 if (elements.at(i)->isEnumeratable()) { // Skip option elements, other duds
1207 controls[*cControls] = DOMElement::createInstance(elements.at(i));
1214 HRESULT WebFrame::elementIsPassword(IDOMElement *element, bool *result)
1216 HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1217 *result = inputElement != 0
1218 && inputElement->inputType() == HTMLInputElement::PASSWORD;
1222 HRESULT WebFrame::searchForLabelsBeforeElement(const BSTR* labels, int cLabels, IDOMElement* beforeElement, BSTR* result)
1225 ASSERT_NOT_REACHED();
1234 return E_INVALIDARG;
1236 Frame* coreFrame = core(this);
1240 Vector<String> labelStrings(cLabels);
1241 for (int i=0; i<cLabels; i++)
1242 labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
1243 Element *coreElement = elementFromDOMElement(beforeElement);
1247 String label = coreFrame->searchForLabelsBeforeElement(labelStrings, coreElement);
1249 *result = SysAllocStringLen(label.characters(), label.length());
1250 if (label.length() && !*result)
1251 return E_OUTOFMEMORY;
1255 HRESULT WebFrame::matchLabelsAgainstElement(const BSTR* labels, int cLabels, IDOMElement* againstElement, BSTR* result)
1258 ASSERT_NOT_REACHED();
1267 return E_INVALIDARG;
1269 Frame* coreFrame = core(this);
1273 Vector<String> labelStrings(cLabels);
1274 for (int i=0; i<cLabels; i++)
1275 labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
1276 Element *coreElement = elementFromDOMElement(againstElement);
1280 String label = coreFrame->matchLabelsAgainstElement(labelStrings, coreElement);
1282 *result = SysAllocStringLen(label.characters(), label.length());
1283 if (label.length() && !*result)
1284 return E_OUTOFMEMORY;
1288 HRESULT WebFrame::canProvideDocumentSource(bool* result)
1293 COMPtr<IWebDataSource> dataSource;
1294 hr = WebFrame::dataSource(&dataSource);
1298 COMPtr<IWebURLResponse> urlResponse;
1299 hr = dataSource->response(&urlResponse);
1300 if (SUCCEEDED(hr) && urlResponse) {
1302 if (SUCCEEDED(urlResponse->MIMEType(&mimeTypeBStr))) {
1303 String mimeType(mimeTypeBStr, SysStringLen(mimeTypeBStr));
1304 *result = mimeType == "text/html" || WebCore::DOMImplementation::isXMLMIMEType(mimeType);
1305 SysFreeString(mimeTypeBStr);
1313 void WebFrame::ref()
1318 void WebFrame::deref()
1323 void WebFrame::frameLoaderDestroyed()
1325 // The FrameLoader going away is equivalent to the Frame going away,
1326 // so we now need to clear our frame pointer.
1332 PassRefPtr<Frame> WebFrame::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
1334 Frame* coreFrame = core(this);
1337 COMPtr<WebFrame> webFrame;
1338 webFrame.adoptRef(WebFrame::createInstance());
1340 webFrame->initWithWebFrameView(0, d->webView, coreFrame->page(), ownerElement);
1342 RefPtr<Frame> childFrame(adoptRef(core(webFrame.get()))); // We have to adopt, because Frames start out with a refcount of 1.
1345 coreFrame->tree()->appendChild(childFrame);
1346 childFrame->tree()->setName(name);
1349 loadURLIntoChild(URL, referrer, webFrame.get());
1351 // The frame's onload handler may have removed it from the document.
1352 if (!childFrame->tree()->parent())
1355 return childFrame.release();
1358 void WebFrame::loadURLIntoChild(const KURL& originalURL, const String& referrer, WebFrame* childFrame)
1361 ASSERT(core(childFrame));
1363 Frame* coreFrame = core(this);
1366 HistoryItem* parentItem = coreFrame->loader()->currentHistoryItem();
1367 FrameLoadType loadType = coreFrame->loader()->loadType();
1368 FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
1370 KURL url = originalURL;
1372 // If we're moving in the backforward list, we might want to replace the content
1373 // of this child frame with whatever was there at that point.
1374 // Reload will maintain the frame contents, LoadSame will not.
1375 if (parentItem && parentItem->children().size() &&
1376 (isBackForwardLoadType(loadType)
1377 || loadType == FrameLoadTypeReload
1378 || loadType == FrameLoadTypeReloadAllowingStaleData))
1380 if (HistoryItem* childItem = parentItem->childItemWithName(core(childFrame)->tree()->name())) {
1381 // Use the original URL to ensure we get all the side-effects, such as
1382 // onLoad handlers, of any redirects that happened. An example of where
1383 // this is needed is Radar 3213556.
1384 url = childItem->originalURLString().deprecatedString();
1385 // These behaviors implied by these loadTypes should apply to the child frames
1386 childLoadType = loadType;
1388 if (isBackForwardLoadType(loadType))
1389 // For back/forward, remember this item so we can traverse any child items as child frames load
1390 core(childFrame)->loader()->setProvisionalHistoryItem(childItem);
1392 // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item
1393 core(childFrame)->loader()->setCurrentHistoryItem(childItem);
1397 // FIXME: Handle loading WebArchives here
1399 core(childFrame)->loader()->load(url, referrer, childLoadType, String(), 0, 0);
1402 void WebFrame::openURL(const String& URL, const Event* triggeringEvent, bool newWindow, bool lockHistory)
1404 bool ctrlPressed = false;
1405 bool shiftPressed = false;
1406 if (triggeringEvent) {
1407 if (triggeringEvent->isMouseEvent()) {
1408 const MouseRelatedEvent* mouseEvent = static_cast<const MouseRelatedEvent*>(triggeringEvent);
1409 ctrlPressed = mouseEvent->ctrlKey();
1410 shiftPressed = mouseEvent->shiftKey();
1411 } else if (triggeringEvent->isKeyboardEvent()) {
1412 const KeyboardEvent* keyEvent = static_cast<const KeyboardEvent*>(triggeringEvent);
1413 ctrlPressed = keyEvent->ctrlKey();
1414 shiftPressed = keyEvent->shiftKey();
1421 BString urlBStr = URL;
1423 IWebMutableURLRequest* request = WebMutableURLRequest::createInstance();
1424 if (FAILED(request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 0)))
1430 IWebView* newWebView;
1431 if (SUCCEEDED(d->webView->uiDelegate(&ui)) && ui) {
1432 if (SUCCEEDED(ui->createWebViewWithRequest(d->webView, request, &newWebView))) {
1434 // Ctrl-Option-Shift-click: Opens a link in a new window and selects it.
1435 // Ctrl-Shift-click: Opens a link in a new tab and selects it.
1436 ui->webViewShow(d->webView);
1438 newWebView->Release();
1444 m_quickRedirectComing = lockHistory;
1445 loadRequest(request);
1452 void WebFrame::dispatchDidHandleOnloadEvents()
1454 IWebFrameLoadDelegatePrivate* frameLoadDelegatePriv;
1455 if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv) {
1456 frameLoadDelegatePriv->didHandleOnloadEventsForFrame(d->webView, this);
1457 frameLoadDelegatePriv->Release();
1461 void WebFrame::windowScriptObjectAvailable(JSContextRef context, JSObjectRef windowObject)
1463 IWebFrameLoadDelegate* frameLoadDelegate;
1464 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)) && frameLoadDelegate) {
1465 frameLoadDelegate->windowScriptObjectAvailable(d->webView, context, windowObject);
1466 frameLoadDelegate->Release();
1470 WebHistory* WebFrame::webHistory()
1472 if (this != d->webView->topLevelFrame())
1475 IWebHistoryPrivate* historyInternal = WebHistory::optionalSharedHistoryInternal(); // does not add a ref
1476 if (!historyInternal)
1479 WebHistory* webHistory;
1480 if (FAILED(historyInternal->QueryInterface(CLSID_WebHistory, (void**)&webHistory)))
1486 bool WebFrame::hasWebView() const
1488 return !!d->webView;
1491 bool WebFrame::hasFrameView() const
1493 return !!d->frameView();
1496 bool WebFrame::privateBrowsingEnabled() const
1498 BOOL privateBrowsingEnabled = FALSE;
1499 COMPtr<IWebPreferences> preferences;
1500 if (SUCCEEDED(d->webView->preferences(&preferences)))
1501 preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
1502 return !!privateBrowsingEnabled;
1505 void WebFrame::makeDocumentView()
1509 // On the mac, this is done in Frame::setView, but since we don't have separate
1510 // frame views, we'll just do it here instead.
1511 core(this)->loader()->resetMultipleFormSubmissionProtection();
1514 void WebFrame::makeRepresentation(DocumentLoader*)
1519 void WebFrame::forceLayout()
1524 void WebFrame::forceLayoutForNonHTML()
1529 void WebFrame::setCopiesOnScroll()
1534 void WebFrame::detachedFromParent1()
1539 void WebFrame::detachedFromParent2()
1544 void WebFrame::detachedFromParent3()
1549 void WebFrame::detachedFromParent4()
1554 void WebFrame::loadedFromCachedPage()
1559 void WebFrame::dispatchDidReceiveServerRedirectForProvisionalLoad()
1561 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1562 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1563 frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(d->webView, this);
1566 void WebFrame::dispatchDidCancelClientRedirect()
1568 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1569 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1570 frameLoadDelegate->didCancelClientRedirectForFrame(d->webView, this);
1573 void WebFrame::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
1575 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1576 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1577 frameLoadDelegate->willPerformClientRedirectToURL(d->webView, BString(url.url()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), this);
1580 void WebFrame::dispatchDidChangeLocationWithinPage()
1582 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1583 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1584 frameLoadDelegate->didChangeLocationWithinPageForFrame(d->webView, this);
1587 void WebFrame::dispatchWillClose()
1589 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1590 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1591 frameLoadDelegate->willCloseFrame(d->webView, this);
1594 void WebFrame::dispatchDidReceiveIcon()
1596 d->webView->dispatchDidReceiveIconFromWebFrame(this);
1599 void WebFrame::dispatchDidStartProvisionalLoad()
1601 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1602 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1603 frameLoadDelegate->didStartProvisionalLoadForFrame(d->webView, this);
1606 void WebFrame::dispatchDidReceiveTitle(const String& title)
1608 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1609 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1610 frameLoadDelegate->didReceiveTitle(d->webView, BString(title), this);
1613 void WebFrame::dispatchDidCommitLoad()
1615 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1616 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1617 frameLoadDelegate->didCommitLoadForFrame(d->webView, this);
1620 void WebFrame::dispatchDidFinishDocumentLoad()
1622 COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
1623 if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
1624 frameLoadDelegatePriv->didFinishDocumentLoadForFrame(d->webView, this);
1627 void WebFrame::dispatchDidFinishLoad()
1629 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1630 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1631 frameLoadDelegate->didFinishLoadForFrame(d->webView, this);
1634 void WebFrame::dispatchDidFirstLayout()
1636 COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
1637 if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
1638 frameLoadDelegatePriv->didFirstLayoutInFrame(d->webView, this);
1641 void WebFrame::dispatchShow()
1643 COMPtr<IWebUIDelegate> ui;
1645 if (SUCCEEDED(d->webView->uiDelegate(&ui)))
1646 ui->webViewShow(d->webView);
1649 void WebFrame::cancelPolicyCheck()
1651 if (d->m_policyListener) {
1652 d->m_policyListener->invalidate();
1653 d->m_policyListener = 0;
1656 d->m_policyFunction = 0;
1659 void WebFrame::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
1661 Frame* coreFrame = core(this);
1664 COMPtr<IWebFormDelegate> formDelegate;
1666 if (FAILED(d->webView->formDelegate(&formDelegate))) {
1667 (coreFrame->loader()->*function)(PolicyUse);
1671 COMPtr<IDOMElement> formElement;
1672 formElement.adoptRef(DOMElement::createInstance(formState->form()));
1674 // FIXME: The FormValuesPropertyBag constructor should take a const pointer
1675 FormValuesPropertyBag formValuesPropBag(const_cast<HashMap<String, String>*>(&formState->values()));
1677 COMPtr<WebFrame> sourceFrame(kit(formState->sourceFrame()));
1678 if (SUCCEEDED(formDelegate->willSubmitForm(this, sourceFrame.get(), formElement.get(), &formValuesPropBag, setUpPolicyListener(function).get())))
1681 // FIXME: Add a sane default implementation
1682 (coreFrame->loader()->*function)(PolicyUse);
1685 void WebFrame::dispatchDidLoadMainResource(DocumentLoader* loader)
1687 if (WebScriptDebugServer::listenerCount() > 0) {
1688 Frame* coreFrame = core(this);
1692 WebScriptDebugServer::sharedWebScriptDebugServer()->didLoadMainResourceForDataSource(
1693 kit(coreFrame->page()),
1694 loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0);
1698 void WebFrame::revertToProvisionalState(DocumentLoader*)
1703 void WebFrame::clearUnarchivingState(DocumentLoader*)
1708 void WebFrame::setMainFrameDocumentReady(bool)
1713 void WebFrame::willChangeTitle(DocumentLoader*)
1718 void WebFrame::didChangeTitle(DocumentLoader*)
1723 void WebFrame::finishedLoading(DocumentLoader* loader)
1725 // Telling the frame we received some data and passing 0 as the data is our
1726 // way to get work done that is normally done when the first bit of data is
1727 // received, even for the case of a document with no data (like about:blank)
1728 if (!d->m_pluginView)
1729 committedLoad(loader, 0, 0);
1731 d->m_pluginView->didFinishLoading();
1732 d->m_pluginView = 0;
1733 d->m_hasSentResponseToPlugin = false;
1737 void WebFrame::finalSetupForReplace(DocumentLoader*)
1742 void WebFrame::setDefersLoading(bool)
1747 bool WebFrame::isArchiveLoadPending(ResourceLoader*) const
1753 void WebFrame::cancelPendingArchiveLoad(ResourceLoader*)
1758 void WebFrame::clearArchivedResources()
1763 bool WebFrame::canHandleRequest(const ResourceRequest& request) const
1765 return WebView::canHandleRequest(request);
1768 bool WebFrame::canShowMIMEType(const String& /*MIMEType*/) const
1774 bool WebFrame::representationExistsForURLScheme(const String& /*URLScheme*/) const
1780 String WebFrame::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
1783 ASSERT_NOT_REACHED();
1787 void WebFrame::frameLoadCompleted()
1789 if (Frame* coreFrame = core(this))
1790 coreFrame->loader()->setPreviousHistoryItem(0);
1793 void WebFrame::restoreViewState()
1795 // FIXME: Need to restore view state for page caching
1799 void WebFrame::provisionalLoadStarted()
1804 bool WebFrame::shouldTreatURLAsSameAsCurrent(const KURL&) const
1810 void WebFrame::addHistoryItemForFragmentScroll()
1815 void WebFrame::didFinishLoad()
1820 void WebFrame::prepareForDataSourceReplacement()
1825 void WebFrame::setTitle(const String& title, const KURL& url)
1827 BOOL privateBrowsingEnabled = FALSE;
1828 COMPtr<IWebPreferences> preferences;
1829 if (SUCCEEDED(d->webView->preferences(&preferences)))
1830 preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
1831 if (!privateBrowsingEnabled) {
1832 // update title in global history
1833 COMPtr<WebHistory> history;
1834 history.adoptRef(webHistory());
1836 COMPtr<IWebHistoryItem> item;
1837 if (SUCCEEDED(history->itemForURL(BString(url.url()), &item))) {
1838 COMPtr<IWebHistoryItemPrivate> itemPrivate;
1839 if (SUCCEEDED(item->QueryInterface(IID_IWebHistoryItemPrivate, (void**)&itemPrivate)))
1840 itemPrivate->setTitle(BString(title));
1846 String WebFrame::userAgent(const KURL& url)
1848 return d->webView->userAgentForKURL(url);
1851 void WebFrame::setDocumentViewFromCachedPage(CachedPage*)
1856 void WebFrame::updateGlobalHistoryForStandardLoad(const KURL& url)
1858 COMPtr<WebHistory> history;
1859 history.adoptRef(webHistory());
1864 history->addItemForURL(BString(url.url()), 0);
1867 void WebFrame::updateGlobalHistoryForReload(const KURL& url)
1869 BString urlBStr(url.url());
1871 COMPtr<WebHistory> history;
1872 history.adoptRef(webHistory());
1877 COMPtr<IWebHistoryItem> item;
1878 if (SUCCEEDED(history->itemForURL(urlBStr, &item))) {
1879 COMPtr<IWebHistoryItemPrivate> itemPrivate;
1880 if (SUCCEEDED(item->QueryInterface(IID_IWebHistoryItemPrivate, (void**)&itemPrivate))) {
1881 SYSTEMTIME currentTime;
1882 GetSystemTime(¤tTime);
1883 DATE visitedTime = 0;
1884 SystemTimeToVariantTime(¤tTime, &visitedTime);
1886 // FIXME - bumping the last visited time doesn't mark the history as changed
1887 itemPrivate->setLastVisitedTimeInterval(visitedTime);
1892 bool WebFrame::shouldGoToHistoryItem(HistoryItem*) const
1898 void WebFrame::saveViewStateToItem(HistoryItem*)
1900 // FIXME: Need to save view state for page caching
1904 void WebFrame::saveDocumentViewToCachedPage(CachedPage*)
1909 bool WebFrame::canCachePage() const
1915 PassRefPtr<DocumentLoader> WebFrame::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
1917 RefPtr<WebDocumentLoader> loader = new WebDocumentLoader(request, substituteData);
1919 COMPtr<WebDataSource> dataSource;
1920 dataSource.adoptRef(WebDataSource::createInstance(loader.get()));
1922 loader->setDataSource(dataSource.get());
1923 return loader.release();
1926 void WebFrame::setMainDocumentError(DocumentLoader*, const ResourceError& error)
1928 if (d->m_pluginView) {
1929 d->m_pluginView->didFail(error);
1930 d->m_pluginView = 0;
1931 d->m_hasSentResponseToPlugin = false;
1935 ResourceError WebFrame::cancelledError(const ResourceRequest& request)
1937 // FIXME: Need ChickenCat to include CFNetwork/CFURLError.h to get these values
1938 // Alternatively, we could create our own error domain/codes.
1939 return ResourceError(String(WebURLErrorDomain), -999, request.url().url(), String());
1942 ResourceError WebFrame::blockedError(const ResourceRequest& request)
1944 // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1945 return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotUseRestrictedPort, request.url().url(), String());
1948 ResourceError WebFrame::cannotShowURLError(const ResourceRequest&)
1951 return ResourceError();
1954 ResourceError WebFrame::interruptForPolicyChangeError(const ResourceRequest& request)
1956 // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1957 return ResourceError(String(WebKitErrorDomain), WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().url(), String());
1960 ResourceError WebFrame::cannotShowMIMETypeError(const ResourceResponse&)
1963 return ResourceError();
1966 ResourceError WebFrame::fileDoesNotExistError(const ResourceResponse&)
1969 return ResourceError();
1972 bool WebFrame::shouldFallBack(const ResourceError& error)
1974 return error.errorCode() != WebURLErrorCancelled;
1977 void WebFrame::receivedData(const char* data, int length, const String& textEncoding)
1979 Frame* coreFrame = core(this);
1983 // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
1984 String encoding = coreFrame->loader()->documentLoader()->overrideEncoding();
1985 bool userChosen = !encoding.isNull();
1986 if (encoding.isNull())
1987 encoding = textEncoding;
1988 coreFrame->loader()->setEncoding(encoding, userChosen);
1990 coreFrame->loader()->addData(data, length);
1993 COMPtr<WebFramePolicyListener> WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction function)
1995 ASSERT(!d->m_policyListener);
1996 ASSERT(!d->m_policyFunction);
1998 Frame* coreFrame = core(this);
2001 d->m_policyListener.adoptRef(WebFramePolicyListener::createInstance(coreFrame));
2002 d->m_policyFunction = function;
2004 return d->m_policyListener;
2007 void WebFrame::receivedPolicyDecision(PolicyAction action)
2009 ASSERT(d->m_policyListener);
2010 ASSERT(d->m_policyFunction);
2012 FramePolicyFunction function = d->m_policyFunction;
2014 d->m_policyListener = 0;
2015 d->m_policyFunction = 0;
2017 Frame* coreFrame = core(this);
2020 (coreFrame->loader()->*function)(action);
2023 void WebFrame::committedLoad(DocumentLoader* loader, const char* data, int length)
2025 // FIXME: This should probably go through the data source.
2026 const String& textEncoding = loader->response().textEncodingName();
2028 if (!d->m_pluginView)
2029 receivedData(data, length, textEncoding);
2031 if (d->m_pluginView) {
2032 if (!d->m_hasSentResponseToPlugin) {
2033 d->m_pluginView->didReceiveResponse(d->frame->loader()->documentLoader()->response());
2034 // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
2035 // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
2037 if (!d->m_pluginView)
2039 d->m_hasSentResponseToPlugin = true;
2041 d->m_pluginView->didReceiveData(data, length);
2045 void WebFrame::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const String& mimeType, const ResourceRequest& request)
2047 COMPtr<IWebPolicyDelegate> policyDelegate;
2048 if (SUCCEEDED(d->webView->policyDelegate(&policyDelegate))) {
2049 COMPtr<IWebURLRequest> urlRequest;
2050 urlRequest.adoptRef(WebMutableURLRequest::createInstance(request));
2051 if (SUCCEEDED(policyDelegate->decidePolicyForMIMEType(d->webView, BString(mimeType), urlRequest.get(), this, setUpPolicyListener(function).get())))
2055 Frame* coreFrame = core(this);
2058 // FIXME: This is a stopgap default implementation to tide us over until
2059 // <rdar://4911042/> is taken care of
2060 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType) || MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
2061 (coreFrame->loader()->*function)(PolicyUse);
2063 (coreFrame->loader()->*function)(PolicyDownload);
2066 void WebFrame::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request, const String& frameName)
2068 Frame* coreFrame = core(this);
2071 COMPtr<IWebPolicyDelegate> policyDelegate;
2072 if (SUCCEEDED(d->webView->policyDelegate(&policyDelegate))) {
2073 COMPtr<IWebURLRequest> urlRequest;
2074 urlRequest.adoptRef(WebMutableURLRequest::createInstance(request));
2075 COMPtr<WebActionPropertyBag> actionInformation;
2076 actionInformation.adoptRef(WebActionPropertyBag::createInstance(action, coreFrame));
2078 if (SUCCEEDED(policyDelegate->decidePolicyForNewWindowAction(d->webView, actionInformation.get(), urlRequest.get(), BString(frameName), setUpPolicyListener(function).get())))
2082 // FIXME: Add a sane default implementation
2083 (coreFrame->loader()->*function)(PolicyUse);
2086 void WebFrame::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request)
2088 Frame* coreFrame = core(this);
2091 COMPtr<IWebPolicyDelegate> policyDelegate;
2092 if (FAILED(d->webView->policyDelegate(&policyDelegate)))
2093 policyDelegate = DefaultPolicyDelegate::sharedInstance();
2095 COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
2096 COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, coreFrame));
2098 if (SUCCEEDED(policyDelegate->decidePolicyForNavigationAction(d->webView, actionInformation.get(), urlRequest.get(), this, setUpPolicyListener(function).get())))
2101 (coreFrame->loader()->*function)(PolicyUse);
2104 void WebFrame::dispatchUnableToImplementPolicy(const ResourceError& error)
2106 COMPtr<IWebPolicyDelegate> policyDelegate;
2107 if (SUCCEEDED(d->webView->policyDelegate(&policyDelegate))) {
2108 COMPtr<IWebError> webError;
2109 webError.adoptRef(WebError::createInstance(error));
2110 policyDelegate->unableToImplementPolicyWithError(d->webView, webError.get(), this);
2114 void WebFrame::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest&, const ResourceResponse& response)
2116 COMPtr<IWebDownloadDelegate> downloadDelegate;
2117 COMPtr<IWebView> webView;
2118 if (SUCCEEDED(this->webView(&webView))) {
2119 if (FAILED(webView->downloadDelegate(&downloadDelegate))) {
2120 // If the WebView doesn't successfully provide a download delegate we'll pass a null one
2121 // into the WebDownload - which may or may not decide to use a DefaultDownloadDelegate
2122 LOG_ERROR("Failed to get downloadDelegate from WebView");
2123 downloadDelegate = 0;
2127 // Its the delegate's job to ref the WebDownload to keep it alive - otherwise it will be destroyed
2128 // when this method returns
2129 COMPtr<WebDownload> download;
2130 download.adoptRef(WebDownload::createInstance(handle, request, response, downloadDelegate.get()));
2133 bool WebFrame::willUseArchive(ResourceLoader*, const ResourceRequest&, const KURL&) const
2139 void WebFrame::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
2141 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2142 if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2143 COMPtr<IWebURLRequest> webURLRequest;
2144 webURLRequest.adoptRef(WebMutableURLRequest::createInstance(request));
2146 resourceLoadDelegate->identifierForInitialRequest(d->webView, webURLRequest.get(), getWebDataSource(loader), identifier);
2150 void WebFrame::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
2152 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2153 if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2154 COMPtr<IWebURLRequest> webURLRequest;
2155 webURLRequest.adoptRef(WebMutableURLRequest::createInstance(request));
2156 COMPtr<IWebURLResponse> webURLRedirectResponse;
2157 webURLRedirectResponse.adoptRef(WebURLResponse::createInstance(redirectResponse));
2158 COMPtr<IWebURLRequest> newWebURLRequest;
2160 if (FAILED(resourceLoadDelegate->willSendRequest(d->webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest)))
2163 if (webURLRequest == newWebURLRequest)
2166 COMPtr<WebMutableURLRequest> newWebURLRequestImpl;
2167 if (FAILED(newWebURLRequest->QueryInterface(CLSID_WebMutableURLRequest, (void**)&newWebURLRequestImpl)))
2170 request = newWebURLRequestImpl->resourceRequest();
2174 void WebFrame::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
2176 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2177 if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2178 COMPtr<IWebURLResponse> webURLResponse;
2179 webURLResponse.adoptRef(WebURLResponse::createInstance(response));
2181 resourceLoadDelegate->didReceiveResponse(d->webView, identifier, webURLResponse.get(), getWebDataSource(loader));
2185 void WebFrame::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
2187 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2188 if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
2189 resourceLoadDelegate->didReceiveContentLength(d->webView, identifier, length, getWebDataSource(loader));
2192 void WebFrame::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
2194 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2195 if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
2196 resourceLoadDelegate->didFinishLoadingFromDataSource(d->webView, identifier, getWebDataSource(loader));
2199 void WebFrame::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
2201 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2202 if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2203 COMPtr<IWebError> webError;
2204 webError.adoptRef(WebError::createInstance(error));
2205 resourceLoadDelegate->didFailLoadingWithError(d->webView, identifier, webError.get(), getWebDataSource(loader));
2209 bool WebFrame::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
2215 void WebFrame::dispatchDidFailProvisionalLoad(const ResourceError& error)
2217 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
2218 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
2219 COMPtr<IWebError> webError;
2220 webError.adoptRef(WebError::createInstance(error));
2221 frameLoadDelegate->didFailProvisionalLoadWithError(d->webView, webError.get(), this);
2225 void WebFrame::dispatchDidFailLoad(const ResourceError& error)
2227 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
2228 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
2229 COMPtr<IWebError> webError;
2230 webError.adoptRef(WebError::createInstance(error));
2231 frameLoadDelegate->didFailLoadWithError(d->webView, webError.get(), this);
2235 Frame* WebFrame::dispatchCreatePage()
2237 COMPtr<IWebUIDelegate> ui;
2239 if (SUCCEEDED(d->webView->uiDelegate(&ui))) {
2240 COMPtr<IWebView> newWebView;
2242 if (SUCCEEDED(ui->createWebViewWithRequest(d->webView, 0, &newWebView))) {
2243 COMPtr<IWebFrame> mainFrame;
2245 if (SUCCEEDED(newWebView->mainFrame(&mainFrame))) {
2246 COMPtr<WebFrame> mainFrameImpl;
2248 if (SUCCEEDED(mainFrame->QueryInterface(IID_WebFrame, (void**)&mainFrameImpl)))
2249 return core(mainFrameImpl.get());
2256 void WebFrame::postProgressStartedNotification()
2258 static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
2259 IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
2260 notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(d->webView), 0);
2263 void WebFrame::postProgressEstimateChangedNotification()
2265 static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
2266 IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
2267 notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(d->webView), 0);
2270 void WebFrame::postProgressFinishedNotification()
2272 static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
2273 IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
2274 notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(d->webView), 0);
2277 void WebFrame::startDownload(const ResourceRequest&)
2282 void WebFrame::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
2284 ASSERT(challenge.sourceHandle());
2286 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2287 if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2288 COMPtr<IWebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
2290 if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(d->webView, identifier, webChallenge.get(), getWebDataSource(loader))))
2294 // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle
2295 // to continue without credential - this is the best approximation of Mac behavior
2296 challenge.sourceHandle()->receivedRequestToContinueWithoutCredential(challenge);
2299 void WebFrame::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
2301 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2302 if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2303 COMPtr<IWebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
2305 if (SUCCEEDED(resourceLoadDelegate->didCancelAuthenticationChallenge(d->webView, identifier, webChallenge.get(), getWebDataSource(loader))))
2310 PassRefPtr<Frame> WebFrame::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
2311 const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
2313 RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
2317 // Propagate the marginwidth/height and scrolling modes to the view.
2318 if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag)) {
2319 HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement);
2320 if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
2321 result->view()->setScrollbarsMode(ScrollbarAlwaysOff);
2322 int marginWidth = frameElt->getMarginWidth();
2323 int marginHeight = frameElt->getMarginHeight();
2324 if (marginWidth != -1)
2325 result->view()->setMarginWidth(marginWidth);
2326 if (marginHeight != -1)
2327 result->view()->setMarginHeight(marginHeight);
2330 return result.release();
2333 Widget* WebFrame::createPlugin(const IntSize& pluginSize, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
2335 PluginViewWin* pluginView = PluginDatabaseWin::installedPlugins()->createPluginView(core(this), pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
2337 if (pluginView->status() == PluginStatusLoadedSuccessfully)
2340 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2342 if (FAILED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
2345 RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
2347 unsigned count = (unsigned)paramNames.size();
2348 for (unsigned i = 0; i < count; i++) {
2349 if (paramNames[i] == "pluginspage") {
2350 static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
2351 RetainPtr<CFStringRef> str(AdoptCF, paramValues[i].createCFString());
2352 CFDictionarySetValue(userInfo.get(), key, str.get());
2357 if (!mimeType.isNull()) {
2358 static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
2360 RetainPtr<CFStringRef> str(AdoptCF, mimeType.createCFString());
2361 CFDictionarySetValue(userInfo.get(), key, str.get());
2365 if (pluginView->plugin())
2366 pluginName = pluginView->plugin()->name();
2367 if (!pluginName.isNull()) {
2368 static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
2369 RetainPtr<CFStringRef> str(AdoptCF, mimeType.createCFString());
2370 CFDictionarySetValue(userInfo.get(), key, str.get());
2373 COMPtr<CFDictionaryPropertyBag> userInfoBag(AdoptCOM, CFDictionaryPropertyBag::createInstance());
2374 userInfoBag->setDictionary(userInfo.get());
2377 switch (pluginView->status()) {
2378 case PluginStatusCanNotFindPlugin:
2379 errorCode = WebKitErrorCannotFindPlugIn;
2381 case PluginStatusCanNotLoadPlugin:
2382 errorCode = WebKitErrorCannotLoadPlugIn;
2385 ASSERT_NOT_REACHED();
2388 ResourceError resourceError(String(WebKitErrorDomain), errorCode, url.url(), String());
2389 COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
2391 resourceLoadDelegate->plugInFailedWithError(d->webView, error.get(), getWebDataSource(d->frame->loader()->documentLoader()));
2396 void WebFrame::redirectDataToPlugin(Widget* pluginWidget)
2398 // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
2400 d->m_pluginView = static_cast<PluginViewWin*>(pluginWidget);
2403 Widget* WebFrame::createJavaAppletWidget(const IntSize& pluginSize, Element* element, const KURL& /*baseURL*/, const Vector<String>& paramNames, const Vector<String>& paramValues)
2405 PluginViewWin* pluginView = PluginDatabaseWin::installedPlugins()->
2406 createPluginView(core(this), pluginSize, element, KURL(), paramNames, paramValues, "application/x-java-applet", false);
2408 // Check if the plugin can be loaded successfully
2409 if (pluginView->plugin()->load())
2412 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2413 if (FAILED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
2416 COMPtr<CFDictionaryPropertyBag> userInfoBag(AdoptCOM, CFDictionaryPropertyBag::createInstance());
2418 ResourceError resourceError(String(WebKitErrorDomain), WebKitErrorJavaUnavailable, String(), String());
2419 COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
2421 resourceLoadDelegate->plugInFailedWithError(d->webView, error.get(), getWebDataSource(d->frame->loader()->documentLoader()));
2426 ObjectContentType WebFrame::objectContentType(const KURL& url, const String& mimeTypeIn)
2428 String mimeType = mimeTypeIn;
2429 if (mimeType.isEmpty())
2430 mimeType = MIMETypeRegistry::getMIMETypeForExtension(url.path().mid(url.path().findRev('.')+1));
2432 if (mimeType.isEmpty())
2433 return ObjectContentFrame; // Go ahead and hope that we can display the content.
2435 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
2436 return WebCore::ObjectContentImage;
2438 if (PluginDatabaseWin::installedPlugins()->isMIMETypeRegistered(mimeType))
2439 return WebCore::ObjectContentNetscapePlugin;
2441 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
2442 return WebCore::ObjectContentFrame;
2444 return WebCore::ObjectContentNone;
2447 String WebFrame::overrideMediaType() const
2453 void WebFrame::windowObjectCleared()
2455 Frame* coreFrame = core(this);
2458 Settings* settings = coreFrame->settings();
2459 if (!settings || !settings->isJavaScriptEnabled())
2462 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
2463 if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
2464 JSContextRef context = toRef(coreFrame->scriptProxy()->interpreter()->globalExec());
2465 JSObjectRef windowObject = toRef(KJS::Window::retrieve(coreFrame)->getObject());
2466 ASSERT(windowObject);
2468 frameLoadDelegate->windowScriptObjectAvailable(d->webView, context, windowObject);
2471 if (WebScriptDebugServer::listenerCount() > 0) {
2472 detachScriptDebugger();
2473 attachScriptDebugger();
2477 void WebFrame::didPerformFirstNavigation() const
2479 COMPtr<IWebPreferences> preferences;
2480 if (FAILED(d->webView->preferences(&preferences)))
2483 COMPtr<IWebPreferencesPrivate> preferencesPrivate(Query, preferences);
2484 if (!preferencesPrivate)
2486 BOOL automaticallyDetectsCacheModel;
2487 if (FAILED(preferencesPrivate->automaticallyDetectsCacheModel(&automaticallyDetectsCacheModel)))
2490 WebCacheModel cacheModel;
2491 if (FAILED(preferences->cacheModel(&cacheModel)))
2494 if (automaticallyDetectsCacheModel && cacheModel < WebCacheModelDocumentBrowser)
2495 preferences->setCacheModel(WebCacheModelDocumentBrowser);
2498 void WebFrame::registerForIconNotification(bool listen)
2500 d->webView->registerForIconNotification(listen);
2503 static IntRect printerRect(HDC printDC)
2505 return IntRect(0, 0,
2506 GetDeviceCaps(printDC, PHYSICALWIDTH) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETX),
2507 GetDeviceCaps(printDC, PHYSICALHEIGHT) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETY));
2510 void WebFrame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
2512 Frame* coreFrame = core(this);
2514 coreFrame->setPrinting(printing, minPageWidth, maxPageWidth, adjustViewSize);
2517 HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode(
2518 /* [in] */ BOOL value,
2519 /* [in] */ HDC printDC)
2521 if (m_inPrintingMode == !!value)
2524 Frame* coreFrame = core(this);
2528 m_inPrintingMode = !!value;
2530 // If we are a frameset just print with the layout we have onscreen, otherwise relayout
2531 // according to the paper size
2532 float minLayoutWidth = 0.0f;
2533 float maxLayoutWidth = 0.0f;
2534 if (m_inPrintingMode && !coreFrame->isFrameSet()) {
2536 ASSERT_NOT_REACHED();
2540 const int desiredHorizontalPixelsPerInch = 72;
2541 int paperHorizontalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSX);
2542 int paperWidth = printerRect(printDC).width() * desiredHorizontalPixelsPerInch / paperHorizontalPixelsPerInch;
2543 minLayoutWidth = paperWidth * PrintingMinimumShrinkFactor;
2544 maxLayoutWidth = paperWidth * PrintingMaximumShrinkFactor;
2547 setPrinting(m_inPrintingMode, minLayoutWidth, maxLayoutWidth, true);
2549 if (!m_inPrintingMode)
2550 m_pageRects.clear();
2555 void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight)
2562 COMPtr<IWebUIDelegate> ui;
2563 if (FAILED(d->webView->uiDelegate(&ui)))
2565 COMPtr<IWebUIDelegate2> ui2;
2566 if (FAILED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
2568 if (headerHeight && SUCCEEDED(ui2->webViewHeaderHeight(d->webView, &height)))
2569 *headerHeight = height;
2570 if (footerHeight && SUCCEEDED(ui2->webViewFooterHeight(d->webView, &height)))
2571 *footerHeight = height;
2574 IntRect WebFrame::printerMarginRect(HDC printDC)
2576 IntRect emptyRect(0, 0, 0, 0);
2578 COMPtr<IWebUIDelegate> ui;
2579 if (FAILED(d->webView->uiDelegate(&ui)))
2581 COMPtr<IWebUIDelegate2> ui2;
2582 if (FAILED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
2586 if (FAILED(ui2->webViewPrintingMarginRect(d->webView, &rect)))
2589 rect.left = MulDiv(rect.left, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
2590 rect.top = MulDiv(rect.top, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
2591 rect.right = MulDiv(rect.right, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
2592 rect.bottom = MulDiv(rect.bottom, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
2594 return IntRect(rect.left, rect.top, (rect.right - rect.left), rect.bottom - rect.top);
2597 const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC)
2599 ASSERT(m_inPrintingMode);
2601 Frame* coreFrame = core(this);
2603 ASSERT(coreFrame->document());
2608 // adjust the page rect by the header and footer
2609 float headerHeight = 0, footerHeight = 0;
2610 headerAndFooterHeights(&headerHeight, &footerHeight);
2611 IntRect pageRect = printerRect(printDC);
2612 IntRect marginRect = printerMarginRect(printDC);
2613 IntRect adjustedRect = IntRect(
2614 pageRect.x() + marginRect.x(),
2615 pageRect.y() + marginRect.y(),
2616 pageRect.width() - marginRect.x() - marginRect.right(),
2617 pageRect.height() - marginRect.y() - marginRect.bottom());
2619 computePageRectsForFrame(coreFrame, adjustedRect, headerHeight, footerHeight, 1.0,m_pageRects, m_pageHeight);
2624 HRESULT STDMETHODCALLTYPE WebFrame::getPrintedPageCount(
2625 /* [in] */ HDC printDC,
2626 /* [retval][out] */ UINT *pageCount)
2628 if (!pageCount || !printDC) {
2629 ASSERT_NOT_REACHED();
2635 if (!m_inPrintingMode) {
2636 ASSERT_NOT_REACHED();
2640 Frame* coreFrame = core(this);
2641 if (!coreFrame || !coreFrame->document())
2644 const Vector<IntRect>& pages = computePageRects(printDC);
2645 *pageCount = (UINT) pages.size();
2650 HRESULT STDMETHODCALLTYPE WebFrame::spoolPages(
2651 /* [in] */ HDC printDC,
2652 /* [in] */ UINT startPage,
2653 /* [in] */ UINT endPage,
2654 /* [retval][out] */ void* ctx)
2656 if (!printDC || !ctx) {
2657 ASSERT_NOT_REACHED();
2661 if (!m_inPrintingMode) {
2662 ASSERT_NOT_REACHED();
2666 Frame* coreFrame = core(this);
2667 if (!coreFrame || !coreFrame->document())
2670 UINT pageCount = (UINT) m_pageRects.size();
2671 PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx;
2673 if (!pageCount || startPage > pageCount) {
2674 ASSERT_NOT_REACHED();
2682 endPage = pageCount;
2684 COMPtr<IWebUIDelegate> ui;
2685 if (FAILED(d->webView->uiDelegate(&ui)))
2687 // FIXME: we can return early after the updated app is released
2688 COMPtr<IWebUIDelegate2> ui2;
2689 if (FAILED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
2692 float headerHeight = 0, footerHeight = 0;
2693 headerAndFooterHeights(&headerHeight, &footerHeight);
2694 GraphicsContext spoolCtx(pctx);
2696 for (UINT ii = startPage; ii < endPage; ii++) {
2697 IntRect pageRect = m_pageRects[ii];
2699 CGContextSaveGState(pctx);
2701 IntRect printRect = printerRect(printDC);
2702 CGRect mediaBox = CGRectMake(CGFloat(0),
2704 CGFloat(printRect.width()),
2705 CGFloat(printRect.height()));
2707 CGContextBeginPage(pctx, &mediaBox);
2709 CGFloat scale = (float)mediaBox.size.width/ (float)pageRect.width();
2710 CGAffineTransform ctm = CGContextGetBaseCTM(pctx);
2711 ctm = CGAffineTransformScale(ctm, -scale, -scale);
2712 ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header
2713 CGContextScaleCTM(pctx, scale, scale);
2714 CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header
2715 CGContextSetBaseCTM(pctx, ctm);
2717 coreFrame->paint(&spoolCtx, pageRect);
2720 CGContextTranslateCTM(pctx, CGFloat(pageRect.x()), CGFloat(pageRect.y())-headerHeight);
2722 int x = pageRect.x();
2725 RECT headerRect = {x, y, x+pageRect.width(), y+(int)headerHeight};
2726 ui2->drawHeaderInRect(d->webView, &headerRect, (OLE_HANDLE)(LONG64)pctx);
2730 y = max((int)headerHeight+pageRect.height(), m_pageHeight-(int)footerHeight);
2731 RECT footerRect = {x, y, x+pageRect.width(), y+(int)footerHeight};
2732 ui2->drawFooterInRect(d->webView, &footerRect, (OLE_HANDLE)(LONG64)pctx, ii+1, pageCount);
2736 CGContextEndPage(pctx);
2737 CGContextRestoreGState(pctx);
2743 HRESULT STDMETHODCALLTYPE WebFrame::isFrameSet(
2744 /* [retval][out] */ BOOL* result)
2748 Frame* coreFrame = core(this);
2752 *result = coreFrame->isFrameSet() ? TRUE : FALSE;
2756 HRESULT STDMETHODCALLTYPE WebFrame::string(
2757 /* [retval][out] */ BSTR *result)
2761 Frame* coreFrame = core(this);
2765 RefPtr<Range> allRange(rangeOfContents(coreFrame->document()));
2766 String allString = plainText(allRange.get());
2767 *result = BString(allString).release();
2771 HRESULT STDMETHODCALLTYPE WebFrame::size(
2772 /* [retval][out] */ SIZE *size)
2776 size->cx = size->cy = 0;
2778 Frame* coreFrame = core(this);
2781 FrameView* view = coreFrame->view();
2784 size->cx = view->width();
2785 size->cy = view->height();
2789 HRESULT STDMETHODCALLTYPE WebFrame::hasScrollBars(
2790 /* [retval][out] */ BOOL *result)
2796 Frame* coreFrame = core(this);
2800 FrameView* view = coreFrame->view();
2804 if (view->vScrollbarMode() == ScrollbarAlwaysOn || view->visibleHeight() < view->contentsHeight() ||
2805 view->hScrollbarMode() == ScrollbarAlwaysOn || view->visibleWidth() < view->contentsWidth())
2811 HRESULT STDMETHODCALLTYPE WebFrame::contentBounds(
2812 /* [retval][out] */ RECT *result)
2816 ::SetRectEmpty(result);
2818 Frame* coreFrame = core(this);
2822 FrameView* view = coreFrame->view();
2826 result->bottom = view->contentsHeight();
2827 result->right = view->contentsWidth();
2831 HRESULT STDMETHODCALLTYPE WebFrame::frameBounds(
2832 /* [retval][out] */ RECT *result)
2836 ::SetRectEmpty(result);
2838 Frame* coreFrame = core(this);
2842 FrameView* view = coreFrame->view();
2846 FloatRect bounds = view->visibleContentRectConsideringExternalScrollers();
2847 result->bottom = (LONG) bounds.height();
2848 result->right = (LONG) bounds.width();
2852 HRESULT STDMETHODCALLTYPE WebFrame::isDescendantOfFrame(
2853 /* [in] */ IWebFrame *ancestor,
2854 /* [retval][out] */ BOOL *result)
2860 Frame* coreFrame = core(this);
2861 COMPtr<WebFrame> ancestorWebFrame;
2862 if (!ancestor || FAILED(ancestor->QueryInterface(IID_WebFrame, (void**)&ancestorWebFrame)))
2865 *result = (coreFrame && coreFrame->tree()->isDescendantOf(core(ancestorWebFrame.get()))) ? TRUE : FALSE;
2869 void WebFrame::unmarkAllMisspellings()
2871 Frame* coreFrame = core(this);
2872 for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
2873 Document *doc = frame->document();
2877 doc->removeMarkers(DocumentMarker::Spelling);
2881 void WebFrame::unmarkAllBadGrammar()
2883 Frame* coreFrame = core(this);
2884 for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
2885 Document *doc = frame->document();
2889 doc->removeMarkers(DocumentMarker::Grammar);