Speculative Windows build fix
[WebKit-https.git] / WebKit / win / WebFrame.cpp
1 /*
2  * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 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.
12  *
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. 
24  */
25
26 #include "config.h"
27 #include "WebKitDLL.h"
28 #include "WebFrame.h"
29
30 #include "CFDictionaryPropertyBag.h"
31 #include "COMPtr.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"
46 #include "WebError.h"
47 #include "WebMutableURLRequest.h"
48 #include "WebEditorClient.h"
49 #include "WebFramePolicyListener.h"
50 #include "WebHistory.h"
51 #include "WebKit.h"
52 #include "WebKitStatisticsPrivate.h"
53 #include "WebNotificationCenter.h"
54 #include "WebView.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>
104 #pragma warning(pop)
105
106 #include <CoreGraphics/CoreGraphics.h>
107
108 // CG SPI used for printing
109 extern "C" {
110     CGAffineTransform CGContextGetBaseCTM(CGContextRef c); 
111     void CGContextSetBaseCTM(CGContextRef c, CGAffineTransform m); 
112 }
113
114 using namespace WebCore;
115 using namespace HTMLNames;
116
117 #define FLASH_REDRAW 0
118
119
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;
126
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;
132
133
134 // {A3676398-4485-4a9d-87DC-CB5A40E6351D}
135 const GUID IID_WebFrame = 
136 { 0xa3676398, 0x4485, 0x4a9d, { 0x87, 0xdc, 0xcb, 0x5a, 0x40, 0xe6, 0x35, 0x1d } };
137
138
139 //-----------------------------------------------------------------------------
140 // Helpers to convert from WebCore to WebKit type
141 WebFrame* kit(Frame* frame)
142 {
143     if (!frame)
144         return 0;
145
146     FrameLoaderClient* frameLoaderClient = frame->loader()->client();
147     if (frameLoaderClient)
148         return static_cast<WebFrame*>(frameLoaderClient);  // eek, is there a better way than static cast?
149     return 0;
150 }
151
152 Frame* core(WebFrame* webFrame)
153 {
154     if (!webFrame)
155         return 0;
156     return webFrame->impl();
157 }
158
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)
161 {
162     if (!webFrame)
163         return 0;
164     return const_cast<WebFrame*>(webFrame)->impl();
165 }
166
167 WebView* kit(Page* page)
168 {
169     return page ? static_cast<WebChromeClient*>(page->chrome()->client())->webView() : 0;
170 }
171
172 //-----------------------------------------------------------------------------
173
174 class FormValuesPropertyBag : public IPropertyBag, public IPropertyBag2
175 {
176 public:
177     FormValuesPropertyBag(HashMap<String, String>* formValues) : m_formValues(formValues) {}
178
179     // IUnknown
180     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
181     virtual ULONG STDMETHODCALLTYPE AddRef(void);
182     virtual ULONG STDMETHODCALLTYPE Release(void);
183
184     // IPropertyBag
185     virtual /* [local] */ HRESULT STDMETHODCALLTYPE Read( 
186         /* [in] */ LPCOLESTR pszPropName,
187         /* [out][in] */ VARIANT* pVar,
188         /* [in] */ IErrorLog* pErrorLog);
189
190     virtual HRESULT STDMETHODCALLTYPE Write( 
191         /* [in] */ LPCOLESTR pszPropName,
192         /* [in] */ VARIANT* pVar);
193
194     // IPropertyBag2
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);
201     
202     virtual HRESULT STDMETHODCALLTYPE Write( 
203         /* [in] */ ULONG cProperties,
204         /* [in] */ PROPBAG2 *pPropBag,
205         /* [in] */ VARIANT *pvarValue);
206     
207     virtual HRESULT STDMETHODCALLTYPE CountProperties( 
208         /* [out] */ ULONG *pcProperties);
209     
210     virtual HRESULT STDMETHODCALLTYPE GetPropertyInfo( 
211         /* [in] */ ULONG iProperty,
212         /* [in] */ ULONG cProperties,
213         /* [out] */ PROPBAG2 *pPropBag,
214         /* [out] */ ULONG *pcProperties);
215     
216     virtual HRESULT STDMETHODCALLTYPE LoadObject( 
217         /* [in] */ LPCOLESTR pstrName,
218         /* [in] */ DWORD dwHint,
219         /* [in] */ IUnknown *pUnkObject,
220         /* [in] */ IErrorLog *pErrLog);
221     
222 protected:
223     HashMap<String, String>* m_formValues;
224 };
225
226 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::QueryInterface(REFIID riid, void** ppvObject)
227 {
228     *ppvObject = 0;
229     if (IsEqualGUID(riid, IID_IUnknown))
230         *ppvObject = this;
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);
235     else
236         return E_NOINTERFACE;
237
238     AddRef();
239     return S_OK;
240 }
241
242 ULONG STDMETHODCALLTYPE FormValuesPropertyBag::AddRef(void)
243 {
244     return 1;
245 }
246
247 ULONG STDMETHODCALLTYPE FormValuesPropertyBag::Release(void)
248 {
249     return 0;
250 }
251
252 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Read(LPCOLESTR pszPropName, VARIANT* pVar, IErrorLog* /*pErrorLog*/)
253 {
254     HRESULT hr = S_OK;
255
256     if (!pszPropName || !pVar)
257         return E_POINTER;
258
259     String key(pszPropName);
260     if (!m_formValues->contains(key))
261         return E_INVALIDARG;
262     
263     String value = m_formValues->get(key);
264
265     VARTYPE requestedType = V_VT(pVar);
266     VariantClear(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;
271
272     if (requestedType != VT_BSTR && requestedType != VT_EMPTY)
273         hr = VariantChangeType(pVar, pVar, VARIANT_NOUSEROVERRIDE | VARIANT_ALPHABOOL, requestedType);
274     
275     return hr;
276 }
277
278 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar)
279 {
280     if (!pszPropName || !pVar)
281         return E_POINTER;
282     VariantClear(pVar);
283     return E_FAIL;
284 }
285
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)
292 {
293     if (cProperties > (size_t)m_formValues->size())
294         return E_INVALIDARG;
295     if (!pPropBag || !pvarValue || !phrError)
296         return E_POINTER;
297
298     for (ULONG i=0; i<cProperties; i++) {
299         VariantInit(&pvarValue[i]);
300         phrError[i] = Read(pPropBag->pstrName, &pvarValue[i], pErrLog);
301     }
302
303     return S_OK;
304 }
305
306 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::Write( 
307     /* [in] */ ULONG /*cProperties*/,
308     /* [in] */ PROPBAG2* pPropBag,
309     /* [in] */ VARIANT* pvarValue)
310 {
311     if (!pPropBag || !pvarValue)
312         return E_POINTER;
313     return E_FAIL;
314 }
315
316 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::CountProperties( 
317     /* [out] */ ULONG* pcProperties)
318 {
319     *pcProperties = m_formValues->size();
320     return S_OK;
321 }
322
323 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::GetPropertyInfo( 
324     /* [in] */ ULONG iProperty,
325     /* [in] */ ULONG cProperties,
326     /* [out] */ PROPBAG2* pPropBag,
327     /* [out] */ ULONG* pcProperties)
328 {
329     if (iProperty > (size_t)m_formValues->size() || iProperty+cProperties > (size_t)m_formValues->size())
330         return E_INVALIDARG;
331     if (!pPropBag || !pcProperties)
332         return E_POINTER;
333
334     *pcProperties = 0;
335     ULONG i = 0;
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());
345         }
346         ++it;
347     }
348
349     return S_OK;
350 }
351
352 HRESULT STDMETHODCALLTYPE FormValuesPropertyBag::LoadObject( 
353     /* [in] */ LPCOLESTR pstrName,
354     /* [in] */ DWORD /*dwHint*/,
355     /* [in] */ IUnknown* pUnkObject,
356     /* [in] */ IErrorLog* /*pErrLog*/)
357 {
358     if (!pstrName || !pUnkObject)
359         return E_POINTER;
360     return E_FAIL;
361 }
362
363 //-----------------------------------------------------------------------------
364
365 static Element *elementFromDOMElement(IDOMElement *element)
366 {
367     if (!element)
368         return 0;
369
370     COMPtr<IDOMElementPrivate> elePriv;
371     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
372     if (SUCCEEDED(hr)) {
373         Element* ele;
374         hr = elePriv->coreElement((void**)&ele);
375         if (SUCCEEDED(hr))
376             return ele;
377     }
378     return 0;
379 }
380
381 static HTMLFormElement *formElementFromDOMElement(IDOMElement *element)
382 {
383     if (!element)
384         return 0;
385
386     IDOMElementPrivate* elePriv;
387     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
388     if (SUCCEEDED(hr)) {
389         Element* ele;
390         hr = elePriv->coreElement((void**)&ele);
391         elePriv->Release();
392         if (SUCCEEDED(hr) && ele && ele->hasTagName(formTag))
393             return static_cast<HTMLFormElement*>(ele);
394     }
395     return 0;
396 }
397
398 static HTMLInputElement* inputElementFromDOMElement(IDOMElement* element)
399 {
400     if (!element)
401         return 0;
402
403     IDOMElementPrivate* elePriv;
404     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
405     if (SUCCEEDED(hr)) {
406         Element* ele;
407         hr = elePriv->coreElement((void**)&ele);
408         elePriv->Release();
409         if (SUCCEEDED(hr) && ele && ele->hasTagName(inputTag))
410             return static_cast<HTMLInputElement*>(ele);
411     }
412     return 0;
413 }
414
415 // WebFramePrivate ------------------------------------------------------------
416
417 class WebFrame::WebFramePrivate {
418 public:
419     WebFramePrivate() 
420         : frame(0)
421         , webView(0)
422         , m_policyFunction(0)
423         , m_pluginView(0) 
424         , m_hasSentResponseToPlugin(false) 
425     { 
426     }
427
428     ~WebFramePrivate() { }
429     FrameView* frameView() { return frame ? frame->view() : 0; }
430
431     Frame* frame;
432     WebView* webView;
433     FramePolicyFunction m_policyFunction;
434     COMPtr<WebFramePolicyListener> m_policyListener;
435     
436     // Points to the plugin view that data should be redirected to.
437     PluginViewWin* m_pluginView;
438     bool m_hasSentResponseToPlugin;
439 };
440
441 // WebFrame ----------------------------------------------------------------
442
443 WebFrame::WebFrame()
444     : m_refCount(0)
445     , d(new WebFrame::WebFramePrivate)
446     , m_quickRedirectComing(false)
447     , m_inPrintingMode(false)
448     , m_pageHeight(0)
449     , m_scriptDebugger(0)
450 {
451     WebFrameCount++;
452     gClassCount++;
453 }
454
455 WebFrame::~WebFrame()
456 {
457     delete d;
458     WebFrameCount--;
459     gClassCount--;
460 }
461
462 WebFrame* WebFrame::createInstance()
463 {
464     WebFrame* instance = new WebFrame();
465     instance->AddRef();
466     return instance;
467 }
468
469 HRESULT STDMETHODCALLTYPE WebFrame::setAllowsScrolling(
470     /* [in] */ BOOL flag)
471 {
472     if (Frame* frame = core(this))
473         if (FrameView* view = frame->view())
474             view->setAllowsScrolling(!!flag);
475
476     return S_OK;
477 }
478
479 HRESULT STDMETHODCALLTYPE WebFrame::allowsScrolling(
480     /* [retval][out] */ BOOL *flag)
481 {
482     if (flag)
483         if (Frame* frame = core(this))
484             if (FrameView* view = frame->view())
485                 *flag = view->allowsScrolling();
486
487     return S_OK;
488 }
489
490
491 // IUnknown -------------------------------------------------------------------
492
493 HRESULT STDMETHODCALLTYPE WebFrame::QueryInterface(REFIID riid, void** ppvObject)
494 {
495     *ppvObject = 0;
496     if (IsEqualGUID(riid, IID_WebFrame))
497         *ppvObject = this;
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);
506     else
507         return E_NOINTERFACE;
508
509     AddRef();
510     return S_OK;
511 }
512
513 ULONG STDMETHODCALLTYPE WebFrame::AddRef(void)
514 {
515     return ++m_refCount;
516 }
517
518 ULONG STDMETHODCALLTYPE WebFrame::Release(void)
519 {
520     ULONG newRef = --m_refCount;
521     if (!newRef)
522         delete(this);
523
524     return newRef;
525 }
526
527 // IWebFrame -------------------------------------------------------------------
528
529 HRESULT STDMETHODCALLTYPE WebFrame::name( 
530     /* [retval][out] */ BSTR* frameName)
531 {
532     if (!frameName) {
533         ASSERT_NOT_REACHED();
534         return E_POINTER;
535     }
536
537     *frameName = 0;
538
539     Frame* coreFrame = core(this);
540     if (!coreFrame)
541         return E_FAIL;
542
543     *frameName = BString(coreFrame->tree()->name()).release();
544     return S_OK;
545 }
546
547 HRESULT STDMETHODCALLTYPE WebFrame::webView( 
548     /* [retval][out] */ IWebView** view)
549 {
550     *view = 0;
551     if (!d->webView)
552         return E_FAIL;
553     *view = d->webView;
554     (*view)->AddRef();
555     return S_OK;
556 }
557
558 HRESULT STDMETHODCALLTYPE WebFrame::frameView(
559     /* [retval][out] */ IWebFrameView** /*view*/)
560 {
561     ASSERT_NOT_REACHED();
562     return E_NOTIMPL;
563 }
564
565 HRESULT STDMETHODCALLTYPE WebFrame::DOMDocument( 
566     /* [retval][out] */ IDOMDocument** result)
567 {
568     if (!result) {
569         ASSERT_NOT_REACHED();
570         return E_POINTER;
571     }
572
573     *result = 0;
574
575     if (Frame* coreFrame = core(this))
576         if (Document* document = coreFrame->document())
577             *result = DOMDocument::createInstance(document);
578
579     return *result ? S_OK : E_FAIL;
580 }
581
582 HRESULT STDMETHODCALLTYPE WebFrame::frameElement( 
583     /* [retval][out] */ IDOMHTMLElement** /*frameElement*/)
584 {
585     ASSERT_NOT_REACHED();
586     return E_NOTIMPL;
587 }
588
589 HRESULT STDMETHODCALLTYPE WebFrame::currentForm( 
590         /* [retval][out] */ IDOMElement **currentForm)
591 {
592     if (!currentForm) {
593         ASSERT_NOT_REACHED();
594         return E_POINTER;
595     }
596
597     *currentForm = 0;
598
599     if (Frame* coreFrame = core(this))
600         if (HTMLFormElement* formElement = coreFrame->currentForm())
601             *currentForm = DOMElement::createInstance(formElement);
602
603     return *currentForm ? S_OK : E_FAIL;
604 }
605
606 JSGlobalContextRef STDMETHODCALLTYPE WebFrame::globalContext()
607 {
608     Frame* coreFrame = core(this);
609     if (!coreFrame)
610         return 0;
611
612     return toGlobalRef(coreFrame->scriptProxy()->globalObject()->globalExec());
613 }
614
615 HRESULT STDMETHODCALLTYPE WebFrame::loadRequest( 
616     /* [in] */ IWebURLRequest* request)
617 {
618     COMPtr<WebMutableURLRequest> requestImpl;
619
620     HRESULT hr = request->QueryInterface(&requestImpl);
621     if (FAILED(hr))
622         return hr;
623  
624     Frame* coreFrame = core(this);
625     if (!coreFrame)
626         return E_FAIL;
627
628     coreFrame->loader()->load(requestImpl->resourceRequest());
629     return S_OK;
630 }
631
632 void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL)
633 {
634     String mimeTypeString(mimeType, SysStringLen(mimeType));
635     if (!mimeType)
636         mimeTypeString = "text/html";
637
638     String encodingString(textEncodingName, SysStringLen(textEncodingName));
639     KURL baseKURL = DeprecatedString((DeprecatedChar*)baseURL, SysStringLen(baseURL));
640     KURL failingKURL = DeprecatedString((DeprecatedChar*)failingURL, SysStringLen(failingURL));
641
642     ResourceRequest request(baseKURL);
643     SubstituteData substituteData(data, mimeTypeString, encodingString, failingKURL);
644
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);
648 }
649
650
651 HRESULT STDMETHODCALLTYPE WebFrame::loadData( 
652     /* [in] */ IStream* data,
653     /* [in] */ BSTR mimeType,
654     /* [in] */ BSTR textEncodingName,
655     /* [in] */ BSTR url)
656 {
657     RefPtr<SharedBuffer> sharedBuffer = new SharedBuffer();
658
659     STATSTG stat;
660     if (SUCCEEDED(data->Stat(&stat, STATFLAG_NONAME))) {
661         if (!stat.cbSize.HighPart && stat.cbSize.LowPart) {
662             Vector<char> dataBuffer(stat.cbSize.LowPart);
663             ULONG read;
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()));
668         }
669     }
670
671     loadData(sharedBuffer, mimeType, textEncodingName, url, 0);
672     return S_OK;
673 }
674
675 void WebFrame::loadHTMLString(BSTR string, BSTR baseURL, BSTR unreachableURL)
676 {
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);
680 }
681
682 HRESULT STDMETHODCALLTYPE WebFrame::loadHTMLString( 
683     /* [in] */ BSTR string,
684     /* [in] */ BSTR baseURL)
685 {
686     loadHTMLString(string, baseURL, 0);
687     return S_OK;
688 }
689
690 HRESULT STDMETHODCALLTYPE WebFrame::loadAlternateHTMLString( 
691     /* [in] */ BSTR str,
692     /* [in] */ BSTR baseURL,
693     /* [in] */ BSTR unreachableURL)
694 {
695     loadHTMLString(str, baseURL, unreachableURL);
696     return S_OK;
697 }
698
699 HRESULT STDMETHODCALLTYPE WebFrame::loadArchive( 
700     /* [in] */ IWebArchive* /*archive*/)
701 {
702     ASSERT_NOT_REACHED();
703     return E_NOTIMPL;
704 }
705
706 static inline WebDataSource *getWebDataSource(DocumentLoader* loader)
707 {
708     return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
709 }
710
711 HRESULT STDMETHODCALLTYPE WebFrame::dataSource( 
712     /* [retval][out] */ IWebDataSource** source)
713 {
714     if (!source) {
715         ASSERT_NOT_REACHED();
716         return E_POINTER;
717     }
718
719     *source = 0;
720
721     Frame* coreFrame = core(this);
722     if (!coreFrame)
723         return E_FAIL;
724
725     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->documentLoader());
726
727     *source = webDataSource;
728
729     if (webDataSource)
730         webDataSource->AddRef(); 
731
732     return *source ? S_OK : E_FAIL;
733 }
734
735 HRESULT STDMETHODCALLTYPE WebFrame::provisionalDataSource( 
736     /* [retval][out] */ IWebDataSource** source)
737 {
738     if (!source) {
739         ASSERT_NOT_REACHED();
740         return E_POINTER;
741     }
742
743     *source = 0;
744
745     Frame* coreFrame = core(this);
746     if (!coreFrame)
747         return E_FAIL;
748
749     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->provisionalDocumentLoader());
750
751     *source = webDataSource;
752
753     if (webDataSource)
754         webDataSource->AddRef(); 
755
756     return *source ? S_OK : E_FAIL;
757 }
758
759 KURL WebFrame::url() const
760 {
761     Frame* coreFrame = core(this);
762     if (!coreFrame)
763         return KURL();
764
765     return coreFrame->loader()->URL();
766 }
767
768 void WebFrame::attachScriptDebugger()
769 {
770     if (!m_scriptDebugger && core(this)->scriptProxy()->haveInterpreter())
771         m_scriptDebugger.set(new WebScriptDebugger(this));
772 }
773
774 void WebFrame::detachScriptDebugger()
775 {
776     m_scriptDebugger.clear();
777 }
778
779 HRESULT STDMETHODCALLTYPE WebFrame::stopLoading( void)
780 {
781     if (Frame* coreFrame = core(this))
782         coreFrame->loader()->stopAllLoaders();
783     return S_OK;
784 }
785
786 HRESULT STDMETHODCALLTYPE WebFrame::reload( void)
787 {
788     Frame* coreFrame = core(this);
789     if (!coreFrame)
790         return E_FAIL;
791
792     coreFrame->loader()->reload();
793     return S_OK;
794 }
795
796 HRESULT STDMETHODCALLTYPE WebFrame::findFrameNamed( 
797     /* [in] */ BSTR name,
798     /* [retval][out] */ IWebFrame** frame)
799 {
800     if (!frame) {
801         ASSERT_NOT_REACHED();
802         return E_POINTER;
803     }
804
805     *frame = 0;
806
807     Frame* coreFrame = core(this);
808     if (!coreFrame)
809         return E_FAIL;
810
811     Frame* foundFrame = coreFrame->tree()->find(AtomicString(name, SysStringLen(name)));
812     if (!foundFrame)
813         return S_OK;
814
815     WebFrame* foundWebFrame = kit(foundFrame);
816     if (!foundWebFrame)
817         return E_FAIL;
818
819     return foundWebFrame->QueryInterface(IID_IWebFrame, (void**)frame);
820 }
821
822 HRESULT STDMETHODCALLTYPE WebFrame::parentFrame( 
823     /* [retval][out] */ IWebFrame** frame)
824 {
825     HRESULT hr = S_OK;
826     *frame = 0;
827     if (Frame* coreFrame = core(this))
828         if (WebFrame* webFrame = kit(coreFrame->tree()->parent()))
829             hr = webFrame->QueryInterface(IID_IWebFrame, (void**) frame);
830
831     return hr;
832 }
833
834 class EnumChildFrames : public IEnumVARIANT
835 {
836 public:
837     EnumChildFrames(Frame* f) : m_refCount(1), m_frame(f), m_curChild(f ? f->tree()->firstChild() : 0) { }
838
839     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject)
840     {
841         *ppvObject = 0;
842         if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IEnumVARIANT))
843             *ppvObject = this;
844         else
845             return E_NOINTERFACE;
846
847         AddRef();
848         return S_OK;
849     }
850
851     virtual ULONG STDMETHODCALLTYPE AddRef(void)
852     {
853         return ++m_refCount;
854     }
855
856     virtual ULONG STDMETHODCALLTYPE Release(void)
857     {
858         ULONG newRef = --m_refCount;
859         if (!newRef)
860             delete(this);
861         return newRef;
862     }
863
864     virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
865     {
866         if (pCeltFetched)
867             *pCeltFetched = 0;
868         if (!rgVar)
869             return E_POINTER;
870         VariantInit(rgVar);
871         if (!celt || celt > 1)
872             return S_FALSE;
873         if (!m_frame || !m_curChild)
874             return S_FALSE;
875
876         WebFrame* webFrame = kit(m_curChild);
877         IUnknown* unknown;
878         HRESULT hr = webFrame->QueryInterface(IID_IUnknown, (void**)&unknown);
879         if (FAILED(hr))
880             return hr;
881
882         V_VT(rgVar) = VT_UNKNOWN;
883         V_UNKNOWN(rgVar) = unknown;
884
885         m_curChild = m_curChild->tree()->nextSibling();
886         if (pCeltFetched)
887             *pCeltFetched = 1;
888         return S_OK;
889     }
890
891     virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
892     {
893         if (!m_frame)
894             return S_FALSE;
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;
898     }
899
900     virtual HRESULT STDMETHODCALLTYPE Reset(void)
901     {
902         if (!m_frame)
903             return S_FALSE;
904         m_curChild = m_frame->tree()->firstChild();
905         return S_OK;
906     }
907
908     virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT**)
909     {
910         return E_NOTIMPL;
911     }
912
913 private:
914     ULONG m_refCount;
915     Frame* m_frame;
916     Frame* m_curChild;
917 };
918
919 HRESULT STDMETHODCALLTYPE WebFrame::childFrames( 
920     /* [retval][out] */ IEnumVARIANT **enumFrames)
921 {
922     if (!enumFrames)
923         return E_POINTER;
924
925     *enumFrames = new EnumChildFrames(core(this));
926     return S_OK;
927 }
928
929 // IWebFramePrivate ------------------------------------------------------
930
931 HRESULT STDMETHODCALLTYPE WebFrame::renderTreeAsExternalRepresentation(
932     /* [retval][out] */ BSTR *result)
933 {
934     if (!result) {
935         ASSERT_NOT_REACHED();
936         return E_POINTER;
937     }
938
939     *result = 0;
940
941     Frame* coreFrame = core(this);
942     if (!coreFrame)
943         return E_FAIL;
944
945     DeprecatedString representation = externalRepresentation(coreFrame->renderer());
946
947     *result = SysAllocStringLen((LPCOLESTR)representation.unicode(), representation.length());
948
949     return S_OK;
950 }
951
952 HRESULT STDMETHODCALLTYPE WebFrame::scrollOffset(
953         /* [retval][out] */ SIZE* offset)
954 {
955     if (!offset) {
956         ASSERT_NOT_REACHED();
957         return E_POINTER;
958     }
959
960     Frame* coreFrame = core(this);
961     if (!coreFrame)
962         return E_FAIL;
963
964     FrameView* view = coreFrame->view();
965     if (!view)
966         return E_FAIL;
967
968     *offset = view->scrollOffset();
969     return S_OK;
970 }
971
972 HRESULT STDMETHODCALLTYPE WebFrame::layout()
973 {
974     Frame* coreFrame = core(this);
975     if (!coreFrame)
976         return E_FAIL;
977
978     FrameView* view = coreFrame->view();
979     if (!view)
980         return E_FAIL;
981
982     view->layout();
983     return S_OK;
984 }
985
986 HRESULT STDMETHODCALLTYPE WebFrame::firstLayoutDone(
987     /* [retval][out] */ BOOL* result)
988 {
989     if (!result) {
990         ASSERT_NOT_REACHED();
991         return E_POINTER;
992     }
993
994     *result = 0;
995
996     Frame* coreFrame = core(this);
997     if (!coreFrame)
998         return E_FAIL;
999
1000     *result = coreFrame->loader()->firstLayoutDone();
1001     return S_OK;
1002 }
1003
1004 HRESULT STDMETHODCALLTYPE WebFrame::loadType( 
1005     /* [retval][out] */ WebFrameLoadType* type)
1006 {
1007     if (!type) {
1008         ASSERT_NOT_REACHED();
1009         return E_POINTER;
1010     }
1011
1012     *type = (WebFrameLoadType)0;
1013
1014     Frame* coreFrame = core(this);
1015     if (!coreFrame)
1016         return E_FAIL;
1017
1018     *type = (WebFrameLoadType)coreFrame->loader()->loadType();
1019     return S_OK;
1020 }
1021
1022 // IWebDocumentText -----------------------------------------------------------
1023
1024 HRESULT STDMETHODCALLTYPE WebFrame::supportsTextEncoding( 
1025     /* [retval][out] */ BOOL* result)
1026 {
1027     *result = FALSE;
1028     return E_NOTIMPL;
1029 }
1030
1031 HRESULT STDMETHODCALLTYPE WebFrame::selectedString( 
1032     /* [retval][out] */ BSTR* result)
1033 {
1034     *result = 0;
1035
1036     Frame* coreFrame = core(this);
1037     if (!coreFrame)
1038         return E_FAIL;
1039
1040     String text = coreFrame->selectedText();
1041     text.replace('\\', coreFrame->backslashAsCurrencySymbol());
1042
1043     *result = BString(text).release();
1044     return S_OK;
1045 }
1046
1047 HRESULT STDMETHODCALLTYPE WebFrame::selectAll()
1048 {
1049     return E_NOTIMPL;
1050 }
1051
1052 HRESULT STDMETHODCALLTYPE WebFrame::deselectAll()
1053 {
1054     return E_NOTIMPL;
1055 }
1056
1057 // WebFrame ---------------------------------------------------------------
1058
1059 void WebFrame::initWithWebFrameView(IWebFrameView* /*view*/, IWebView* webView, Page* page, HTMLFrameOwnerElement* ownerElement)
1060 {
1061     if (FAILED(webView->QueryInterface(&d->webView)))
1062         return;
1063     d->webView->Release(); // don't hold the extra ref
1064
1065     HWND viewWindow;
1066     d->webView->viewWindow((OLE_HANDLE*)&viewWindow);
1067
1068     this->AddRef(); // We release this ref in frameLoaderDestroyed()
1069     Frame* frame = new Frame(page, ownerElement, this);
1070     d->frame = frame;
1071
1072     FrameView* frameView = new FrameView(frame);
1073
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.
1076
1077     frameView->setContainingWindow(viewWindow);
1078 }
1079
1080 Frame* WebFrame::impl()
1081 {
1082     return d->frame;
1083 }
1084
1085 void WebFrame::invalidate()
1086 {
1087     Frame* coreFrame = core(this);
1088     ASSERT(coreFrame);
1089
1090     if (Document* document = coreFrame->document())
1091         document->recalcStyle(Node::Force);
1092 }
1093
1094 void WebFrame::setTextSizeMultiplier(float multiplier)
1095 {
1096     int newZoomFactor = (int)round(multiplier * 100);
1097     Frame* coreFrame = core(this);
1098     ASSERT(coreFrame);
1099
1100     if (coreFrame->zoomFactor() == newZoomFactor)
1101         return;
1102
1103     coreFrame->setZoomFactor(newZoomFactor);
1104 }
1105
1106 HRESULT WebFrame::inViewSourceMode(BOOL* flag)
1107 {
1108     if (!flag) {
1109         ASSERT_NOT_REACHED();
1110         return E_POINTER;
1111     }
1112
1113     *flag = FALSE;
1114
1115     Frame* coreFrame = core(this);
1116     if (!coreFrame)
1117         return E_FAIL;
1118
1119     *flag = coreFrame->inViewSourceMode() ? TRUE : FALSE;
1120     return S_OK;
1121 }
1122
1123 HRESULT WebFrame::setInViewSourceMode(BOOL flag)
1124 {
1125     Frame* coreFrame = core(this);
1126     if (!coreFrame)
1127         return E_FAIL;
1128
1129     coreFrame->setInViewSourceMode(!!flag);
1130     return S_OK;
1131 }
1132
1133 HRESULT WebFrame::elementWithName(BSTR name, IDOMElement* form, IDOMElement** element)
1134 {
1135     if (!form)
1136         return E_INVALIDARG;
1137
1138     HTMLFormElement *formElement = formElementFromDOMElement(form);
1139     if (formElement) {
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);
1147                 return S_OK;
1148             }
1149         }
1150     }
1151     return E_FAIL;
1152 }
1153
1154 HRESULT WebFrame::formForElement(IDOMElement* element, IDOMElement** form)
1155 {
1156     if (!element)
1157         return E_INVALIDARG;
1158
1159     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1160     if (!inputElement)
1161         return E_FAIL;
1162
1163     HTMLFormElement *formElement = inputElement->form();
1164     if (!formElement)
1165         return E_FAIL;
1166
1167     *form = DOMElement::createInstance(formElement);
1168     return S_OK;
1169 }
1170
1171 HRESULT WebFrame::elementDoesAutoComplete(IDOMElement *element, bool *result)
1172 {
1173     *result = false;
1174     if (!element)
1175         return E_INVALIDARG;
1176
1177     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1178     if (!inputElement)
1179         *result = false;
1180     else
1181         *result = (inputElement->inputType() == HTMLInputElement::TEXT && inputElement->autoComplete());
1182
1183     return S_OK;
1184 }
1185
1186 HRESULT WebFrame::controlsInForm(IDOMElement* form, IDOMElement** controls, int* cControls)
1187 {
1188     if (!form)
1189         return E_INVALIDARG;
1190
1191     HTMLFormElement *formElement = formElementFromDOMElement(form);
1192     if (!formElement)
1193         return E_FAIL;
1194
1195     int inCount = *cControls;
1196     int count = (int) formElement->formElements.size();
1197     *cControls = count;
1198     if (!controls)
1199         return S_OK;
1200     if (inCount < count)
1201         return E_FAIL;
1202
1203     *cControls = 0;
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));
1208             (*cControls)++;
1209         }
1210     }
1211     return S_OK;
1212 }
1213
1214 HRESULT WebFrame::elementIsPassword(IDOMElement *element, bool *result)
1215 {
1216     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1217     *result = inputElement != 0
1218         && inputElement->inputType() == HTMLInputElement::PASSWORD;
1219     return S_OK;
1220 }
1221
1222 HRESULT WebFrame::searchForLabelsBeforeElement(const BSTR* labels, int cLabels, IDOMElement* beforeElement, BSTR* result)
1223 {
1224     if (!result) {
1225         ASSERT_NOT_REACHED();
1226         return E_POINTER;
1227     }
1228
1229     *result = 0;
1230
1231     if (!cLabels)
1232         return S_OK;
1233     if (cLabels < 1)
1234         return E_INVALIDARG;
1235
1236     Frame* coreFrame = core(this);
1237     if (!coreFrame)
1238         return E_FAIL;
1239
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);
1244     if (!coreElement)
1245         return E_FAIL;
1246
1247     String label = coreFrame->searchForLabelsBeforeElement(labelStrings, coreElement);
1248     
1249     *result = SysAllocStringLen(label.characters(), label.length());
1250     if (label.length() && !*result)
1251         return E_OUTOFMEMORY;
1252     return S_OK;
1253 }
1254
1255 HRESULT WebFrame::matchLabelsAgainstElement(const BSTR* labels, int cLabels, IDOMElement* againstElement, BSTR* result)
1256 {
1257     if (!result) {
1258         ASSERT_NOT_REACHED();
1259         return E_POINTER;
1260     }
1261
1262     *result = 0;
1263
1264     if (!cLabels)
1265         return S_OK;
1266     if (cLabels < 1)
1267         return E_INVALIDARG;
1268
1269     Frame* coreFrame = core(this);
1270     if (!coreFrame)
1271         return E_FAIL;
1272
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);
1277     if (!coreElement)
1278         return E_FAIL;
1279
1280     String label = coreFrame->matchLabelsAgainstElement(labelStrings, coreElement);
1281     
1282     *result = SysAllocStringLen(label.characters(), label.length());
1283     if (label.length() && !*result)
1284         return E_OUTOFMEMORY;
1285     return S_OK;
1286 }
1287
1288 HRESULT WebFrame::canProvideDocumentSource(bool* result)
1289 {
1290     HRESULT hr = S_OK;
1291     *result = false;
1292
1293     COMPtr<IWebDataSource> dataSource;
1294     hr = WebFrame::dataSource(&dataSource);
1295     if (FAILED(hr))
1296         return hr;
1297
1298     COMPtr<IWebURLResponse> urlResponse;
1299     hr = dataSource->response(&urlResponse);
1300     if (SUCCEEDED(hr) && urlResponse) {
1301         BSTR mimeTypeBStr;
1302         if (SUCCEEDED(urlResponse->MIMEType(&mimeTypeBStr))) {
1303             String mimeType(mimeTypeBStr, SysStringLen(mimeTypeBStr));
1304             *result = mimeType == "text/html" || WebCore::DOMImplementation::isXMLMIMEType(mimeType);
1305             SysFreeString(mimeTypeBStr);
1306         }
1307     }
1308     return hr;
1309 }
1310
1311 // FrameWinClient
1312
1313 void WebFrame::ref()
1314 {
1315     this->AddRef();
1316 }
1317
1318 void WebFrame::deref()
1319 {
1320     this->Release();
1321 }
1322
1323 void WebFrame::frameLoaderDestroyed()
1324 {
1325     // The FrameLoader going away is equivalent to the Frame going away,
1326     // so we now need to clear our frame pointer.
1327     d->frame = 0;
1328
1329     this->Release();
1330 }
1331
1332 PassRefPtr<Frame> WebFrame::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
1333 {
1334     Frame* coreFrame = core(this);
1335     ASSERT(coreFrame);
1336
1337     COMPtr<WebFrame> webFrame;
1338     webFrame.adoptRef(WebFrame::createInstance());
1339
1340     webFrame->initWithWebFrameView(0, d->webView, coreFrame->page(), ownerElement);
1341
1342     RefPtr<Frame> childFrame(adoptRef(core(webFrame.get()))); // We have to adopt, because Frames start out with a refcount of 1.
1343     ASSERT(childFrame);
1344
1345     coreFrame->tree()->appendChild(childFrame);
1346     childFrame->tree()->setName(name);
1347     childFrame->init();
1348
1349     loadURLIntoChild(URL, referrer, webFrame.get());
1350
1351     // The frame's onload handler may have removed it from the document.
1352     if (!childFrame->tree()->parent())
1353         return 0;
1354
1355     return childFrame.release();
1356 }
1357
1358 void WebFrame::loadURLIntoChild(const KURL& originalURL, const String& referrer, WebFrame* childFrame)
1359 {
1360     ASSERT(childFrame);
1361     ASSERT(core(childFrame));
1362
1363     Frame* coreFrame = core(this);
1364     ASSERT(coreFrame);
1365
1366     HistoryItem* parentItem = coreFrame->loader()->currentHistoryItem();
1367     FrameLoadType loadType = coreFrame->loader()->loadType();
1368     FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedHistory;
1369
1370     KURL url = originalURL;
1371
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))
1379     {
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;
1387
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);
1391             else
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);
1394         }
1395     }
1396
1397     // FIXME: Handle loading WebArchives here
1398
1399     core(childFrame)->loader()->load(url, referrer, childLoadType, String(), 0, 0);
1400 }
1401
1402 void WebFrame::openURL(const String& URL, const Event* triggeringEvent, bool newWindow, bool lockHistory)
1403 {
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();
1415         }
1416     }
1417
1418     if (ctrlPressed)
1419         newWindow = true;
1420
1421     BString urlBStr = URL;
1422
1423     IWebMutableURLRequest* request = WebMutableURLRequest::createInstance();
1424     if (FAILED(request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 0)))
1425         goto exit;
1426
1427     if (newWindow) {
1428         // new tab/window
1429         IWebUIDelegate* ui;
1430         IWebView* newWebView;
1431         if (SUCCEEDED(d->webView->uiDelegate(&ui)) && ui) {
1432             if (SUCCEEDED(ui->createWebViewWithRequest(d->webView, request, &newWebView))) {
1433                 if (shiftPressed) {
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);
1437                 }
1438                 newWebView->Release();
1439                 newWebView = 0;
1440             }
1441             ui->Release();
1442         }
1443     } else {
1444         m_quickRedirectComing = lockHistory;
1445         loadRequest(request);
1446     }
1447
1448 exit:
1449     request->Release();
1450 }
1451
1452 void WebFrame::dispatchDidHandleOnloadEvents()
1453 {
1454     IWebFrameLoadDelegatePrivate* frameLoadDelegatePriv;
1455     if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv))  && frameLoadDelegatePriv) {
1456         frameLoadDelegatePriv->didHandleOnloadEventsForFrame(d->webView, this);
1457         frameLoadDelegatePriv->Release();
1458     }
1459 }
1460
1461 void WebFrame::windowScriptObjectAvailable(JSContextRef context, JSObjectRef windowObject)
1462 {
1463     IWebFrameLoadDelegate* frameLoadDelegate;
1464     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)) && frameLoadDelegate) {
1465         frameLoadDelegate->windowScriptObjectAvailable(d->webView, context, windowObject);
1466         frameLoadDelegate->Release();
1467     }
1468 }
1469
1470 WebHistory* WebFrame::webHistory()
1471 {
1472     if (this != d->webView->topLevelFrame())
1473         return 0;
1474
1475     IWebHistoryPrivate* historyInternal = WebHistory::optionalSharedHistoryInternal(); // does not add a ref
1476     if (!historyInternal)
1477         return 0;
1478
1479     WebHistory* webHistory;
1480     if (FAILED(historyInternal->QueryInterface(&webHistory)))
1481         return 0;
1482
1483     return webHistory;
1484 }
1485
1486 bool WebFrame::hasWebView() const
1487 {
1488     return !!d->webView;
1489 }
1490
1491 bool WebFrame::hasFrameView() const
1492 {
1493     return !!d->frameView();
1494 }
1495
1496 bool WebFrame::privateBrowsingEnabled() const
1497 {
1498     BOOL privateBrowsingEnabled = FALSE;
1499     COMPtr<IWebPreferences> preferences;
1500     if (SUCCEEDED(d->webView->preferences(&preferences)))
1501         preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
1502     return !!privateBrowsingEnabled;
1503 }
1504
1505 void WebFrame::makeDocumentView()
1506 {
1507     ASSERT(core(this));
1508     
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();
1512 }
1513
1514 void WebFrame::makeRepresentation(DocumentLoader*)
1515 {
1516     notImplemented();
1517 }
1518
1519 void WebFrame::forceLayout()
1520 {
1521     notImplemented();
1522 }
1523
1524 void WebFrame::forceLayoutForNonHTML()
1525 {
1526     notImplemented();
1527 }
1528
1529 void WebFrame::setCopiesOnScroll()
1530 {
1531     notImplemented();
1532 }
1533
1534 void WebFrame::detachedFromParent1()
1535 {
1536     notImplemented();
1537 }
1538
1539 void WebFrame::detachedFromParent2()
1540 {
1541     notImplemented();
1542 }
1543
1544 void WebFrame::detachedFromParent3()
1545 {
1546     notImplemented();
1547 }
1548
1549 void WebFrame::detachedFromParent4()
1550 {
1551     notImplemented();
1552 }
1553
1554 void WebFrame::loadedFromCachedPage()
1555 {
1556     notImplemented();
1557 }
1558
1559 void WebFrame::dispatchDidReceiveServerRedirectForProvisionalLoad()
1560 {
1561     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1562     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1563         frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(d->webView, this);
1564 }
1565
1566 void WebFrame::dispatchDidCancelClientRedirect()
1567 {
1568     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1569     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1570         frameLoadDelegate->didCancelClientRedirectForFrame(d->webView, this);
1571 }
1572
1573 void WebFrame::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
1574 {
1575     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1576     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1577         frameLoadDelegate->willPerformClientRedirectToURL(d->webView, BString(url.url()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), this);
1578 }
1579
1580 void WebFrame::dispatchDidChangeLocationWithinPage()
1581 {
1582     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1583     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1584         frameLoadDelegate->didChangeLocationWithinPageForFrame(d->webView, this);
1585 }
1586
1587 void WebFrame::dispatchWillClose()
1588 {
1589     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1590     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1591         frameLoadDelegate->willCloseFrame(d->webView, this);
1592 }
1593
1594 void WebFrame::dispatchDidReceiveIcon()
1595 {
1596     d->webView->dispatchDidReceiveIconFromWebFrame(this);
1597 }
1598
1599 void WebFrame::dispatchDidStartProvisionalLoad()
1600 {
1601     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1602     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1603         frameLoadDelegate->didStartProvisionalLoadForFrame(d->webView, this);
1604 }
1605
1606 void WebFrame::dispatchDidReceiveTitle(const String& title)
1607 {
1608     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1609     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1610         frameLoadDelegate->didReceiveTitle(d->webView, BString(title), this);
1611 }
1612
1613 void WebFrame::dispatchDidCommitLoad()
1614 {
1615     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1616     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) 
1617         frameLoadDelegate->didCommitLoadForFrame(d->webView, this);
1618 }
1619
1620 void WebFrame::dispatchDidFinishDocumentLoad()
1621 {
1622     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
1623     if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
1624         frameLoadDelegatePriv->didFinishDocumentLoadForFrame(d->webView, this);
1625 }
1626
1627 void WebFrame::dispatchDidFinishLoad()
1628 {
1629     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1630     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) 
1631         frameLoadDelegate->didFinishLoadForFrame(d->webView, this);
1632 }
1633
1634 void WebFrame::dispatchDidFirstLayout()
1635 {
1636     COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
1637     if (SUCCEEDED(d->webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
1638         frameLoadDelegatePriv->didFirstLayoutInFrame(d->webView, this);
1639 }
1640
1641 void WebFrame::dispatchShow()
1642 {
1643     COMPtr<IWebUIDelegate> ui;
1644
1645     if (SUCCEEDED(d->webView->uiDelegate(&ui)))
1646         ui->webViewShow(d->webView);
1647 }
1648
1649 void WebFrame::cancelPolicyCheck()
1650 {
1651     if (d->m_policyListener) {
1652         d->m_policyListener->invalidate();
1653         d->m_policyListener = 0;
1654     }
1655
1656     d->m_policyFunction = 0;
1657 }
1658
1659 void WebFrame::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
1660 {
1661     Frame* coreFrame = core(this);
1662     ASSERT(coreFrame);
1663
1664     COMPtr<IWebFormDelegate> formDelegate;
1665
1666     if (FAILED(d->webView->formDelegate(&formDelegate))) {
1667         (coreFrame->loader()->*function)(PolicyUse);
1668         return;
1669     }
1670
1671     COMPtr<IDOMElement> formElement;
1672     formElement.adoptRef(DOMElement::createInstance(formState->form()));
1673
1674     // FIXME: The FormValuesPropertyBag constructor should take a const pointer
1675     FormValuesPropertyBag formValuesPropBag(const_cast<HashMap<String, String>*>(&formState->values()));
1676
1677     COMPtr<WebFrame> sourceFrame(kit(formState->sourceFrame()));
1678     if (SUCCEEDED(formDelegate->willSubmitForm(this, sourceFrame.get(), formElement.get(), &formValuesPropBag, setUpPolicyListener(function).get())))
1679         return;
1680
1681     // FIXME: Add a sane default implementation
1682     (coreFrame->loader()->*function)(PolicyUse);
1683 }
1684
1685 void WebFrame::dispatchDidLoadMainResource(DocumentLoader* loader)
1686 {
1687     if (WebScriptDebugServer::listenerCount() > 0) {
1688         Frame* coreFrame = core(this);
1689         if (!coreFrame)
1690             return;
1691
1692         WebScriptDebugServer::sharedWebScriptDebugServer()->didLoadMainResourceForDataSource(
1693             kit(coreFrame->page()),
1694             loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0);
1695     }
1696 }
1697
1698 void WebFrame::revertToProvisionalState(DocumentLoader*)
1699 {
1700     notImplemented();
1701 }
1702
1703 void WebFrame::clearUnarchivingState(DocumentLoader*)
1704 {
1705     notImplemented();
1706 }
1707
1708 void WebFrame::setMainFrameDocumentReady(bool)
1709 {
1710     notImplemented();
1711 }
1712
1713 void WebFrame::willChangeTitle(DocumentLoader*)
1714 {
1715     notImplemented();
1716 }
1717
1718 void WebFrame::didChangeTitle(DocumentLoader*)
1719 {
1720     notImplemented();
1721 }
1722
1723 void WebFrame::finishedLoading(DocumentLoader* loader)
1724 {
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);
1730     else {
1731         if (d->m_pluginView->status() == PluginStatusLoadedSuccessfully)
1732             d->m_pluginView->didFinishLoading();
1733         d->m_pluginView = 0;
1734         d->m_hasSentResponseToPlugin = false;
1735     }
1736 }
1737
1738 void WebFrame::finalSetupForReplace(DocumentLoader*)
1739 {
1740     notImplemented();
1741 }
1742
1743 void WebFrame::setDefersLoading(bool)
1744 {
1745     notImplemented();
1746 }
1747
1748 bool WebFrame::isArchiveLoadPending(ResourceLoader*) const
1749 {
1750     notImplemented();
1751     return false;
1752 }
1753
1754 void WebFrame::cancelPendingArchiveLoad(ResourceLoader*)
1755 {
1756     notImplemented();
1757 }
1758
1759 void WebFrame::clearArchivedResources()
1760 {
1761     notImplemented();
1762 }
1763
1764 bool WebFrame::canHandleRequest(const ResourceRequest& request) const
1765 {
1766     return WebView::canHandleRequest(request);
1767 }
1768
1769 bool WebFrame::canShowMIMEType(const String& /*MIMEType*/) const
1770 {
1771     notImplemented();
1772     return true;
1773 }
1774
1775 bool WebFrame::representationExistsForURLScheme(const String& /*URLScheme*/) const
1776 {
1777     notImplemented();
1778     return false;
1779 }
1780
1781 String WebFrame::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
1782 {
1783     notImplemented();
1784     ASSERT_NOT_REACHED();
1785     return String();
1786 }
1787
1788 void WebFrame::frameLoadCompleted()
1789 {
1790     if (Frame* coreFrame = core(this))
1791         coreFrame->loader()->setPreviousHistoryItem(0);
1792 }
1793
1794 void WebFrame::restoreViewState()
1795 {
1796     // FIXME: Need to restore view state for page caching
1797     notImplemented();
1798 }
1799
1800 void WebFrame::provisionalLoadStarted()
1801 {
1802     notImplemented();
1803 }
1804
1805 bool WebFrame::shouldTreatURLAsSameAsCurrent(const KURL&) const
1806 {
1807     notImplemented();
1808     return false;
1809 }
1810
1811 void WebFrame::addHistoryItemForFragmentScroll()
1812 {
1813     notImplemented();
1814 }
1815
1816 void WebFrame::didFinishLoad()
1817 {
1818     notImplemented();
1819 }
1820
1821 void WebFrame::prepareForDataSourceReplacement()
1822 {
1823     notImplemented();
1824 }
1825
1826 void WebFrame::setTitle(const String& title, const KURL& url)
1827 {
1828     BOOL privateBrowsingEnabled = FALSE;
1829     COMPtr<IWebPreferences> preferences;
1830     if (SUCCEEDED(d->webView->preferences(&preferences)))
1831         preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
1832     if (!privateBrowsingEnabled) {
1833         // update title in global history
1834         COMPtr<WebHistory> history;
1835         history.adoptRef(webHistory());
1836         if (history) {
1837             COMPtr<IWebHistoryItem> item;
1838             if (SUCCEEDED(history->itemForURL(BString(url.url()), &item))) {
1839                 COMPtr<IWebHistoryItemPrivate> itemPrivate;
1840                 if (SUCCEEDED(item->QueryInterface(IID_IWebHistoryItemPrivate, (void**)&itemPrivate)))
1841                     itemPrivate->setTitle(BString(title));
1842             }
1843         }
1844     }
1845 }
1846
1847 String WebFrame::userAgent(const KURL& url)
1848 {
1849     return d->webView->userAgentForKURL(url);
1850 }
1851
1852 void WebFrame::setDocumentViewFromCachedPage(CachedPage*)
1853 {
1854     notImplemented();
1855 }
1856
1857 void WebFrame::updateGlobalHistoryForStandardLoad(const KURL& url)
1858 {
1859     COMPtr<WebHistory> history;
1860     history.adoptRef(webHistory());
1861
1862     if (!history)
1863         return;
1864
1865     history->addItemForURL(BString(url.url()), 0);                 
1866 }
1867
1868 void WebFrame::updateGlobalHistoryForReload(const KURL& url)
1869 {
1870     BString urlBStr(url.url());
1871
1872     COMPtr<WebHistory> history;
1873     history.adoptRef(webHistory());
1874
1875     if (!history)
1876         return;
1877
1878     COMPtr<IWebHistoryItem> item;
1879     if (SUCCEEDED(history->itemForURL(urlBStr, &item))) {
1880         COMPtr<IWebHistoryItemPrivate> itemPrivate;
1881         if (SUCCEEDED(item->QueryInterface(IID_IWebHistoryItemPrivate, (void**)&itemPrivate))) {
1882             SYSTEMTIME currentTime;
1883             GetSystemTime(&currentTime);
1884             DATE visitedTime = 0;
1885             SystemTimeToVariantTime(&currentTime, &visitedTime);
1886
1887             // FIXME - bumping the last visited time doesn't mark the history as changed
1888             itemPrivate->setLastVisitedTimeInterval(visitedTime);
1889         }
1890     }
1891 }
1892
1893 bool WebFrame::shouldGoToHistoryItem(HistoryItem*) const
1894 {
1895     notImplemented();
1896     return true;
1897 }
1898
1899 void WebFrame::saveViewStateToItem(HistoryItem*)
1900 {
1901     // FIXME: Need to save view state for page caching
1902     notImplemented();
1903 }
1904
1905 void WebFrame::saveDocumentViewToCachedPage(CachedPage*)
1906 {
1907     notImplemented();
1908 }
1909
1910 bool WebFrame::canCachePage() const
1911 {
1912     notImplemented();
1913     return false;
1914 }
1915
1916 PassRefPtr<DocumentLoader> WebFrame::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
1917 {
1918     RefPtr<WebDocumentLoader> loader = new WebDocumentLoader(request, substituteData);
1919  
1920     COMPtr<WebDataSource> dataSource;
1921     dataSource.adoptRef(WebDataSource::createInstance(loader.get()));
1922
1923     loader->setDataSource(dataSource.get());
1924     return loader.release();
1925 }
1926
1927 void WebFrame::setMainDocumentError(DocumentLoader*, const ResourceError& error)
1928 {
1929     if (d->m_pluginView) {
1930         if (d->m_pluginView->status() == PluginStatusLoadedSuccessfully)
1931             d->m_pluginView->didFail(error);
1932         d->m_pluginView = 0;
1933         d->m_hasSentResponseToPlugin = false;
1934     }
1935 }
1936
1937 ResourceError WebFrame::cancelledError(const ResourceRequest& request)
1938 {
1939     // FIXME: Need ChickenCat to include CFNetwork/CFURLError.h to get these values
1940     // Alternatively, we could create our own error domain/codes.
1941     return ResourceError(String(WebURLErrorDomain), -999, request.url().url(), String());
1942 }
1943
1944 ResourceError WebFrame::blockedError(const ResourceRequest& request)
1945 {
1946     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1947     return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotUseRestrictedPort, request.url().url(), String());
1948 }
1949
1950 ResourceError WebFrame::cannotShowURLError(const ResourceRequest&)
1951 {
1952     notImplemented();
1953     return ResourceError();
1954 }
1955
1956 ResourceError WebFrame::interruptForPolicyChangeError(const ResourceRequest& request)
1957 {
1958     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1959     return ResourceError(String(WebKitErrorDomain), WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().url(), String());
1960 }
1961
1962 ResourceError WebFrame::cannotShowMIMETypeError(const ResourceResponse&)
1963 {
1964     notImplemented();
1965     return ResourceError();
1966 }
1967
1968 ResourceError WebFrame::fileDoesNotExistError(const ResourceResponse&)
1969 {
1970     notImplemented();
1971     return ResourceError();
1972 }
1973
1974 bool WebFrame::shouldFallBack(const ResourceError& error)
1975 {
1976     return error.errorCode() != WebURLErrorCancelled;
1977 }
1978
1979 void WebFrame::receivedData(const char* data, int length, const String& textEncoding)
1980 {
1981     Frame* coreFrame = core(this);
1982     if (!coreFrame)
1983         return;
1984
1985     // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
1986     String encoding = coreFrame->loader()->documentLoader()->overrideEncoding();
1987     bool userChosen = !encoding.isNull();
1988     if (encoding.isNull())
1989         encoding = textEncoding;
1990     coreFrame->loader()->setEncoding(encoding, userChosen);
1991
1992     coreFrame->loader()->addData(data, length);
1993 }
1994
1995 COMPtr<WebFramePolicyListener> WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction function)
1996 {
1997     ASSERT(!d->m_policyListener);
1998     ASSERT(!d->m_policyFunction);
1999
2000     Frame* coreFrame = core(this);
2001     ASSERT(coreFrame);
2002
2003     d->m_policyListener.adoptRef(WebFramePolicyListener::createInstance(coreFrame));
2004     d->m_policyFunction = function;
2005
2006     return d->m_policyListener;
2007 }
2008
2009 void WebFrame::receivedPolicyDecision(PolicyAction action)
2010 {
2011     ASSERT(d->m_policyListener);
2012     ASSERT(d->m_policyFunction);
2013
2014     FramePolicyFunction function = d->m_policyFunction;
2015
2016     d->m_policyListener = 0;
2017     d->m_policyFunction = 0;
2018
2019     Frame* coreFrame = core(this);
2020     ASSERT(coreFrame);
2021
2022     (coreFrame->loader()->*function)(action);
2023 }
2024
2025 void WebFrame::committedLoad(DocumentLoader* loader, const char* data, int length)
2026 {
2027     // FIXME: This should probably go through the data source.
2028     const String& textEncoding = loader->response().textEncodingName();
2029
2030     if (!d->m_pluginView)
2031         receivedData(data, length, textEncoding);
2032
2033     if (d->m_pluginView && d->m_pluginView->status() == PluginStatusLoadedSuccessfully) {
2034         if (!d->m_hasSentResponseToPlugin) {
2035             d->m_pluginView->didReceiveResponse(d->frame->loader()->documentLoader()->response());
2036             // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
2037             // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
2038             // to null
2039             if (!d->m_pluginView)
2040                 return;
2041             d->m_hasSentResponseToPlugin = true;
2042         }
2043         d->m_pluginView->didReceiveData(data, length);
2044     }
2045 }
2046
2047 void WebFrame::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const String& mimeType, const ResourceRequest& request)
2048 {
2049     Frame* coreFrame = core(this);
2050     ASSERT(coreFrame);
2051
2052     COMPtr<IWebPolicyDelegate> policyDelegate;
2053     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
2054         policyDelegate = DefaultPolicyDelegate::sharedInstance();
2055
2056     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
2057
2058     if (SUCCEEDED(policyDelegate->decidePolicyForMIMEType(d->webView, BString(mimeType), urlRequest.get(), this, setUpPolicyListener(function).get())))
2059         return;
2060
2061     (coreFrame->loader()->*function)(PolicyUse);
2062 }
2063
2064 void WebFrame::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request, const String& frameName)
2065 {
2066     Frame* coreFrame = core(this);
2067     ASSERT(coreFrame);
2068
2069     COMPtr<IWebPolicyDelegate> policyDelegate;
2070     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
2071         policyDelegate = DefaultPolicyDelegate::sharedInstance();
2072
2073     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
2074     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, coreFrame));
2075
2076     if (SUCCEEDED(policyDelegate->decidePolicyForNewWindowAction(d->webView, actionInformation.get(), urlRequest.get(), BString(frameName), setUpPolicyListener(function).get())))
2077         return;
2078
2079     (coreFrame->loader()->*function)(PolicyUse);
2080 }
2081
2082 void WebFrame::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request)
2083 {
2084     Frame* coreFrame = core(this);
2085     ASSERT(coreFrame);
2086
2087     COMPtr<IWebPolicyDelegate> policyDelegate;
2088     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
2089         policyDelegate = DefaultPolicyDelegate::sharedInstance();
2090
2091     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
2092     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, coreFrame));
2093
2094     if (SUCCEEDED(policyDelegate->decidePolicyForNavigationAction(d->webView, actionInformation.get(), urlRequest.get(), this, setUpPolicyListener(function).get())))
2095         return;
2096
2097     (coreFrame->loader()->*function)(PolicyUse);
2098 }
2099
2100 void WebFrame::dispatchUnableToImplementPolicy(const ResourceError& error)
2101 {
2102     COMPtr<IWebPolicyDelegate> policyDelegate;
2103     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
2104         policyDelegate = DefaultPolicyDelegate::sharedInstance();
2105
2106     COMPtr<IWebError> webError(AdoptCOM, WebError::createInstance(error));
2107     policyDelegate->unableToImplementPolicyWithError(d->webView, webError.get(), this);
2108 }
2109
2110 void WebFrame::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest&, const ResourceResponse& response)
2111 {
2112     COMPtr<IWebDownloadDelegate> downloadDelegate;
2113     COMPtr<IWebView> webView;
2114     if (SUCCEEDED(this->webView(&webView))) {
2115         if (FAILED(webView->downloadDelegate(&downloadDelegate))) {
2116             // If the WebView doesn't successfully provide a download delegate we'll pass a null one
2117             // into the WebDownload - which may or may not decide to use a DefaultDownloadDelegate
2118             LOG_ERROR("Failed to get downloadDelegate from WebView");
2119             downloadDelegate = 0;
2120         }
2121     }
2122
2123     // Its the delegate's job to ref the WebDownload to keep it alive - otherwise it will be destroyed
2124     // when this method returns
2125     COMPtr<WebDownload> download;
2126     download.adoptRef(WebDownload::createInstance(handle, request, response, downloadDelegate.get()));
2127 }
2128
2129 bool WebFrame::willUseArchive(ResourceLoader*, const ResourceRequest&, const KURL&) const
2130 {
2131     notImplemented();
2132     return false;
2133 }
2134
2135 void WebFrame::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
2136 {
2137     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2138     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2139         COMPtr<IWebURLRequest> webURLRequest;
2140         webURLRequest.adoptRef(WebMutableURLRequest::createInstance(request));
2141
2142         resourceLoadDelegate->identifierForInitialRequest(d->webView, webURLRequest.get(), getWebDataSource(loader), identifier);
2143     }
2144 }
2145
2146 void WebFrame::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
2147 {
2148     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2149     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2150         COMPtr<IWebURLRequest> webURLRequest;
2151         webURLRequest.adoptRef(WebMutableURLRequest::createInstance(request));
2152         COMPtr<IWebURLResponse> webURLRedirectResponse;
2153         webURLRedirectResponse.adoptRef(WebURLResponse::createInstance(redirectResponse));
2154         COMPtr<IWebURLRequest> newWebURLRequest;
2155
2156         if (FAILED(resourceLoadDelegate->willSendRequest(d->webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest)))
2157             return;
2158
2159         if (webURLRequest == newWebURLRequest)
2160             return;
2161
2162         COMPtr<WebMutableURLRequest> newWebURLRequestImpl;
2163         if (FAILED(newWebURLRequest->QueryInterface(&newWebURLRequestImpl)))
2164             return;
2165
2166         request = newWebURLRequestImpl->resourceRequest();
2167     }
2168 }
2169
2170 void WebFrame::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
2171 {
2172     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2173     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2174         COMPtr<IWebURLResponse> webURLResponse;
2175         webURLResponse.adoptRef(WebURLResponse::createInstance(response));
2176
2177         resourceLoadDelegate->didReceiveResponse(d->webView, identifier, webURLResponse.get(), getWebDataSource(loader));
2178     }
2179 }
2180
2181 void WebFrame::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
2182 {
2183     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2184     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
2185         resourceLoadDelegate->didReceiveContentLength(d->webView, identifier, length, getWebDataSource(loader));
2186 }
2187
2188 void WebFrame::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
2189 {
2190     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2191     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
2192         resourceLoadDelegate->didFinishLoadingFromDataSource(d->webView, identifier, getWebDataSource(loader));
2193 }
2194
2195 void WebFrame::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
2196 {
2197     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2198     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2199         COMPtr<IWebError> webError;
2200         webError.adoptRef(WebError::createInstance(error));
2201         resourceLoadDelegate->didFailLoadingWithError(d->webView, identifier, webError.get(), getWebDataSource(loader));
2202     }
2203 }
2204
2205 bool WebFrame::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
2206 {
2207     notImplemented();
2208     return false;
2209 }
2210
2211 void WebFrame::dispatchDidFailProvisionalLoad(const ResourceError& error)
2212 {
2213     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
2214     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
2215         COMPtr<IWebError> webError;
2216         webError.adoptRef(WebError::createInstance(error));
2217         frameLoadDelegate->didFailProvisionalLoadWithError(d->webView, webError.get(), this);
2218     }
2219 }
2220
2221 void WebFrame::dispatchDidFailLoad(const ResourceError& error)
2222 {
2223     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
2224     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
2225         COMPtr<IWebError> webError;
2226         webError.adoptRef(WebError::createInstance(error));
2227         frameLoadDelegate->didFailLoadWithError(d->webView, webError.get(), this);
2228     }
2229 }
2230
2231 Frame* WebFrame::dispatchCreatePage()
2232 {
2233     COMPtr<IWebUIDelegate> ui;
2234
2235     if (SUCCEEDED(d->webView->uiDelegate(&ui))) {
2236         COMPtr<IWebView> newWebView;
2237
2238         if (SUCCEEDED(ui->createWebViewWithRequest(d->webView, 0, &newWebView))) {
2239             COMPtr<IWebFrame> mainFrame;
2240
2241             if (SUCCEEDED(newWebView->mainFrame(&mainFrame))) {
2242                 COMPtr<WebFrame> mainFrameImpl;
2243
2244                 if (SUCCEEDED(mainFrame->QueryInterface(IID_WebFrame, (void**)&mainFrameImpl)))
2245                     return core(mainFrameImpl.get());
2246             }
2247         }
2248     }
2249     return 0;
2250 }
2251
2252 void WebFrame::postProgressStartedNotification()
2253 {
2254     static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
2255     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
2256     notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(d->webView), 0);
2257 }
2258
2259 void WebFrame::postProgressEstimateChangedNotification()
2260 {
2261     static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
2262     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
2263     notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(d->webView), 0);
2264 }
2265
2266 void WebFrame::postProgressFinishedNotification()
2267 {
2268     static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
2269     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
2270     notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(d->webView), 0);
2271 }
2272
2273 void WebFrame::startDownload(const ResourceRequest&)
2274 {
2275     notImplemented();
2276 }
2277
2278 void WebFrame::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
2279 {
2280     ASSERT(challenge.sourceHandle());
2281
2282     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2283     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2284         COMPtr<IWebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
2285
2286         if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(d->webView, identifier, webChallenge.get(), getWebDataSource(loader))))
2287             return;
2288     }
2289
2290     // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle
2291     // to continue without credential - this is the best approximation of Mac behavior
2292     challenge.sourceHandle()->receivedRequestToContinueWithoutCredential(challenge);
2293 }
2294
2295 void WebFrame::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
2296 {
2297     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2298     if (SUCCEEDED(d->webView->resourceLoadDelegate(&resourceLoadDelegate))) {
2299         COMPtr<IWebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
2300
2301         if (SUCCEEDED(resourceLoadDelegate->didCancelAuthenticationChallenge(d->webView, identifier, webChallenge.get(), getWebDataSource(loader))))
2302             return;
2303     }
2304 }
2305
2306 PassRefPtr<Frame> WebFrame::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
2307                             const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
2308 {
2309     RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
2310     if (!result)
2311         return 0;
2312
2313     // Propagate the marginwidth/height and scrolling modes to the view.
2314     if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag)) {
2315         HTMLFrameElement* frameElt = static_cast<HTMLFrameElement*>(ownerElement);
2316         if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
2317             result->view()->setScrollbarsMode(ScrollbarAlwaysOff);
2318         int marginWidth = frameElt->getMarginWidth();
2319         int marginHeight = frameElt->getMarginHeight();
2320         if (marginWidth != -1)
2321             result->view()->setMarginWidth(marginWidth);
2322         if (marginHeight != -1)
2323             result->view()->setMarginHeight(marginHeight);
2324     }
2325
2326     return result.release();
2327 }
2328
2329 Widget* WebFrame::createPlugin(const IntSize& pluginSize, Element* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
2330 {
2331     PluginViewWin* pluginView = PluginDatabaseWin::installedPlugins()->createPluginView(core(this), pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
2332
2333     if (pluginView->status() == PluginStatusLoadedSuccessfully)
2334         return pluginView;
2335
2336     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2337
2338     if (FAILED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
2339         return pluginView;
2340
2341     RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
2342
2343     unsigned count = (unsigned)paramNames.size();
2344     for (unsigned i = 0; i < count; i++) {
2345         if (paramNames[i] == "pluginspage") {
2346             static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
2347             RetainPtr<CFStringRef> str(AdoptCF, paramValues[i].createCFString());
2348             CFDictionarySetValue(userInfo.get(), key, str.get());
2349             break;
2350         }
2351     }
2352
2353     if (!mimeType.isNull()) {
2354         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
2355
2356         RetainPtr<CFStringRef> str(AdoptCF, mimeType.createCFString());
2357         CFDictionarySetValue(userInfo.get(), key, str.get());
2358     }
2359
2360     String pluginName;
2361     if (pluginView->plugin())
2362         pluginName = pluginView->plugin()->name();
2363     if (!pluginName.isNull()) {
2364         static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
2365         RetainPtr<CFStringRef> str(AdoptCF, pluginName.createCFString());
2366         CFDictionarySetValue(userInfo.get(), key, str.get());
2367     }
2368
2369     COMPtr<CFDictionaryPropertyBag> userInfoBag(AdoptCOM, CFDictionaryPropertyBag::createInstance());
2370     userInfoBag->setDictionary(userInfo.get());
2371  
2372     int errorCode = 0;
2373     switch (pluginView->status()) {
2374         case PluginStatusCanNotFindPlugin:
2375             errorCode = WebKitErrorCannotFindPlugIn;
2376             break;
2377         case PluginStatusCanNotLoadPlugin:
2378             errorCode = WebKitErrorCannotLoadPlugIn;
2379             break;
2380         default:
2381             ASSERT_NOT_REACHED();
2382     }
2383
2384     ResourceError resourceError(String(WebKitErrorDomain), errorCode, url.url(), String());
2385     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
2386      
2387     resourceLoadDelegate->plugInFailedWithError(d->webView, error.get(), getWebDataSource(d->frame->loader()->documentLoader()));
2388
2389     return pluginView;
2390 }
2391
2392 void WebFrame::redirectDataToPlugin(Widget* pluginWidget)
2393 {
2394     // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
2395
2396     d->m_pluginView = static_cast<PluginViewWin*>(pluginWidget);
2397 }
2398
2399 Widget* WebFrame::createJavaAppletWidget(const IntSize& pluginSize, Element* element, const KURL& /*baseURL*/, const Vector<String>& paramNames, const Vector<String>& paramValues)
2400 {
2401     PluginViewWin* pluginView = PluginDatabaseWin::installedPlugins()->
2402         createPluginView(core(this), pluginSize, element, KURL(), paramNames, paramValues, "application/x-java-applet", false);
2403
2404     // Check if the plugin can be loaded successfully
2405     if (pluginView->plugin()->load())
2406         return pluginView;
2407
2408     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
2409     if (FAILED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
2410         return pluginView;
2411
2412     COMPtr<CFDictionaryPropertyBag> userInfoBag(AdoptCOM, CFDictionaryPropertyBag::createInstance());
2413
2414     ResourceError resourceError(String(WebKitErrorDomain), WebKitErrorJavaUnavailable, String(), String());
2415     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
2416      
2417     resourceLoadDelegate->plugInFailedWithError(d->webView, error.get(), getWebDataSource(d->frame->loader()->documentLoader()));
2418
2419     return pluginView;
2420 }
2421
2422 ObjectContentType WebFrame::objectContentType(const KURL& url, const String& mimeTypeIn)
2423 {
2424     String mimeType = mimeTypeIn;
2425     if (mimeType.isEmpty())
2426         mimeType = MIMETypeRegistry::getMIMETypeForExtension(url.path().mid(url.path().findRev('.')+1));
2427
2428     if (mimeType.isEmpty())
2429         return ObjectContentFrame; // Go ahead and hope that we can display the content.
2430
2431     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
2432         return WebCore::ObjectContentImage;
2433
2434     if (PluginDatabaseWin::installedPlugins()->isMIMETypeRegistered(mimeType))
2435         return WebCore::ObjectContentNetscapePlugin;
2436
2437     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
2438         return WebCore::ObjectContentFrame;
2439
2440     return WebCore::ObjectContentNone;
2441 }
2442
2443 String WebFrame::overrideMediaType() const
2444 {
2445     notImplemented();
2446     return String();
2447 }
2448
2449 void WebFrame::windowObjectCleared()
2450 {
2451     Frame* coreFrame = core(this);
2452     ASSERT(coreFrame);
2453
2454     Settings* settings = coreFrame->settings();
2455     if (!settings || !settings->isJavaScriptEnabled())
2456         return;
2457
2458     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
2459     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
2460         COMPtr<IWebFrameLoadDelegate2> frameLoadDelegate2(Query, frameLoadDelegate);
2461
2462         JSContextRef context = toRef(coreFrame->scriptProxy()->globalObject()->globalExec());
2463         JSObjectRef windowObject = toRef(KJS::Window::retrieve(coreFrame)->getObject());
2464         ASSERT(windowObject);
2465
2466         if (!frameLoadDelegate2 || 
2467             FAILED(frameLoadDelegate2->didClearWindowObject(d->webView, context, windowObject, this)))
2468             frameLoadDelegate->windowScriptObjectAvailable(d->webView, context, windowObject);
2469     }
2470
2471     if (WebScriptDebugServer::listenerCount() > 0) {
2472         detachScriptDebugger();
2473         attachScriptDebugger();
2474     }
2475 }
2476
2477 void WebFrame::didPerformFirstNavigation() const
2478 {
2479     COMPtr<IWebPreferences> preferences;
2480     if (FAILED(d->webView->preferences(&preferences)))
2481         return;
2482
2483     COMPtr<IWebPreferencesPrivate> preferencesPrivate(Query, preferences);
2484     if (!preferencesPrivate)
2485         return;
2486     BOOL automaticallyDetectsCacheModel;
2487     if (FAILED(preferencesPrivate->automaticallyDetectsCacheModel(&automaticallyDetectsCacheModel)))
2488         return;
2489
2490     WebCacheModel cacheModel;
2491     if (FAILED(preferences->cacheModel(&cacheModel)))
2492         return;
2493
2494     if (automaticallyDetectsCacheModel && cacheModel < WebCacheModelDocumentBrowser)
2495         preferences->setCacheModel(WebCacheModelDocumentBrowser);
2496 }
2497
2498 void WebFrame::registerForIconNotification(bool listen)
2499 {
2500     d->webView->registerForIconNotification(listen);
2501 }
2502
2503 static IntRect printerRect(HDC printDC)
2504 {
2505     return IntRect(0, 0, 
2506                    GetDeviceCaps(printDC, PHYSICALWIDTH)  - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETX),
2507                    GetDeviceCaps(printDC, PHYSICALHEIGHT) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETY));
2508 }
2509
2510 void WebFrame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
2511 {
2512     Frame* coreFrame = core(this);
2513     ASSERT(coreFrame);
2514     coreFrame->setPrinting(printing, minPageWidth, maxPageWidth, adjustViewSize);
2515 }
2516
2517 HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode( 
2518     /* [in] */ BOOL value,
2519     /* [in] */ HDC printDC)
2520 {
2521     if (m_inPrintingMode == !!value)
2522         return S_OK;
2523
2524     Frame* coreFrame = core(this);
2525     if (!coreFrame)
2526         return E_FAIL;
2527
2528     m_inPrintingMode = !!value;
2529
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()) {
2535         if (!printDC) {
2536             ASSERT_NOT_REACHED();
2537             return E_POINTER;
2538         }
2539
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;
2545     }
2546
2547     setPrinting(m_inPrintingMode, minLayoutWidth, maxLayoutWidth, true);
2548
2549     if (!m_inPrintingMode)
2550         m_pageRects.clear();
2551
2552     return S_OK;
2553 }
2554
2555 void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight)
2556 {
2557     if (headerHeight)
2558         *headerHeight = 0;
2559     if (footerHeight)
2560         *footerHeight = 0;
2561     float height = 0;
2562     COMPtr<IWebUIDelegate> ui;
2563     if (FAILED(d->webView->uiDelegate(&ui)))
2564         return;
2565     COMPtr<IWebUIDelegate2> ui2;
2566     if (FAILED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
2567         return;
2568     if (headerHeight && SUCCEEDED(ui2->webViewHeaderHeight(d->webView, &height)))
2569         *headerHeight = height;
2570     if (footerHeight && SUCCEEDED(ui2->webViewFooterHeight(d->webView, &height)))
2571         *footerHeight = height;
2572 }
2573
2574 IntRect WebFrame::printerMarginRect(HDC printDC)
2575 {
2576     IntRect emptyRect(0, 0, 0, 0);
2577
2578     COMPtr<IWebUIDelegate> ui;
2579     if (FAILED(d->webView->uiDelegate(&ui)))
2580         return emptyRect;
2581     COMPtr<IWebUIDelegate2> ui2;
2582     if (FAILED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
2583         return emptyRect;
2584
2585     RECT rect;
2586     if (FAILED(ui2->webViewPrintingMarginRect(d->webView, &rect)))
2587         return emptyRect;
2588
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);
2593
2594     return IntRect(rect.left, rect.top, (rect.right - rect.left), rect.bottom - rect.top);
2595 }
2596
2597 const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC)
2598 {
2599     ASSERT(m_inPrintingMode);
2600     
2601     Frame* coreFrame = core(this);
2602     ASSERT(coreFrame);
2603     ASSERT(coreFrame->document());
2604
2605     if (!printDC)
2606         return m_pageRects;
2607
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());
2618
2619     computePageRectsForFrame(coreFrame, adjustedRect, headerHeight, footerHeight, 1.0,m_pageRects, m_pageHeight);
2620     
2621     return m_pageRects;
2622 }
2623
2624 HRESULT STDMETHODCALLTYPE WebFrame::getPrintedPageCount( 
2625     /* [in] */ HDC printDC,
2626     /* [retval][out] */ UINT *pageCount)
2627 {
2628     if (!pageCount || !printDC) {
2629         ASSERT_NOT_REACHED();
2630         return E_POINTER;
2631     }
2632
2633     *pageCount = 0;
2634
2635     if (!m_inPrintingMode) {
2636         ASSERT_NOT_REACHED();
2637         return E_FAIL;
2638     }
2639
2640     Frame* coreFrame = core(this);
2641     if (!coreFrame || !coreFrame->document())
2642         return E_FAIL;
2643
2644     const Vector<IntRect>& pages = computePageRects(printDC);
2645     *pageCount = (UINT) pages.size();
2646     
2647     return S_OK;
2648 }
2649
2650 HRESULT STDMETHODCALLTYPE WebFrame::spoolPages( 
2651     /* [in] */ HDC printDC,
2652     /* [in] */ UINT startPage,
2653     /* [in] */ UINT endPage,
2654     /* [retval][out] */ void* ctx)
2655 {
2656     if (!printDC || !ctx) {
2657         ASSERT_NOT_REACHED();
2658         return E_POINTER;
2659     }
2660
2661     if (!m_inPrintingMode) {
2662         ASSERT_NOT_REACHED();
2663         return E_FAIL;
2664     }
2665
2666     Frame* coreFrame = core(this);
2667     if (!coreFrame || !coreFrame->document())
2668         return E_FAIL;
2669
2670     UINT pageCount = (UINT) m_pageRects.size();
2671     PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx;
2672
2673     if (!pageCount || startPage > pageCount) {
2674         ASSERT_NOT_REACHED();
2675         return E_FAIL;
2676     }
2677
2678     if (startPage > 0)
2679         startPage--;
2680
2681     if (endPage == 0)
2682         endPage = pageCount;
2683
2684     COMPtr<IWebUIDelegate> ui;
2685     if (FAILED(d->webView->uiDelegate(&ui)))
2686         return E_FAIL;
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)))
2690         ui2 = 0;
2691
2692     float headerHeight = 0, footerHeight = 0;
2693     headerAndFooterHeights(&headerHeight, &footerHeight);
2694     GraphicsContext spoolCtx(pctx);
2695
2696     for (UINT ii = startPage; ii < endPage; ii++) {
2697         IntRect pageRect = m_pageRects[ii];
2698
2699         CGContextSaveGState(pctx);
2700
2701         IntRect printRect = printerRect(printDC);
2702         CGRect mediaBox = CGRectMake(CGFloat(0),
2703                                      CGFloat(0),
2704                                      CGFloat(printRect.width()),
2705                                      CGFloat(printRect.height()));
2706
2707         CGContextBeginPage(pctx, &mediaBox);
2708
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);
2716
2717         coreFrame->paint(&spoolCtx, pageRect);
2718
2719         if (ui2) {
2720             CGContextTranslateCTM(pctx, CGFloat(pageRect.x()), CGFloat(pageRect.y())-headerHeight);
2721
2722             int x = pageRect.x();
2723             int y = 0;
2724             if (headerHeight) {
2725                 RECT headerRect = {x, y, x+pageRect.width(), y+(int)headerHeight};
2726                 ui2->drawHeaderInRect(d->webView, &headerRect, (OLE_HANDLE)(LONG64)pctx);
2727             }
2728
2729             if (footerHeight) {
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);
2733             }
2734         }
2735
2736         CGContextEndPage(pctx);
2737         CGContextRestoreGState(pctx);
2738     }
2739  
2740     return S_OK;
2741 }
2742
2743 HRESULT STDMETHODCALLTYPE WebFrame::isFrameSet( 
2744     /* [retval][out] */ BOOL* result)
2745 {
2746     *result = FALSE;
2747
2748     Frame* coreFrame = core(this);
2749     if (!coreFrame)
2750         return E_FAIL;
2751
2752     *result = coreFrame->isFrameSet() ? TRUE : FALSE;
2753     return S_OK;
2754 }
2755
2756 HRESULT STDMETHODCALLTYPE WebFrame::string( 
2757     /* [retval][out] */ BSTR *result)
2758 {
2759     *result = 0;
2760
2761     Frame* coreFrame = core(this);
2762     if (!coreFrame)
2763         return E_FAIL;
2764
2765     RefPtr<Range> allRange(rangeOfContents(coreFrame->document()));
2766     String allString = plainText(allRange.get());
2767     *result = BString(allString).release();
2768     return S_OK;
2769 }
2770
2771 HRESULT STDMETHODCALLTYPE WebFrame::size( 
2772     /* [retval][out] */ SIZE *size)
2773 {
2774     if (!size)
2775         return E_POINTER;
2776     size->cx = size->cy = 0;
2777
2778     Frame* coreFrame = core(this);
2779     if (!coreFrame)
2780         return E_FAIL;
2781     FrameView* view = coreFrame->view();
2782     if (!view)
2783         return E_FAIL;
2784     size->cx = view->width();
2785     size->cy = view->height();
2786     return S_OK;
2787 }
2788
2789 HRESULT STDMETHODCALLTYPE WebFrame::hasScrollBars( 
2790     /* [retval][out] */ BOOL *result)
2791 {
2792     if (!result)
2793         return E_POINTER;
2794     *result = FALSE;
2795
2796     Frame* coreFrame = core(this);
2797     if (!coreFrame)
2798         return E_FAIL;
2799
2800     FrameView* view = coreFrame->view();
2801     if (!view)
2802         return E_FAIL;
2803
2804     if (view->vScrollbarMode() == ScrollbarAlwaysOn || view->visibleHeight() < view->contentsHeight() ||
2805             view->hScrollbarMode() == ScrollbarAlwaysOn || view->visibleWidth() < view->contentsWidth())
2806         *result = TRUE;
2807
2808     return S_OK;
2809 }
2810
2811 HRESULT STDMETHODCALLTYPE WebFrame::contentBounds( 
2812     /* [retval][out] */ RECT *result)
2813 {
2814     if (!result)
2815         return E_POINTER;
2816     ::SetRectEmpty(result);
2817
2818     Frame* coreFrame = core(this);
2819     if (!coreFrame)
2820         return E_FAIL;
2821
2822     FrameView* view = coreFrame->view();
2823     if (!view)
2824         return E_FAIL;
2825
2826     result->bottom = view->contentsHeight();
2827     result->right = view->contentsWidth();
2828     return S_OK;
2829 }
2830
2831 HRESULT STDMETHODCALLTYPE WebFrame::frameBounds( 
2832     /* [retval][out] */ RECT *result)
2833 {
2834     if (!result)
2835         return E_POINTER;
2836     ::SetRectEmpty(result);
2837
2838     Frame* coreFrame = core(this);
2839     if (!coreFrame)
2840         return E_FAIL;
2841
2842     FrameView* view = coreFrame->view();
2843     if (!view)
2844         return E_FAIL;
2845
2846     FloatRect bounds = view->visibleContentRectConsideringExternalScrollers();
2847     result->bottom = (LONG) bounds.height();
2848     result->right = (LONG) bounds.width();
2849     return S_OK;
2850 }
2851
2852 HRESULT STDMETHODCALLTYPE WebFrame::isDescendantOfFrame( 
2853     /* [in] */ IWebFrame *ancestor,
2854     /* [retval][out] */ BOOL *result)
2855 {
2856     if (!result)
2857         return E_POINTER;
2858     *result = FALSE;
2859
2860     Frame* coreFrame = core(this);
2861     COMPtr<WebFrame> ancestorWebFrame;
2862     if (!ancestor || FAILED(ancestor->QueryInterface(IID_WebFrame, (void**)&ancestorWebFrame)))
2863         return S_OK;
2864
2865     *result = (coreFrame && coreFrame->tree()->isDescendantOf(core(ancestorWebFrame.get()))) ? TRUE : FALSE;
2866     return S_OK;
2867 }
2868
2869 void WebFrame::unmarkAllMisspellings()
2870 {
2871     Frame* coreFrame = core(this);
2872     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
2873         Document *doc = frame->document();
2874         if (!doc)
2875             return;
2876
2877         doc->removeMarkers(DocumentMarker::Spelling);
2878     }
2879 }
2880
2881 void WebFrame::unmarkAllBadGrammar()
2882 {
2883     Frame* coreFrame = core(this);
2884     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
2885         Document *doc = frame->document();
2886         if (!doc)
2887             return;
2888
2889         doc->removeMarkers(DocumentMarker::Grammar);
2890     }
2891 }