• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009 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 "COMPropertyBag.h"
33 #include "DefaultPolicyDelegate.h"
34 #include "DOMCoreClasses.h"
35 #include "HTMLFrameOwnerElement.h"
36 #include "MarshallingHelpers.h"
37 #include "WebActionPropertyBag.h"
38 #include "WebChromeClient.h"
39 #include "WebDocumentLoader.h"
40 #include "WebDownload.h"
41 #include "WebError.h"
42 #include "WebMutableURLRequest.h"
43 #include "WebEditorClient.h"
44 #include "WebFramePolicyListener.h"
45 #include "WebHistory.h"
46 #include "WebIconFetcher.h"
47 #include "WebKit.h"
48 #include "WebKitStatisticsPrivate.h"
49 #include "WebNotificationCenter.h"
50 #include "WebView.h"
51 #include "WebDataSource.h"
52 #include "WebHistoryItem.h"
53 #include "WebURLResponse.h"
54 #pragma warning( push, 0 )
55 #include <WebCore/BString.h>
56 #include <WebCore/Cache.h>
57 #include <WebCore/Document.h>
58 #include <WebCore/DocumentLoader.h>
59 #include <WebCore/DOMImplementation.h>
60 #include <WebCore/DOMWindow.h>
61 #include <WebCore/Event.h>
62 #include <WebCore/EventHandler.h>
63 #include <WebCore/FormState.h>
64 #include <WebCore/FrameLoader.h>
65 #include <WebCore/FrameLoadRequest.h>
66 #include <WebCore/FrameTree.h>
67 #include <WebCore/FrameView.h>
68 #include <WebCore/FrameWin.h>
69 #include <WebCore/GDIObjectCounter.h>
70 #include <WebCore/GraphicsContext.h>
71 #include <WebCore/HistoryItem.h>
72 #include <WebCore/HTMLAppletElement.h>
73 #include <WebCore/HTMLFormElement.h>
74 #include <WebCore/HTMLFormControlElement.h>
75 #include <WebCore/HTMLInputElement.h>
76 #include <WebCore/HTMLNames.h>
77 #include <WebCore/HTMLPlugInElement.h>
78 #include <WebCore/JSDOMWindow.h>
79 #include <WebCore/KeyboardEvent.h>
80 #include <WebCore/MIMETypeRegistry.h>
81 #include <WebCore/MouseRelatedEvent.h>
82 #include <WebCore/NotImplemented.h>
83 #include <WebCore/Page.h>
84 #include <WebCore/PlatformKeyboardEvent.h>
85 #include <WebCore/PluginInfoStore.h>
86 #include <WebCore/PluginDatabase.h>
87 #include <WebCore/PluginView.h>
88 #include <WebCore/ResourceHandle.h>
89 #include <WebCore/ResourceHandleWin.h>
90 #include <WebCore/ResourceRequest.h>
91 #include <WebCore/RenderView.h>
92 #include <WebCore/RenderTreeAsText.h>
93 #include <WebCore/Settings.h>
94 #include <WebCore/TextIterator.h>
95 #include <WebCore/JSDOMBinding.h>
96 #include <WebCore/ScriptController.h>
97 #include <JavaScriptCore/APICast.h>
98 #include <wtf/MathExtras.h>
99 #pragma warning(pop)
100 
101 #if PLATFORM(CG)
102 #include <CoreGraphics/CoreGraphics.h>
103 #elif PLATFORM(CAIRO)
104 #include <cairo-win32.h>
105 #endif
106 
107 #if PLATFORM(CG)
108 // CG SPI used for printing
109 extern "C" {
110     CGAffineTransform CGContextGetBaseCTM(CGContextRef c);
111     void CGContextSetBaseCTM(CGContextRef c, CGAffineTransform m);
112 }
113 #endif
114 
115 using namespace WebCore;
116 using namespace HTMLNames;
117 
118 #define FLASH_REDRAW 0
119 
120 
121 // By imaging to a width a little wider than the available pixels,
122 // thin pages will be scaled down a little, matching the way they
123 // print in IE and Camino. This lets them use fewer sheets than they
124 // would otherwise, which is presumably why other browsers do this.
125 // Wide pages will be scaled down more than this.
126 const float PrintingMinimumShrinkFactor = 1.25f;
127 
128 // This number determines how small we are willing to reduce the page content
129 // in order to accommodate the widest line. If the page would have to be
130 // reduced smaller to make the widest line fit, we just clip instead (this
131 // behavior matches MacIE and Mozilla, at least)
132 const float PrintingMaximumShrinkFactor = 2.0f;
133 
134 //-----------------------------------------------------------------------------
135 // Helpers to convert from WebCore to WebKit type
kit(Frame * frame)136 WebFrame* kit(Frame* frame)
137 {
138     if (!frame)
139         return 0;
140 
141     FrameLoaderClient* frameLoaderClient = frame->loader()->client();
142     if (frameLoaderClient)
143         return static_cast<WebFrame*>(frameLoaderClient);  // eek, is there a better way than static cast?
144     return 0;
145 }
146 
core(WebFrame * webFrame)147 Frame* core(WebFrame* webFrame)
148 {
149     if (!webFrame)
150         return 0;
151     return webFrame->impl();
152 }
153 
154 // 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
core(const WebFrame * webFrame)155 Frame* core(const WebFrame* webFrame)
156 {
157     if (!webFrame)
158         return 0;
159     return const_cast<WebFrame*>(webFrame)->impl();
160 }
161 
162 //-----------------------------------------------------------------------------
163 
elementFromDOMElement(IDOMElement * element)164 static Element *elementFromDOMElement(IDOMElement *element)
165 {
166     if (!element)
167         return 0;
168 
169     COMPtr<IDOMElementPrivate> elePriv;
170     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
171     if (SUCCEEDED(hr)) {
172         Element* ele;
173         hr = elePriv->coreElement((void**)&ele);
174         if (SUCCEEDED(hr))
175             return ele;
176     }
177     return 0;
178 }
179 
formElementFromDOMElement(IDOMElement * element)180 static HTMLFormElement *formElementFromDOMElement(IDOMElement *element)
181 {
182     if (!element)
183         return 0;
184 
185     IDOMElementPrivate* elePriv;
186     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
187     if (SUCCEEDED(hr)) {
188         Element* ele;
189         hr = elePriv->coreElement((void**)&ele);
190         elePriv->Release();
191         if (SUCCEEDED(hr) && ele && ele->hasTagName(formTag))
192             return static_cast<HTMLFormElement*>(ele);
193     }
194     return 0;
195 }
196 
inputElementFromDOMElement(IDOMElement * element)197 static HTMLInputElement* inputElementFromDOMElement(IDOMElement* element)
198 {
199     if (!element)
200         return 0;
201 
202     IDOMElementPrivate* elePriv;
203     HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
204     if (SUCCEEDED(hr)) {
205         Element* ele;
206         hr = elePriv->coreElement((void**)&ele);
207         elePriv->Release();
208         if (SUCCEEDED(hr) && ele && ele->hasTagName(inputTag))
209             return static_cast<HTMLInputElement*>(ele);
210     }
211     return 0;
212 }
213 
214 // WebFramePrivate ------------------------------------------------------------
215 
216 class WebFrame::WebFramePrivate {
217 public:
WebFramePrivate()218     WebFramePrivate()
219         : frame(0)
220         , webView(0)
221         , m_policyFunction(0)
222     {
223     }
224 
~WebFramePrivate()225     ~WebFramePrivate() { }
frameView()226     FrameView* frameView() { return frame ? frame->view() : 0; }
227 
228     Frame* frame;
229     WebView* webView;
230     FramePolicyFunction m_policyFunction;
231     COMPtr<WebFramePolicyListener> m_policyListener;
232 };
233 
234 // WebFrame ----------------------------------------------------------------
235 
WebFrame()236 WebFrame::WebFrame()
237     : WebFrameLoaderClient(this)
238     , m_refCount(0)
239     , d(new WebFrame::WebFramePrivate)
240     , m_quickRedirectComing(false)
241     , m_inPrintingMode(false)
242     , m_pageHeight(0)
243 {
244     WebFrameCount++;
245     gClassCount++;
246     gClassNameCount.add("WebFrame");
247 }
248 
~WebFrame()249 WebFrame::~WebFrame()
250 {
251     delete d;
252     WebFrameCount--;
253     gClassCount--;
254     gClassNameCount.remove("WebFrame");
255 }
256 
createInstance()257 WebFrame* WebFrame::createInstance()
258 {
259     WebFrame* instance = new WebFrame();
260     instance->AddRef();
261     return instance;
262 }
263 
setAllowsScrolling(BOOL flag)264 HRESULT STDMETHODCALLTYPE WebFrame::setAllowsScrolling(
265     /* [in] */ BOOL flag)
266 {
267     if (Frame* frame = core(this))
268         if (FrameView* view = frame->view())
269             view->setCanHaveScrollbars(!!flag);
270 
271     return S_OK;
272 }
273 
allowsScrolling(BOOL * flag)274 HRESULT STDMETHODCALLTYPE WebFrame::allowsScrolling(
275     /* [retval][out] */ BOOL *flag)
276 {
277     if (flag)
278         if (Frame* frame = core(this))
279             if (FrameView* view = frame->view())
280                 *flag = view->canHaveScrollbars();
281 
282     return S_OK;
283 }
284 
setIsDisconnected(BOOL flag)285 HRESULT STDMETHODCALLTYPE WebFrame::setIsDisconnected(
286     /* [in] */ BOOL flag)
287 {
288     if (Frame* frame = core(this)) {
289         frame->setIsDisconnected(flag);
290         return S_OK;
291     }
292 
293     return E_FAIL;
294 }
295 
setExcludeFromTextSearch(BOOL flag)296 HRESULT STDMETHODCALLTYPE WebFrame::setExcludeFromTextSearch(
297     /* [in] */ BOOL flag)
298 {
299     if (Frame* frame = core(this)) {
300         frame->setExcludeFromTextSearch(flag);
301         return S_OK;
302     }
303 
304     return E_FAIL;
305 }
306 
paintDocumentRectToContext(RECT rect,OLE_HANDLE deviceContext)307 HRESULT STDMETHODCALLTYPE WebFrame::paintDocumentRectToContext(
308     /* [in] */ RECT rect,
309     /* [in] */ OLE_HANDLE deviceContext)
310 {
311     Frame* coreFrame = core(this);
312     if (!coreFrame)
313         return E_FAIL;
314 
315     FrameView* view = coreFrame->view();
316     if (!view)
317         return E_FAIL;
318 
319     // We can't paint with a layout still pending.
320     view->layoutIfNeededRecursive();
321 
322     HDC dc = (HDC)(ULONG64)deviceContext;
323     GraphicsContext gc(dc);
324     gc.setShouldIncludeChildWindows(true);
325     gc.save();
326     LONG width = rect.right - rect.left;
327     LONG height = rect.bottom - rect.top;
328     FloatRect dirtyRect;
329     dirtyRect.setWidth(width);
330     dirtyRect.setHeight(height);
331     gc.clip(dirtyRect);
332     gc.translate(-rect.left, -rect.top);
333     view->paintContents(&gc, rect);
334     gc.restore();
335 
336     return S_OK;
337 }
338 
339 // IUnknown -------------------------------------------------------------------
340 
QueryInterface(REFIID riid,void ** ppvObject)341 HRESULT STDMETHODCALLTYPE WebFrame::QueryInterface(REFIID riid, void** ppvObject)
342 {
343     *ppvObject = 0;
344     if (IsEqualGUID(riid, __uuidof(WebFrame)))
345         *ppvObject = this;
346     else if (IsEqualGUID(riid, IID_IUnknown))
347         *ppvObject = static_cast<IWebFrame*>(this);
348     else if (IsEqualGUID(riid, IID_IWebFrame))
349         *ppvObject = static_cast<IWebFrame*>(this);
350     else if (IsEqualGUID(riid, IID_IWebFramePrivate))
351         *ppvObject = static_cast<IWebFramePrivate*>(this);
352     else if (IsEqualGUID(riid, IID_IWebDocumentText))
353         *ppvObject = static_cast<IWebDocumentText*>(this);
354     else
355         return E_NOINTERFACE;
356 
357     AddRef();
358     return S_OK;
359 }
360 
AddRef(void)361 ULONG STDMETHODCALLTYPE WebFrame::AddRef(void)
362 {
363     return ++m_refCount;
364 }
365 
Release(void)366 ULONG STDMETHODCALLTYPE WebFrame::Release(void)
367 {
368     ULONG newRef = --m_refCount;
369     if (!newRef)
370         delete(this);
371 
372     return newRef;
373 }
374 
375 // IWebFrame -------------------------------------------------------------------
376 
name(BSTR * frameName)377 HRESULT STDMETHODCALLTYPE WebFrame::name(
378     /* [retval][out] */ BSTR* frameName)
379 {
380     if (!frameName) {
381         ASSERT_NOT_REACHED();
382         return E_POINTER;
383     }
384 
385     *frameName = 0;
386 
387     Frame* coreFrame = core(this);
388     if (!coreFrame)
389         return E_FAIL;
390 
391     *frameName = BString(coreFrame->tree()->name()).release();
392     return S_OK;
393 }
394 
webView(IWebView ** view)395 HRESULT STDMETHODCALLTYPE WebFrame::webView(
396     /* [retval][out] */ IWebView** view)
397 {
398     *view = 0;
399     if (!d->webView)
400         return E_FAIL;
401     *view = d->webView;
402     (*view)->AddRef();
403     return S_OK;
404 }
405 
frameView(IWebFrameView **)406 HRESULT STDMETHODCALLTYPE WebFrame::frameView(
407     /* [retval][out] */ IWebFrameView** /*view*/)
408 {
409     ASSERT_NOT_REACHED();
410     return E_NOTIMPL;
411 }
412 
DOMDocument(IDOMDocument ** result)413 HRESULT STDMETHODCALLTYPE WebFrame::DOMDocument(
414     /* [retval][out] */ IDOMDocument** result)
415 {
416     if (!result) {
417         ASSERT_NOT_REACHED();
418         return E_POINTER;
419     }
420 
421     *result = 0;
422 
423     if (Frame* coreFrame = core(this))
424         if (Document* document = coreFrame->document())
425             *result = DOMDocument::createInstance(document);
426 
427     return *result ? S_OK : E_FAIL;
428 }
429 
frameElement(IDOMHTMLElement ** frameElement)430 HRESULT STDMETHODCALLTYPE WebFrame::frameElement(
431     /* [retval][out] */ IDOMHTMLElement** frameElement)
432 {
433     if (!frameElement)
434         return E_POINTER;
435 
436     *frameElement = 0;
437     Frame* coreFrame = core(this);
438     if (!coreFrame)
439         return E_FAIL;
440 
441     COMPtr<IDOMElement> domElement(AdoptCOM, DOMElement::createInstance(coreFrame->ownerElement()));
442     COMPtr<IDOMHTMLElement> htmlElement(Query, domElement);
443     if (!htmlElement)
444         return E_FAIL;
445     return htmlElement.copyRefTo(frameElement);
446 }
447 
currentForm(IDOMElement ** currentForm)448 HRESULT STDMETHODCALLTYPE WebFrame::currentForm(
449         /* [retval][out] */ IDOMElement **currentForm)
450 {
451     if (!currentForm) {
452         ASSERT_NOT_REACHED();
453         return E_POINTER;
454     }
455 
456     *currentForm = 0;
457 
458     if (Frame* coreFrame = core(this))
459         if (HTMLFormElement* formElement = coreFrame->currentForm())
460             *currentForm = DOMElement::createInstance(formElement);
461 
462     return *currentForm ? S_OK : E_FAIL;
463 }
464 
globalContext()465 JSGlobalContextRef STDMETHODCALLTYPE WebFrame::globalContext()
466 {
467     Frame* coreFrame = core(this);
468     if (!coreFrame)
469         return 0;
470 
471     return toGlobalRef(coreFrame->script()->globalObject()->globalExec());
472 }
473 
loadRequest(IWebURLRequest * request)474 HRESULT STDMETHODCALLTYPE WebFrame::loadRequest(
475     /* [in] */ IWebURLRequest* request)
476 {
477     COMPtr<WebMutableURLRequest> requestImpl;
478 
479     HRESULT hr = request->QueryInterface(&requestImpl);
480     if (FAILED(hr))
481         return hr;
482 
483     Frame* coreFrame = core(this);
484     if (!coreFrame)
485         return E_FAIL;
486 
487     coreFrame->loader()->load(requestImpl->resourceRequest(), false);
488     return S_OK;
489 }
490 
loadData(PassRefPtr<WebCore::SharedBuffer> data,BSTR mimeType,BSTR textEncodingName,BSTR baseURL,BSTR failingURL)491 void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL)
492 {
493     String mimeTypeString(mimeType, SysStringLen(mimeType));
494     if (!mimeType)
495         mimeTypeString = "text/html";
496 
497     String encodingString(textEncodingName, SysStringLen(textEncodingName));
498 
499     // FIXME: We should really be using MarshallingHelpers::BSTRToKURL here,
500     // but that would turn a null BSTR into a null KURL, and we crash inside of
501     // WebCore if we use a null KURL in constructing the ResourceRequest.
502     KURL baseKURL = KURL(KURL(), String(baseURL ? baseURL : L"", SysStringLen(baseURL)));
503 
504     KURL failingKURL = MarshallingHelpers::BSTRToKURL(failingURL);
505 
506     ResourceRequest request(baseKURL);
507     SubstituteData substituteData(data, mimeTypeString, encodingString, failingKURL);
508 
509     // This method is only called from IWebFrame methods, so don't ASSERT that the Frame pointer isn't null.
510     if (Frame* coreFrame = core(this))
511         coreFrame->loader()->load(request, substituteData, false);
512 }
513 
514 
loadData(IStream * data,BSTR mimeType,BSTR textEncodingName,BSTR url)515 HRESULT STDMETHODCALLTYPE WebFrame::loadData(
516     /* [in] */ IStream* data,
517     /* [in] */ BSTR mimeType,
518     /* [in] */ BSTR textEncodingName,
519     /* [in] */ BSTR url)
520 {
521     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create();
522 
523     STATSTG stat;
524     if (SUCCEEDED(data->Stat(&stat, STATFLAG_NONAME))) {
525         if (!stat.cbSize.HighPart && stat.cbSize.LowPart) {
526             Vector<char> dataBuffer(stat.cbSize.LowPart);
527             ULONG read;
528             // FIXME: this does a needless copy, would be better to read right into the SharedBuffer
529             // or adopt the Vector or something.
530             if (SUCCEEDED(data->Read(dataBuffer.data(), static_cast<ULONG>(dataBuffer.size()), &read)))
531                 sharedBuffer->append(dataBuffer.data(), static_cast<int>(dataBuffer.size()));
532         }
533     }
534 
535     loadData(sharedBuffer, mimeType, textEncodingName, url, 0);
536     return S_OK;
537 }
538 
loadHTMLString(BSTR string,BSTR baseURL,BSTR unreachableURL)539 void WebFrame::loadHTMLString(BSTR string, BSTR baseURL, BSTR unreachableURL)
540 {
541     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(string), sizeof(UChar) * SysStringLen(string));
542     BString utf16Encoding(TEXT("utf-16"), 6);
543     loadData(sharedBuffer.release(), 0, utf16Encoding, baseURL, unreachableURL);
544 }
545 
loadHTMLString(BSTR string,BSTR baseURL)546 HRESULT STDMETHODCALLTYPE WebFrame::loadHTMLString(
547     /* [in] */ BSTR string,
548     /* [in] */ BSTR baseURL)
549 {
550     loadHTMLString(string, baseURL, 0);
551     return S_OK;
552 }
553 
loadAlternateHTMLString(BSTR str,BSTR baseURL,BSTR unreachableURL)554 HRESULT STDMETHODCALLTYPE WebFrame::loadAlternateHTMLString(
555     /* [in] */ BSTR str,
556     /* [in] */ BSTR baseURL,
557     /* [in] */ BSTR unreachableURL)
558 {
559     loadHTMLString(str, baseURL, unreachableURL);
560     return S_OK;
561 }
562 
loadArchive(IWebArchive *)563 HRESULT STDMETHODCALLTYPE WebFrame::loadArchive(
564     /* [in] */ IWebArchive* /*archive*/)
565 {
566     ASSERT_NOT_REACHED();
567     return E_NOTIMPL;
568 }
569 
getWebDataSource(DocumentLoader * loader)570 static inline WebDataSource *getWebDataSource(DocumentLoader* loader)
571 {
572     return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
573 }
574 
dataSource(IWebDataSource ** source)575 HRESULT STDMETHODCALLTYPE WebFrame::dataSource(
576     /* [retval][out] */ IWebDataSource** source)
577 {
578     if (!source) {
579         ASSERT_NOT_REACHED();
580         return E_POINTER;
581     }
582 
583     *source = 0;
584 
585     Frame* coreFrame = core(this);
586     if (!coreFrame)
587         return E_FAIL;
588 
589     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->documentLoader());
590 
591     *source = webDataSource;
592 
593     if (webDataSource)
594         webDataSource->AddRef();
595 
596     return *source ? S_OK : E_FAIL;
597 }
598 
provisionalDataSource(IWebDataSource ** source)599 HRESULT STDMETHODCALLTYPE WebFrame::provisionalDataSource(
600     /* [retval][out] */ IWebDataSource** source)
601 {
602     if (!source) {
603         ASSERT_NOT_REACHED();
604         return E_POINTER;
605     }
606 
607     *source = 0;
608 
609     Frame* coreFrame = core(this);
610     if (!coreFrame)
611         return E_FAIL;
612 
613     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader()->provisionalDocumentLoader());
614 
615     *source = webDataSource;
616 
617     if (webDataSource)
618         webDataSource->AddRef();
619 
620     return *source ? S_OK : E_FAIL;
621 }
622 
url() const623 KURL WebFrame::url() const
624 {
625     Frame* coreFrame = core(this);
626     if (!coreFrame)
627         return KURL();
628 
629     return coreFrame->loader()->url();
630 }
631 
stopLoading(void)632 HRESULT STDMETHODCALLTYPE WebFrame::stopLoading( void)
633 {
634     if (Frame* coreFrame = core(this))
635         coreFrame->loader()->stopAllLoaders();
636     return S_OK;
637 }
638 
reload(void)639 HRESULT STDMETHODCALLTYPE WebFrame::reload( void)
640 {
641     Frame* coreFrame = core(this);
642     if (!coreFrame)
643         return E_FAIL;
644 
645     coreFrame->loader()->reload();
646     return S_OK;
647 }
648 
findFrameNamed(BSTR name,IWebFrame ** frame)649 HRESULT STDMETHODCALLTYPE WebFrame::findFrameNamed(
650     /* [in] */ BSTR name,
651     /* [retval][out] */ IWebFrame** frame)
652 {
653     if (!frame) {
654         ASSERT_NOT_REACHED();
655         return E_POINTER;
656     }
657 
658     *frame = 0;
659 
660     Frame* coreFrame = core(this);
661     if (!coreFrame)
662         return E_FAIL;
663 
664     Frame* foundFrame = coreFrame->tree()->find(AtomicString(name, SysStringLen(name)));
665     if (!foundFrame)
666         return S_OK;
667 
668     WebFrame* foundWebFrame = kit(foundFrame);
669     if (!foundWebFrame)
670         return E_FAIL;
671 
672     return foundWebFrame->QueryInterface(IID_IWebFrame, (void**)frame);
673 }
674 
parentFrame(IWebFrame ** frame)675 HRESULT STDMETHODCALLTYPE WebFrame::parentFrame(
676     /* [retval][out] */ IWebFrame** frame)
677 {
678     HRESULT hr = S_OK;
679     *frame = 0;
680     if (Frame* coreFrame = core(this))
681         if (WebFrame* webFrame = kit(coreFrame->tree()->parent()))
682             hr = webFrame->QueryInterface(IID_IWebFrame, (void**) frame);
683 
684     return hr;
685 }
686 
687 class EnumChildFrames : public IEnumVARIANT
688 {
689 public:
EnumChildFrames(Frame * f)690     EnumChildFrames(Frame* f) : m_refCount(1), m_frame(f), m_curChild(f ? f->tree()->firstChild() : 0) { }
691 
QueryInterface(REFIID riid,void ** ppvObject)692     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject)
693     {
694         *ppvObject = 0;
695         if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IEnumVARIANT))
696             *ppvObject = this;
697         else
698             return E_NOINTERFACE;
699 
700         AddRef();
701         return S_OK;
702     }
703 
AddRef(void)704     virtual ULONG STDMETHODCALLTYPE AddRef(void)
705     {
706         return ++m_refCount;
707     }
708 
Release(void)709     virtual ULONG STDMETHODCALLTYPE Release(void)
710     {
711         ULONG newRef = --m_refCount;
712         if (!newRef)
713             delete(this);
714         return newRef;
715     }
716 
Next(ULONG celt,VARIANT * rgVar,ULONG * pCeltFetched)717     virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
718     {
719         if (pCeltFetched)
720             *pCeltFetched = 0;
721         if (!rgVar)
722             return E_POINTER;
723         VariantInit(rgVar);
724         if (!celt || celt > 1)
725             return S_FALSE;
726         if (!m_frame || !m_curChild)
727             return S_FALSE;
728 
729         WebFrame* webFrame = kit(m_curChild);
730         IUnknown* unknown;
731         HRESULT hr = webFrame->QueryInterface(IID_IUnknown, (void**)&unknown);
732         if (FAILED(hr))
733             return hr;
734 
735         V_VT(rgVar) = VT_UNKNOWN;
736         V_UNKNOWN(rgVar) = unknown;
737 
738         m_curChild = m_curChild->tree()->nextSibling();
739         if (pCeltFetched)
740             *pCeltFetched = 1;
741         return S_OK;
742     }
743 
Skip(ULONG celt)744     virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
745     {
746         if (!m_frame)
747             return S_FALSE;
748         for (unsigned i = 0; i < celt && m_curChild; i++)
749             m_curChild = m_curChild->tree()->nextSibling();
750         return m_curChild ? S_OK : S_FALSE;
751     }
752 
Reset(void)753     virtual HRESULT STDMETHODCALLTYPE Reset(void)
754     {
755         if (!m_frame)
756             return S_FALSE;
757         m_curChild = m_frame->tree()->firstChild();
758         return S_OK;
759     }
760 
Clone(IEnumVARIANT **)761     virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT**)
762     {
763         return E_NOTIMPL;
764     }
765 
766 private:
767     ULONG m_refCount;
768     Frame* m_frame;
769     Frame* m_curChild;
770 };
771 
childFrames(IEnumVARIANT ** enumFrames)772 HRESULT STDMETHODCALLTYPE WebFrame::childFrames(
773     /* [retval][out] */ IEnumVARIANT **enumFrames)
774 {
775     if (!enumFrames)
776         return E_POINTER;
777 
778     *enumFrames = new EnumChildFrames(core(this));
779     return S_OK;
780 }
781 
782 // IWebFramePrivate ------------------------------------------------------
783 
renderTreeAsExternalRepresentation(BSTR * result)784 HRESULT STDMETHODCALLTYPE WebFrame::renderTreeAsExternalRepresentation(
785     /* [retval][out] */ BSTR *result)
786 {
787     if (!result)
788         return E_POINTER;
789 
790     Frame* coreFrame = core(this);
791     if (!coreFrame)
792         return E_FAIL;
793 
794     *result = BString(externalRepresentation(coreFrame->contentRenderer())).release();
795     return S_OK;
796 }
797 
scrollOffset(SIZE * offset)798 HRESULT STDMETHODCALLTYPE WebFrame::scrollOffset(
799         /* [retval][out] */ SIZE* offset)
800 {
801     if (!offset) {
802         ASSERT_NOT_REACHED();
803         return E_POINTER;
804     }
805 
806     Frame* coreFrame = core(this);
807     if (!coreFrame)
808         return E_FAIL;
809 
810     FrameView* view = coreFrame->view();
811     if (!view)
812         return E_FAIL;
813 
814     *offset = view->scrollOffset();
815     return S_OK;
816 }
817 
layout()818 HRESULT STDMETHODCALLTYPE WebFrame::layout()
819 {
820     Frame* coreFrame = core(this);
821     if (!coreFrame)
822         return E_FAIL;
823 
824     FrameView* view = coreFrame->view();
825     if (!view)
826         return E_FAIL;
827 
828     view->layout();
829     return S_OK;
830 }
831 
firstLayoutDone(BOOL * result)832 HRESULT STDMETHODCALLTYPE WebFrame::firstLayoutDone(
833     /* [retval][out] */ BOOL* result)
834 {
835     if (!result) {
836         ASSERT_NOT_REACHED();
837         return E_POINTER;
838     }
839 
840     *result = 0;
841 
842     Frame* coreFrame = core(this);
843     if (!coreFrame)
844         return E_FAIL;
845 
846     *result = coreFrame->loader()->firstLayoutDone();
847     return S_OK;
848 }
849 
loadType(WebFrameLoadType * type)850 HRESULT STDMETHODCALLTYPE WebFrame::loadType(
851     /* [retval][out] */ WebFrameLoadType* type)
852 {
853     if (!type) {
854         ASSERT_NOT_REACHED();
855         return E_POINTER;
856     }
857 
858     *type = (WebFrameLoadType)0;
859 
860     Frame* coreFrame = core(this);
861     if (!coreFrame)
862         return E_FAIL;
863 
864     *type = (WebFrameLoadType)coreFrame->loader()->loadType();
865     return S_OK;
866 }
867 
pendingFrameUnloadEventCount(UINT * result)868 HRESULT STDMETHODCALLTYPE WebFrame::pendingFrameUnloadEventCount(
869     /* [retval][out] */ UINT* result)
870 {
871     if (!result) {
872         ASSERT_NOT_REACHED();
873         return E_POINTER;
874     }
875 
876     *result = 0;
877 
878     Frame* coreFrame = core(this);
879     if (!coreFrame)
880         return E_FAIL;
881 
882     *result = coreFrame->domWindow()->pendingUnloadEventListeners();
883     return S_OK;
884 }
885 
fetchApplicationIcon(IWebIconFetcherDelegate * delegate,IWebIconFetcher ** result)886 HRESULT STDMETHODCALLTYPE WebFrame::fetchApplicationIcon(
887     /* [in] */ IWebIconFetcherDelegate *delegate,
888     /* [retval][out] */ IWebIconFetcher **result)
889 {
890     if (!result)
891         return E_POINTER;
892 
893     *result = 0;
894 
895     if (!delegate)
896         return E_FAIL;
897 
898     Frame* coreFrame = core(this);
899     if (!coreFrame)
900         return E_FAIL;
901 
902     *result = WebIconFetcher::fetchApplicationIcon(coreFrame, delegate);
903     if (!*result)
904         return E_FAIL;
905 
906     return S_OK;
907 }
908 
909 // IWebDocumentText -----------------------------------------------------------
910 
supportsTextEncoding(BOOL * result)911 HRESULT STDMETHODCALLTYPE WebFrame::supportsTextEncoding(
912     /* [retval][out] */ BOOL* result)
913 {
914     *result = FALSE;
915     return E_NOTIMPL;
916 }
917 
selectedString(BSTR * result)918 HRESULT STDMETHODCALLTYPE WebFrame::selectedString(
919     /* [retval][out] */ BSTR* result)
920 {
921     *result = 0;
922 
923     Frame* coreFrame = core(this);
924     if (!coreFrame)
925         return E_FAIL;
926 
927     String text = coreFrame->displayStringModifiedByEncoding(coreFrame->selectedText());
928 
929     *result = BString(text).release();
930     return S_OK;
931 }
932 
selectAll()933 HRESULT STDMETHODCALLTYPE WebFrame::selectAll()
934 {
935     return E_NOTIMPL;
936 }
937 
deselectAll()938 HRESULT STDMETHODCALLTYPE WebFrame::deselectAll()
939 {
940     return E_NOTIMPL;
941 }
942 
943 // WebFrame ---------------------------------------------------------------
944 
init(IWebView * webView,Page * page,HTMLFrameOwnerElement * ownerElement)945 PassRefPtr<Frame> WebFrame::init(IWebView* webView, Page* page, HTMLFrameOwnerElement* ownerElement)
946 {
947     webView->QueryInterface(&d->webView);
948     d->webView->Release(); // don't hold the extra ref
949 
950     HWND viewWindow;
951     d->webView->viewWindow((OLE_HANDLE*)&viewWindow);
952 
953     this->AddRef(); // We release this ref in frameLoaderDestroyed()
954     RefPtr<Frame> frame = Frame::create(page, ownerElement, this);
955     d->frame = frame.get();
956     return frame.release();
957 }
958 
impl()959 Frame* WebFrame::impl()
960 {
961     return d->frame;
962 }
963 
invalidate()964 void WebFrame::invalidate()
965 {
966     Frame* coreFrame = core(this);
967     ASSERT(coreFrame);
968 
969     if (Document* document = coreFrame->document())
970         document->recalcStyle(Node::Force);
971 }
972 
setTextSizeMultiplier(float multiplier)973 void WebFrame::setTextSizeMultiplier(float multiplier)
974 {
975     Frame* coreFrame = core(this);
976     ASSERT(coreFrame);
977     coreFrame->setZoomFactor(multiplier, true);
978 }
979 
inViewSourceMode(BOOL * flag)980 HRESULT WebFrame::inViewSourceMode(BOOL* flag)
981 {
982     if (!flag) {
983         ASSERT_NOT_REACHED();
984         return E_POINTER;
985     }
986 
987     *flag = FALSE;
988 
989     Frame* coreFrame = core(this);
990     if (!coreFrame)
991         return E_FAIL;
992 
993     *flag = coreFrame->inViewSourceMode() ? TRUE : FALSE;
994     return S_OK;
995 }
996 
setInViewSourceMode(BOOL flag)997 HRESULT WebFrame::setInViewSourceMode(BOOL flag)
998 {
999     Frame* coreFrame = core(this);
1000     if (!coreFrame)
1001         return E_FAIL;
1002 
1003     coreFrame->setInViewSourceMode(!!flag);
1004     return S_OK;
1005 }
1006 
elementWithName(BSTR name,IDOMElement * form,IDOMElement ** element)1007 HRESULT WebFrame::elementWithName(BSTR name, IDOMElement* form, IDOMElement** element)
1008 {
1009     if (!form)
1010         return E_INVALIDARG;
1011 
1012     HTMLFormElement *formElement = formElementFromDOMElement(form);
1013     if (formElement) {
1014         Vector<HTMLFormControlElement*>& elements = formElement->formElements;
1015         AtomicString targetName((UChar*)name, SysStringLen(name));
1016         for (unsigned int i = 0; i < elements.size(); i++) {
1017             HTMLFormControlElement *elt = elements[i];
1018             // Skip option elements, other duds
1019             if (elt->name() == targetName) {
1020                 *element = DOMElement::createInstance(elt);
1021                 return S_OK;
1022             }
1023         }
1024     }
1025     return E_FAIL;
1026 }
1027 
formForElement(IDOMElement * element,IDOMElement ** form)1028 HRESULT WebFrame::formForElement(IDOMElement* element, IDOMElement** form)
1029 {
1030     if (!element)
1031         return E_INVALIDARG;
1032 
1033     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1034     if (!inputElement)
1035         return E_FAIL;
1036 
1037     HTMLFormElement *formElement = inputElement->form();
1038     if (!formElement)
1039         return E_FAIL;
1040 
1041     *form = DOMElement::createInstance(formElement);
1042     return S_OK;
1043 }
1044 
elementDoesAutoComplete(IDOMElement * element,BOOL * result)1045 HRESULT WebFrame::elementDoesAutoComplete(IDOMElement *element, BOOL *result)
1046 {
1047     *result = false;
1048     if (!element)
1049         return E_INVALIDARG;
1050 
1051     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1052     if (!inputElement)
1053         *result = false;
1054     else
1055         *result = (inputElement->inputType() == HTMLInputElement::TEXT && inputElement->autoComplete());
1056 
1057     return S_OK;
1058 }
1059 
pauseAnimation(BSTR animationName,IDOMNode * node,double secondsFromNow,BOOL * animationWasRunning)1060 HRESULT WebFrame::pauseAnimation(BSTR animationName, IDOMNode* node, double secondsFromNow, BOOL* animationWasRunning)
1061 {
1062     if (!node || !animationWasRunning)
1063         return E_POINTER;
1064 
1065     *animationWasRunning = FALSE;
1066 
1067     Frame* frame = core(this);
1068     if (!frame)
1069         return E_FAIL;
1070 
1071     AnimationController* controller = frame->animation();
1072     if (!controller)
1073         return E_FAIL;
1074 
1075     COMPtr<DOMNode> domNode(Query, node);
1076     if (!domNode)
1077         return E_FAIL;
1078 
1079     *animationWasRunning = controller->pauseAnimationAtTime(domNode->node()->renderer(), String(animationName, SysStringLen(animationName)), secondsFromNow);
1080     return S_OK;
1081 }
1082 
pauseTransition(BSTR propertyName,IDOMNode * node,double secondsFromNow,BOOL * transitionWasRunning)1083 HRESULT WebFrame::pauseTransition(BSTR propertyName, IDOMNode* node, double secondsFromNow, BOOL* transitionWasRunning)
1084 {
1085     if (!node || !transitionWasRunning)
1086         return E_POINTER;
1087 
1088     *transitionWasRunning = FALSE;
1089 
1090     Frame* frame = core(this);
1091     if (!frame)
1092         return E_FAIL;
1093 
1094     AnimationController* controller = frame->animation();
1095     if (!controller)
1096         return E_FAIL;
1097 
1098     COMPtr<DOMNode> domNode(Query, node);
1099     if (!domNode)
1100         return E_FAIL;
1101 
1102     *transitionWasRunning = controller->pauseTransitionAtTime(domNode->node()->renderer(), String(propertyName, SysStringLen(propertyName)), secondsFromNow);
1103     return S_OK;
1104 }
1105 
numberOfActiveAnimations(UINT * number)1106 HRESULT WebFrame::numberOfActiveAnimations(UINT* number)
1107 {
1108     if (!number)
1109         return E_POINTER;
1110 
1111     *number = 0;
1112 
1113     Frame* frame = core(this);
1114     if (!frame)
1115         return E_FAIL;
1116 
1117     AnimationController* controller = frame->animation();
1118     if (!controller)
1119         return E_FAIL;
1120 
1121     *number = controller->numberOfActiveAnimations();
1122     return S_OK;
1123 }
1124 
isDisplayingStandaloneImage(BOOL * result)1125 HRESULT WebFrame::isDisplayingStandaloneImage(BOOL* result)
1126 {
1127     if (!result)
1128         return E_POINTER;
1129 
1130     *result = FALSE;
1131 
1132     Frame* frame = core(this);
1133     if (!frame)
1134         return E_FAIL;
1135 
1136     Document* document = frame->document();
1137     *result = document && document->isImageDocument();
1138     return S_OK;
1139 }
1140 
controlsInForm(IDOMElement * form,IDOMElement ** controls,int * cControls)1141 HRESULT WebFrame::controlsInForm(IDOMElement* form, IDOMElement** controls, int* cControls)
1142 {
1143     if (!form)
1144         return E_INVALIDARG;
1145 
1146     HTMLFormElement *formElement = formElementFromDOMElement(form);
1147     if (!formElement)
1148         return E_FAIL;
1149 
1150     int inCount = *cControls;
1151     int count = (int) formElement->formElements.size();
1152     *cControls = count;
1153     if (!controls)
1154         return S_OK;
1155     if (inCount < count)
1156         return E_FAIL;
1157 
1158     *cControls = 0;
1159     Vector<HTMLFormControlElement*>& elements = formElement->formElements;
1160     for (int i = 0; i < count; i++) {
1161         if (elements.at(i)->isEnumeratable()) { // Skip option elements, other duds
1162             controls[*cControls] = DOMElement::createInstance(elements.at(i));
1163             (*cControls)++;
1164         }
1165     }
1166     return S_OK;
1167 }
1168 
elementIsPassword(IDOMElement * element,bool * result)1169 HRESULT WebFrame::elementIsPassword(IDOMElement *element, bool *result)
1170 {
1171     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1172     *result = inputElement != 0
1173         && inputElement->inputType() == HTMLInputElement::PASSWORD;
1174     return S_OK;
1175 }
1176 
searchForLabelsBeforeElement(const BSTR * labels,int cLabels,IDOMElement * beforeElement,BSTR * result)1177 HRESULT WebFrame::searchForLabelsBeforeElement(const BSTR* labels, int cLabels, IDOMElement* beforeElement, BSTR* result)
1178 {
1179     if (!result) {
1180         ASSERT_NOT_REACHED();
1181         return E_POINTER;
1182     }
1183 
1184     *result = 0;
1185 
1186     if (!cLabels)
1187         return S_OK;
1188     if (cLabels < 1)
1189         return E_INVALIDARG;
1190 
1191     Frame* coreFrame = core(this);
1192     if (!coreFrame)
1193         return E_FAIL;
1194 
1195     Vector<String> labelStrings(cLabels);
1196     for (int i=0; i<cLabels; i++)
1197         labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
1198     Element *coreElement = elementFromDOMElement(beforeElement);
1199     if (!coreElement)
1200         return E_FAIL;
1201 
1202     String label = coreFrame->searchForLabelsBeforeElement(labelStrings, coreElement);
1203 
1204     *result = SysAllocStringLen(label.characters(), label.length());
1205     if (label.length() && !*result)
1206         return E_OUTOFMEMORY;
1207     return S_OK;
1208 }
1209 
matchLabelsAgainstElement(const BSTR * labels,int cLabels,IDOMElement * againstElement,BSTR * result)1210 HRESULT WebFrame::matchLabelsAgainstElement(const BSTR* labels, int cLabels, IDOMElement* againstElement, BSTR* result)
1211 {
1212     if (!result) {
1213         ASSERT_NOT_REACHED();
1214         return E_POINTER;
1215     }
1216 
1217     *result = 0;
1218 
1219     if (!cLabels)
1220         return S_OK;
1221     if (cLabels < 1)
1222         return E_INVALIDARG;
1223 
1224     Frame* coreFrame = core(this);
1225     if (!coreFrame)
1226         return E_FAIL;
1227 
1228     Vector<String> labelStrings(cLabels);
1229     for (int i=0; i<cLabels; i++)
1230         labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
1231     Element *coreElement = elementFromDOMElement(againstElement);
1232     if (!coreElement)
1233         return E_FAIL;
1234 
1235     String label = coreFrame->matchLabelsAgainstElement(labelStrings, coreElement);
1236 
1237     *result = SysAllocStringLen(label.characters(), label.length());
1238     if (label.length() && !*result)
1239         return E_OUTOFMEMORY;
1240     return S_OK;
1241 }
1242 
canProvideDocumentSource(bool * result)1243 HRESULT WebFrame::canProvideDocumentSource(bool* result)
1244 {
1245     HRESULT hr = S_OK;
1246     *result = false;
1247 
1248     COMPtr<IWebDataSource> dataSource;
1249     hr = WebFrame::dataSource(&dataSource);
1250     if (FAILED(hr))
1251         return hr;
1252 
1253     COMPtr<IWebURLResponse> urlResponse;
1254     hr = dataSource->response(&urlResponse);
1255     if (SUCCEEDED(hr) && urlResponse) {
1256         BSTR mimeTypeBStr;
1257         if (SUCCEEDED(urlResponse->MIMEType(&mimeTypeBStr))) {
1258             String mimeType(mimeTypeBStr, SysStringLen(mimeTypeBStr));
1259             *result = mimeType == "text/html" || WebCore::DOMImplementation::isXMLMIMEType(mimeType);
1260             SysFreeString(mimeTypeBStr);
1261         }
1262     }
1263     return hr;
1264 }
1265 
frameLoaderDestroyed()1266 void WebFrame::frameLoaderDestroyed()
1267 {
1268     // The FrameLoader going away is equivalent to the Frame going away,
1269     // so we now need to clear our frame pointer.
1270     d->frame = 0;
1271 
1272     this->Release();
1273 }
1274 
makeRepresentation(DocumentLoader *)1275 void WebFrame::makeRepresentation(DocumentLoader*)
1276 {
1277     notImplemented();
1278 }
1279 
forceLayoutForNonHTML()1280 void WebFrame::forceLayoutForNonHTML()
1281 {
1282     notImplemented();
1283 }
1284 
setCopiesOnScroll()1285 void WebFrame::setCopiesOnScroll()
1286 {
1287     notImplemented();
1288 }
1289 
detachedFromParent2()1290 void WebFrame::detachedFromParent2()
1291 {
1292     notImplemented();
1293 }
1294 
detachedFromParent3()1295 void WebFrame::detachedFromParent3()
1296 {
1297     notImplemented();
1298 }
1299 
cancelPolicyCheck()1300 void WebFrame::cancelPolicyCheck()
1301 {
1302     if (d->m_policyListener) {
1303         d->m_policyListener->invalidate();
1304         d->m_policyListener = 0;
1305     }
1306 
1307     d->m_policyFunction = 0;
1308 }
1309 
dispatchWillSubmitForm(FramePolicyFunction function,PassRefPtr<FormState> formState)1310 void WebFrame::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> formState)
1311 {
1312     Frame* coreFrame = core(this);
1313     ASSERT(coreFrame);
1314 
1315     COMPtr<IWebFormDelegate> formDelegate;
1316 
1317     if (FAILED(d->webView->formDelegate(&formDelegate))) {
1318         (coreFrame->loader()->*function)(PolicyUse);
1319         return;
1320     }
1321 
1322     COMPtr<IDOMElement> formElement(AdoptCOM, DOMElement::createInstance(formState->form()));
1323 
1324     HashMap<String, String> formValuesMap;
1325     const StringPairVector& textFieldValues = formState->textFieldValues();
1326     size_t size = textFieldValues.size();
1327     for (size_t i = 0; i < size; ++i)
1328         formValuesMap.add(textFieldValues[i].first, textFieldValues[i].second);
1329 
1330     COMPtr<IPropertyBag> formValuesPropertyBag(AdoptCOM, COMPropertyBag<String>::createInstance(formValuesMap));
1331 
1332     COMPtr<WebFrame> sourceFrame(kit(formState->sourceFrame()));
1333     if (SUCCEEDED(formDelegate->willSubmitForm(this, sourceFrame.get(), formElement.get(), formValuesPropertyBag.get(), setUpPolicyListener(function).get())))
1334         return;
1335 
1336     // FIXME: Add a sane default implementation
1337     (coreFrame->loader()->*function)(PolicyUse);
1338 }
1339 
revertToProvisionalState(DocumentLoader *)1340 void WebFrame::revertToProvisionalState(DocumentLoader*)
1341 {
1342     notImplemented();
1343 }
1344 
setMainFrameDocumentReady(bool)1345 void WebFrame::setMainFrameDocumentReady(bool)
1346 {
1347     notImplemented();
1348 }
1349 
willChangeTitle(DocumentLoader *)1350 void WebFrame::willChangeTitle(DocumentLoader*)
1351 {
1352     notImplemented();
1353 }
1354 
didChangeTitle(DocumentLoader *)1355 void WebFrame::didChangeTitle(DocumentLoader*)
1356 {
1357     notImplemented();
1358 }
1359 
canHandleRequest(const ResourceRequest & request) const1360 bool WebFrame::canHandleRequest(const ResourceRequest& request) const
1361 {
1362     return WebView::canHandleRequest(request);
1363 }
1364 
canShowMIMEType(const String &) const1365 bool WebFrame::canShowMIMEType(const String& /*MIMEType*/) const
1366 {
1367     notImplemented();
1368     return true;
1369 }
1370 
representationExistsForURLScheme(const String &) const1371 bool WebFrame::representationExistsForURLScheme(const String& /*URLScheme*/) const
1372 {
1373     notImplemented();
1374     return false;
1375 }
1376 
generatedMIMETypeForURLScheme(const String &) const1377 String WebFrame::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
1378 {
1379     notImplemented();
1380     ASSERT_NOT_REACHED();
1381     return String();
1382 }
1383 
frameLoadCompleted()1384 void WebFrame::frameLoadCompleted()
1385 {
1386 }
1387 
restoreViewState()1388 void WebFrame::restoreViewState()
1389 {
1390 }
1391 
provisionalLoadStarted()1392 void WebFrame::provisionalLoadStarted()
1393 {
1394     notImplemented();
1395 }
1396 
shouldTreatURLAsSameAsCurrent(const KURL &) const1397 bool WebFrame::shouldTreatURLAsSameAsCurrent(const KURL&) const
1398 {
1399     notImplemented();
1400     return false;
1401 }
1402 
addHistoryItemForFragmentScroll()1403 void WebFrame::addHistoryItemForFragmentScroll()
1404 {
1405     notImplemented();
1406 }
1407 
didFinishLoad()1408 void WebFrame::didFinishLoad()
1409 {
1410     notImplemented();
1411 }
1412 
prepareForDataSourceReplacement()1413 void WebFrame::prepareForDataSourceReplacement()
1414 {
1415     notImplemented();
1416 }
1417 
userAgent(const KURL & url)1418 String WebFrame::userAgent(const KURL& url)
1419 {
1420     return d->webView->userAgentForKURL(url);
1421 }
1422 
saveViewStateToItem(HistoryItem *)1423 void WebFrame::saveViewStateToItem(HistoryItem*)
1424 {
1425 }
1426 
cancelledError(const ResourceRequest & request)1427 ResourceError WebFrame::cancelledError(const ResourceRequest& request)
1428 {
1429     // FIXME: Need ChickenCat to include CFNetwork/CFURLError.h to get these values
1430     // Alternatively, we could create our own error domain/codes.
1431     return ResourceError(String(WebURLErrorDomain), -999, request.url().string(), String());
1432 }
1433 
blockedError(const ResourceRequest & request)1434 ResourceError WebFrame::blockedError(const ResourceRequest& request)
1435 {
1436     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1437     return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotUseRestrictedPort, request.url().string(), String());
1438 }
1439 
cannotShowURLError(const ResourceRequest & request)1440 ResourceError WebFrame::cannotShowURLError(const ResourceRequest& request)
1441 {
1442     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1443     return ResourceError(String(WebKitErrorDomain), WebKitErrorCannotShowURL, request.url().string(), String());
1444 }
1445 
interruptForPolicyChangeError(const ResourceRequest & request)1446 ResourceError WebFrame::interruptForPolicyChangeError(const ResourceRequest& request)
1447 {
1448     // FIXME: Need to implement the String descriptions for errors in the WebKitErrorDomain and have them localized
1449     return ResourceError(String(WebKitErrorDomain), WebKitErrorFrameLoadInterruptedByPolicyChange, request.url().string(), String());
1450 }
1451 
cannotShowMIMETypeError(const ResourceResponse &)1452 ResourceError WebFrame::cannotShowMIMETypeError(const ResourceResponse&)
1453 {
1454     notImplemented();
1455     return ResourceError();
1456 }
1457 
fileDoesNotExistError(const ResourceResponse &)1458 ResourceError WebFrame::fileDoesNotExistError(const ResourceResponse&)
1459 {
1460     notImplemented();
1461     return ResourceError();
1462 }
1463 
pluginWillHandleLoadError(const ResourceResponse & response)1464 ResourceError WebFrame::pluginWillHandleLoadError(const ResourceResponse& response)
1465 {
1466     return ResourceError(String(WebKitErrorDomain), WebKitErrorPlugInWillHandleLoad, response.url().string(), String());
1467 }
1468 
shouldFallBack(const ResourceError & error)1469 bool WebFrame::shouldFallBack(const ResourceError& error)
1470 {
1471     return error.errorCode() != WebURLErrorCancelled;
1472 }
1473 
setUpPolicyListener(WebCore::FramePolicyFunction function)1474 COMPtr<WebFramePolicyListener> WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction function)
1475 {
1476     // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
1477 
1478     if (d->m_policyListener)
1479         d->m_policyListener->invalidate();
1480 
1481     Frame* coreFrame = core(this);
1482     ASSERT(coreFrame);
1483 
1484     d->m_policyListener.adoptRef(WebFramePolicyListener::createInstance(coreFrame));
1485     d->m_policyFunction = function;
1486 
1487     return d->m_policyListener;
1488 }
1489 
receivedPolicyDecision(PolicyAction action)1490 void WebFrame::receivedPolicyDecision(PolicyAction action)
1491 {
1492     ASSERT(d->m_policyListener);
1493     ASSERT(d->m_policyFunction);
1494 
1495     FramePolicyFunction function = d->m_policyFunction;
1496 
1497     d->m_policyListener = 0;
1498     d->m_policyFunction = 0;
1499 
1500     Frame* coreFrame = core(this);
1501     ASSERT(coreFrame);
1502 
1503     (coreFrame->loader()->*function)(action);
1504 }
1505 
dispatchDecidePolicyForMIMEType(FramePolicyFunction function,const String & mimeType,const ResourceRequest & request)1506 void WebFrame::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const String& mimeType, const ResourceRequest& request)
1507 {
1508     Frame* coreFrame = core(this);
1509     ASSERT(coreFrame);
1510 
1511     COMPtr<IWebPolicyDelegate> policyDelegate;
1512     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1513         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1514 
1515     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
1516 
1517     if (SUCCEEDED(policyDelegate->decidePolicyForMIMEType(d->webView, BString(mimeType), urlRequest.get(), this, setUpPolicyListener(function).get())))
1518         return;
1519 
1520     (coreFrame->loader()->*function)(PolicyUse);
1521 }
1522 
dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function,const NavigationAction & action,const ResourceRequest & request,PassRefPtr<FormState> formState,const String & frameName)1523 void WebFrame::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
1524 {
1525     Frame* coreFrame = core(this);
1526     ASSERT(coreFrame);
1527 
1528     COMPtr<IWebPolicyDelegate> policyDelegate;
1529     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1530         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1531 
1532     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
1533     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, formState ? formState->form() : 0, coreFrame));
1534 
1535     if (SUCCEEDED(policyDelegate->decidePolicyForNewWindowAction(d->webView, actionInformation.get(), urlRequest.get(), BString(frameName), setUpPolicyListener(function).get())))
1536         return;
1537 
1538     (coreFrame->loader()->*function)(PolicyUse);
1539 }
1540 
dispatchDecidePolicyForNavigationAction(FramePolicyFunction function,const NavigationAction & action,const ResourceRequest & request,PassRefPtr<FormState> formState)1541 void WebFrame::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& action, const ResourceRequest& request, PassRefPtr<FormState> formState)
1542 {
1543     Frame* coreFrame = core(this);
1544     ASSERT(coreFrame);
1545 
1546     COMPtr<IWebPolicyDelegate> policyDelegate;
1547     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1548         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1549 
1550     COMPtr<IWebURLRequest> urlRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
1551     COMPtr<WebActionPropertyBag> actionInformation(AdoptCOM, WebActionPropertyBag::createInstance(action, formState ? formState->form() : 0, coreFrame));
1552 
1553     if (SUCCEEDED(policyDelegate->decidePolicyForNavigationAction(d->webView, actionInformation.get(), urlRequest.get(), this, setUpPolicyListener(function).get())))
1554         return;
1555 
1556     (coreFrame->loader()->*function)(PolicyUse);
1557 }
1558 
dispatchUnableToImplementPolicy(const ResourceError & error)1559 void WebFrame::dispatchUnableToImplementPolicy(const ResourceError& error)
1560 {
1561     COMPtr<IWebPolicyDelegate> policyDelegate;
1562     if (FAILED(d->webView->policyDelegate(&policyDelegate)))
1563         policyDelegate = DefaultPolicyDelegate::sharedInstance();
1564 
1565     COMPtr<IWebError> webError(AdoptCOM, WebError::createInstance(error));
1566     policyDelegate->unableToImplementPolicyWithError(d->webView, webError.get(), this);
1567 }
1568 
download(ResourceHandle * handle,const ResourceRequest & request,const ResourceRequest &,const ResourceResponse & response)1569 void WebFrame::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest&, const ResourceResponse& response)
1570 {
1571     COMPtr<IWebDownloadDelegate> downloadDelegate;
1572     COMPtr<IWebView> webView;
1573     if (SUCCEEDED(this->webView(&webView))) {
1574         if (FAILED(webView->downloadDelegate(&downloadDelegate))) {
1575             // If the WebView doesn't successfully provide a download delegate we'll pass a null one
1576             // into the WebDownload - which may or may not decide to use a DefaultDownloadDelegate
1577             LOG_ERROR("Failed to get downloadDelegate from WebView");
1578             downloadDelegate = 0;
1579         }
1580     }
1581 
1582     // Its the delegate's job to ref the WebDownload to keep it alive - otherwise it will be destroyed
1583     // when this method returns
1584     COMPtr<WebDownload> download;
1585     download.adoptRef(WebDownload::createInstance(handle, request, response, downloadDelegate.get()));
1586 }
1587 
dispatchDidLoadResourceFromMemoryCache(DocumentLoader *,const ResourceRequest &,const ResourceResponse &,int)1588 bool WebFrame::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
1589 {
1590     notImplemented();
1591     return false;
1592 }
1593 
dispatchDidFailProvisionalLoad(const ResourceError & error)1594 void WebFrame::dispatchDidFailProvisionalLoad(const ResourceError& error)
1595 {
1596     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1597     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
1598         COMPtr<IWebError> webError;
1599         webError.adoptRef(WebError::createInstance(error));
1600         frameLoadDelegate->didFailProvisionalLoadWithError(d->webView, webError.get(), this);
1601     }
1602 }
1603 
dispatchDidFailLoad(const ResourceError & error)1604 void WebFrame::dispatchDidFailLoad(const ResourceError& error)
1605 {
1606     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1607     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
1608         COMPtr<IWebError> webError;
1609         webError.adoptRef(WebError::createInstance(error));
1610         frameLoadDelegate->didFailLoadWithError(d->webView, webError.get(), this);
1611     }
1612 }
1613 
startDownload(const ResourceRequest & request)1614 void WebFrame::startDownload(const ResourceRequest& request)
1615 {
1616     d->webView->downloadURL(request.url());
1617 }
1618 
createJavaAppletWidget(const IntSize & pluginSize,HTMLAppletElement * element,const KURL &,const Vector<String> & paramNames,const Vector<String> & paramValues)1619 PassRefPtr<Widget> WebFrame::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* element, const KURL& /*baseURL*/, const Vector<String>& paramNames, const Vector<String>& paramValues)
1620 {
1621     RefPtr<PluginView> pluginView = PluginView::create(core(this), pluginSize, element, KURL(), paramNames, paramValues, "application/x-java-applet", false);
1622 
1623     // Check if the plugin can be loaded successfully
1624     if (pluginView->plugin() && pluginView->plugin()->load())
1625         return pluginView;
1626 
1627     COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
1628     if (FAILED(d->webView->resourceLoadDelegate(&resourceLoadDelegate)))
1629         return pluginView;
1630 
1631     COMPtr<CFDictionaryPropertyBag> userInfoBag(AdoptCOM, CFDictionaryPropertyBag::createInstance());
1632 
1633     ResourceError resourceError(String(WebKitErrorDomain), WebKitErrorJavaUnavailable, String(), String());
1634     COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
1635 
1636     resourceLoadDelegate->plugInFailedWithError(d->webView, error.get(), getWebDataSource(d->frame->loader()->documentLoader()));
1637 
1638     return pluginView;
1639 }
1640 
objectContentType(const KURL & url,const String & mimeTypeIn)1641 ObjectContentType WebFrame::objectContentType(const KURL& url, const String& mimeTypeIn)
1642 {
1643     String mimeType = mimeTypeIn;
1644     if (mimeType.isEmpty())
1645         mimeType = MIMETypeRegistry::getMIMETypeForExtension(url.path().substring(url.path().reverseFind('.') + 1));
1646 
1647     if (mimeType.isEmpty())
1648         return ObjectContentFrame; // Go ahead and hope that we can display the content.
1649 
1650     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1651         return WebCore::ObjectContentImage;
1652 
1653     if (PluginDatabase::installedPlugins()->isMIMETypeRegistered(mimeType))
1654         return WebCore::ObjectContentNetscapePlugin;
1655 
1656     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1657         return WebCore::ObjectContentFrame;
1658 
1659     return WebCore::ObjectContentNone;
1660 }
1661 
overrideMediaType() const1662 String WebFrame::overrideMediaType() const
1663 {
1664     notImplemented();
1665     return String();
1666 }
1667 
windowObjectCleared()1668 void WebFrame::windowObjectCleared()
1669 {
1670     Frame* coreFrame = core(this);
1671     ASSERT(coreFrame);
1672 
1673     Settings* settings = coreFrame->settings();
1674     if (!settings || !settings->isJavaScriptEnabled())
1675         return;
1676 
1677     COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
1678     if (SUCCEEDED(d->webView->frameLoadDelegate(&frameLoadDelegate))) {
1679         JSContextRef context = toRef(coreFrame->script()->globalObject()->globalExec());
1680         JSObjectRef windowObject = toRef(coreFrame->script()->globalObject());
1681         ASSERT(windowObject);
1682 
1683         if (FAILED(frameLoadDelegate->didClearWindowObject(d->webView, context, windowObject, this)))
1684             frameLoadDelegate->windowScriptObjectAvailable(d->webView, context, windowObject);
1685     }
1686 }
1687 
documentElementAvailable()1688 void WebFrame::documentElementAvailable()
1689 {
1690 }
1691 
didPerformFirstNavigation() const1692 void WebFrame::didPerformFirstNavigation() const
1693 {
1694     COMPtr<IWebPreferences> preferences;
1695     if (FAILED(d->webView->preferences(&preferences)))
1696         return;
1697 
1698     COMPtr<IWebPreferencesPrivate> preferencesPrivate(Query, preferences);
1699     if (!preferencesPrivate)
1700         return;
1701     BOOL automaticallyDetectsCacheModel;
1702     if (FAILED(preferencesPrivate->automaticallyDetectsCacheModel(&automaticallyDetectsCacheModel)))
1703         return;
1704 
1705     WebCacheModel cacheModel;
1706     if (FAILED(preferences->cacheModel(&cacheModel)))
1707         return;
1708 
1709     if (automaticallyDetectsCacheModel && cacheModel < WebCacheModelDocumentBrowser)
1710         preferences->setCacheModel(WebCacheModelDocumentBrowser);
1711 }
1712 
registerForIconNotification(bool listen)1713 void WebFrame::registerForIconNotification(bool listen)
1714 {
1715     d->webView->registerForIconNotification(listen);
1716 }
1717 
printerRect(HDC printDC)1718 static IntRect printerRect(HDC printDC)
1719 {
1720     return IntRect(0, 0,
1721                    GetDeviceCaps(printDC, PHYSICALWIDTH)  - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETX),
1722                    GetDeviceCaps(printDC, PHYSICALHEIGHT) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETY));
1723 }
1724 
setPrinting(bool printing,float minPageWidth,float maxPageWidth,bool adjustViewSize)1725 void WebFrame::setPrinting(bool printing, float minPageWidth, float maxPageWidth, bool adjustViewSize)
1726 {
1727     Frame* coreFrame = core(this);
1728     ASSERT(coreFrame);
1729     coreFrame->setPrinting(printing, minPageWidth, maxPageWidth, adjustViewSize);
1730 }
1731 
setInPrintingMode(BOOL value,HDC printDC)1732 HRESULT STDMETHODCALLTYPE WebFrame::setInPrintingMode(
1733     /* [in] */ BOOL value,
1734     /* [in] */ HDC printDC)
1735 {
1736     if (m_inPrintingMode == !!value)
1737         return S_OK;
1738 
1739     Frame* coreFrame = core(this);
1740     if (!coreFrame || !coreFrame->document())
1741         return E_FAIL;
1742 
1743     m_inPrintingMode = !!value;
1744 
1745     // If we are a frameset just print with the layout we have onscreen, otherwise relayout
1746     // according to the paper size
1747     float minLayoutWidth = 0.0f;
1748     float maxLayoutWidth = 0.0f;
1749     if (m_inPrintingMode && !coreFrame->document()->isFrameSet()) {
1750         if (!printDC) {
1751             ASSERT_NOT_REACHED();
1752             return E_POINTER;
1753         }
1754 
1755         const int desiredHorizontalPixelsPerInch = 72;
1756         int paperHorizontalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSX);
1757         int paperWidth = printerRect(printDC).width() * desiredHorizontalPixelsPerInch / paperHorizontalPixelsPerInch;
1758         minLayoutWidth = paperWidth * PrintingMinimumShrinkFactor;
1759         maxLayoutWidth = paperWidth * PrintingMaximumShrinkFactor;
1760     }
1761 
1762     setPrinting(m_inPrintingMode, minLayoutWidth, maxLayoutWidth, true);
1763 
1764     if (!m_inPrintingMode)
1765         m_pageRects.clear();
1766 
1767     return S_OK;
1768 }
1769 
headerAndFooterHeights(float * headerHeight,float * footerHeight)1770 void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight)
1771 {
1772     if (headerHeight)
1773         *headerHeight = 0;
1774     if (footerHeight)
1775         *footerHeight = 0;
1776     float height = 0;
1777     COMPtr<IWebUIDelegate> ui;
1778     if (FAILED(d->webView->uiDelegate(&ui)))
1779         return;
1780     if (headerHeight && SUCCEEDED(ui->webViewHeaderHeight(d->webView, &height)))
1781         *headerHeight = height;
1782     if (footerHeight && SUCCEEDED(ui->webViewFooterHeight(d->webView, &height)))
1783         *footerHeight = height;
1784 }
1785 
printerMarginRect(HDC printDC)1786 IntRect WebFrame::printerMarginRect(HDC printDC)
1787 {
1788     IntRect emptyRect(0, 0, 0, 0);
1789 
1790     COMPtr<IWebUIDelegate> ui;
1791     if (FAILED(d->webView->uiDelegate(&ui)))
1792         return emptyRect;
1793 
1794     RECT rect;
1795     if (FAILED(ui->webViewPrintingMarginRect(d->webView, &rect)))
1796         return emptyRect;
1797 
1798     rect.left = MulDiv(rect.left, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
1799     rect.top = MulDiv(rect.top, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
1800     rect.right = MulDiv(rect.right, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
1801     rect.bottom = MulDiv(rect.bottom, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
1802 
1803     return IntRect(rect.left, rect.top, (rect.right - rect.left), rect.bottom - rect.top);
1804 }
1805 
computePageRects(HDC printDC)1806 const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC)
1807 {
1808     ASSERT(m_inPrintingMode);
1809 
1810     Frame* coreFrame = core(this);
1811     ASSERT(coreFrame);
1812     ASSERT(coreFrame->document());
1813 
1814     if (!printDC)
1815         return m_pageRects;
1816 
1817     // adjust the page rect by the header and footer
1818     float headerHeight = 0, footerHeight = 0;
1819     headerAndFooterHeights(&headerHeight, &footerHeight);
1820     IntRect pageRect = printerRect(printDC);
1821     IntRect marginRect = printerMarginRect(printDC);
1822     IntRect adjustedRect = IntRect(
1823         pageRect.x() + marginRect.x(),
1824         pageRect.y() + marginRect.y(),
1825         pageRect.width() - marginRect.x() - marginRect.right(),
1826         pageRect.height() - marginRect.y() - marginRect.bottom());
1827 
1828     computePageRectsForFrame(coreFrame, adjustedRect, headerHeight, footerHeight, 1.0,m_pageRects, m_pageHeight);
1829 
1830     return m_pageRects;
1831 }
1832 
getPrintedPageCount(HDC printDC,UINT * pageCount)1833 HRESULT STDMETHODCALLTYPE WebFrame::getPrintedPageCount(
1834     /* [in] */ HDC printDC,
1835     /* [retval][out] */ UINT *pageCount)
1836 {
1837     if (!pageCount || !printDC) {
1838         ASSERT_NOT_REACHED();
1839         return E_POINTER;
1840     }
1841 
1842     *pageCount = 0;
1843 
1844     if (!m_inPrintingMode) {
1845         ASSERT_NOT_REACHED();
1846         return E_FAIL;
1847     }
1848 
1849     Frame* coreFrame = core(this);
1850     if (!coreFrame || !coreFrame->document())
1851         return E_FAIL;
1852 
1853     const Vector<IntRect>& pages = computePageRects(printDC);
1854     *pageCount = (UINT) pages.size();
1855 
1856     return S_OK;
1857 }
1858 
drawHeader(PlatformGraphicsContext * pctx,IWebUIDelegate * ui,const IntRect & pageRect,float headerHeight)1859 void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
1860 {
1861     int x = pageRect.x();
1862     int y = 0;
1863     RECT headerRect = {x, y, x+pageRect.width(), y+static_cast<int>(headerHeight)};
1864     ui->drawHeaderInRect(d->webView, &headerRect, static_cast<OLE_HANDLE>(reinterpret_cast<LONG64>(pctx)));
1865 }
1866 
drawFooter(PlatformGraphicsContext * pctx,IWebUIDelegate * ui,const IntRect & pageRect,UINT page,UINT pageCount,float headerHeight,float footerHeight)1867 void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight)
1868 {
1869     int x = pageRect.x();
1870     int y = max((int)headerHeight+pageRect.height(), m_pageHeight-static_cast<int>(footerHeight));
1871     RECT footerRect = {x, y, x+pageRect.width(), y+static_cast<int>(footerHeight)};
1872     ui->drawFooterInRect(d->webView, &footerRect, static_cast<OLE_HANDLE>(reinterpret_cast<LONG64>(pctx)), page+1, pageCount);
1873 }
1874 
1875 #if PLATFORM(CG)
spoolPage(PlatformGraphicsContext * pctx,GraphicsContext * spoolCtx,HDC printDC,IWebUIDelegate * ui,float headerHeight,float footerHeight,UINT page,UINT pageCount)1876 void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount)
1877 {
1878     Frame* coreFrame = core(this);
1879 
1880     IntRect pageRect = m_pageRects[page];
1881 
1882     CGContextSaveGState(pctx);
1883 
1884     IntRect printRect = printerRect(printDC);
1885     CGRect mediaBox = CGRectMake(CGFloat(0),
1886                                  CGFloat(0),
1887                                  CGFloat(printRect.width()),
1888                                  CGFloat(printRect.height()));
1889 
1890     CGContextBeginPage(pctx, &mediaBox);
1891 
1892     // FIXME: Could some of this coordinate space manipulation be shared with Cairo?
1893     CGFloat scale = static_cast<float>(mediaBox.size.width)/static_cast<float>(pageRect.width());
1894     CGAffineTransform ctm = CGContextGetBaseCTM(pctx);
1895     ctm = CGAffineTransformScale(ctm, -scale, -scale);
1896     ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header
1897     CGContextScaleCTM(pctx, scale, scale);
1898     CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight));   // reserves space for header
1899     CGContextSetBaseCTM(pctx, ctm);
1900 
1901     coreFrame->view()->paintContents(spoolCtx, pageRect);
1902 
1903     CGContextTranslateCTM(pctx, CGFloat(pageRect.x()), CGFloat(pageRect.y())-headerHeight);
1904 
1905     if (headerHeight)
1906         drawHeader(pctx, ui, pageRect, headerHeight);
1907 
1908     if (footerHeight)
1909         drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight);
1910 
1911     CGContextEndPage(pctx);
1912     CGContextRestoreGState(pctx);
1913 }
1914 #elif PLATFORM(CAIRO)
spoolPage(PlatformGraphicsContext * pctx,GraphicsContext * spoolCtx,HDC printDC,IWebUIDelegate * ui,float headerHeight,float footerHeight,UINT page,UINT pageCount)1915 void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount)
1916 {
1917     Frame* coreFrame = core(this);
1918 
1919     IntRect pageRect = m_pageRects[page];
1920 
1921     cairo_save(pctx);
1922 
1923     IntRect printRect = printerRect(printDC);
1924     IntRect mediaBox(0, 0, printRect.width(), printRect.height());
1925 
1926     ::StartPage(printDC);
1927 
1928     // FIXME: Could some of this coordinate space manipulation be shared with CG?
1929     float scale = static_cast<float>(mediaBox.size().width())/static_cast<float>(pageRect.width());
1930     cairo_scale(pctx, -scale, -scale);
1931     cairo_translate(pctx, -pageRect.x(), -pageRect.y()+headerHeight);
1932     cairo_scale(pctx, scale, scale);
1933     cairo_translate(pctx, -pageRect.x(), -pageRect.y()+headerHeight);   // reserves space for header
1934 
1935     coreFrame->view()->paintContents(spoolCtx, pageRect);
1936 
1937     cairo_translate(pctx, pageRect.x(), pageRect.y()-headerHeight);
1938 
1939     if (headerHeight)
1940         drawHeader(pctx, ui, pageRect, headerHeight);
1941 
1942     if (footerHeight)
1943         drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight);
1944 
1945     cairo_show_page(pctx);
1946     ::EndPage(printDC);
1947     cairo_restore(pctx);
1948 }
1949 #endif
1950 
spoolPages(HDC printDC,UINT startPage,UINT endPage,void * ctx)1951 HRESULT STDMETHODCALLTYPE WebFrame::spoolPages(
1952     /* [in] */ HDC printDC,
1953     /* [in] */ UINT startPage,
1954     /* [in] */ UINT endPage,
1955     /* [retval][out] */ void* ctx)
1956 {
1957     if (!printDC || !ctx) {
1958         ASSERT_NOT_REACHED();
1959         return E_POINTER;
1960     }
1961 
1962     if (!m_inPrintingMode) {
1963         ASSERT_NOT_REACHED();
1964         return E_FAIL;
1965     }
1966 
1967     Frame* coreFrame = core(this);
1968     if (!coreFrame || !coreFrame->document())
1969         return E_FAIL;
1970 
1971     UINT pageCount = (UINT) m_pageRects.size();
1972     PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx;
1973 
1974     if (!pageCount || startPage > pageCount) {
1975         ASSERT_NOT_REACHED();
1976         return E_FAIL;
1977     }
1978 
1979     if (startPage > 0)
1980         startPage--;
1981 
1982     if (endPage == 0)
1983         endPage = pageCount;
1984 
1985     COMPtr<IWebUIDelegate> ui;
1986     if (FAILED(d->webView->uiDelegate(&ui)))
1987         return E_FAIL;
1988 
1989     float headerHeight = 0, footerHeight = 0;
1990     headerAndFooterHeights(&headerHeight, &footerHeight);
1991     GraphicsContext spoolCtx(pctx);
1992     spoolCtx.setShouldIncludeChildWindows(true);
1993 
1994     for (UINT ii = startPage; ii < endPage; ii++)
1995         spoolPage(pctx, &spoolCtx, printDC, ui.get(), headerHeight, footerHeight, ii, pageCount);
1996 
1997     return S_OK;
1998 }
1999 
isFrameSet(BOOL * result)2000 HRESULT STDMETHODCALLTYPE WebFrame::isFrameSet(
2001     /* [retval][out] */ BOOL* result)
2002 {
2003     *result = FALSE;
2004 
2005     Frame* coreFrame = core(this);
2006     if (!coreFrame || !coreFrame->document())
2007         return E_FAIL;
2008 
2009     *result = coreFrame->document()->isFrameSet() ? TRUE : FALSE;
2010     return S_OK;
2011 }
2012 
string(BSTR * result)2013 HRESULT STDMETHODCALLTYPE WebFrame::string(
2014     /* [retval][out] */ BSTR *result)
2015 {
2016     *result = 0;
2017 
2018     Frame* coreFrame = core(this);
2019     if (!coreFrame)
2020         return E_FAIL;
2021 
2022     RefPtr<Range> allRange(rangeOfContents(coreFrame->document()));
2023     String allString = plainText(allRange.get());
2024     *result = BString(allString).release();
2025     return S_OK;
2026 }
2027 
size(SIZE * size)2028 HRESULT STDMETHODCALLTYPE WebFrame::size(
2029     /* [retval][out] */ SIZE *size)
2030 {
2031     if (!size)
2032         return E_POINTER;
2033     size->cx = size->cy = 0;
2034 
2035     Frame* coreFrame = core(this);
2036     if (!coreFrame)
2037         return E_FAIL;
2038     FrameView* view = coreFrame->view();
2039     if (!view)
2040         return E_FAIL;
2041     size->cx = view->width();
2042     size->cy = view->height();
2043     return S_OK;
2044 }
2045 
hasScrollBars(BOOL * result)2046 HRESULT STDMETHODCALLTYPE WebFrame::hasScrollBars(
2047     /* [retval][out] */ BOOL *result)
2048 {
2049     if (!result)
2050         return E_POINTER;
2051     *result = FALSE;
2052 
2053     Frame* coreFrame = core(this);
2054     if (!coreFrame)
2055         return E_FAIL;
2056 
2057     FrameView* view = coreFrame->view();
2058     if (!view)
2059         return E_FAIL;
2060 
2061     if (view->horizontalScrollbar() || view->verticalScrollbar())
2062         *result = TRUE;
2063 
2064     return S_OK;
2065 }
2066 
contentBounds(RECT * result)2067 HRESULT STDMETHODCALLTYPE WebFrame::contentBounds(
2068     /* [retval][out] */ RECT *result)
2069 {
2070     if (!result)
2071         return E_POINTER;
2072     ::SetRectEmpty(result);
2073 
2074     Frame* coreFrame = core(this);
2075     if (!coreFrame)
2076         return E_FAIL;
2077 
2078     FrameView* view = coreFrame->view();
2079     if (!view)
2080         return E_FAIL;
2081 
2082     result->bottom = view->contentsHeight();
2083     result->right = view->contentsWidth();
2084     return S_OK;
2085 }
2086 
frameBounds(RECT * result)2087 HRESULT STDMETHODCALLTYPE WebFrame::frameBounds(
2088     /* [retval][out] */ RECT *result)
2089 {
2090     if (!result)
2091         return E_POINTER;
2092     ::SetRectEmpty(result);
2093 
2094     Frame* coreFrame = core(this);
2095     if (!coreFrame)
2096         return E_FAIL;
2097 
2098     FrameView* view = coreFrame->view();
2099     if (!view)
2100         return E_FAIL;
2101 
2102     FloatRect bounds = view->visibleContentRect(true);
2103     result->bottom = (LONG) bounds.height();
2104     result->right = (LONG) bounds.width();
2105     return S_OK;
2106 }
2107 
isDescendantOfFrame(IWebFrame * ancestor,BOOL * result)2108 HRESULT STDMETHODCALLTYPE WebFrame::isDescendantOfFrame(
2109     /* [in] */ IWebFrame *ancestor,
2110     /* [retval][out] */ BOOL *result)
2111 {
2112     if (!result)
2113         return E_POINTER;
2114     *result = FALSE;
2115 
2116     Frame* coreFrame = core(this);
2117     COMPtr<WebFrame> ancestorWebFrame(Query, ancestor);
2118     if (!ancestorWebFrame)
2119         return S_OK;
2120 
2121     *result = (coreFrame && coreFrame->tree()->isDescendantOf(core(ancestorWebFrame.get()))) ? TRUE : FALSE;
2122     return S_OK;
2123 }
2124 
unmarkAllMisspellings()2125 void WebFrame::unmarkAllMisspellings()
2126 {
2127     Frame* coreFrame = core(this);
2128     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
2129         Document *doc = frame->document();
2130         if (!doc)
2131             return;
2132 
2133         doc->removeMarkers(DocumentMarker::Spelling);
2134     }
2135 }
2136 
unmarkAllBadGrammar()2137 void WebFrame::unmarkAllBadGrammar()
2138 {
2139     Frame* coreFrame = core(this);
2140     for (Frame* frame = coreFrame; frame; frame = frame->tree()->traverseNext(coreFrame)) {
2141         Document *doc = frame->document();
2142         if (!doc)
2143             return;
2144 
2145         doc->removeMarkers(DocumentMarker::Grammar);
2146     }
2147 }
2148 
webView() const2149 WebView* WebFrame::webView() const
2150 {
2151     return d->webView;
2152 }
2153 
accessible() const2154 COMPtr<IAccessible> WebFrame::accessible() const
2155 {
2156     Frame* coreFrame = core(this);
2157     ASSERT(coreFrame);
2158 
2159     Document* currentDocument = coreFrame->document();
2160     if (!currentDocument)
2161         m_accessible = 0;
2162     else if (!m_accessible || m_accessible->document() != currentDocument) {
2163         // Either we've never had a wrapper for this frame's top-level Document,
2164         // the Document renderer was destroyed and its wrapper was detached, or
2165         // the previous Document is in the page cache, and the current document
2166         // needs to be wrapped.
2167         m_accessible = new AccessibleDocument(currentDocument);
2168     }
2169     return m_accessible.get();
2170 }
2171 
updateBackground()2172 void WebFrame::updateBackground()
2173 {
2174     Color backgroundColor = webView()->transparent() ? Color::transparent : Color::white;
2175     Frame* coreFrame = core(this);
2176 
2177     if (!coreFrame || !coreFrame->view())
2178         return;
2179 
2180     coreFrame->view()->updateBackgroundRecursively(backgroundColor, webView()->transparent());
2181 }
2182