OSDN Git Service

5a99b66e6d294476259949b76b17d9d6e674c250
[android-x86/external-webkit.git] / Source / WebKit / win / WebFrame.cpp
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserved.
3  * Copyright (C) Research In Motion Limited 2009. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #include "config.h"
28 #include "WebKitDLL.h"
29 #include "WebFrame.h"
30
31 #include "CFDictionaryPropertyBag.h"
32 #include "COMPropertyBag.h"
33 #include "DOMCoreClasses.h"
34 #include "DefaultPolicyDelegate.h"
35 #include "HTMLFrameOwnerElement.h"
36 #include "MarshallingHelpers.h"
37 #include "WebActionPropertyBag.h"
38 #include "WebChromeClient.h"
39 #include "WebDataSource.h"
40 #include "WebDocumentLoader.h"
41 #include "WebDownload.h"
42 #include "WebEditorClient.h"
43 #include "WebError.h"
44 #include "WebFrameNetworkingContext.h"
45 #include "WebFramePolicyListener.h"
46 #include "WebHistory.h"
47 #include "WebHistoryItem.h"
48 #include "WebKit.h"
49 #include "WebKitStatisticsPrivate.h"
50 #include "WebMutableURLRequest.h"
51 #include "WebNotificationCenter.h"
52 #include "WebScriptWorld.h"
53 #include "WebURLResponse.h"
54 #include "WebView.h"
55 #include <WebCore/BString.h>
56 #include <WebCore/COMPtr.h>
57 #include <WebCore/MemoryCache.h>
58 #include <WebCore/Document.h>
59 #include <WebCore/DocumentLoader.h>
60 #include <WebCore/DocumentMarkerController.h>
61 #include <WebCore/DOMImplementation.h>
62 #include <WebCore/DOMWindow.h>
63 #include <WebCore/Event.h>
64 #include <WebCore/EventHandler.h>
65 #include <WebCore/FormState.h>
66 #include <WebCore/FrameLoader.h>
67 #include <WebCore/FrameLoadRequest.h>
68 #include <WebCore/FrameTree.h>
69 #include <WebCore/FrameView.h>
70 #include <WebCore/FrameWin.h>
71 #include <WebCore/GDIObjectCounter.h>
72 #include <WebCore/GraphicsContext.h>
73 #include <WebCore/HistoryItem.h>
74 #include <WebCore/HTMLAppletElement.h>
75 #include <WebCore/HTMLFormElement.h>
76 #include <WebCore/HTMLFormControlElement.h>
77 #include <WebCore/HTMLInputElement.h>
78 #include <WebCore/HTMLNames.h>
79 #include <WebCore/HTMLPlugInElement.h>
80 #include <WebCore/JSDOMWindow.h>
81 #include <WebCore/KeyboardEvent.h>
82 #include <WebCore/MouseRelatedEvent.h>
83 #include <WebCore/NotImplemented.h>
84 #include <WebCore/Page.h>
85 #include <WebCore/PlatformKeyboardEvent.h>
86 #include <WebCore/PluginData.h>
87 #include <WebCore/PluginDatabase.h>
88 #include <WebCore/PluginView.h>
89 #include <WebCore/PrintContext.h>
90 #include <WebCore/ResourceHandle.h>
91 #include <WebCore/ResourceRequest.h>
92 #include <WebCore/RenderView.h>
93 #include <WebCore/RenderTreeAsText.h>
94 #include <WebCore/Settings.h>
95 #include <WebCore/SVGDocumentExtensions.h>
96 #include <WebCore/SVGSMILElement.h>
97 #include <WebCore/TextIterator.h>
98 #include <WebCore/JSDOMBinding.h>
99 #include <WebCore/ScriptController.h>
100 #include <WebCore/SecurityOrigin.h>
101 #include <JavaScriptCore/APICast.h>
102 #include <JavaScriptCore/JSLock.h>
103 #include <JavaScriptCore/JSObject.h>
104 #include <JavaScriptCore/JSValue.h>
105 #include <wtf/MathExtras.h>
106
107 #if USE(CG)
108 #include <CoreGraphics/CoreGraphics.h>
109 #elif USE(CAIRO)
110 #include "PlatformContextCairo.h"
111 #include <cairo-win32.h>
112 #endif
113
114 #if USE(CG)
115 // CG SPI used for printing
116 extern "C" {
117     CGAffineTransform CGContextGetBaseCTM(CGContextRef c); 
118     void CGContextSetBaseCTM(CGContextRef c, CGAffineTransform m); 
119 }
120 #endif
121
122 using namespace WebCore;
123 using namespace HTMLNames;
124 using namespace std;
125
126 using JSC::JSGlobalObject;
127 using JSC::JSLock;
128 using JSC::JSValue;
129 using JSC::SilenceAssertionsOnly;
130
131 #define FLASH_REDRAW 0
132
133
134 // By imaging to a width a little wider than the available pixels,
135 // thin pages will be scaled down a little, matching the way they
136 // print in IE and Camino. This lets them use fewer sheets than they
137 // would otherwise, which is presumably why other browsers do this.
138 // Wide pages will be scaled down more than this.
139 const float PrintingMinimumShrinkFactor = 1.25f;
140
141 // This number determines how small we are willing to reduce the page content
142 // in order to accommodate the widest line. If the page would have to be
143 // reduced smaller to make the widest line fit, we just clip instead (this
144 // behavior matches MacIE and Mozilla, at least)
145 const float PrintingMaximumShrinkFactor = 2.0f;
146
147 //-----------------------------------------------------------------------------
148 // Helpers to convert from WebCore to WebKit type
149 WebFrame* kit(Frame* frame)
150 {
151     if (!frame)
152         return 0;
153
154     FrameLoaderClient* frameLoaderClient = frame->loader()->client();
155     if (frameLoaderClient)
156         return static_cast<WebFrame*>(frameLoaderClient);  // eek, is there a better way than static cast?
157     return 0;
158 }
159
160 Frame* core(WebFrame* webFrame)
161 {
162     if (!webFrame)
163         return 0;
164     return webFrame->impl();
165 }
166
167 // 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
168 Frame* core(const WebFrame* webFrame)
169 {
170     if (!webFrame)
171         return 0;
172     return const_cast<WebFrame*>(webFrame)->impl();
173 }
174
175 //-----------------------------------------------------------------------------
176
177 static Element *elementFromDOMElement(IDOMElement *element)
178 {
179     if (!element)
180         return 0;
181
182     COMPtr<IDOMElementPrivate> elePriv;
183     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
184     if (SUCCEEDED(hr)) {
185         Element* ele;
186         hr = elePriv->coreElement((void**)&ele);
187         if (SUCCEEDED(hr))
188             return ele;
189     }
190     return 0;
191 }
192
193 static HTMLFormElement *formElementFromDOMElement(IDOMElement *element)
194 {
195     if (!element)
196         return 0;
197
198     IDOMElementPrivate* elePriv;
199     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
200     if (SUCCEEDED(hr)) {
201         Element* ele;
202         hr = elePriv->coreElement((void**)&ele);
203         elePriv->Release();
204         if (SUCCEEDED(hr) && ele && ele->hasTagName(formTag))
205             return static_cast<HTMLFormElement*>(ele);
206     }
207     return 0;
208 }
209
210 static HTMLInputElement* inputElementFromDOMElement(IDOMElement* element)
211 {
212     if (!element)
213         return 0;
214
215     IDOMElementPrivate* elePriv;
216     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
217     if (SUCCEEDED(hr)) {
218         Element* ele;
219         hr = elePriv->coreElement((void**)&ele);
220         elePriv->Release();
221         if (SUCCEEDED(hr) && ele && ele->hasTagName(inputTag))
222             return static_cast<HTMLInputElement*>(ele);
223     }
224     return 0;
225 }
226
227 // WebFramePrivate ------------------------------------------------------------
228
229 class WebFrame::WebFramePrivate {
230 public:
231     WebFramePrivate() 
232         : frame(0)
233         , webView(0)
234         , m_policyFunction(0)
235     { 
236     }
237
238     ~WebFramePrivate() { }
239     FrameView* frameView() { return frame ? frame->view() : 0; }
240
241     Frame* frame;
242     WebView* webView;
243     FramePolicyFunction m_policyFunction;
244     COMPtr<WebFramePolicyListener> m_policyListener;
245 };
246
247 // WebFrame ----------------------------------------------------------------
248
249 WebFrame::WebFrame()
250     : WebFrameLoaderClient(this)
251     , m_refCount(0)
252     , d(new WebFrame::WebFramePrivate)
253     , m_quickRedirectComing(false)
254     , m_inPrintingMode(false)
255     , m_pageHeight(0)
256 {
257     WebFrameCount++;
258     gClassCount++;
259     gClassNameCount.add("WebFrame");
260 }
261
262 WebFrame::~WebFrame()
263 {
264     delete d;
265     WebFrameCount--;
266     gClassCount--;
267     gClassNameCount.remove("WebFrame");
268 }
269
270 WebFrame* WebFrame::createInstance()
271 {
272     WebFrame* instance = new WebFrame();
273     instance->AddRef();
274     return instance;
275 }
276
277 HRESULT STDMETHODCALLTYPE WebFrame::setAllowsScrolling(
278     /* [in] */ BOOL flag)
279 {
280     if (Frame* frame = core(this))
281         if (FrameView* view = frame->view())
282             view->setCanHaveScrollbars(!!flag);
283
284     return S_OK;
285 }
286
287 HRESULT STDMETHODCALLTYPE WebFrame::allowsScrolling(
288     /* [retval][out] */ BOOL *flag)
289 {
290     if (flag)
291         if (Frame* frame = core(this))
292             if (FrameView* view = frame->view())
293                 *flag = view->canHaveScrollbars();
294
295     return S_OK;
296 }
297
298 HRESULT STDMETHODCALLTYPE WebFrame::setIsDisconnected(
299     /* [in] */ BOOL flag)
300 {
301     if (Frame* frame = core(this)) {
302         frame->setIsDisconnected(flag);
303         return S_OK;
304     }
305
306     return E_FAIL;
307 }
308
309 HRESULT STDMETHODCALLTYPE WebFrame::setExcludeFromTextSearch(
310     /* [in] */ BOOL flag)
311 {
312     if (Frame* frame = core(this)) {
313         frame->setExcludeFromTextSearch(flag);
314         return S_OK;
315     }
316
317     return E_FAIL;
318 }
319
320 HRESULT WebFrame::reloadFromOrigin()
321 {
322     Frame* coreFrame = core(this);
323     if (!coreFrame)
324         return E_FAIL;
325
326     coreFrame->loader()->reload(true);
327     return S_OK;
328 }
329
330 HRESULT STDMETHODCALLTYPE WebFrame::paintDocumentRectToContext(
331     /* [in] */ RECT rect,
332     /* [in] */ OLE_HANDLE deviceContext)
333 {
334     Frame* coreFrame = core(this);
335     if (!coreFrame)
336         return E_FAIL;
337
338     FrameView* view = coreFrame->view();
339     if (!view)
340         return E_FAIL;
341
342     // We can't paint with a layout still pending.
343     view->updateLayoutAndStyleIfNeededRecursive();
344
345     HDC dc = reinterpret_cast<HDC>(static_cast<ULONG64>(deviceContext));
346     GraphicsContext gc(dc);
347     gc.setShouldIncludeChildWindows(true);
348     gc.save();
349     LONG width = rect.right - rect.left;
350     LONG height = rect.bottom - rect.top;
351     FloatRect dirtyRect;
352     dirtyRect.setWidth(width);
353     dirtyRect.setHeight(height);
354     gc.clip(dirtyRect);
355     gc.translate(-rect.left, -rect.top);
356     view->paintContents(&gc, rect);
357     gc.restore();
358
359     return S_OK;
360 }
361
362 HRESULT STDMETHODCALLTYPE WebFrame::paintScrollViewRectToContextAtPoint(
363     /* [in] */ RECT rect,
364     /* [in] */ POINT pt,
365     /* [in] */ OLE_HANDLE deviceContext)
366 {
367     Frame* coreFrame = core(this);
368     if (!coreFrame)
369         return E_FAIL;
370
371     FrameView* view = coreFrame->view();
372     if (!view)
373         return E_FAIL;
374
375     // We can't paint with a layout still pending.
376     view->updateLayoutAndStyleIfNeededRecursive();
377
378     HDC dc = reinterpret_cast<HDC>(static_cast<ULONG64>(deviceContext));
379     GraphicsContext gc(dc);
380     gc.setShouldIncludeChildWindows(true);
381     gc.save();
382     IntRect dirtyRect(rect);
383     dirtyRect.move(-pt.x, -pt.y);
384     view->paint(&gc, dirtyRect);
385     gc.restore();
386
387     return S_OK;
388 }
389
390 // IUnknown -------------------------------------------------------------------
391
392 HRESULT STDMETHODCALLTYPE WebFrame::QueryInterface(REFIID riid, void** ppvObject)
393 {
394     *ppvObject = 0;
395     if (IsEqualGUID(riid, __uuidof(WebFrame)))
396         *ppvObject = this;
397     else if (IsEqualGUID(riid, IID_IUnknown))
398         *ppvObject = static_cast<IWebFrame*>(this);
399     else if (IsEqualGUID(riid, IID_IWebFrame))
400         *ppvObject = static_cast<IWebFrame*>(this);
401     else if (IsEqualGUID(riid, IID_IWebFramePrivate))
402         *ppvObject = static_cast<IWebFramePrivate*>(this);
403     else if (IsEqualGUID(riid, IID_IWebDocumentText))
404         *ppvObject = static_cast<IWebDocumentText*>(this);
405     else
406         return E_NOINTERFACE;
407
408     AddRef();
409     return S_OK;
410 }
411
412 ULONG STDMETHODCALLTYPE WebFrame::AddRef(void)
413 {
414     return ++m_refCount;
415 }
416
417 ULONG STDMETHODCALLTYPE WebFrame::Release(void)
418 {
419     ULONG newRef = --m_refCount;
420     if (!newRef)
421         delete(this);
422
423     return newRef;
424 }
425
426 // IWebFrame -------------------------------------------------------------------
427
428 HRESULT STDMETHODCALLTYPE WebFrame::name( 
429     /* [retval][out] */ BSTR* frameName)
430 {
431     if (!frameName) {
432         ASSERT_NOT_REACHED();
433         return E_POINTER;
434     }
435
436     *frameName = 0;
437
438     Frame* coreFrame = core(this);
439     if (!coreFrame)
440         return E_FAIL;
441
442     *frameName = BString(coreFrame->tree()->uniqueName()).release();
443     return S_OK;
444 }
445
446 HRESULT STDMETHODCALLTYPE WebFrame::webView( 
447     /* [retval][out] */ IWebView** view)
448 {
449     *view = 0;
450     if (!d->webView)
451         return E_FAIL;
452     *view = d->webView;
453     (*view)->AddRef();
454     return S_OK;
455 }
456
457 HRESULT STDMETHODCALLTYPE WebFrame::frameView(
458     /* [retval][out] */ IWebFrameView** /*view*/)
459 {
460     ASSERT_NOT_REACHED();
461     return E_NOTIMPL;
462 }
463
464 HRESULT STDMETHODCALLTYPE WebFrame::DOMDocument( 
465     /* [retval][out] */ IDOMDocument** result)
466 {
467     if (!result) {
468         ASSERT_NOT_REACHED();
469         return E_POINTER;
470     }
471
472     *result = 0;
473
474     if (Frame* coreFrame = core(this))
475         if (Document* document = coreFrame->document())
476             *result = DOMDocument::createInstance(document);
477
478     return *result ? S_OK : E_FAIL;
479 }
480
481 HRESULT STDMETHODCALLTYPE WebFrame::frameElement( 
482     /* [retval][out] */ IDOMHTMLElement** frameElement)
483 {
484     if (!frameElement)
485         return E_POINTER;
486
487     *frameElement = 0;
488     Frame* coreFrame = core(this);
489     if (!coreFrame)
490         return E_FAIL;
491
492     COMPtr<IDOMElement> domElement(AdoptCOM, DOMElement::createInstance(coreFrame->ownerElement()));
493     COMPtr<IDOMHTMLElement> htmlElement(Query, domElement);
494     if (!htmlElement)
495         return E_FAIL;
496     return htmlElement.copyRefTo(frameElement);
497 }
498
499 HRESULT STDMETHODCALLTYPE WebFrame::currentForm( 
500         /* [retval][out] */ IDOMElement **currentForm)
501 {
502     if (!currentForm) {
503         ASSERT_NOT_REACHED();
504         return E_POINTER;
505     }
506
507     *currentForm = 0;
508
509     if (Frame* coreFrame = core(this)) {
510         if (HTMLFormElement* formElement = coreFrame->selection()->currentForm())
511             *currentForm = DOMElement::createInstance(formElement);
512     }
513
514     return *currentForm ? S_OK : E_FAIL;
515 }
516
517 JSGlobalContextRef STDMETHODCALLTYPE WebFrame::globalContext()
518 {
519     Frame* coreFrame = core(this);
520     if (!coreFrame)
521         return 0;
522
523     return toGlobalRef(coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
524 }
525
526 JSGlobalContextRef WebFrame::globalContextForScriptWorld(IWebScriptWorld* iWorld)
527 {
528     Frame* coreFrame = core(this);
529     if (!coreFrame)
530         return 0;
531
532     COMPtr<WebScriptWorld> world(Query, iWorld);
533     if (!world)
534         return 0;
535
536     return toGlobalRef(coreFrame->script()->globalObject(world->world())->globalExec());
537 }
538
539 HRESULT STDMETHODCALLTYPE WebFrame::loadRequest( 
540     /* [in] */ IWebURLRequest* request)
541 {
542     COMPtr<WebMutableURLRequest> requestImpl;
543
544     HRESULT hr = request->QueryInterface(&requestImpl);
545     if (FAILED(hr))
546         return hr;
547  
548     Frame* coreFrame = core(this);
549     if (!coreFrame)
550         return E_FAIL;
551
552     coreFrame->loader()->load(requestImpl->resourceRequest(), false);
553     return S_OK;
554 }
555
556 void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL)
557 {
558     String mimeTypeString(mimeType, SysStringLen(mimeType));
559     if (!mimeType)
560         mimeTypeString = "text/html";
561
562     String encodingString(textEncodingName, SysStringLen(textEncodingName));
563
564     // FIXME: We should really be using MarshallingHelpers::BSTRToKURL here,
565     // but that would turn a null BSTR into a null KURL, and we crash inside of
566     // WebCore if we use a null KURL in constructing the ResourceRequest.
567     KURL baseKURL = KURL(KURL(), String(baseURL ? baseURL : L"", SysStringLen(baseURL)));
568
569     KURL failingKURL = MarshallingHelpers::BSTRToKURL(failingURL);
570
571     ResourceRequest request(baseKURL);
572     SubstituteData substituteData(data, mimeTypeString, encodingString, failingKURL);
573
574     // This method is only called from IWebFrame methods, so don't ASSERT that the Frame pointer isn't null.
575     if (Frame* coreFrame = core(this))
576         coreFrame->loader()->load(request, substituteData, false);
577 }
578
579
580 HRESULT STDMETHODCALLTYPE WebFrame::loadData( 
581     /* [in] */ IStream* data,
582     /* [in] */ BSTR mimeType,
583     /* [in] */ BSTR textEncodingName,
584     /* [in] */ BSTR url)
585 {
586     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create();
587
588     STATSTG stat;
589     if (SUCCEEDED(data->Stat(&stat, STATFLAG_NONAME))) {
590         if (!stat.cbSize.HighPart && stat.cbSize.LowPart) {
591             Vector<char> dataBuffer(stat.cbSize.LowPart);
592             ULONG read;
593             // FIXME: this does a needless copy, would be better to read right into the SharedBuffer
594             // or adopt the Vector or something.
595             if (SUCCEEDED(data->Read(dataBuffer.data(), static_cast<ULONG>(dataBuffer.size()), &read)))
596                 sharedBuffer->append(dataBuffer.data(), static_cast<int>(dataBuffer.size()));
597         }
598     }
599
600     loadData(sharedBuffer, mimeType, textEncodingName, url, 0);
601     return S_OK;
602 }
603
604 HRESULT WebFrame::loadPlainTextString(
605     /* [in] */ BSTR string,
606     /* [in] */ BSTR url)
607 {
608     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(string), sizeof(UChar) * SysStringLen(string));
609     BString plainTextMimeType(TEXT("text/plain"), 10);
610     BString utf16Encoding(TEXT("utf-16"), 6);
611     loadData(sharedBuffer.release(), plainTextMimeType, utf16Encoding, url, 0);
612     return S_OK;
613 }
614
615 void WebFrame::loadHTMLString(BSTR string, BSTR baseURL, BSTR unreachableURL)
616 {
617     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(string), sizeof(UChar) * SysStringLen(string));
618     BString utf16Encoding(TEXT("utf-16"), 6);
619     loadData(sharedBuffer.release(), 0, utf16Encoding, baseURL, unreachableURL);
620 }
621
622 HRESULT STDMETHODCALLTYPE WebFrame::loadHTMLString( 
623     /* [in] */ BSTR string,
624     /* [in] */ BSTR baseURL)
625 {
626     loadHTMLString(string, baseURL, 0);
627     return S_OK;
628 }
629
630 HRESULT STDMETHODCALLTYPE WebFrame::loadAlternateHTMLString( 
631     /* [in] */ BSTR str,
632     /* [in] */ BSTR baseURL,
633     /* [in] */ BSTR unreachableURL)
634 {
635     loadHTMLString(str, baseURL, unreachableURL);
636     return S_OK;
637 }
638
639 HRESULT STDMETHODCALLTYPE WebFrame::loadArchive( 
640     /* [in] */ IWebArchive* /*archive*/)
641 {
642     ASSERT_NOT_REACHED();
643     return E_NOTIMPL;
644 }
645
646 static inline WebDataSource *getWebDataSource(DocumentLoader* loader)
647 {
648     return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
649 }
650
651 HRESULT STDMETHODCALLTYPE WebFrame::dataSource( 
652     /* [retval][out] */ IWebDataSource** source)
653 {
654     if (!source) {
655         ASSERT_NOT_REACHED();
656         return E_POINTER;
657     }
658
659     *source = 0;
660
661     Frame* coreFrame = core(this);
662     if (!coreFrame)
663         return E_FAIL;
664
665     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->documentLoader());
666
667     *source = webDataSource;
668
669     if (webDataSource)
670         webDataSource->AddRef(); 
671
672     return *source ? S_OK : E_FAIL;
673 }
674
675 HRESULT STDMETHODCALLTYPE WebFrame::provisionalDataSource( 
676     /* [retval][out] */ IWebDataSource** source)
677 {
678     if (!source) {
679         ASSERT_NOT_REACHED();
680         return E_POINTER;
681     }
682
683     *source = 0;
684
685     Frame* coreFrame = core(this);
686     if (!coreFrame)
687         return E_FAIL;
688
689     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->provisionalDocumentLoader());
690
691     *source = webDataSource;
692
693     if (webDataSource)
694         webDataSource->AddRef(); 
695
696     return *source ? S_OK : E_FAIL;
697 }
698
699 KURL WebFrame::url() const
700 {
701     Frame* coreFrame = core(this);
702     if (!coreFrame)
703         return KURL();
704
705     return coreFrame->document()->url();
706 }
707
708 HRESULT STDMETHODCALLTYPE WebFrame::stopLoading( void)
709 {
710     if (Frame* coreFrame = core(this))
711         coreFrame->loader()->stopAllLoaders();
712     return S_OK;
713 }
714
715 HRESULT STDMETHODCALLTYPE WebFrame::reload( void)
716 {
717     Frame* coreFrame = core(this);
718     if (!coreFrame)
719         return E_FAIL;
720
721     coreFrame->loader()->reload();
722     return S_OK;
723 }
724
725 HRESULT STDMETHODCALLTYPE WebFrame::findFrameNamed( 
726     /* [in] */ BSTR name,
727     /* [retval][out] */ IWebFrame** frame)
728 {
729     if (!frame) {
730         ASSERT_NOT_REACHED();
731         return E_POINTER;
732     }
733
734     *frame = 0;
735
736     Frame* coreFrame = core(this);
737     if (!coreFrame)
738         return E_FAIL;
739
740     Frame* foundFrame = coreFrame->tree()->find(AtomicString(name, SysStringLen(name)));
741     if (!foundFrame)
742         return S_OK;
743
744     WebFrame* foundWebFrame = kit(foundFrame);
745     if (!foundWebFrame)
746         return E_FAIL;
747
748     return foundWebFrame->QueryInterface(IID_IWebFrame, (void**)frame);
749 }
750
751 HRESULT STDMETHODCALLTYPE WebFrame::parentFrame( 
752     /* [retval][out] */ IWebFrame** frame)
753 {
754     HRESULT hr = S_OK;
755     *frame = 0;
756     if (Frame* coreFrame = core(this))
757         if (WebFrame* webFrame = kit(coreFrame->tree()->parent()))
758             hr = webFrame->QueryInterface(IID_IWebFrame, (void**) frame);
759
760     return hr;
761 }
762
763 class EnumChildFrames : public IEnumVARIANT
764 {
765 public:
766     EnumChildFrames(Frame* f) : m_refCount(1), m_frame(f), m_curChild(f ? f->tree()->firstChild() : 0) { }
767
768     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject)
769     {
770         *ppvObject = 0;
771         if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IEnumVARIANT))
772             *ppvObject = this;
773         else
774             return E_NOINTERFACE;
775
776         AddRef();
777         return S_OK;
778     }
779
780     virtual ULONG STDMETHODCALLTYPE AddRef(void)
781     {
782         return ++m_refCount;
783     }
784
785     virtual ULONG STDMETHODCALLTYPE Release(void)
786     {
787         ULONG newRef = --m_refCount;
788         if (!newRef)
789             delete(this);
790         return newRef;
791     }
792
793     virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
794     {
795         if (pCeltFetched)
796             *pCeltFetched = 0;
797         if (!rgVar)
798             return E_POINTER;
799         VariantInit(rgVar);
800         if (!celt || celt > 1)
801             return S_FALSE;
802         if (!m_frame || !m_curChild)
803             return S_FALSE;
804
805         WebFrame* webFrame = kit(m_curChild);
806         IUnknown* unknown;
807         HRESULT hr = webFrame->QueryInterface(IID_IUnknown, (void**)&unknown);
808         if (FAILED(hr))
809             return hr;
810
811         V_VT(rgVar) = VT_UNKNOWN;
812         V_UNKNOWN(rgVar) = unknown;
813
814         m_curChild = m_curChild->tree()->nextSibling();
815         if (pCeltFetched)
816             *pCeltFetched = 1;
817         return S_OK;
818     }
819
820     virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
821     {
822         if (!m_frame)
823             return S_FALSE;
824         for (unsigned i = 0; i < celt && m_curChild; i++)
825             m_curChild = m_curChild->tree()->nextSibling();
826         return m_curChild ? S_OK : S_FALSE;
827     }
828
829     virtual HRESULT STDMETHODCALLTYPE Reset(void)
830     {
831         if (!m_frame)
832             return S_FALSE;
833         m_curChild = m_frame->tree()->firstChild();
834         return S_OK;
835     }
836
837     virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT**)
838     {
839         return E_NOTIMPL;
840     }
841
842 private:
843     ULONG m_refCount;
844     Frame* m_frame;
845     Frame* m_curChild;
846 };
847
848 HRESULT STDMETHODCALLTYPE WebFrame::childFrames( 
849     /* [retval][out] */ IEnumVARIANT **enumFrames)
850 {
851     if (!enumFrames)
852         return E_POINTER;
853
854     *enumFrames = new EnumChildFrames(core(this));
855     return S_OK;
856 }
857
858 // IWebFramePrivate ------------------------------------------------------
859
860 HRESULT WebFrame::renderTreeAsExternalRepresentation(BOOL forPrinting, BSTR *result)
861 {
862     if (!result)
863         return E_POINTER;
864
865     Frame* coreFrame = core(this);
866     if (!coreFrame)
867         return E_FAIL;
868
869     *result = BString(externalRepresentation(coreFrame, forPrinting ? RenderAsTextPrintingMode : RenderAsTextBehaviorNormal)).release();
870     return S_OK;
871 }
872
873 HRESULT STDMETHODCALLTYPE WebFrame::counterValueForElementById(
874     /* [in] */ BSTR id, /* [retval][out] */ BSTR *result)
875 {
876     if (!result)
877         return E_POINTER;
878
879     Frame* coreFrame = core(this);
880     if (!coreFrame)
881         return E_FAIL;
882
883     String coreId = String(id, SysStringLen(id));
884
885     Element* element = coreFrame->document()->getElementById(coreId);
886     if (!element)
887         return E_FAIL;
888     *result = BString(counterValueForElement(element)).release();
889     return S_OK;
890 }
891
892 HRESULT STDMETHODCALLTYPE WebFrame::pageNumberForElementById(
893     /* [in] */ BSTR id,
894     /* [in] */ float pageWidthInPixels,
895     /* [in] */ float pageHeightInPixels,
896     /* [retval][out] */ int* result)
897 {
898     if (!result)
899         return E_POINTER;
900
901     Frame* coreFrame = core(this);
902     if (!coreFrame)
903         return E_FAIL;
904
905     String coreId = String(id, SysStringLen(id));
906
907     Element* element = coreFrame->document()->getElementById(coreId);
908     if (!element)
909         return E_FAIL;
910     *result = PrintContext::pageNumberForElement(element, FloatSize(pageWidthInPixels, pageHeightInPixels));
911     return S_OK;
912 }
913
914 HRESULT STDMETHODCALLTYPE WebFrame::numberOfPages(
915     /* [in] */ float pageWidthInPixels,
916     /* [in] */ float pageHeightInPixels,
917     /* [retval][out] */ int* result)
918 {
919     if (!result)
920         return E_POINTER;
921
922     Frame* coreFrame = core(this);
923     if (!coreFrame)
924         return E_FAIL;
925
926     *result = PrintContext::numberOfPages(coreFrame, FloatSize(pageWidthInPixels, pageHeightInPixels));
927     return S_OK;
928 }
929
930 HRESULT STDMETHODCALLTYPE WebFrame::scrollOffset(
931         /* [retval][out] */ SIZE* offset)
932 {
933     if (!offset) {
934         ASSERT_NOT_REACHED();
935         return E_POINTER;
936     }
937
938     Frame* coreFrame = core(this);
939     if (!coreFrame)
940         return E_FAIL;
941
942     FrameView* view = coreFrame->view();
943     if (!view)
944         return E_FAIL;
945
946     *offset = view->scrollOffset();
947     return S_OK;
948 }
949
950 HRESULT STDMETHODCALLTYPE WebFrame::layout()
951 {
952     Frame* coreFrame = core(this);
953     if (!coreFrame)
954         return E_FAIL;
955
956     FrameView* view = coreFrame->view();
957     if (!view)
958         return E_FAIL;
959
960     view->layout();
961     return S_OK;
962 }
963
964 HRESULT STDMETHODCALLTYPE WebFrame::firstLayoutDone(
965     /* [retval][out] */ BOOL* result)
966 {
967     if (!result) {
968         ASSERT_NOT_REACHED();
969         return E_POINTER;
970     }
971
972     *result = 0;
973
974     Frame* coreFrame = core(this);
975     if (!coreFrame)
976         return E_FAIL;
977
978     *result = coreFrame->loader()->stateMachine()->firstLayoutDone();
979     return S_OK;
980 }
981
982 HRESULT STDMETHODCALLTYPE WebFrame::loadType( 
983     /* [retval][out] */ WebFrameLoadType* type)
984 {
985     if (!type) {
986         ASSERT_NOT_REACHED();
987         return E_POINTER;
988     }
989
990     *type = (WebFrameLoadType)0;
991
992     Frame* coreFrame = core(this);
993     if (!coreFrame)
994         return E_FAIL;
995
996     *type = (WebFrameLoadType)coreFrame->loader()->loadType();
997     return S_OK;
998 }
999
1000 HRESULT STDMETHODCALLTYPE WebFrame::pendingFrameUnloadEventCount( 
1001     /* [retval][out] */ UINT* result)
1002 {
1003     if (!result) {
1004         ASSERT_NOT_REACHED();
1005         return E_POINTER;
1006     }
1007
1008     *result = 0;
1009
1010     Frame* coreFrame = core(this);
1011     if (!coreFrame)
1012         return E_FAIL;
1013
1014     *result = coreFrame->domWindow()->pendingUnloadEventListeners();
1015     return S_OK;
1016 }
1017
1018 HRESULT STDMETHODCALLTYPE WebFrame::unused2()
1019 {
1020     return E_NOTIMPL;
1021 }
1022
1023 HRESULT STDMETHODCALLTYPE WebFrame::hasSpellingMarker(
1024         /* [in] */ UINT from,
1025         /* [in] */ UINT length,
1026         /* [retval][out] */ BOOL* result)
1027 {
1028     Frame* coreFrame = core(this);
1029     if (!coreFrame)
1030         return E_FAIL;
1031     *result = coreFrame->editor()->selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
1032     return S_OK;
1033 }
1034
1035 HRESULT STDMETHODCALLTYPE WebFrame::clearOpener()
1036 {
1037     HRESULT hr = S_OK;
1038     if (Frame* coreFrame = core(this))
1039         coreFrame->loader()->setOpener(0);
1040
1041     return hr;
1042 }
1043
1044 // IWebDocumentText -----------------------------------------------------------
1045
1046 HRESULT STDMETHODCALLTYPE WebFrame::supportsTextEncoding( 
1047     /* [retval][out] */ BOOL* result)
1048 {
1049     *result = FALSE;
1050     return E_NOTIMPL;
1051 }
1052
1053 HRESULT STDMETHODCALLTYPE WebFrame::selectedString( 
1054     /* [retval][out] */ BSTR* result)
1055 {
1056     *result = 0;
1057
1058     Frame* coreFrame = core(this);
1059     if (!coreFrame)
1060         return E_FAIL;
1061
1062     String text = coreFrame->displayStringModifiedByEncoding(coreFrame->editor()->selectedText());
1063
1064     *result = BString(text).release();
1065     return S_OK;
1066 }
1067
1068 HRESULT STDMETHODCALLTYPE WebFrame::selectAll()
1069 {
1070     Frame* coreFrame = core(this);
1071     if (!coreFrame)
1072         return E_FAIL;
1073
1074     if (!coreFrame->editor()->command("SelectAll").execute())
1075         return E_FAIL;
1076
1077     return S_OK;
1078 }
1079
1080 HRESULT STDMETHODCALLTYPE WebFrame::deselectAll()
1081 {
1082     return E_NOTIMPL;
1083 }
1084
1085 // WebFrame ---------------------------------------------------------------
1086
1087 PassRefPtr<Frame> WebFrame::init(IWebView* webView, Page* page, HTMLFrameOwnerElement* ownerElement)
1088 {
1089     webView->QueryInterface(&d->webView);
1090     d->webView->Release(); // don't hold the extra ref
1091
1092     HWND viewWindow;
1093     d->webView->viewWindow((OLE_HANDLE*)&viewWindow);
1094
1095     this->AddRef(); // We release this ref in frameLoaderDestroyed()
1096     RefPtr<Frame> frame = Frame::create(page, ownerElement, this);
1097     d->frame = frame.get();
1098     return frame.release();
1099 }
1100
1101 Frame* WebFrame::impl()
1102 {
1103     return d->frame;
1104 }
1105
1106 void WebFrame::invalidate()
1107 {
1108     Frame* coreFrame = core(this);
1109     ASSERT(coreFrame);
1110
1111     if (Document* document = coreFrame->document())
1112         document->recalcStyle(Node::Force);
1113 }
1114
1115 HRESULT WebFrame::inViewSourceMode(BOOL* flag)
1116 {
1117     if (!flag) {
1118         ASSERT_NOT_REACHED();
1119         return E_POINTER;
1120     }
1121
1122     *flag = FALSE;
1123
1124     Frame* coreFrame = core(this);
1125     if (!coreFrame)
1126         return E_FAIL;
1127
1128     *flag = coreFrame->inViewSourceMode() ? TRUE : FALSE;
1129     return S_OK;
1130 }
1131
1132 HRESULT WebFrame::setInViewSourceMode(BOOL flag)
1133 {
1134     Frame* coreFrame = core(this);
1135     if (!coreFrame)
1136         return E_FAIL;
1137
1138     coreFrame->setInViewSourceMode(!!flag);
1139     return S_OK;
1140 }
1141
1142 HRESULT WebFrame::elementWithName(BSTR name, IDOMElement* form, IDOMElement** element)
1143 {
1144     if (!form)
1145         return E_INVALIDARG;
1146
1147     HTMLFormElement* formElement = formElementFromDOMElement(form);
1148     if (formElement) {
1149         const Vector<FormAssociatedElement*>& elements = formElement->associatedElements();
1150         AtomicString targetName((UChar*)name, SysStringLen(name));
1151         for (unsigned int i = 0; i < elements.size(); i++) {
1152             if (!elements[i]->isFormControlElement())
1153                 continue;
1154             HTMLFormControlElement* elt = static_cast<HTMLFormControlElement*>(elements[i]);
1155             // Skip option elements, other duds
1156             if (elt->name() == targetName) {
1157                 *element = DOMElement::createInstance(elt);
1158                 return S_OK;
1159             }
1160         }
1161     }
1162     return E_FAIL;
1163 }
1164
1165 HRESULT WebFrame::formForElement(IDOMElement* element, IDOMElement** form)
1166 {
1167     if (!element)
1168         return E_INVALIDARG;
1169
1170     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1171     if (!inputElement)
1172         return E_FAIL;
1173
1174     HTMLFormElement *formElement = inputElement->form();
1175     if (!formElement)
1176         return E_FAIL;
1177
1178     *form = DOMElement::createInstance(formElement);
1179     return S_OK;
1180 }
1181
1182 HRESULT WebFrame::elementDoesAutoComplete(IDOMElement *element, BOOL *result)
1183 {
1184     *result = false;
1185     if (!element)
1186         return E_INVALIDARG;
1187
1188     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1189     if (!inputElement)
1190         *result = false;
1191     else
1192         *result = inputElement->isTextField() && !inputElement->isPasswordField() && inputElement->autoComplete();
1193
1194     return S_OK;
1195 }
1196
1197 HRESULT WebFrame::pauseAnimation(BSTR animationName, IDOMNode* node, double secondsFromNow, BOOL* animationWasRunning)
1198 {
1199     if (!node || !animationWasRunning)
1200         return E_POINTER;
1201
1202     *animationWasRunning = FALSE;
1203
1204     Frame* frame = core(this);
1205     if (!frame)
1206         return E_FAIL;
1207
1208     AnimationController* controller = frame->animation();
1209     if (!controller)
1210         return E_FAIL;
1211
1212     COMPtr<DOMNode> domNode(Query, node);
1213     if (!domNode)
1214         return E_FAIL;
1215
1216     *animationWasRunning = controller->pauseAnimationAtTime(domNode->node()->renderer(), String(animationName, SysStringLen(animationName)), secondsFromNow);
1217     return S_OK;
1218 }
1219
1220 HRESULT WebFrame::pauseTransition(BSTR propertyName, IDOMNode* node, double secondsFromNow, BOOL* transitionWasRunning)
1221 {
1222     if (!node || !transitionWasRunning)
1223         return E_POINTER;
1224
1225     *transitionWasRunning = FALSE;
1226
1227     Frame* frame = core(this);
1228     if (!frame)
1229         return E_FAIL;
1230
1231     AnimationController* controller = frame->animation();
1232     if (!controller)
1233         return E_FAIL;
1234
1235     COMPtr<DOMNode> domNode(Query, node);
1236     if (!domNode)
1237         return E_FAIL;
1238
1239     *transitionWasRunning = controller->pauseTransitionAtTime(domNode->node()->renderer(), String(propertyName, SysStringLen(propertyName)), secondsFromNow);
1240     return S_OK;
1241 }
1242
1243 HRESULT WebFrame::pauseSVGAnimation(BSTR elementId, IDOMNode* node, double secondsFromNow, BOOL* animationWasRunning)
1244 {
1245     if (!node || !animationWasRunning)
1246         return E_POINTER;
1247
1248     *animationWasRunning = FALSE;
1249
1250     Frame* frame = core(this);
1251     if (!frame)
1252         return E_FAIL;
1253
1254     Document* document = frame->document();
1255     if (!document || !document->svgExtensions())
1256         return E_FAIL;
1257
1258     COMPtr<DOMNode> domNode(Query, node);
1259     if (!domNode || !SVGSMILElement::isSMILElement(domNode->node()))
1260         return E_FAIL;
1261
1262 #if ENABLE(SVG)
1263     *animationWasRunning = document->accessSVGExtensions()->sampleAnimationAtTime(String(elementId, SysStringLen(elementId)), static_cast<SVGSMILElement*>(domNode->node()), secondsFromNow);
1264 #else
1265     *animationWasRunning = FALSE;
1266 #endif
1267
1268     return S_OK;
1269 }
1270
1271 HRESULT WebFrame::visibleContentRect(RECT* rect)
1272 {
1273     if (!rect)
1274         return E_POINTER;
1275     SetRectEmpty(rect);
1276
1277     Frame* frame = core(this);
1278     if (!frame)
1279         return E_FAIL;
1280
1281     FrameView* view = frame->view();
1282     if (!view)
1283         return E_FAIL;
1284
1285     *rect = view->visibleContentRect(false);
1286     return S_OK;
1287 }
1288
1289 HRESULT WebFrame::numberOfActiveAnimations(UINT* number)
1290 {
1291     if (!number)
1292         return E_POINTER;
1293
1294     *number = 0;
1295
1296     Frame* frame = core(this);
1297     if (!frame)
1298         return E_FAIL;
1299
1300     AnimationController* controller = frame->animation();
1301     if (!controller)
1302         return E_FAIL;
1303
1304     *number = controller->numberOfActiveAnimations();
1305     return S_OK;
1306 }
1307
1308 HRESULT WebFrame::suspendAnimations()
1309 {
1310     Frame* frame = core(this);
1311     if (!frame)
1312         return E_FAIL;
1313
1314     frame->animation()->suspendAnimations();
1315     return S_OK;
1316 }
1317
1318 HRESULT WebFrame::resumeAnimations()
1319 {
1320     Frame* frame = core(this);
1321     if (!frame)
1322         return E_FAIL;
1323
1324     frame->animation()->resumeAnimations();
1325     return S_OK;
1326 }
1327
1328 HRESULT WebFrame::isDisplayingStandaloneImage(BOOL* result)
1329 {
1330     if (!result)
1331         return E_POINTER;
1332
1333     *result = FALSE;
1334
1335     Frame* frame = core(this);
1336     if (!frame)
1337         return E_FAIL;
1338
1339     Document* document = frame->document();
1340     *result = document && document->isImageDocument();
1341     return S_OK;
1342 }
1343
1344 HRESULT WebFrame::allowsFollowingLink(BSTR url, BOOL* result)
1345 {
1346     if (!result)
1347         return E_POINTER;
1348
1349     *result = TRUE;
1350
1351     Frame* frame = core(this);
1352     if (!frame)
1353         return E_FAIL;
1354
1355     *result = frame->document()->securityOrigin()->canDisplay(MarshallingHelpers::BSTRToKURL(url));
1356     return S_OK;
1357 }
1358
1359 HRESULT WebFrame::controlsInForm(IDOMElement* form, IDOMElement** controls, int* cControls)
1360 {
1361     if (!form)
1362         return E_INVALIDARG;
1363
1364     HTMLFormElement* formElement = formElementFromDOMElement(form);
1365     if (!formElement)
1366         return E_FAIL;
1367
1368     int inCount = *cControls;
1369     int count = (int) formElement->associatedElements().size();
1370     *cControls = count;
1371     if (!controls)
1372         return S_OK;
1373     if (inCount < count)
1374         return E_FAIL;
1375
1376     *cControls = 0;
1377     const Vector<FormAssociatedElement*>& elements = formElement->associatedElements();
1378     for (int i = 0; i < count; i++) {
1379         if (elements.at(i)->isEnumeratable()) { // Skip option elements, other duds
1380             controls[*cControls] = DOMElement::createInstance(toHTMLElement(elements.at(i)));
1381             (*cControls)++;
1382         }
1383     }
1384     return S_OK;
1385 }
1386
1387 HRESULT WebFrame::elementIsPassword(IDOMElement *element, bool *result)
1388 {
1389     HTMLInputElement* inputElement = inputElementFromDOMElement(element);
1390     *result = inputElement && inputElement->isPasswordField();
1391     return S_OK;
1392 }
1393
1394 HRESULT WebFrame::searchForLabelsBeforeElement(const BSTR* labels, unsigned cLabels, IDOMElement* beforeElement, unsigned* outResultDistance, BOOL* outResultIsInCellAbove, BSTR* result)
1395 {
1396     if (!result) {
1397         ASSERT_NOT_REACHED();
1398         return E_POINTER;
1399     }
1400
1401     if (outResultDistance)
1402         *outResultDistance = 0;
1403     if (outResultIsInCellAbove)
1404         *outResultIsInCellAbove = FALSE;
1405     *result = 0;
1406
1407     if (!cLabels)
1408         return S_OK;
1409     if (cLabels < 1)
1410         return E_INVALIDARG;
1411
1412     Frame* coreFrame = core(this);
1413     if (!coreFrame)
1414         return E_FAIL;
1415
1416     Vector<String> labelStrings(cLabels);
1417     for (int i=0; i<cLabels; i++)
1418         labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
1419     Element *coreElement = elementFromDOMElement(beforeElement);
1420     if (!coreElement)
1421         return E_FAIL;
1422
1423     size_t resultDistance;
1424     bool resultIsInCellAbove;
1425     String label = coreFrame->searchForLabelsBeforeElement(labelStrings, coreElement, &resultDistance, &resultIsInCellAbove);
1426     
1427     *result = SysAllocStringLen(label.characters(), label.length());
1428     if (label.length() && !*result)
1429         return E_OUTOFMEMORY;
1430     if (outResultDistance)
1431         *outResultDistance = resultDistance;
1432     if (outResultIsInCellAbove)
1433         *outResultIsInCellAbove = resultIsInCellAbove;
1434
1435     return S_OK;
1436 }
1437
1438 HRESULT WebFrame::matchLabelsAgainstElement(const BSTR* labels, int cLabels, IDOMElement* againstElement, BSTR* result)
1439 {
1440     if (!result) {
1441         ASSERT_NOT_REACHED();
1442         return E_POINTER;
1443     }
1444
1445     *result = 0;
1446
1447     if (!cLabels)
1448         return S_OK;
1449     if (cLabels < 1)
1450         return E_INVALIDARG;
1451
1452     Frame* coreFrame = core(this);
1453     if (!coreFrame)
1454         return E_FAIL;
1455
1456     Vector<String> labelStrings(cLabels);
1457     for (int i=0; i<cLabels; i++)
1458         labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
1459     Element *coreElement = elementFromDOMElement(againstElement);
1460     if (!coreElement)
1461         return E_FAIL;
1462
1463     String label = coreFrame->matchLabelsAgainstElement(labelStrings, coreElement);
1464     
1465     *result = SysAllocStringLen(label.characters(), label.length());
1466     if (label.length() && !*result)
1467         return E_OUTOFMEMORY;
1468     return S_OK;
1469 }
1470
1471 HRESULT WebFrame::canProvideDocumentSource(bool* result)
1472 {
1473     HRESULT hr = S_OK;
1474     *result = false;
1475
1476     COMPtr<IWebDataSource> dataSource;
1477     hr = WebFrame::dataSource(&dataSource);
1478     if (FAILED(hr))
1479         return hr;
1480
1481     COMPtr<IWebURLResponse> urlResponse;
1482     hr = dataSource->response(&urlResponse);
1483     if (SUCCEEDED(hr) && urlResponse) {
1484         BSTR mimeTypeBStr;
1485         if (SUCCEEDED(urlResponse->MIMEType(&mimeTypeBStr))) {
1486             String mimeType(mimeTypeBStr, SysStringLen(mimeTypeBStr));
1487             *result = mimeType == "text/html" || WebCore::DOMImplementation::isXMLMIMEType(mimeType);
1488             SysFreeString(mimeTypeBStr);
1489         }
1490     }
1491     return hr;
1492 }
1493
1494 HRESULT STDMETHODCALLTYPE WebFrame::layerTreeAsText(BSTR* result)
1495 {
1496     if (!result)
1497         return E_POINTER;
1498     *result = 0;
1499
1500     Frame* frame = core(this);
1501     if (!frame)
1502         return E_FAIL;
1503
1504     String text = frame->layerTreeAsText();
1505     *result = BString(text).release();
1506     return S_OK;
1507 }
1508
1509 void WebFrame::frameLoaderDestroyed()
1510 {
1511     // The FrameLoader going away is equivalent to the Frame going away,
1512     // so we now need to clear our frame pointer.
1513     d->frame = 0;
1514
1515     this->Release();
1516 }
1517
1518 void WebFrame::makeRepresentation(DocumentLoader*)
1519 {
1520     notImplemented();
1521 }
1522
1523 void WebFrame::forceLayoutForNonHTML()
1524 {
1525     notImplemented();
1526 }
1527
1528 void WebFrame::setCopiesOnScroll()
1529 {
1530     notImplemented();
1531 }
1532
1533 void WebFrame::detachedFromParent2()
1534 {
1535     notImplemented();
1536 }
1537
1538 void WebFrame::detachedFromParent3()
1539 {
1540     notImplemented();
1541 }
1542
1543 void WebFrame::cancelPolicyCheck()
1544 {
1545     if (d->m_policyListener) {
1546         d->m_policyListener->invalidate();
1547         d->m_policyListener = 0;
1548     }
1549
1550     d->m_policyFunction = 0;
1551 }
1552
1553 void WebFrame::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
1554 {
1555     Frame* coreFrame = core(this);
1556     ASSERT(coreFrame);
1557
1558     COMPtr<IWebFormDelegate> formDelegate;
1559
1560     if (FAILED(d->webView->formDelegate(&formDelegate))) {
1561         (coreFrame->loader()->policyChecker()->*function)(PolicyUse);
1562         return;
1563     }
1564
1565     COMPtr<IDOMElement> formElement(AdoptCOM, DOMElement::createInstance(formState->form()));
1566
1567     HashMap<String, String> formValuesMap;
1568     const StringPairVector& textFieldValues = formState->textFieldValues();
1569     size_t size = textFieldValues.size();
1570     for (size_t i = 0; i < size; ++i)
1571         formValuesMap.add(textFieldValues[i].first, textFieldValues[i].second);
1572
1573     COMPtr<IPropertyBag> formValuesPropertyBag(AdoptCOM, COMPropertyBag<String>::createInstance(formValuesMap));
1574
1575     COMPtr<WebFrame> sourceFrame(kit(formState->sourceFrame()));
1576     if (SUCCEEDED(formDelegate->willSubmitForm(this, sourceFrame.get(), formElement.get(), formValuesPropertyBag.get(), setUpPolicyListener(function).get())))
1577         return;
1578
1579     // FIXME: Add a sane default implementation
1580     (coreFrame->loader()->policyChecker()->*function)(PolicyUse);
1581 }
1582
1583 void WebFrame::revertToProvisionalState(DocumentLoader*)
1584 {
1585     notImplemented();
1586 }
1587
1588 void WebFrame::setMainFrameDocumentReady(bool)
1589 {
1590     notImplemented();
1591 }
1592
1593 void WebFrame::willChangeTitle(DocumentLoader*)
1594 {
1595     notImplemented();
1596 }
1597
1598 void WebFrame::didChangeTitle(DocumentLoader*)
1599 {
1600     notImplemented();
1601 }
1602
1603 void WebFrame::didChangeIcons(DocumentLoader*)
1604 {
1605     notImplemented();
1606 }
1607
1608 bool WebFrame::canHandleRequest(const ResourceRequest& request) const
1609 {
1610     return WebView::canHandleRequest(request);
1611 }
1612
1613 bool WebFrame::canShowMIMETypeAsHTML(const String& /*MIMEType*/) const
1614 {
1615     notImplemented();
1616     return true;
1617 }
1618
1619 bool WebFrame::canShowMIMEType(const String& /*MIMEType*/) const
1620 {
1621     notImplemented();
1622     return true;
1623 }
1624
1625 bool WebFrame::representationExistsForURLScheme(const String& /*URLScheme*/) const
1626 {
1627     notImplemented();
1628     return false;
1629 }
1630
1631 String WebFrame::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
1632 {
1633     notImplemented();
1634     ASSERT_NOT_REACHED();
1635     return String();
1636 }
1637
1638 void WebFrame::frameLoadCompleted()
1639 {
1640 }
1641
1642 void WebFrame::restoreViewState()
1643 {
1644 }
1645
1646 void WebFrame::provisionalLoadStarted()
1647 {
1648     notImplemented();
1649 }
1650
1651 bool WebFrame::shouldTreatURLAsSameAsCurrent(const KURL&) const
1652 {
1653     notImplemented();
1654     return false;
1655 }
1656
1657 void WebFrame::addHistoryItemForFragmentScroll()
1658 {
1659     notImplemented();
1660 }
1661
1662 void WebFrame::didFinishLoad()
1663 {
1664     notImplemented();
1665 }
1666
1667 void WebFrame::prepareForDataSourceReplacement()
1668 {
1669     notImplemented();
1670 }
1671
1672 String WebFrame::userAgent(const KURL& url)
1673 {
1674     return d->webView->userAgentForKURL(url);
1675 }
1676
1677 void WebFrame::saveViewStateToItem(HistoryItem*)
1678 {
1679 }
1680
1681 ResourceError WebFrame::cancelledError(const ResourceRequest& request)
1682 {
1683     // FIXME: Need ChickenCat to include CFNetwork/CFURLError.h to get these values
1684     // Alternatively, we could create our own error domain/codes.
1685     return ResourceError(String(WebURLErrorDomain), -999, request.url().string(), String());
1686 }
1687
1688 ResourceError WebFrame::blockedError(const ResourceRequest& request)
1689 {
1690     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1691     return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotUseRestrictedPort, request.url().string(), String());
1692 }
1693
1694 ResourceError WebFrame::cannotShowURLError(const ResourceRequest& request)
1695 {
1696     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1697     return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotShowURL, request.url().string(), String());
1698 }
1699
1700 ResourceError WebFrame::interruptForPolicyChangeError(const ResourceRequest& request)
1701 {
1702     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1703     return ResourceError(String(WebKitErrorDomain), WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(), String());
1704 }
1705
1706 ResourceError WebFrame::cannotShowMIMETypeError(const ResourceResponse&)
1707 {
1708     notImplemented();
1709     return ResourceError();
1710 }
1711
1712 ResourceError WebFrame::fileDoesNotExistError(const ResourceResponse&)
1713 {
1714     notImplemented();
1715     return ResourceError();
1716 }
1717
1718 ResourceError WebFrame::pluginWillHandleLoadError(const ResourceResponse& response)
1719 {
1720     return ResourceError(String(WebKitErrorDomain), WebKitErrorPlugInWillHandleLoad, response.url().string(), String());
1721 }
1722
1723 bool WebFrame::shouldFallBack(const ResourceError& error)
1724 {
1725     if (error.errorCode() == WebURLErrorCancelled && error.domain() == String(WebURLErrorDomain))
1726         return false;
1727
1728     if (error.errorCode() == WebKitErrorPlugInWillHandleLoad && error.domain() == String(WebKitErrorDomain))
1729         return false;
1730
1731     return true;
1732 }
1733
1734 COMPtr<WebFramePolicyListener> WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction function)
1735 {
1736     // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
1737
1738     if (d->m_policyListener)
1739         d->m_policyListener->invalidate();
1740
1741     Frame* coreFrame = core(this);
1742     ASSERT(coreFrame);
1743
1744     d->m_policyListener.adoptRef(WebFramePolicyListener::createInstance(coreFrame));
1745     d->m_policyFunction = function;
1746
1747     return d->m_policyListener;
1748 }
1749
1750 void WebFrame::receivedPolicyDecision(PolicyAction action)
1751 {
1752     ASSERT(d->m_policyListener);
1753     ASSERT(d->m_policyFunction);
1754
1755     FramePolicyFunction function = d->m_policyFunction;
1756
1757     d->m_policyListener = 0;
1758     d->m_policyFunction = 0;
1759
1760     Frame* coreFrame = core(this);
1761     ASSERT(coreFrame);
1762
1763     (coreFrame->loader()->policyChecker()->*function)(action);
1764 }
1765
1766 void WebFrame::dispatchDecidePolicyForResponse(FramePolicyFunction function, const ResourceResponse& response, const ResourceRequest& request)
1767 {
1768     Frame* coreFrame = core(this);
1769     ASSERT(coreFrame);
1770
1771     COMPtr<IWebPolicyDelegate> policyDelegate;
1772     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1773         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1774
1775     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
1776
1777     if (SUCCEEDED(policyDelegate->decidePolicyForMIMEType(d->webView, BString(response.mimeType()), urlRequest.get(), this, setUpPolicyListener(function).get())))
1778         return;
1779
1780     (coreFrame->loader()->policyChecker()->*function)(PolicyUse);
1781 }
1782
1783 void WebFrame::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
1784 {
1785     Frame* coreFrame = core(this);
1786     ASSERT(coreFrame);
1787
1788     COMPtr<IWebPolicyDelegate> policyDelegate;
1789     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1790         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1791
1792     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
1793     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, formState ? formState->form() : 0, coreFrame));
1794
1795     if (SUCCEEDED(policyDelegate->decidePolicyForNewWindowAction(d->webView, actionInformation.get(), urlRequest.get(), BString(frameName), setUpPolicyListener(function).get())))
1796         return;
1797
1798     (coreFrame->loader()->policyChecker()->*function)(PolicyUse);
1799 }
1800
1801 void WebFrame::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState)
1802 {
1803     Frame* coreFrame = core(this);
1804     ASSERT(coreFrame);
1805
1806     COMPtr<IWebPolicyDelegate> policyDelegate;
1807     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1808         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1809
1810     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
1811     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, formState ? formState->form() : 0, coreFrame));
1812
1813     if (SUCCEEDED(policyDelegate->decidePolicyForNavigationAction(d->webView, actionInformation.get(), urlRequest.get(), this, setUpPolicyListener(function).get())))
1814         return;
1815
1816     (coreFrame->loader()->policyChecker()->*function)(PolicyUse);
1817 }
1818
1819 void WebFrame::dispatchUnableToImplementPolicy(const ResourceError& error)
1820 {
1821     COMPtr<IWebPolicyDelegate> policyDelegate;
1822     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1823         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1824
1825     COMPtr<IWebError> webError(AdoptCOM, WebError::createInstance(error));
1826     policyDelegate->unableToImplementPolicyWithError(d->webView, webError.get(), this);
1827 }
1828
1829 void WebFrame::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest&, const ResourceResponse& response)
1830 {
1831     COMPtr<IWebDownloadDelegate> downloadDelegate;
1832     COMPtr<IWebView> webView;
1833     if (SUCCEEDED(this->webView(&webView))) {
1834         if (FAILED(webView->downloadDelegate(&downloadDelegate))) {
1835             // If the WebView doesn't successfully provide a download delegate we'll pass a null one
1836             // into the WebDownload - which may or may not decide to use a DefaultDownloadDelegate
1837             LOG_ERROR("Failed to get downloadDelegate from WebView");
1838             downloadDelegate = 0;
1839         }
1840     }
1841
1842     // Its the delegate's job to ref the WebDownload to keep it alive - otherwise it will be destroyed
1843     // when this method returns
1844     COMPtr<WebDownload> download;
1845     download.adoptRef(WebDownload::createInstance(handle, request, response, downloadDelegate.get()));
1846 }
1847
1848 bool WebFrame::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
1849 {
1850     notImplemented();
1851     return false;
1852 }
1853
1854 void WebFrame::dispatchDidFailProvisionalLoad(const ResourceError& error)
1855 {
1856     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1857     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
1858         COMPtr<IWebError> webError;
1859         webError.adoptRef(WebError::createInstance(error));
1860         frameLoadDelegate->didFailProvisionalLoadWithError(d->webView, webError.get(), this);
1861     }
1862 }
1863
1864 void WebFrame::dispatchDidFailLoad(const ResourceError& error)
1865 {
1866     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1867     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
1868         COMPtr<IWebError> webError;
1869         webError.adoptRef(WebError::createInstance(error));
1870         frameLoadDelegate->didFailLoadWithError(d->webView, webError.get(), this);
1871     }
1872 }
1873
1874 void WebFrame::startDownload(const ResourceRequest& request)
1875 {
1876     d->webView->downloadURL(request.url());
1877 }
1878
1879 PassRefPtr<Widget> WebFrame::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const KURL& /*baseURL*/, const Vector<String>& paramNames, const Vector<String>& paramValues)
1880 {
1881     RefPtr<PluginView> pluginView = PluginView::create(core(this), pluginSize, element, KURL(), paramNames, paramValues, "application/x-java-applet", false);
1882
1883     // Check if the plugin can be loaded successfully
1884     if (pluginView->plugin() && pluginView->plugin()->load())
1885         return pluginView;
1886
1887     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
1888     if (FAILED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
1889         return pluginView;
1890
1891     COMPtr<CFDictionaryPropertyBag> userInfoBag = CFDictionaryPropertyBag::createInstance();
1892
1893     ResourceError resourceError(String(WebKitErrorDomain), WebKitErrorJavaUnavailable, String(), String());
1894     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
1895      
1896     resourceLoadDelegate->plugInFailedWithError(d->webView, error.get(), getWebDataSource(d->frame->loader()->documentLoader()));
1897
1898     return pluginView;
1899 }
1900
1901 ObjectContentType WebFrame::objectContentType(const KURL& url, const String& mimeType, bool shouldPreferPlugInsForImages)
1902 {
1903     return WebCore::FrameLoader::defaultObjectContentType(url, mimeType, shouldPreferPlugInsForImages);
1904 }
1905
1906 String WebFrame::overrideMediaType() const
1907 {
1908     notImplemented();
1909     return String();
1910 }
1911
1912 void WebFrame::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1913 {
1914     Frame* coreFrame = core(this);
1915     ASSERT(coreFrame);
1916
1917     Settings* settings = coreFrame->settings();
1918     if (!settings || !settings->isJavaScriptEnabled())
1919         return;
1920
1921     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1922     if (FAILED(d->webView->frameLoadDelegate(&frameLoadDelegate)))
1923         return;
1924
1925     COMPtr<IWebFrameLoadDelegatePrivate2> delegatePrivate(Query, frameLoadDelegate);
1926     if (delegatePrivate && delegatePrivate->didClearWindowObjectForFrameInScriptWorld(d->webView, this, WebScriptWorld::findOrCreateWorld(world).get()) != E_NOTIMPL)
1927         return;
1928
1929     if (world != mainThreadNormalWorld())
1930         return;
1931
1932     JSContextRef context = toRef(coreFrame->script()->globalObject(world)->globalExec());
1933     JSObjectRef windowObject = toRef(coreFrame->script()->globalObject(world));
1934     ASSERT(windowObject);
1935
1936     if (FAILED(frameLoadDelegate->didClearWindowObject(d->webView, context, windowObject, this)))
1937         frameLoadDelegate->windowScriptObjectAvailable(d->webView, context, windowObject);
1938 }
1939
1940 void WebFrame::documentElementAvailable()
1941 {
1942 }
1943
1944 void WebFrame::didPerformFirstNavigation() const
1945 {
1946     COMPtr<IWebPreferences> preferences;
1947     if (FAILED(d->webView->preferences(&preferences)))
1948         return;
1949
1950     COMPtr<IWebPreferencesPrivate> preferencesPrivate(Query, preferences);
1951     if (!preferencesPrivate)
1952         return;
1953     BOOL automaticallyDetectsCacheModel;
1954     if (FAILED(preferencesPrivate->automaticallyDetectsCacheModel(&automaticallyDetectsCacheModel)))
1955         return;
1956
1957     WebCacheModel cacheModel;
1958     if (FAILED(preferences->cacheModel(&cacheModel)))
1959         return;
1960
1961     if (automaticallyDetectsCacheModel && cacheModel < WebCacheModelDocumentBrowser)
1962         preferences->setCacheModel(WebCacheModelDocumentBrowser);
1963 }
1964
1965 void WebFrame::registerForIconNotification(bool listen)
1966 {
1967     d->webView->registerForIconNotification(listen);
1968 }
1969
1970 static IntRect printerRect(HDC printDC)
1971 {
1972     return IntRect(0, 0, 
1973                    GetDeviceCaps(printDC, PHYSICALWIDTH)  - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETX),
1974                    GetDeviceCaps(printDC, PHYSICALHEIGHT) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETY));
1975 }
1976
1977 void WebFrame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, float minPageHeight, bool adjustViewSize)
1978 {
1979     Frame* coreFrame = core(this);
1980     ASSERT(coreFrame);
1981     coreFrame->setPrinting(printing, FloatSize(minPageWidth, minPageHeight), maxPageWidth / minPageWidth, adjustViewSize ? Frame::AdjustViewSize : Frame::DoNotAdjustViewSize);
1982 }
1983
1984 HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode( 
1985     /* [in] */ BOOL value,
1986     /* [in] */ HDC printDC)
1987 {
1988     if (m_inPrintingMode == !!value)
1989         return S_OK;
1990
1991     Frame* coreFrame = core(this);
1992     if (!coreFrame || !coreFrame->document())
1993         return E_FAIL;
1994
1995     m_inPrintingMode = !!value;
1996
1997     // If we are a frameset just print with the layout we have onscreen, otherwise relayout
1998     // according to the paper size
1999     float minLayoutWidth = 0.0f;
2000     float maxLayoutWidth = 0.0f;
2001     float minLayoutHeight = 0.0f;
2002     if (m_inPrintingMode && !coreFrame->document()->isFrameSet()) {
2003         if (!printDC) {
2004             ASSERT_NOT_REACHED();
2005             return E_POINTER;
2006         }
2007
2008         const int desiredPixelsPerInch = 72;
2009         IntRect printRect = printerRect(printDC);
2010         int paperHorizontalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSX);
2011         int paperWidth = printRect.width() * desiredPixelsPerInch / paperHorizontalPixelsPerInch;
2012         int paperVerticalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSY);
2013         int paperHeight = printRect.height() * desiredPixelsPerInch / paperVerticalPixelsPerInch;
2014         minLayoutWidth = paperWidth * PrintingMinimumShrinkFactor;
2015         maxLayoutWidth = paperWidth * PrintingMaximumShrinkFactor;
2016         minLayoutHeight = paperHeight * PrintingMinimumShrinkFactor;
2017     }
2018
2019     setPrinting(m_inPrintingMode, minLayoutWidth, maxLayoutWidth, minLayoutHeight, true);
2020
2021     if (!m_inPrintingMode)
2022         m_pageRects.clear();
2023
2024     return S_OK;
2025 }
2026
2027 void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight)
2028 {
2029     if (headerHeight)
2030         *headerHeight = 0;
2031     if (footerHeight)
2032         *footerHeight = 0;
2033     float height = 0;
2034     COMPtr<IWebUIDelegate> ui;
2035     if (FAILED(d->webView->uiDelegate(&ui)))
2036         return;
2037     if (headerHeight && SUCCEEDED(ui->webViewHeaderHeight(d->webView, &height)))
2038         *headerHeight = height;
2039     if (footerHeight && SUCCEEDED(ui->webViewFooterHeight(d->webView, &height)))
2040         *footerHeight = height;
2041 }
2042
2043 IntRect WebFrame::printerMarginRect(HDC printDC)
2044 {
2045     IntRect emptyRect(0, 0, 0, 0);
2046
2047     COMPtr<IWebUIDelegate> ui;
2048     if (FAILED(d->webView->uiDelegate(&ui)))
2049         return emptyRect;
2050
2051     RECT rect;
2052     if (FAILED(ui->webViewPrintingMarginRect(d->webView, &rect)))
2053         return emptyRect;
2054
2055     rect.left = MulDiv(rect.left, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
2056     rect.top = MulDiv(rect.top, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
2057     rect.right = MulDiv(rect.right, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
2058     rect.bottom = MulDiv(rect.bottom, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
2059
2060     return IntRect(rect.left, rect.top, (rect.right - rect.left), rect.bottom - rect.top);
2061 }
2062
2063 const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC)
2064 {
2065     ASSERT(m_inPrintingMode);
2066     
2067     Frame* coreFrame = core(this);
2068     ASSERT(coreFrame);
2069     ASSERT(coreFrame->document());
2070
2071     if (!printDC)
2072         return m_pageRects;
2073
2074     // adjust the page rect by the header and footer
2075     float headerHeight = 0, footerHeight = 0;
2076     headerAndFooterHeights(&headerHeight, &footerHeight);
2077     IntRect pageRect = printerRect(printDC);
2078     IntRect marginRect = printerMarginRect(printDC);
2079     IntRect adjustedRect = IntRect(
2080         pageRect.x() + marginRect.x(),
2081         pageRect.y() + marginRect.y(),
2082         pageRect.width() - marginRect.x() - marginRect.maxX(),
2083         pageRect.height() - marginRect.y() - marginRect.maxY());
2084
2085     computePageRectsForFrame(coreFrame, adjustedRect, headerHeight, footerHeight, 1.0,m_pageRects, m_pageHeight);
2086     
2087     return m_pageRects;
2088 }
2089
2090 HRESULT STDMETHODCALLTYPE WebFrame::getPrintedPageCount( 
2091     /* [in] */ HDC printDC,
2092     /* [retval][out] */ UINT *pageCount)
2093 {
2094     if (!pageCount || !printDC) {
2095         ASSERT_NOT_REACHED();
2096         return E_POINTER;
2097     }
2098
2099     *pageCount = 0;
2100
2101     if (!m_inPrintingMode) {
2102         ASSERT_NOT_REACHED();
2103         return E_FAIL;
2104     }
2105
2106     Frame* coreFrame = core(this);
2107     if (!coreFrame || !coreFrame->document())
2108         return E_FAIL;
2109
2110     const Vector<IntRect>& pages = computePageRects(printDC);
2111     *pageCount = (UINT) pages.size();
2112     
2113     return S_OK;
2114 }
2115
2116 #if USE(CG)
2117 void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
2118 {
2119     int x = pageRect.x();
2120     int y = 0;
2121     RECT headerRect = {x, y, x+pageRect.width(), y+static_cast<int>(headerHeight)};
2122     ui->drawHeaderInRect(d->webView, &headerRect, static_cast<OLE_HANDLE>(reinterpret_cast<LONG64>(pctx)));
2123 }
2124
2125 void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight)
2126 {
2127     int x = pageRect.x();
2128     int y = max((int)headerHeight+pageRect.height(), m_pageHeight-static_cast<int>(footerHeight));
2129     RECT footerRect = {x, y, x+pageRect.width(), y+static_cast<int>(footerHeight)};
2130     ui->drawFooterInRect(d->webView, &footerRect, static_cast<OLE_HANDLE>(reinterpret_cast<LONG64>(pctx)), page+1, pageCount);
2131 }
2132
2133 void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount)
2134 {
2135     Frame* coreFrame = core(this);
2136
2137     IntRect pageRect = m_pageRects[page];
2138
2139     CGContextSaveGState(pctx);
2140
2141     IntRect printRect = printerRect(printDC);
2142     CGRect mediaBox = CGRectMake(CGFloat(0),
2143                                  CGFloat(0),
2144                                  CGFloat(printRect.width()),
2145                                  CGFloat(printRect.height()));
2146
2147     CGContextBeginPage(pctx, &mediaBox);
2148
2149     CGFloat scale = static_cast<float>(mediaBox.size.width)/static_cast<float>(pageRect.width());
2150     CGAffineTransform ctm = CGContextGetBaseCTM(pctx);
2151     ctm = CGAffineTransformScale(ctm, -scale, -scale);
2152     ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header
2153     CGContextScaleCTM(pctx, scale, scale);
2154     CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight));   // reserves space for header
2155     CGContextSetBaseCTM(pctx, ctm);
2156
2157     coreFrame->view()->paintContents(spoolCtx, pageRect);
2158
2159     CGContextTranslateCTM(pctx, CGFloat(pageRect.x()), CGFloat(pageRect.y())-headerHeight);
2160
2161     if (headerHeight)
2162         drawHeader(pctx, ui, pageRect, headerHeight);
2163
2164     if (footerHeight)
2165         drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight);
2166
2167     CGContextEndPage(pctx);
2168     CGContextRestoreGState(pctx);
2169 }
2170 #elif USE(CAIRO)
2171 static float scaleFactor(HDC printDC, const IntRect& marginRect, const IntRect& pageRect)
2172 {
2173     const IntRect& printRect = printerRect(printDC);
2174
2175     IntRect adjustedRect = IntRect(
2176         printRect.x() + marginRect.x(),
2177         printRect.y() + marginRect.y(),
2178         printRect.width() - marginRect.x() - marginRect.maxX(),
2179         printRect.height() - marginRect.y() - marginRect.maxY());
2180
2181     float scale = static_cast<float>(adjustedRect.width()) / static_cast<float>(pageRect.width());
2182     if (!scale)
2183        scale = 1.0;
2184
2185     return scale;
2186 }
2187
2188 static HDC hdcFromContext(PlatformGraphicsContext* pctx)
2189 {
2190     return cairo_win32_surface_get_dc(cairo_get_target(pctx->cr()));
2191 }
2192
2193 void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
2194 {
2195     HDC hdc = hdcFromContext(pctx);
2196
2197     int x = pageRect.x();
2198     int y = 0;
2199     RECT headerRect = {x, y, x + pageRect.width(), y + static_cast<int>(headerHeight)};
2200
2201     ui->drawHeaderInRect(d->webView, &headerRect, static_cast<OLE_HANDLE>(reinterpret_cast<LONG64>(hdc)));
2202 }
2203
2204 void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight)
2205 {
2206     HDC hdc = hdcFromContext(pctx);
2207     
2208     int x = pageRect.x();
2209     int y = max(static_cast<int>(headerHeight) + pageRect.height(), m_pageHeight  -static_cast<int>(footerHeight));
2210     RECT footerRect = {x, y, x + pageRect.width(), y + static_cast<int>(footerHeight)};
2211
2212     ui->drawFooterInRect(d->webView, &footerRect, static_cast<OLE_HANDLE>(reinterpret_cast<LONG64>(hdc)), page+1, pageCount);
2213 }
2214
2215 static XFORM buildXFORMFromCairo(HDC targetDC, cairo_t* previewContext)
2216 {
2217     XFORM scaled;
2218     GetWorldTransform(targetDC, &scaled);
2219
2220     cairo_matrix_t ctm;
2221     cairo_get_matrix(previewContext, &ctm);    
2222         
2223     // Scale to the preview screen bounds
2224     scaled.eM11 = ctm.xx;
2225     scaled.eM22 = ctm.yy;
2226
2227     return scaled;
2228 }
2229
2230 void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount)
2231 {
2232     Frame* coreFrame = core(this);
2233
2234     const IntRect& pageRect = m_pageRects[page];
2235     const IntRect& marginRect = printerMarginRect(printDC);
2236
2237     // In preview, the printDC is a placeholder, so just always use the HDC backing the graphics context.
2238     HDC hdc = hdcFromContext(pctx);
2239
2240     spoolCtx->save();
2241     
2242     XFORM original, scaled;
2243     GetWorldTransform(hdc, &original);
2244     
2245     cairo_t* cr = pctx->cr();
2246     bool preview = (hdc != printDC);
2247     if (preview) {
2248         // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo will
2249         // draw correctly.  We need to retain the correct preview scale here for use when the Cairo
2250         // drawing completes so that we can scale our GDI-based header/footer calls. This is a
2251         // workaround for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
2252         scaled = buildXFORMFromCairo(hdc, cr);
2253     }
2254
2255     float scale = scaleFactor(printDC, marginRect, pageRect);
2256     
2257     IntRect cairoMarginRect(marginRect);
2258     cairoMarginRect.scale(1 / scale);
2259
2260     // We cannot scale the display HDC because the print surface also scales fonts,
2261     // resulting in invalid printing (and print preview)
2262     cairo_scale(cr, scale, scale);
2263     cairo_translate(cr, cairoMarginRect.x(), cairoMarginRect.y() + headerHeight);
2264
2265     // Modify Cairo (only) to account for page position.
2266     cairo_translate(cr, -pageRect.x(), -pageRect.y());
2267     coreFrame->view()->paintContents(spoolCtx, pageRect);
2268     cairo_translate(cr, pageRect.x(), pageRect.y());
2269     
2270     if (preview) {
2271         // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo would
2272         // draw correctly.  We need to rescale the HDC to the correct preview scale so our GDI-based
2273         // header/footer calls will draw properly.  This is a workaround for a bug in Cairo.
2274         // (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
2275         SetWorldTransform(hdc, &scaled);
2276     }
2277     
2278     XFORM xform = TransformationMatrix().translate(marginRect.x(), marginRect.y()).scale(scale);
2279     ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
2280    
2281     if (headerHeight)
2282         drawHeader(pctx, ui, pageRect, headerHeight);
2283     
2284     if (footerHeight)
2285         drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight);
2286
2287     SetWorldTransform(hdc, &original);
2288
2289     cairo_show_page(cr);
2290     ASSERT(!cairo_status(cr));
2291     spoolCtx->restore();
2292 }
2293
2294 static void setCairoTransformToPreviewHDC(cairo_t* previewCtx, HDC previewDC)
2295 {
2296     XFORM passedCTM;
2297     GetWorldTransform(previewDC, &passedCTM);
2298
2299     // Reset HDC WorldTransform to unscaled state.  Scaling must be
2300     // done in Cairo to avoid drawing errors.
2301     XFORM unscaledCTM = passedCTM;
2302     unscaledCTM.eM11 = 1.0;
2303     unscaledCTM.eM22 = 1.0;
2304         
2305     SetWorldTransform(previewDC, &unscaledCTM);
2306
2307     // Make the Cairo transform match the information passed to WebKit
2308     // in the HDC's WorldTransform.
2309     cairo_matrix_t ctm = { passedCTM.eM11, passedCTM.eM12, passedCTM.eM21,
2310                            passedCTM.eM22, passedCTM.eDx, passedCTM.eDy };
2311
2312     cairo_set_matrix(previewCtx, &ctm);    
2313 }
2314
2315 #endif
2316
2317 HRESULT STDMETHODCALLTYPE WebFrame::spoolPages( 
2318     /* [in] */ HDC printDC,
2319     /* [in] */ UINT startPage,
2320     /* [in] */ UINT endPage,
2321     /* [retval][out] */ void* ctx)
2322 {
2323 #if USE(CG)
2324     if (!printDC || !ctx) {
2325         ASSERT_NOT_REACHED();
2326         return E_POINTER;
2327     }
2328 #elif USE(CAIRO)
2329     if (!printDC) {
2330         ASSERT_NOT_REACHED();
2331         return E_POINTER;
2332     }
2333     
2334     HDC targetDC = (ctx) ? (HDC)ctx : printDC;
2335
2336     cairo_surface_t* printSurface = 0;
2337     if (ctx)
2338         printSurface = cairo_win32_surface_create(targetDC); // in-memory
2339     else
2340         printSurface = cairo_win32_printing_surface_create(targetDC); // metafile
2341     
2342     cairo_t* cr = cairo_create(printSurface);
2343     if (!cr) {
2344         cairo_surface_destroy(printSurface);    
2345         return E_FAIL;
2346     }
2347
2348     PlatformContextCairo platformContext(cr);
2349     PlatformGraphicsContext* pctx = &platformContext;
2350     cairo_destroy(cr);
2351
2352     if (ctx) {
2353         // If this is a preview, the Windows HDC was sent with scaling information.
2354         // Retrieve it and reset it so that it draws properly.  This is a workaround
2355         // for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
2356         setCairoTransformToPreviewHDC(cr, targetDC);
2357     }
2358     
2359     cairo_surface_set_fallback_resolution(printSurface, 72.0, 72.0);
2360 #endif
2361
2362     if (!m_inPrintingMode) {
2363         ASSERT_NOT_REACHED();
2364         return E_FAIL;
2365     }
2366
2367     Frame* coreFrame = core(this);
2368     if (!coreFrame || !coreFrame->document())
2369         return E_FAIL;
2370
2371     UINT pageCount = (UINT) m_pageRects.size();
2372 #if USE(CG)
2373     PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx;
2374 #endif
2375
2376     if (!pageCount || startPage > pageCount) {
2377         ASSERT_NOT_REACHED();
2378         return E_FAIL;
2379     }
2380
2381     if (startPage > 0)
2382         startPage--;
2383
2384     if (endPage == 0)
2385         endPage = pageCount;
2386
2387     COMPtr<IWebUIDelegate> ui;
2388     if (FAILED(d->webView->uiDelegate(&ui)))
2389         return E_FAIL;
2390
2391     float headerHeight = 0, footerHeight = 0;
2392     headerAndFooterHeights(&headerHeight, &footerHeight);
2393     GraphicsContext spoolCtx(pctx);
2394     spoolCtx.setShouldIncludeChildWindows(true);
2395
2396     for (UINT ii = startPage; ii < endPage; ii++)
2397         spoolPage(pctx, &spoolCtx, printDC, ui.get(), headerHeight, footerHeight, ii, pageCount);
2398
2399 #if USE(CAIRO)
2400     cairo_surface_finish(printSurface);
2401     ASSERT(!cairo_surface_status(printSurface));
2402     cairo_surface_destroy(printSurface);
2403 #endif
2404
2405     return S_OK;
2406 }
2407
2408 HRESULT STDMETHODCALLTYPE WebFrame::isFrameSet( 
2409     /* [retval][out] */ BOOL* result)
2410 {
2411     *result = FALSE;
2412
2413     Frame* coreFrame = core(this);
2414     if (!coreFrame || !coreFrame->document())
2415         return E_FAIL;
2416
2417     *result = coreFrame->document()->isFrameSet() ? TRUE : FALSE;
2418     return S_OK;
2419 }
2420
2421 HRESULT STDMETHODCALLTYPE WebFrame::string( 
2422     /* [retval][out] */ BSTR *result)
2423 {
2424     *result = 0;
2425
2426     Frame* coreFrame = core(this);
2427     if (!coreFrame)
2428         return E_FAIL;
2429
2430     RefPtr<Range> allRange(rangeOfContents(coreFrame->document()));
2431     String allString = plainText(allRange.get());
2432     *result = BString(allString).release();
2433     return S_OK;
2434 }
2435
2436 HRESULT STDMETHODCALLTYPE WebFrame::size( 
2437     /* [retval][out] */ SIZE *size)
2438 {
2439     if (!size)
2440         return E_POINTER;
2441     size->cx = size->cy = 0;
2442
2443     Frame* coreFrame = core(this);
2444     if (!coreFrame)
2445         return E_FAIL;
2446     FrameView* view = coreFrame->view();
2447     if (!view)
2448         return E_FAIL;
2449     size->cx = view->width();
2450     size->cy = view->height();
2451     return S_OK;
2452 }
2453
2454 HRESULT STDMETHODCALLTYPE WebFrame::hasScrollBars( 
2455     /* [retval][out] */ BOOL *result)
2456 {
2457     if (!result)
2458         return E_POINTER;
2459     *result = FALSE;
2460
2461     Frame* coreFrame = core(this);
2462     if (!coreFrame)
2463         return E_FAIL;
2464
2465     FrameView* view = coreFrame->view();
2466     if (!view)
2467         return E_FAIL;
2468
2469     if (view->horizontalScrollbar() || view->verticalScrollbar())
2470         *result = TRUE;
2471
2472     return S_OK;
2473 }
2474
2475 HRESULT STDMETHODCALLTYPE WebFrame::contentBounds( 
2476     /* [retval][out] */ RECT *result)
2477 {
2478     if (!result)
2479         return E_POINTER;
2480     ::SetRectEmpty(result);
2481
2482     Frame* coreFrame = core(this);
2483     if (!coreFrame)
2484         return E_FAIL;
2485
2486     FrameView* view = coreFrame->view();
2487     if (!view)
2488         return E_FAIL;
2489
2490     result->bottom = view->contentsHeight();
2491     result->right = view->contentsWidth();
2492     return S_OK;
2493 }
2494
2495 HRESULT STDMETHODCALLTYPE WebFrame::frameBounds( 
2496     /* [retval][out] */ RECT *result)
2497 {
2498     if (!result)
2499         return E_POINTER;
2500     ::SetRectEmpty(result);
2501
2502     Frame* coreFrame = core(this);
2503     if (!coreFrame)
2504         return E_FAIL;
2505
2506     FrameView* view = coreFrame->view();
2507     if (!view)
2508         return E_FAIL;
2509
2510     FloatRect bounds = view->visibleContentRect(true);
2511     result->bottom = (LONG) bounds.height();
2512     result->right = (LONG) bounds.width();
2513     return S_OK;
2514 }
2515
2516 HRESULT STDMETHODCALLTYPE WebFrame::isDescendantOfFrame( 
2517     /* [in] */ IWebFrame *ancestor,
2518     /* [retval][out] */ BOOL *result)
2519 {
2520     if (!result)
2521         return E_POINTER;
2522     *result = FALSE;
2523
2524     Frame* coreFrame = core(this);
2525     COMPtr<WebFrame> ancestorWebFrame(Query, ancestor);
2526     if (!ancestorWebFrame)
2527         return S_OK;
2528
2529     *result = (coreFrame && coreFrame->tree()->isDescendantOf(core(ancestorWebFrame.get()))) ? TRUE : FALSE;
2530     return S_OK;
2531 }
2532
2533 HRESULT WebFrame::stringByEvaluatingJavaScriptInScriptWorld(IWebScriptWorld* iWorld, JSObjectRef globalObjectRef, BSTR script, BSTR* evaluationResult)
2534 {
2535     if (!evaluationResult)
2536         return E_POINTER;
2537     *evaluationResult = 0;
2538
2539     if (!iWorld)
2540         return E_POINTER;
2541
2542     COMPtr<WebScriptWorld> world(Query, iWorld);
2543     if (!world)
2544         return E_INVALIDARG;
2545
2546     Frame* coreFrame = core(this);
2547     String string = String(script, SysStringLen(script));
2548
2549     // Start off with some guess at a frame and a global object, we'll try to do better...!
2550     JSDOMWindow* anyWorldGlobalObject = coreFrame->script()->globalObject(mainThreadNormalWorld());
2551
2552     // The global object is probably a shell object? - if so, we know how to use this!
2553     JSC::JSObject* globalObjectObj = toJS(globalObjectRef);
2554     if (!strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell"))
2555         anyWorldGlobalObject = static_cast<JSDOMWindowShell*>(globalObjectObj)->window();
2556
2557     // Get the frame frome the global object we've settled on.
2558     Frame* frame = anyWorldGlobalObject->impl()->frame();
2559     ASSERT(frame->document());
2560     JSValue result = frame->script()->executeScriptInWorld(world->world(), string, true).jsValue();
2561
2562     if (!frame) // In case the script removed our frame from the page.
2563         return S_OK;
2564
2565     // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
2566     // If you don't like it, use -[WebScriptObject evaluateWebScript:] or 
2567     // JSEvaluateScript instead, since they have less surprising semantics.
2568     if (!result || !result.isBoolean() && !result.isString() && !result.isNumber())
2569         return S_OK;
2570
2571     JSLock lock(SilenceAssertionsOnly);
2572     String resultString = ustringToString(result.toString(anyWorldGlobalObject->globalExec()));
2573     *evaluationResult = BString(resultString).release();
2574
2575     return S_OK;
2576 }
2577
2578 void WebFrame::unmarkAllMisspellings()
2579 {
2580     Frame* coreFrame = core(this);
2581     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
2582         Document *doc = frame->document();
2583         if (!doc)
2584             return;
2585
2586         doc->markers()->removeMarkers(DocumentMarker::Spelling);
2587     }
2588 }
2589
2590 void WebFrame::unmarkAllBadGrammar()
2591 {
2592     Frame* coreFrame = core(this);
2593     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
2594         Document *doc = frame->document();
2595         if (!doc)
2596             return;
2597
2598         doc->markers()->removeMarkers(DocumentMarker::Grammar);
2599     }
2600 }
2601
2602 WebView* WebFrame::webView() const
2603 {
2604     return d->webView;
2605 }
2606
2607 void WebFrame::setWebView(WebView* webView)
2608 {
2609     d->webView = webView;
2610 }
2611
2612 COMPtr<IAccessible> WebFrame::accessible() const
2613 {
2614     Frame* coreFrame = core(this);
2615     ASSERT(coreFrame);
2616
2617     Document* currentDocument = coreFrame->document();
2618     if (!currentDocument)
2619         m_accessible = 0;
2620     else if (!m_accessible || m_accessible->document() != currentDocument) {
2621         // Either we've never had a wrapper for this frame's top-level Document,
2622         // the Document renderer was destroyed and its wrapper was detached, or
2623         // the previous Document is in the page cache, and the current document
2624         // needs to be wrapped.
2625         m_accessible = new AccessibleDocument(currentDocument);
2626     }
2627     return m_accessible.get();
2628 }
2629
2630 void WebFrame::updateBackground()
2631 {
2632     Color backgroundColor = webView()->transparent() ? Color::transparent : Color::white;
2633     Frame* coreFrame = core(this);
2634
2635     if (!coreFrame || !coreFrame->view())
2636         return;
2637
2638     coreFrame->view()->updateBackgroundRecursively(backgroundColor, webView()->transparent());
2639 }
2640
2641 PassRefPtr<FrameNetworkingContext> WebFrame::createNetworkingContext()
2642 {
2643     return WebFrameNetworkingContext::create(core(this), userAgent(url()));
2644 }