Document::securityOrigin() should return a reference.
[WebKit-https.git] / Source / WebKit / win / WebFrame.cpp
1 /*
2  * Copyright (C) 2006-2009, 2011, 2013-2015 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 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 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 "WebKitDLL.h"
28 #include "WebFrame.h"
29
30 #include "CFDictionaryPropertyBag.h"
31 #include "COMPropertyBag.h"
32 #include "DOMCoreClasses.h"
33 #include "HTMLFrameOwnerElement.h"
34 #include "MarshallingHelpers.h"
35 #include "PluginDatabase.h"
36 #include "PluginView.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 "WebFrameLoaderClient.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/AnimationController.h>
56 #include <WebCore/BString.h>
57 #include <WebCore/COMPtr.h>
58 #include <WebCore/MemoryCache.h>
59 #include <WebCore/Document.h>
60 #include <WebCore/DocumentLoader.h>
61 #include <WebCore/DocumentMarkerController.h>
62 #include <WebCore/DOMWindow.h>
63 #include <WebCore/Editor.h>
64 #include <WebCore/Event.h>
65 #include <WebCore/EventHandler.h>
66 #include <WebCore/FormState.h>
67 #include <WebCore/FrameLoader.h>
68 #include <WebCore/FrameLoadRequest.h>
69 #include <WebCore/FrameTree.h>
70 #include <WebCore/FrameView.h>
71 #include <WebCore/FrameWin.h>
72 #include <WebCore/GDIObjectCounter.h>
73 #include <WebCore/GraphicsContext.h>
74 #include <WebCore/HistoryItem.h>
75 #include <WebCore/HTMLAppletElement.h>
76 #include <WebCore/HTMLFormElement.h>
77 #include <WebCore/HTMLFormControlElement.h>
78 #include <WebCore/HTMLInputElement.h>
79 #include <WebCore/HTMLNames.h>
80 #include <WebCore/HTMLPlugInElement.h>
81 #include <WebCore/JSDOMWindow.h>
82 #include <WebCore/KeyboardEvent.h>
83 #include <WebCore/MIMETypeRegistry.h>
84 #include <WebCore/MainFrame.h>
85 #include <WebCore/MouseRelatedEvent.h>
86 #include <WebCore/NotImplemented.h>
87 #include <WebCore/Page.h>
88 #include <WebCore/PlatformKeyboardEvent.h>
89 #include <WebCore/PluginData.h>
90 #include <WebCore/PolicyChecker.h>
91 #include <WebCore/PrintContext.h>
92 #include <WebCore/ResourceHandle.h>
93 #include <WebCore/ResourceLoader.h>
94 #include <WebCore/ResourceRequest.h>
95 #include <WebCore/RenderView.h>
96 #include <WebCore/RenderTreeAsText.h>
97 #include <WebCore/Settings.h>
98 #include <WebCore/TextIterator.h>
99 #include <WebCore/JSDOMBinding.h>
100 #include <WebCore/ScriptController.h>
101 #include <WebCore/SecurityOrigin.h>
102 #include <JavaScriptCore/APICast.h>
103 #include <JavaScriptCore/JSCJSValue.h>
104 #include <JavaScriptCore/JSLock.h>
105 #include <JavaScriptCore/JSObject.h>
106 #include <bindings/ScriptValue.h>
107 #include <wtf/MathExtras.h>
108
109 #if USE(CG)
110 #include <CoreGraphics/CoreGraphics.h>
111 #elif USE(CAIRO)
112 #include "PlatformContextCairo.h"
113 #include <cairo-win32.h>
114 #endif
115
116 #if USE(CG)
117 // CG SPI used for printing
118 extern "C" {
119     CGAffineTransform CGContextGetBaseCTM(CGContextRef c); 
120     void CGContextSetBaseCTM(CGContextRef c, CGAffineTransform m); 
121 }
122 #endif
123
124 using namespace WebCore;
125 using namespace HTMLNames;
126 using namespace std;
127
128 using JSC::JSGlobalObject;
129 using JSC::JSLock;
130 using JSC::JSValue;
131
132 #define FLASH_REDRAW 0
133
134
135 // By imaging to a width a little wider than the available pixels,
136 // thin pages will be scaled down a little, matching the way they
137 // print in IE and Camino. This lets them use fewer sheets than they
138 // would otherwise, which is presumably why other browsers do this.
139 // Wide pages will be scaled down more than this.
140 const float PrintingMinimumShrinkFactor = 1.25f;
141
142 // This number determines how small we are willing to reduce the page content
143 // in order to accommodate the widest line. If the page would have to be
144 // reduced smaller to make the widest line fit, we just clip instead (this
145 // behavior matches MacIE and Mozilla, at least)
146 const float PrintingMaximumShrinkFactor = 2.0f;
147
148 //-----------------------------------------------------------------------------
149 // Helpers to convert from WebCore to WebKit type
150 WebFrame* kit(Frame* frame)
151 {
152     if (!frame)
153         return nullptr;
154
155     // FIXME: Doesn't this need to be aware of EmptyFrameLoaderClient?
156     FrameLoaderClient& frameLoaderClient = frame->loader().client();
157     return static_cast<WebFrameLoaderClient&>(frameLoaderClient).webFrame();
158 }
159
160 Frame* core(WebFrame* webFrame)
161 {
162     if (!webFrame)
163         return nullptr;
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 nullptr;
172     return const_cast<WebFrame*>(webFrame)->impl();
173 }
174
175 //-----------------------------------------------------------------------------
176
177 static Element* elementFromDOMElement(IDOMElement* element)
178 {
179     if (!element)
180         return nullptr;
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 nullptr;
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) && is<HTMLFormElement>(ele))
205             return downcast<HTMLFormElement>(ele);
206     }
207     return nullptr;
208 }
209
210 static HTMLInputElement* inputElementFromDOMElement(IDOMElement* element)
211 {
212     if (!element)
213         return nullptr;
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) && is<HTMLInputElement>(ele))
222             return downcast<HTMLInputElement>(ele);
223     }
224     return nullptr;
225 }
226
227 // WebFramePrivate ------------------------------------------------------------
228
229 class WebFrame::WebFramePrivate {
230 public:
231     WebFramePrivate() 
232     {
233     }
234
235     ~WebFramePrivate() { }
236     FrameView* frameView() { return frame ? frame->view() : nullptr; }
237
238     Frame* frame { nullptr };
239     WebView* webView { nullptr };
240 };
241
242 // WebFrame ----------------------------------------------------------------
243
244 WebFrame::WebFrame()
245     : d(new WebFrame::WebFramePrivate)
246 {
247     WebFrameCount++;
248     gClassCount++;
249     gClassNameCount().add("WebFrame");
250 }
251
252 WebFrame::~WebFrame()
253 {
254     delete d;
255     WebFrameCount--;
256     gClassCount--;
257     gClassNameCount().remove("WebFrame");
258 }
259
260 WebFrame* WebFrame::createInstance()
261 {
262     WebFrame* instance = new WebFrame();
263     instance->AddRef();
264     return instance;
265 }
266
267 HRESULT WebFrame::setAllowsScrolling(BOOL flag)
268 {
269     if (Frame* frame = core(this))
270         if (FrameView* view = frame->view())
271             view->setCanHaveScrollbars(!!flag);
272
273     return S_OK;
274 }
275
276 HRESULT WebFrame::allowsScrolling(_Out_ BOOL* flag)
277 {
278     if (!flag)
279         return E_POINTER;
280
281     *flag = FALSE;
282
283     if (Frame* frame = core(this)) {
284         if (FrameView* view = frame->view())
285             *flag = view->canHaveScrollbars();
286     }
287
288     return S_OK;
289 }
290
291 HRESULT WebFrame::setIsDisconnected(BOOL flag)
292 {
293     ASSERT_NOT_REACHED();
294     return E_FAIL;
295 }
296
297 HRESULT WebFrame::setExcludeFromTextSearch(BOOL flag)
298 {
299     ASSERT_NOT_REACHED();
300     return E_NOTIMPL;
301 }
302
303 HRESULT WebFrame::reloadFromOrigin()
304 {
305     Frame* coreFrame = core(this);
306     if (!coreFrame)
307         return E_UNEXPECTED;
308
309     coreFrame->loader().reload(true);
310     return S_OK;
311 }
312
313 HRESULT WebFrame::paintDocumentRectToContext(RECT rect, _In_ HDC deviceContext)
314 {
315     Frame* coreFrame = core(this);
316     if (!coreFrame)
317         return E_UNEXPECTED;
318
319     FrameView* view = coreFrame->view();
320     if (!view)
321         return E_FAIL;
322
323     // We can't paint with a layout still pending.
324     view->updateLayoutAndStyleIfNeededRecursive();
325
326     GraphicsContext gc(deviceContext);
327     gc.setShouldIncludeChildWindows(true);
328     gc.save();
329     LONG width = rect.right - rect.left;
330     LONG height = rect.bottom - rect.top;
331     FloatRect dirtyRect;
332     dirtyRect.setWidth(width);
333     dirtyRect.setHeight(height);
334     gc.clip(dirtyRect);
335     gc.translate(-rect.left, -rect.top);
336     float scaleFactor = webView()->deviceScaleFactor();
337     gc.scale(WebCore::FloatSize(scaleFactor, scaleFactor));
338     view->paintContents(gc, rect);
339     gc.restore();
340
341     return S_OK;
342 }
343
344 HRESULT WebFrame::paintScrollViewRectToContextAtPoint(RECT rect, POINT pt, _In_ HDC deviceContext)
345 {
346     Frame* coreFrame = core(this);
347     if (!coreFrame)
348         return E_UNEXPECTED;
349
350     FrameView* view = coreFrame->view();
351     if (!view)
352         return E_FAIL;
353
354     // We can't paint with a layout still pending.
355     view->updateLayoutAndStyleIfNeededRecursive();
356
357     GraphicsContext gc(deviceContext);
358     gc.setShouldIncludeChildWindows(true);
359     gc.save();
360     IntRect dirtyRect(rect);
361     dirtyRect.move(-pt.x, -pt.y);
362     float scaleFactor = webView()->deviceScaleFactor();
363     gc.scale(WebCore::FloatSize(scaleFactor, scaleFactor));
364     view->paint(gc, dirtyRect);
365     gc.restore();
366
367     return S_OK;
368 }
369
370 // IUnknown -------------------------------------------------------------------
371
372 HRESULT WebFrame::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
373 {
374     if (!ppvObject)
375         return E_POINTER;
376     *ppvObject = nullptr;
377     if (IsEqualGUID(riid, __uuidof(WebFrame)))
378         *ppvObject = this;
379     else if (IsEqualGUID(riid, IID_IUnknown))
380         *ppvObject = static_cast<IWebFrame2*>(this);
381     else if (IsEqualGUID(riid, IID_IWebFrame))
382         *ppvObject = static_cast<IWebFrame2*>(this);
383     else if (IsEqualGUID(riid, IID_IWebFrame2))
384         *ppvObject = static_cast<IWebFrame2*>(this);
385     else if (IsEqualGUID(riid, IID_IWebFramePrivate))
386         *ppvObject = static_cast<IWebFramePrivate*>(this);
387     else if (IsEqualGUID(riid, IID_IWebDocumentText))
388         *ppvObject = static_cast<IWebDocumentText*>(this);
389     else
390         return E_NOINTERFACE;
391
392     AddRef();
393     return S_OK;
394 }
395
396 ULONG WebFrame::AddRef()
397 {
398     return ++m_refCount;
399 }
400
401 ULONG WebFrame::Release()
402 {
403     ULONG newRef = --m_refCount;
404     if (!newRef)
405         delete(this);
406
407     return newRef;
408 }
409
410 // IWebFrame -------------------------------------------------------------------
411
412 HRESULT WebFrame::name(_Deref_opt_out_ BSTR* frameName)
413 {
414     if (!frameName) {
415         ASSERT_NOT_REACHED();
416         return E_POINTER;
417     }
418
419     *frameName = nullptr;
420
421     Frame* coreFrame = core(this);
422     if (!coreFrame)
423         return E_UNEXPECTED;
424
425     *frameName = BString(coreFrame->tree().uniqueName()).release();
426     return S_OK;
427 }
428
429 HRESULT WebFrame::webView(_COM_Outptr_opt_ IWebView** view)
430 {
431     if (!view)
432         return E_POINTER;
433     *view = nullptr;
434     if (!d->webView)
435         return E_FAIL;
436     *view = d->webView;
437     (*view)->AddRef();
438     return S_OK;
439 }
440
441 HRESULT WebFrame::frameView(_COM_Outptr_opt_ IWebFrameView** view)
442 {
443     ASSERT_NOT_REACHED();
444     if (!view)
445         return E_POINTER;
446     *view = nullptr;
447     return E_NOTIMPL;
448 }
449
450 HRESULT WebFrame::DOMDocument(_COM_Outptr_opt_ IDOMDocument** result)
451 {
452     if (!result) {
453         ASSERT_NOT_REACHED();
454         return E_POINTER;
455     }
456
457     *result = nullptr;
458
459     Frame* coreFrame = core(this);
460     if (!coreFrame)
461         return E_UNEXPECTED;
462
463     if (Document* document = coreFrame->document())
464         *result = DOMDocument::createInstance(document);
465
466     return *result ? S_OK : E_FAIL;
467 }
468
469
470 HRESULT WebFrame::DOMWindow(_COM_Outptr_opt_ IDOMWindow** window)
471 {
472     if (!window) {
473         ASSERT_NOT_REACHED();
474         return E_POINTER;
475     }
476
477     *window = nullptr;
478
479     Frame* coreFrame = core(this);
480     if (!coreFrame)
481         return E_UNEXPECTED;
482
483     if (WebCore::DOMWindow* coreWindow = coreFrame->document()->domWindow())
484         *window = ::DOMWindow::createInstance(coreWindow);
485
486     return *window ? S_OK : E_FAIL;
487 }
488
489 HRESULT WebFrame::frameElement(_COM_Outptr_opt_ IDOMHTMLElement** frameElement)
490 {
491     if (!frameElement)
492         return E_POINTER;
493
494     *frameElement = nullptr;
495
496     Frame* coreFrame = core(this);
497     if (!coreFrame)
498         return E_UNEXPECTED;
499
500     COMPtr<IDOMElement> domElement(AdoptCOM, DOMElement::createInstance(coreFrame->ownerElement()));
501     COMPtr<IDOMHTMLElement> htmlElement(Query, domElement);
502     if (!htmlElement)
503         return E_FAIL;
504     return htmlElement.copyRefTo(frameElement);
505 }
506
507 HRESULT WebFrame::currentForm(_COM_Outptr_opt_ IDOMElement** currentForm)
508 {
509     if (!currentForm) {
510         ASSERT_NOT_REACHED();
511         return E_POINTER;
512     }
513
514     *currentForm = nullptr;
515
516     Frame* coreFrame = core(this);
517     if (!coreFrame)
518         return E_UNEXPECTED;
519
520     if (HTMLFormElement* formElement = coreFrame->selection().currentForm())
521         *currentForm = DOMElement::createInstance(formElement);
522
523     return *currentForm ? S_OK : E_FAIL;
524 }
525
526 JSGlobalContextRef WebFrame::globalContext()
527 {
528     Frame* coreFrame = core(this);
529     if (!coreFrame)
530         return nullptr;
531
532     return toGlobalRef(coreFrame->script().globalObject(mainThreadNormalWorld())->globalExec());
533 }
534
535 JSGlobalContextRef WebFrame::globalContextForScriptWorld(IWebScriptWorld* iWorld)
536 {
537     Frame* coreFrame = core(this);
538     if (!coreFrame)
539         return 0;
540
541     COMPtr<WebScriptWorld> world(Query, iWorld);
542     if (!world)
543         return 0;
544
545     return toGlobalRef(coreFrame->script().globalObject(world->world())->globalExec());
546 }
547
548 HRESULT WebFrame::loadRequest(_In_opt_ IWebURLRequest* request)
549 {
550     if (!request)
551         return S_OK;
552
553     COMPtr<WebMutableURLRequest> requestImpl;
554
555     HRESULT hr = request->QueryInterface(&requestImpl);
556     if (FAILED(hr))
557         return hr;
558  
559     Frame* coreFrame = core(this);
560     if (!coreFrame)
561         return E_UNEXPECTED;
562
563     coreFrame->loader().load(FrameLoadRequest(coreFrame, requestImpl->resourceRequest(), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
564     return S_OK;
565 }
566
567 void WebFrame::loadData(PassRefPtr<WebCore::SharedBuffer> data, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL)
568 {
569     String mimeTypeString(mimeType, SysStringLen(mimeType));
570     if (!mimeType)
571         mimeTypeString = "text/html";
572
573     String encodingString(textEncodingName, SysStringLen(textEncodingName));
574
575     // FIXME: We should really be using MarshallingHelpers::BSTRToKURL here,
576     // but that would turn a null BSTR into a null URL, and we crash inside of
577     // WebCore if we use a null URL in constructing the ResourceRequest.
578     URL baseCoreURL = URL(URL(), String(baseURL ? baseURL : L"", SysStringLen(baseURL)));
579
580     URL failingCoreURL = MarshallingHelpers::BSTRToKURL(failingURL);
581
582     ResourceRequest request(baseCoreURL);
583     ResourceResponse response(URL(), mimeTypeString, data->size(), encodingString);
584     SubstituteData substituteData(data, failingCoreURL, response, SubstituteData::SessionHistoryVisibility::Hidden);
585
586     // This method is only called from IWebFrame methods, so don't ASSERT that the Frame pointer isn't null.
587     if (Frame* coreFrame = core(this))
588         coreFrame->loader().load(FrameLoadRequest(coreFrame, request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData));
589 }
590
591 HRESULT WebFrame::loadData(_In_opt_ IStream* data, _In_ BSTR mimeType, _In_ BSTR textEncodingName, _In_ BSTR url)
592 {
593     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create();
594
595     STATSTG stat;
596     if (SUCCEEDED(data->Stat(&stat, STATFLAG_NONAME))) {
597         if (!stat.cbSize.HighPart && stat.cbSize.LowPart) {
598             Vector<char> dataBuffer(stat.cbSize.LowPart);
599             ULONG read;
600             // FIXME: this does a needless copy, would be better to read right into the SharedBuffer
601             // or adopt the Vector or something.
602             if (SUCCEEDED(data->Read(dataBuffer.data(), static_cast<ULONG>(dataBuffer.size()), &read)))
603                 sharedBuffer->append(dataBuffer.data(), static_cast<int>(dataBuffer.size()));
604         }
605     }
606
607     loadData(sharedBuffer, mimeType, textEncodingName, url, nullptr);
608     return S_OK;
609 }
610
611 HRESULT WebFrame::loadPlainTextString(_In_ BSTR plainText, _In_ BSTR url)
612 {
613     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(plainText), sizeof(UChar) * SysStringLen(plainText));
614     BString plainTextMimeType(TEXT("text/plain"), 10);
615     BString utf16Encoding(TEXT("utf-16"), 6);
616     loadData(sharedBuffer.release(), plainTextMimeType, utf16Encoding, url, nullptr);
617     return S_OK;
618 }
619
620 void WebFrame::loadHTMLString(_In_ BSTR htmlString, _In_ BSTR baseURL, _In_ BSTR unreachableURL)
621 {
622     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(htmlString), sizeof(UChar) * SysStringLen(htmlString));
623     BString utf16Encoding(TEXT("utf-16"), 6);
624     loadData(sharedBuffer.release(), 0, utf16Encoding, baseURL, unreachableURL);
625 }
626
627 HRESULT WebFrame::loadHTMLString(_In_ BSTR htmlString, _In_ BSTR baseURL)
628 {
629     loadHTMLString(htmlString, baseURL, nullptr);
630     return S_OK;
631 }
632
633 HRESULT WebFrame::loadAlternateHTMLString(_In_ BSTR str, _In_ BSTR baseURL, _In_ BSTR unreachableURL)
634 {
635     loadHTMLString(str, baseURL, unreachableURL);
636     return S_OK;
637 }
638
639 HRESULT WebFrame::loadArchive(_In_opt_ IWebArchive* /*archive*/)
640 {
641     ASSERT_NOT_REACHED();
642     return E_NOTIMPL;
643 }
644
645 static inline WebDataSource* getWebDataSource(DocumentLoader* loader)
646 {
647     return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : nullptr;
648 }
649
650 HRESULT WebFrame::dataSource(_COM_Outptr_opt_ IWebDataSource** source)
651 {
652     if (!source) {
653         ASSERT_NOT_REACHED();
654         return E_POINTER;
655     }
656
657     *source = nullptr;
658
659     Frame* coreFrame = core(this);
660     if (!coreFrame)
661         return E_UNEXPECTED;
662
663     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader().documentLoader());
664
665     *source = webDataSource;
666
667     if (webDataSource)
668         webDataSource->AddRef(); 
669
670     return *source ? S_OK : E_FAIL;
671 }
672
673 HRESULT WebFrame::provisionalDataSource(_COM_Outptr_opt_ IWebDataSource** source)
674 {
675     if (!source) {
676         ASSERT_NOT_REACHED();
677         return E_POINTER;
678     }
679
680     *source = nullptr;
681
682     Frame* coreFrame = core(this);
683     if (!coreFrame)
684         return E_UNEXPECTED;
685
686     WebDataSource* webDataSource = getWebDataSource(coreFrame->loader().provisionalDocumentLoader());
687
688     *source = webDataSource;
689
690     if (webDataSource)
691         webDataSource->AddRef(); 
692
693     return *source ? S_OK : E_FAIL;
694 }
695
696 URL WebFrame::url() const
697 {
698     Frame* coreFrame = core(this);
699     if (!coreFrame)
700         return URL();
701
702     return coreFrame->document()->url();
703 }
704
705 HRESULT WebFrame::stopLoading()
706 {
707     if (Frame* coreFrame = core(this))
708         coreFrame->loader().stopAllLoaders();
709     return S_OK;
710 }
711
712 HRESULT WebFrame::reload()
713 {
714     Frame* coreFrame = core(this);
715     if (!coreFrame)
716         return E_UNEXPECTED;
717
718     coreFrame->loader().reload();
719     return S_OK;
720 }
721
722 HRESULT WebFrame::findFrameNamed(_In_ BSTR name, _COM_Outptr_opt_ IWebFrame** frame)
723 {
724     if (!frame) {
725         ASSERT_NOT_REACHED();
726         return E_POINTER;
727     }
728
729     *frame = nullptr;
730
731     Frame* coreFrame = core(this);
732     if (!coreFrame)
733         return E_UNEXPECTED;
734
735     Frame* foundFrame = coreFrame->tree().find(AtomicString(name, SysStringLen(name)));
736     if (!foundFrame)
737         return S_OK;
738
739     WebFrame* foundWebFrame = kit(foundFrame);
740     if (!foundWebFrame)
741         return E_FAIL;
742
743     return foundWebFrame->QueryInterface(IID_IWebFrame, (void**)frame);
744 }
745
746 HRESULT WebFrame::parentFrame(_COM_Outptr_opt_ IWebFrame** frame)
747 {
748     if (!frame)
749         return E_POINTER;
750
751     *frame = nullptr;
752
753     HRESULT hr = S_OK;
754     if (Frame* coreFrame = core(this))
755         if (WebFrame* webFrame = kit(coreFrame->tree().parent()))
756             hr = webFrame->QueryInterface(IID_IWebFrame, (void**) frame);
757
758     return hr;
759 }
760
761 class EnumChildFrames : public IEnumVARIANT
762 {
763 public:
764     EnumChildFrames(Frame* f)
765         : m_frame(f), m_curChild(f ? f->tree().firstChild() : nullptr)
766     {
767     }
768
769     virtual HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
770     {
771         *ppvObject = nullptr;
772         if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IEnumVARIANT))
773             *ppvObject = this;
774         else
775             return E_NOINTERFACE;
776
777         AddRef();
778         return S_OK;
779     }
780
781     virtual ULONG STDMETHODCALLTYPE AddRef()
782     {
783         return ++m_refCount;
784     }
785
786     virtual ULONG STDMETHODCALLTYPE Release()
787     {
788         ULONG newRef = --m_refCount;
789         if (!newRef)
790             delete(this);
791         return newRef;
792     }
793
794     virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
795     {
796         if (pCeltFetched)
797             *pCeltFetched = 0;
798         if (!rgVar)
799             return E_POINTER;
800         ::VariantInit(rgVar);
801         if (!celt || celt > 1)
802             return S_FALSE;
803         if (!m_frame || !m_curChild)
804             return S_FALSE;
805
806         WebFrame* webFrame = kit(m_curChild);
807         IUnknown* unknown;
808         HRESULT hr = webFrame->QueryInterface(IID_IUnknown, (void**)&unknown);
809         if (FAILED(hr))
810             return hr;
811
812         V_VT(rgVar) = VT_UNKNOWN;
813         V_UNKNOWN(rgVar) = unknown;
814
815         m_curChild = m_curChild->tree().nextSibling();
816         if (pCeltFetched)
817             *pCeltFetched = 1;
818         return S_OK;
819     }
820
821     virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
822     {
823         if (!m_frame)
824             return S_FALSE;
825         for (unsigned i = 0; i < celt && m_curChild; i++)
826             m_curChild = m_curChild->tree().nextSibling();
827         return m_curChild ? S_OK : S_FALSE;
828     }
829
830     virtual HRESULT STDMETHODCALLTYPE Reset(void)
831     {
832         if (!m_frame)
833             return S_FALSE;
834         m_curChild = m_frame->tree().firstChild();
835         return S_OK;
836     }
837
838     virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT**)
839     {
840         return E_NOTIMPL;
841     }
842
843 private:
844     ULONG m_refCount { 1 };
845     Frame* m_frame;
846     Frame* m_curChild;
847 };
848
849 HRESULT WebFrame::childFrames(_COM_Outptr_opt_ 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, _Deref_opt_out_ BSTR* result)
861 {
862     if (!result)
863         return E_POINTER;
864
865     Frame* coreFrame = core(this);
866     if (!coreFrame)
867         return E_UNEXPECTED;
868
869     *result = BString(externalRepresentation(coreFrame, forPrinting ? RenderAsTextPrintingMode : RenderAsTextBehaviorNormal)).release();
870     return S_OK;
871 }
872
873 HRESULT WebFrame::pageNumberForElementById(_In_ BSTR id, float pageWidthInPixels, float pageHeightInPixels, _Out_ int* pageNumber)
874 {
875     // TODO: Please remove this function if not needed as this is LTC specific function
876     // and has been moved to Internals.
877     ASSERT_NOT_REACHED();
878     return E_NOTIMPL;
879 }
880
881 HRESULT WebFrame::numberOfPages(float pageWidthInPixels, float pageHeightInPixels, _Out_ int* pageCount)
882 {
883     // TODO: Please remove this function if not needed as this is LTC specific function
884     // and has been moved to Internals.
885     ASSERT_NOT_REACHED();
886     return E_NOTIMPL;
887 }
888
889 HRESULT WebFrame::scrollOffset(_Out_ SIZE* offset)
890 {
891     if (!offset) {
892         ASSERT_NOT_REACHED();
893         return E_POINTER;
894     }
895
896     Frame* coreFrame = core(this);
897     if (!coreFrame)
898         return E_UNEXPECTED;
899
900     FrameView* view = coreFrame->view();
901     if (!view)
902         return E_FAIL;
903
904     *offset = toIntSize(view->scrollPosition());
905     return S_OK;
906 }
907
908 HRESULT WebFrame::layout()
909 {
910     Frame* coreFrame = core(this);
911     if (!coreFrame)
912         return E_UNEXPECTED;
913
914     FrameView* view = coreFrame->view();
915     if (!view)
916         return E_FAIL;
917
918     view->layout();
919     return S_OK;
920 }
921
922 HRESULT WebFrame::firstLayoutDone(_Out_ BOOL* result)
923 {
924     if (!result) {
925         ASSERT_NOT_REACHED();
926         return E_POINTER;
927     }
928
929     *result = FALSE;
930
931     Frame* coreFrame = core(this);
932     if (!coreFrame)
933         return E_UNEXPECTED;
934
935     *result = coreFrame->loader().stateMachine().firstLayoutDone();
936     return S_OK;
937 }
938
939 HRESULT WebFrame::pendingFrameUnloadEventCount(_Out_ UINT* result)
940 {
941     if (!result) {
942         ASSERT_NOT_REACHED();
943         return E_POINTER;
944     }
945
946     *result = 0;
947
948     Frame* coreFrame = core(this);
949     if (!coreFrame)
950         return E_UNEXPECTED;
951
952     *result = coreFrame->document()->domWindow()->pendingUnloadEventListeners();
953     return S_OK;
954 }
955
956 HRESULT WebFrame::hasSpellingMarker(UINT from, UINT length, BOOL* result)
957 {
958     Frame* coreFrame = core(this);
959     if (!coreFrame)
960         return E_UNEXPECTED;
961     *result = coreFrame->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
962     return S_OK;
963 }
964
965 HRESULT WebFrame::clearOpener()
966 {
967     HRESULT hr = S_OK;
968     if (Frame* coreFrame = core(this))
969         coreFrame->loader().setOpener(nullptr);
970
971     return hr;
972 }
973
974 HRESULT WebFrame::setTextDirection(_In_ BSTR direction)
975 {
976     Frame* coreFrame = core(this);
977     if (!coreFrame)
978         return E_UNEXPECTED;
979
980     String directionString(direction, SysStringLen(direction));
981     if (directionString == "auto")
982         coreFrame->editor().setBaseWritingDirection(NaturalWritingDirection);
983     else if (directionString == "ltr")
984         coreFrame->editor().setBaseWritingDirection(LeftToRightWritingDirection);
985     else if (directionString == "rtl")
986         coreFrame->editor().setBaseWritingDirection(RightToLeftWritingDirection);
987     return S_OK;
988 }
989
990 // IWebDocumentText -----------------------------------------------------------
991
992 HRESULT WebFrame::supportsTextEncoding(_Out_ BOOL* result)
993 {
994     *result = FALSE;
995     return E_NOTIMPL;
996 }
997
998 HRESULT WebFrame::selectedString(_Deref_opt_out_ BSTR* result)
999 {
1000     if (!result)
1001         return E_POINTER;
1002     *result = nullptr;
1003
1004     Frame* coreFrame = core(this);
1005     if (!coreFrame)
1006         return E_UNEXPECTED;
1007
1008     String text = coreFrame->displayStringModifiedByEncoding(coreFrame->editor().selectedText());
1009
1010     *result = BString(text).release();
1011     return S_OK;
1012 }
1013
1014 HRESULT WebFrame::selectAll()
1015 {
1016     Frame* coreFrame = core(this);
1017     if (!coreFrame)
1018         return E_UNEXPECTED;
1019
1020     if (!coreFrame->editor().command("SelectAll").execute())
1021         return E_FAIL;
1022
1023     return S_OK;
1024 }
1025
1026 HRESULT WebFrame::deselectAll()
1027 {
1028     return E_NOTIMPL;
1029 }
1030
1031 // WebFrame ---------------------------------------------------------------
1032
1033 PassRefPtr<Frame> WebFrame::createSubframeWithOwnerElement(IWebView* webView, Page* page, HTMLFrameOwnerElement* ownerElement)
1034 {
1035     webView->QueryInterface(&d->webView);
1036     d->webView->Release(); // don't hold the extra ref
1037
1038     HWND viewWindow;
1039     d->webView->viewWindow(&viewWindow);
1040
1041     this->AddRef(); // We release this ref in frameLoaderDestroyed()
1042     RefPtr<Frame> frame = Frame::create(page, ownerElement, new WebFrameLoaderClient(this));
1043     d->frame = frame.get();
1044     return frame.release();
1045 }
1046
1047 void WebFrame::initWithWebView(IWebView* webView, Page* page)
1048 {
1049     webView->QueryInterface(&d->webView);
1050     d->webView->Release(); // don't hold the extra ref
1051
1052     HWND viewWindow;
1053     d->webView->viewWindow(&viewWindow);
1054
1055     this->AddRef(); // We release this ref in frameLoaderDestroyed()
1056     d->frame = &page->mainFrame();
1057 }
1058
1059 Frame* WebFrame::impl()
1060 {
1061     return d->frame;
1062 }
1063
1064 void WebFrame::invalidate()
1065 {
1066     Frame* coreFrame = core(this);
1067     ASSERT(coreFrame);
1068
1069     if (Document* document = coreFrame->document())
1070         document->recalcStyle(Style::Force);
1071 }
1072
1073 HRESULT WebFrame::inViewSourceMode(BOOL* flag)
1074 {
1075     return E_NOTIMPL;
1076 }
1077
1078 HRESULT WebFrame::setInViewSourceMode(BOOL flag)
1079 {
1080     return E_NOTIMPL;
1081 }
1082
1083 HRESULT WebFrame::elementWithName(BSTR name, IDOMElement* form, IDOMElement** element)
1084 {
1085     if (!form)
1086         return E_INVALIDARG;
1087
1088     HTMLFormElement* formElement = formElementFromDOMElement(form);
1089     if (formElement) {
1090         const Vector<FormAssociatedElement*>& elements = formElement->associatedElements();
1091         AtomicString targetName((UChar*)name, SysStringLen(name));
1092         for (unsigned int i = 0; i < elements.size(); i++) {
1093             if (!is<HTMLFormControlElement>(*elements[i]))
1094                 continue;
1095             HTMLFormControlElement& elt = downcast<HTMLFormControlElement>(*elements[i]);
1096             // Skip option elements, other duds
1097             if (elt.name() == targetName) {
1098                 *element = DOMElement::createInstance(&elt);
1099                 return S_OK;
1100             }
1101         }
1102     }
1103     return E_FAIL;
1104 }
1105
1106 HRESULT WebFrame::formForElement(IDOMElement* element, IDOMElement** form)
1107 {
1108     if (!element)
1109         return E_INVALIDARG;
1110
1111     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1112     if (!inputElement)
1113         return E_FAIL;
1114
1115     HTMLFormElement *formElement = inputElement->form();
1116     if (!formElement)
1117         return E_FAIL;
1118
1119     *form = DOMElement::createInstance(formElement);
1120     return S_OK;
1121 }
1122
1123 HRESULT WebFrame::elementDoesAutoComplete(_In_opt_ IDOMElement *element, _Out_ BOOL* result)
1124 {
1125     *result = false;
1126     if (!element)
1127         return E_INVALIDARG;
1128
1129     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1130     if (!inputElement)
1131         *result = false;
1132     else
1133         *result = inputElement->isTextField() && !inputElement->isPasswordField() && inputElement->shouldAutocomplete();
1134
1135     return S_OK;
1136 }
1137
1138 HRESULT WebFrame::resumeAnimations()
1139 {
1140     Frame* frame = core(this);
1141     if (!frame)
1142         return E_UNEXPECTED;
1143
1144     frame->animation().resumeAnimations();
1145     return S_OK;
1146 }
1147
1148 HRESULT WebFrame::suspendAnimations()
1149 {
1150     Frame* frame = core(this);
1151     if (!frame)
1152         return E_UNEXPECTED;
1153
1154     frame->animation().suspendAnimations();
1155     return S_OK;
1156 }
1157
1158 HRESULT WebFrame::pauseAnimation(_In_ BSTR animationName, _In_opt_ IDOMNode* node, double secondsFromNow, _Out_ BOOL* animationWasRunning)
1159 {
1160     if (!node || !animationWasRunning)
1161         return E_POINTER;
1162
1163     *animationWasRunning = FALSE;
1164
1165     Frame* frame = core(this);
1166     if (!frame)
1167         return E_UNEXPECTED;
1168
1169     COMPtr<DOMNode> domNode(Query, node);
1170     if (!domNode)
1171         return E_FAIL;
1172
1173     *animationWasRunning = frame->animation().pauseAnimationAtTime(downcast<RenderElement>(domNode->node()->renderer()), String(animationName, SysStringLen(animationName)), secondsFromNow);
1174     return S_OK;
1175 }
1176
1177 HRESULT WebFrame::pauseTransition(_In_ BSTR propertyName, _In_opt_ IDOMNode* node, double secondsFromNow, _Out_ BOOL* transitionWasRunning)
1178 {
1179     if (!node || !transitionWasRunning)
1180         return E_POINTER;
1181
1182     *transitionWasRunning = FALSE;
1183
1184     Frame* frame = core(this);
1185     if (!frame)
1186         return E_UNEXPECTED;
1187
1188     COMPtr<DOMNode> domNode(Query, node);
1189     if (!domNode)
1190         return E_FAIL;
1191
1192     *transitionWasRunning = frame->animation().pauseTransitionAtTime(downcast<RenderElement>(domNode->node()->renderer()), String(propertyName, SysStringLen(propertyName)), secondsFromNow);
1193     return S_OK;
1194 }
1195
1196 HRESULT WebFrame::visibleContentRect(_Out_ RECT* rect)
1197 {
1198     if (!rect)
1199         return E_POINTER;
1200     SetRectEmpty(rect);
1201
1202     Frame* frame = core(this);
1203     if (!frame)
1204         return E_UNEXPECTED;
1205
1206     FrameView* view = frame->view();
1207     if (!view)
1208         return E_FAIL;
1209
1210     *rect = view->visibleContentRect();
1211     return S_OK;
1212 }
1213
1214 HRESULT WebFrame::numberOfActiveAnimations(_Out_ UINT* number)
1215 {
1216     if (!number)
1217         return E_POINTER;
1218
1219     *number = 0;
1220
1221     Frame* frame = core(this);
1222     if (!frame)
1223         return E_UNEXPECTED;
1224
1225     *number = frame->animation().numberOfActiveAnimations(frame->document());
1226     return S_OK;
1227 }
1228
1229 HRESULT WebFrame::isDisplayingStandaloneImage(_Out_ BOOL* result)
1230 {
1231     if (!result)
1232         return E_POINTER;
1233
1234     *result = FALSE;
1235
1236     Frame* frame = core(this);
1237     if (!frame)
1238         return E_UNEXPECTED;
1239
1240     Document* document = frame->document();
1241     *result = document && document->isImageDocument();
1242     return S_OK;
1243 }
1244
1245 HRESULT WebFrame::allowsFollowingLink(_In_ BSTR url, _Out_ BOOL* result)
1246 {
1247     if (!result)
1248         return E_POINTER;
1249
1250     *result = TRUE;
1251
1252     Frame* frame = core(this);
1253     if (!frame)
1254         return E_UNEXPECTED;
1255
1256     *result = frame->document()->securityOrigin().canDisplay(MarshallingHelpers::BSTRToKURL(url));
1257     return S_OK;
1258 }
1259
1260 HRESULT WebFrame::controlsInForm(IDOMElement* form, IDOMElement** controls, int* cControls)
1261 {
1262     if (!form)
1263         return E_INVALIDARG;
1264
1265     HTMLFormElement* formElement = formElementFromDOMElement(form);
1266     if (!formElement)
1267         return E_FAIL;
1268
1269     int inCount = *cControls;
1270     int count = (int) formElement->associatedElements().size();
1271     *cControls = count;
1272     if (!controls)
1273         return S_OK;
1274     if (inCount < count)
1275         return E_FAIL;
1276
1277     *cControls = 0;
1278     const Vector<FormAssociatedElement*>& elements = formElement->associatedElements();
1279     for (int i = 0; i < count; i++) {
1280         if (elements.at(i)->isEnumeratable()) { // Skip option elements, other duds
1281             controls[*cControls] = DOMElement::createInstance(&elements.at(i)->asHTMLElement());
1282             (*cControls)++;
1283         }
1284     }
1285     return S_OK;
1286 }
1287
1288 HRESULT WebFrame::elementIsPassword(IDOMElement *element, bool *result)
1289 {
1290     HTMLInputElement* inputElement = inputElementFromDOMElement(element);
1291     *result = inputElement && inputElement->isPasswordField();
1292     return S_OK;
1293 }
1294
1295 HRESULT WebFrame::searchForLabelsBeforeElement(const BSTR* labels, unsigned cLabels, IDOMElement* beforeElement, unsigned* outResultDistance, BOOL* outResultIsInCellAbove, BSTR* result)
1296 {
1297     if (!result) {
1298         ASSERT_NOT_REACHED();
1299         return E_POINTER;
1300     }
1301
1302     if (outResultDistance)
1303         *outResultDistance = 0;
1304     if (outResultIsInCellAbove)
1305         *outResultIsInCellAbove = FALSE;
1306     *result = 0;
1307
1308     if (!cLabels)
1309         return S_OK;
1310     if (cLabels < 1)
1311         return E_INVALIDARG;
1312
1313     Frame* coreFrame = core(this);
1314     if (!coreFrame)
1315         return E_UNEXPECTED;
1316
1317     Vector<String> labelStrings(cLabels);
1318     for (int i=0; i<cLabels; i++)
1319         labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
1320     Element *coreElement = elementFromDOMElement(beforeElement);
1321     if (!coreElement)
1322         return E_FAIL;
1323
1324     size_t resultDistance;
1325     bool resultIsInCellAbove;
1326     String label = coreFrame->searchForLabelsBeforeElement(labelStrings, coreElement, &resultDistance, &resultIsInCellAbove);
1327     
1328     *result = BString(label).release();
1329     if (label.length() && !*result)
1330         return E_OUTOFMEMORY;
1331     if (outResultDistance)
1332         *outResultDistance = resultDistance;
1333     if (outResultIsInCellAbove)
1334         *outResultIsInCellAbove = resultIsInCellAbove;
1335
1336     return S_OK;
1337 }
1338
1339 HRESULT WebFrame::matchLabelsAgainstElement(const BSTR* labels, int cLabels, IDOMElement* againstElement, BSTR* result)
1340 {
1341     if (!result) {
1342         ASSERT_NOT_REACHED();
1343         return E_POINTER;
1344     }
1345
1346     *result = 0;
1347
1348     if (!cLabels)
1349         return S_OK;
1350     if (cLabels < 1)
1351         return E_INVALIDARG;
1352
1353     Frame* coreFrame = core(this);
1354     if (!coreFrame)
1355         return E_UNEXPECTED;
1356
1357     Vector<String> labelStrings(cLabels);
1358     for (int i=0; i<cLabels; i++)
1359         labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
1360     Element *coreElement = elementFromDOMElement(againstElement);
1361     if (!coreElement)
1362         return E_FAIL;
1363
1364     String label = coreFrame->matchLabelsAgainstElement(labelStrings, coreElement);
1365     
1366     *result = BString(label).release();
1367     if (label.length() && !*result)
1368         return E_OUTOFMEMORY;
1369     return S_OK;
1370 }
1371
1372 HRESULT WebFrame::canProvideDocumentSource(bool* result)
1373 {
1374     HRESULT hr = S_OK;
1375     *result = false;
1376
1377     COMPtr<IWebDataSource> dataSource;
1378     hr = WebFrame::dataSource(&dataSource);
1379     if (FAILED(hr))
1380         return hr;
1381
1382     COMPtr<IWebURLResponse> urlResponse;
1383     hr = dataSource->response(&urlResponse);
1384     if (SUCCEEDED(hr) && urlResponse) {
1385         BString mimeTypeBStr;
1386         if (SUCCEEDED(urlResponse->MIMEType(&mimeTypeBStr))) {
1387             String mimeType(mimeTypeBStr, SysStringLen(mimeTypeBStr));
1388             *result = mimeType == "text/html" || WebCore::MIMETypeRegistry::isXMLMIMEType(mimeType);
1389         }
1390     }
1391     return hr;
1392 }
1393
1394 HRESULT WebFrame::layerTreeAsText(_Deref_out_opt_ BSTR* result)
1395 {
1396     if (!result)
1397         return E_POINTER;
1398     *result = nullptr;
1399
1400     Frame* frame = core(this);
1401     if (!frame)
1402         return E_UNEXPECTED;
1403
1404     String text = frame->layerTreeAsText();
1405     *result = BString(text).release();
1406     return S_OK;
1407 }
1408
1409 void WebFrame::frameLoaderDestroyed()
1410 {
1411     // The FrameLoader going away is equivalent to the Frame going away,
1412     // so we now need to clear our frame pointer.
1413     d->frame = 0;
1414
1415     this->Release();
1416 }
1417
1418 static IntRect printerRect(HDC printDC)
1419 {
1420     return IntRect(0, 0, 
1421                    GetDeviceCaps(printDC, PHYSICALWIDTH)  - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETX),
1422                    GetDeviceCaps(printDC, PHYSICALHEIGHT) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETY));
1423 }
1424
1425 void WebFrame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSizeOrNot adjustViewSize)
1426 {
1427     Frame* coreFrame = core(this);
1428     ASSERT(coreFrame);
1429     coreFrame->setPrinting(printing, pageSize, originalPageSize, maximumShrinkRatio, adjustViewSize ? AdjustViewSize : DoNotAdjustViewSize);
1430 }
1431
1432 HRESULT WebFrame::setInPrintingMode(BOOL value, _In_ HDC printDC)
1433 {
1434     if (m_inPrintingMode == !!value)
1435         return S_OK;
1436
1437     Frame* coreFrame = core(this);
1438     if (!coreFrame)
1439         return E_UNEXPECTED;
1440
1441     if (!coreFrame->document())
1442         return E_FAIL;
1443
1444     m_inPrintingMode = !!value;
1445
1446     // If we are a frameset just print with the layout we have onscreen, otherwise relayout
1447     // according to the paper size
1448     FloatSize minLayoutSize(0.0, 0.0);
1449     FloatSize originalPageSize(0.0, 0.0);
1450     if (m_inPrintingMode && !coreFrame->document()->isFrameSet()) {
1451         if (!printDC) {
1452             ASSERT_NOT_REACHED();
1453             return E_POINTER;
1454         }
1455
1456         const int desiredPixelsPerInch = 72;
1457         IntRect printRect = printerRect(printDC);
1458         int paperHorizontalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSX);
1459         int paperVerticalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSY);
1460         int paperWidth = printRect.width() * desiredPixelsPerInch / paperHorizontalPixelsPerInch;
1461         int paperHeight = printRect.height() * desiredPixelsPerInch / paperVerticalPixelsPerInch;
1462         originalPageSize = FloatSize(paperWidth, paperHeight);
1463         Frame* coreFrame = core(this);
1464         minLayoutSize = coreFrame->resizePageRectsKeepingRatio(originalPageSize, FloatSize(paperWidth * PrintingMinimumShrinkFactor, paperHeight * PrintingMinimumShrinkFactor));
1465     }
1466
1467     setPrinting(m_inPrintingMode, minLayoutSize, originalPageSize, PrintingMaximumShrinkFactor / PrintingMinimumShrinkFactor, AdjustViewSize);
1468
1469     if (!m_inPrintingMode)
1470         m_pageRects.clear();
1471
1472     return S_OK;
1473 }
1474
1475 void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight)
1476 {
1477     if (headerHeight)
1478         *headerHeight = 0;
1479     if (footerHeight)
1480         *footerHeight = 0;
1481     float height = 0;
1482     COMPtr<IWebUIDelegate> ui;
1483     if (FAILED(d->webView->uiDelegate(&ui)))
1484         return;
1485     if (headerHeight && SUCCEEDED(ui->webViewHeaderHeight(d->webView, &height)))
1486         *headerHeight = height;
1487     if (footerHeight && SUCCEEDED(ui->webViewFooterHeight(d->webView, &height)))
1488         *footerHeight = height;
1489 }
1490
1491 IntRect WebFrame::printerMarginRect(HDC printDC)
1492 {
1493     IntRect emptyRect(0, 0, 0, 0);
1494
1495     COMPtr<IWebUIDelegate> ui;
1496     if (FAILED(d->webView->uiDelegate(&ui)))
1497         return emptyRect;
1498
1499     RECT rect;
1500     if (FAILED(ui->webViewPrintingMarginRect(d->webView, &rect)))
1501         return emptyRect;
1502
1503     rect.left = MulDiv(rect.left, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
1504     rect.top = MulDiv(rect.top, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
1505     rect.right = MulDiv(rect.right, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
1506     rect.bottom = MulDiv(rect.bottom, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
1507
1508     return IntRect(rect.left, rect.top, (rect.right - rect.left), rect.bottom - rect.top);
1509 }
1510
1511 const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC)
1512 {
1513     ASSERT(m_inPrintingMode);
1514     
1515     Frame* coreFrame = core(this);
1516     ASSERT(coreFrame);
1517     ASSERT(coreFrame->document());
1518
1519     if (!printDC)
1520         return m_pageRects;
1521
1522     // adjust the page rect by the header and footer
1523     float headerHeight = 0, footerHeight = 0;
1524     headerAndFooterHeights(&headerHeight, &footerHeight);
1525     IntRect pageRect = printerRect(printDC);
1526     IntRect marginRect = printerMarginRect(printDC);
1527     IntRect adjustedRect = IntRect(
1528         pageRect.x() + marginRect.x(),
1529         pageRect.y() + marginRect.y(),
1530         pageRect.width() - marginRect.x() - marginRect.maxX(),
1531         pageRect.height() - marginRect.y() - marginRect.maxY());
1532
1533     computePageRectsForFrame(coreFrame, adjustedRect, headerHeight, footerHeight, 1.0,m_pageRects, m_pageHeight);
1534     
1535     return m_pageRects;
1536 }
1537
1538 HRESULT WebFrame::getPrintedPageCount(_In_ HDC printDC, _Out_ UINT *pageCount)
1539 {
1540     if (!pageCount || !printDC) {
1541         ASSERT_NOT_REACHED();
1542         return E_POINTER;
1543     }
1544
1545     *pageCount = 0;
1546
1547     if (!m_inPrintingMode) {
1548         ASSERT_NOT_REACHED();
1549         return E_FAIL;
1550     }
1551
1552     Frame* coreFrame = core(this);
1553     if (!coreFrame)
1554         return E_UNEXPECTED;
1555
1556     if (!coreFrame->document())
1557         return E_FAIL;
1558
1559     const Vector<IntRect>& pages = computePageRects(printDC);
1560     *pageCount = (UINT) pages.size();
1561     
1562     return S_OK;
1563 }
1564
1565 #if USE(CG)
1566 void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
1567 {
1568     int x = pageRect.x();
1569     int y = 0;
1570     RECT headerRect = {x, y, x+pageRect.width(), y+static_cast<int>(headerHeight)};
1571     ui->drawHeaderInRect(d->webView, &headerRect, reinterpret_cast<ULONG_PTR>(pctx));
1572 }
1573
1574 void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight)
1575 {
1576     int x = pageRect.x();
1577     int y = max((int)headerHeight+pageRect.height(), m_pageHeight-static_cast<int>(footerHeight));
1578     RECT footerRect = {x, y, x+pageRect.width(), y+static_cast<int>(footerHeight)};
1579     ui->drawFooterInRect(d->webView, &footerRect, reinterpret_cast<ULONG_PTR>(pctx), page + 1, pageCount);
1580 }
1581
1582 void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext& spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount)
1583 {
1584     Frame* coreFrame = core(this);
1585
1586     IntRect pageRect = m_pageRects[page];
1587
1588     CGContextSaveGState(pctx);
1589
1590     IntRect printRect = printerRect(printDC);
1591     CGRect mediaBox = CGRectMake(CGFloat(0),
1592                                  CGFloat(0),
1593                                  CGFloat(printRect.width()),
1594                                  CGFloat(printRect.height()));
1595
1596     CGContextBeginPage(pctx, &mediaBox);
1597
1598     CGFloat scale = static_cast<float>(mediaBox.size.width)/static_cast<float>(pageRect.width());
1599     CGAffineTransform ctm = CGContextGetBaseCTM(pctx);
1600     ctm = CGAffineTransformScale(ctm, -scale, -scale);
1601     ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header
1602     CGContextScaleCTM(pctx, scale, scale);
1603     CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight));   // reserves space for header
1604     CGContextSetBaseCTM(pctx, ctm);
1605
1606     coreFrame->view()->paintContents(spoolCtx, pageRect);
1607
1608     CGContextTranslateCTM(pctx, CGFloat(pageRect.x()), CGFloat(pageRect.y())-headerHeight);
1609
1610     if (headerHeight)
1611         drawHeader(pctx, ui, pageRect, headerHeight);
1612
1613     if (footerHeight)
1614         drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight);
1615
1616     CGContextEndPage(pctx);
1617     CGContextRestoreGState(pctx);
1618 }
1619 #elif USE(CAIRO)
1620 static float scaleFactor(HDC printDC, const IntRect& marginRect, const IntRect& pageRect)
1621 {
1622     const IntRect& printRect = printerRect(printDC);
1623
1624     IntRect adjustedRect = IntRect(
1625         printRect.x() + marginRect.x(),
1626         printRect.y() + marginRect.y(),
1627         printRect.width() - marginRect.x() - marginRect.maxX(),
1628         printRect.height() - marginRect.y() - marginRect.maxY());
1629
1630     float scale = static_cast<float>(adjustedRect.width()) / static_cast<float>(pageRect.width());
1631     if (!scale)
1632        scale = 1.0;
1633
1634     return scale;
1635 }
1636
1637 static HDC hdcFromContext(PlatformGraphicsContext* pctx)
1638 {
1639     return cairo_win32_surface_get_dc(cairo_get_target(pctx->cr()));
1640 }
1641
1642 void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
1643 {
1644     HDC hdc = hdcFromContext(pctx);
1645
1646     int x = pageRect.x();
1647     int y = 0;
1648     RECT headerRect = {x, y, x + pageRect.width(), y + static_cast<int>(headerHeight)};
1649
1650     ui->drawHeaderInRect(d->webView, &headerRect, reinterpret_cast<ULONG_PTR>(hdc));
1651 }
1652
1653 void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight)
1654 {
1655     HDC hdc = hdcFromContext(pctx);
1656     
1657     int x = pageRect.x();
1658     int y = max(static_cast<int>(headerHeight) + pageRect.height(), m_pageHeight  -static_cast<int>(footerHeight));
1659     RECT footerRect = {x, y, x + pageRect.width(), y + static_cast<int>(footerHeight)};
1660
1661     ui->drawFooterInRect(d->webView, &footerRect, reinterpret_cast<ULONG_PTR>(hdc), page+1, pageCount);
1662 }
1663
1664 static XFORM buildXFORMFromCairo(HDC targetDC, cairo_t* previewContext)
1665 {
1666     XFORM scaled;
1667     GetWorldTransform(targetDC, &scaled);
1668
1669     cairo_matrix_t ctm;
1670     cairo_get_matrix(previewContext, &ctm);    
1671         
1672     // Scale to the preview screen bounds
1673     scaled.eM11 = ctm.xx;
1674     scaled.eM22 = ctm.yy;
1675
1676     return scaled;
1677 }
1678
1679 void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext& spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount)
1680 {
1681     Frame* coreFrame = core(this);
1682
1683     const IntRect& pageRect = m_pageRects[page];
1684     const IntRect& marginRect = printerMarginRect(printDC);
1685
1686     // In preview, the printDC is a placeholder, so just always use the HDC backing the graphics context.
1687     HDC hdc = hdcFromContext(pctx);
1688
1689     spoolCtx.save();
1690     
1691     XFORM original, scaled;
1692     GetWorldTransform(hdc, &original);
1693     
1694     cairo_t* cr = pctx->cr();
1695     bool preview = (hdc != printDC);
1696     if (preview) {
1697         // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo will
1698         // draw correctly.  We need to retain the correct preview scale here for use when the Cairo
1699         // drawing completes so that we can scale our GDI-based header/footer calls. This is a
1700         // workaround for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
1701         scaled = buildXFORMFromCairo(hdc, cr);
1702     }
1703
1704     float scale = scaleFactor(printDC, marginRect, pageRect);
1705     
1706     IntRect cairoMarginRect(marginRect);
1707     cairoMarginRect.scale(1 / scale);
1708
1709     // We cannot scale the display HDC because the print surface also scales fonts,
1710     // resulting in invalid printing (and print preview)
1711     cairo_scale(cr, scale, scale);
1712     cairo_translate(cr, cairoMarginRect.x(), cairoMarginRect.y() + headerHeight);
1713
1714     // Modify Cairo (only) to account for page position.
1715     cairo_translate(cr, -pageRect.x(), -pageRect.y());
1716     coreFrame->view()->paintContents(spoolCtx, pageRect);
1717     cairo_translate(cr, pageRect.x(), pageRect.y());
1718     
1719     if (preview) {
1720         // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo would
1721         // draw correctly.  We need to rescale the HDC to the correct preview scale so our GDI-based
1722         // header/footer calls will draw properly.  This is a workaround for a bug in Cairo.
1723         // (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
1724         SetWorldTransform(hdc, &scaled);
1725     }
1726     
1727     XFORM xform = TransformationMatrix().translate(marginRect.x(), marginRect.y()).scale(scale);
1728     ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
1729    
1730     if (headerHeight)
1731         drawHeader(pctx, ui, pageRect, headerHeight);
1732     
1733     if (footerHeight)
1734         drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight);
1735
1736     SetWorldTransform(hdc, &original);
1737
1738     cairo_show_page(cr);
1739     ASSERT(!cairo_status(cr));
1740     spoolCtx.restore();
1741 }
1742
1743 static void setCairoTransformToPreviewHDC(cairo_t* previewCtx, HDC previewDC)
1744 {
1745     XFORM passedCTM;
1746     GetWorldTransform(previewDC, &passedCTM);
1747
1748     // Reset HDC WorldTransform to unscaled state.  Scaling must be
1749     // done in Cairo to avoid drawing errors.
1750     XFORM unscaledCTM = passedCTM;
1751     unscaledCTM.eM11 = 1.0;
1752     unscaledCTM.eM22 = 1.0;
1753         
1754     SetWorldTransform(previewDC, &unscaledCTM);
1755
1756     // Make the Cairo transform match the information passed to WebKit
1757     // in the HDC's WorldTransform.
1758     cairo_matrix_t ctm = { passedCTM.eM11, passedCTM.eM12, passedCTM.eM21,
1759                            passedCTM.eM22, passedCTM.eDx, passedCTM.eDy };
1760
1761     cairo_set_matrix(previewCtx, &ctm);    
1762 }
1763
1764 #endif
1765
1766 HRESULT WebFrame::spoolPages(HDC printDC, UINT startPage, UINT endPage, void* ctx)
1767 {
1768 #if USE(CG)
1769     if (!printDC || !ctx) {
1770         ASSERT_NOT_REACHED();
1771         return E_POINTER;
1772     }
1773 #elif USE(CAIRO)
1774     if (!printDC) {
1775         ASSERT_NOT_REACHED();
1776         return E_POINTER;
1777     }
1778     
1779     HDC targetDC = (ctx) ? (HDC)ctx : printDC;
1780
1781     cairo_surface_t* printSurface = 0;
1782     if (ctx)
1783         printSurface = cairo_win32_surface_create(targetDC); // in-memory
1784     else
1785         printSurface = cairo_win32_printing_surface_create(targetDC); // metafile
1786     
1787     cairo_t* cr = cairo_create(printSurface);
1788     if (!cr) {
1789         cairo_surface_destroy(printSurface);    
1790         return E_FAIL;
1791     }
1792
1793     PlatformContextCairo platformContext(cr);
1794     PlatformGraphicsContext* pctx = &platformContext;
1795     cairo_destroy(cr);
1796
1797     if (ctx) {
1798         // If this is a preview, the Windows HDC was sent with scaling information.
1799         // Retrieve it and reset it so that it draws properly.  This is a workaround
1800         // for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
1801         setCairoTransformToPreviewHDC(cr, targetDC);
1802     }
1803     
1804     cairo_surface_set_fallback_resolution(printSurface, 72.0, 72.0);
1805 #endif
1806
1807     if (!m_inPrintingMode) {
1808         ASSERT_NOT_REACHED();
1809         return E_FAIL;
1810     }
1811
1812     Frame* coreFrame = core(this);
1813     if (!coreFrame)
1814         return E_UNEXPECTED;
1815
1816     if (!coreFrame->document())
1817         return E_FAIL;
1818
1819     UINT pageCount = (UINT) m_pageRects.size();
1820 #if USE(CG)
1821     PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx;
1822 #endif
1823
1824     if (!pageCount || startPage > pageCount) {
1825         ASSERT_NOT_REACHED();
1826         return E_FAIL;
1827     }
1828
1829     if (startPage > 0)
1830         startPage--;
1831
1832     if (endPage == 0)
1833         endPage = pageCount;
1834
1835     COMPtr<IWebUIDelegate> ui;
1836     if (FAILED(d->webView->uiDelegate(&ui)))
1837         return E_FAIL;
1838
1839     float headerHeight = 0, footerHeight = 0;
1840     headerAndFooterHeights(&headerHeight, &footerHeight);
1841 #if USE(CG) || USE(CAIRO)
1842     GraphicsContext spoolCtx(pctx);
1843     spoolCtx.setShouldIncludeChildWindows(true);
1844
1845     for (UINT ii = startPage; ii < endPage; ii++)
1846         spoolPage(pctx, spoolCtx, printDC, ui.get(), headerHeight, footerHeight, ii, pageCount);
1847 #endif
1848
1849 #if USE(CAIRO)
1850     cairo_surface_finish(printSurface);
1851     ASSERT(!cairo_surface_status(printSurface));
1852     cairo_surface_destroy(printSurface);
1853 #endif
1854
1855     return S_OK;
1856 }
1857
1858 HRESULT WebFrame::isFrameSet(_Out_ BOOL* result)
1859 {
1860     if (!result)
1861         return E_POINTER;
1862
1863     *result = FALSE;
1864
1865     Frame* coreFrame = core(this);
1866     if (!coreFrame)
1867         return E_UNEXPECTED;
1868
1869     if (!coreFrame->document())
1870         return E_FAIL;
1871
1872     *result = coreFrame->document()->isFrameSet() ? TRUE : FALSE;
1873     return S_OK;
1874 }
1875
1876 HRESULT WebFrame::string(_Deref_opt_out_ BSTR* result)
1877 {
1878     if (!result)
1879         return E_POINTER;
1880
1881     *result = nullptr;
1882
1883     Frame* coreFrame = core(this);
1884     if (!coreFrame)
1885         return E_UNEXPECTED;
1886
1887     RefPtr<Range> allRange(rangeOfContents(*coreFrame->document()));
1888     String allString = plainText(allRange.get());
1889     *result = BString(allString).release();
1890     return S_OK;
1891 }
1892
1893 HRESULT WebFrame::size(_Out_ SIZE* size)
1894 {
1895     if (!size)
1896         return E_POINTER;
1897     size->cx = size->cy = 0;
1898
1899     Frame* coreFrame = core(this);
1900     if (!coreFrame)
1901         return E_UNEXPECTED;
1902     FrameView* view = coreFrame->view();
1903     if (!view)
1904         return E_FAIL;
1905     size->cx = view->width();
1906     size->cy = view->height();
1907     return S_OK;
1908 }
1909
1910 HRESULT WebFrame::hasScrollBars(_Out_ BOOL* result)
1911 {
1912     if (!result)
1913         return E_POINTER;
1914     *result = FALSE;
1915
1916     Frame* coreFrame = core(this);
1917     if (!coreFrame)
1918         return E_UNEXPECTED;
1919
1920     FrameView* view = coreFrame->view();
1921     if (!view)
1922         return E_FAIL;
1923
1924     if (view->horizontalScrollbar() || view->verticalScrollbar())
1925         *result = TRUE;
1926
1927     return S_OK;
1928 }
1929
1930 HRESULT WebFrame::contentBounds(_Out_ RECT* result)
1931 {
1932     if (!result)
1933         return E_POINTER;
1934     ::SetRectEmpty(result);
1935
1936     Frame* coreFrame = core(this);
1937     if (!coreFrame)
1938         return E_UNEXPECTED;
1939
1940     FrameView* view = coreFrame->view();
1941     if (!view)
1942         return E_FAIL;
1943
1944     result->bottom = view->contentsHeight();
1945     result->right = view->contentsWidth();
1946     return S_OK;
1947 }
1948
1949 HRESULT WebFrame::frameBounds(_Out_ RECT* result)
1950 {
1951     if (!result)
1952         return E_POINTER;
1953     ::SetRectEmpty(result);
1954
1955     Frame* coreFrame = core(this);
1956     if (!coreFrame)
1957         return E_UNEXPECTED;
1958
1959     FrameView* view = coreFrame->view();
1960     if (!view)
1961         return E_FAIL;
1962
1963     FloatRect bounds = view->visibleContentRectIncludingScrollbars();
1964     result->bottom = (LONG) bounds.height();
1965     result->right = (LONG) bounds.width();
1966     return S_OK;
1967 }
1968
1969 HRESULT WebFrame::isDescendantOfFrame(_In_opt_ IWebFrame* ancestor, _Out_ BOOL* result)
1970 {
1971     if (!result)
1972         return E_POINTER;
1973     *result = FALSE;
1974
1975     Frame* coreFrame = core(this);
1976     COMPtr<WebFrame> ancestorWebFrame(Query, ancestor);
1977     if (!ancestorWebFrame)
1978         return S_OK;
1979
1980     *result = (coreFrame && coreFrame->tree().isDescendantOf(core(ancestorWebFrame.get()))) ? TRUE : FALSE;
1981     return S_OK;
1982 }
1983
1984 HRESULT WebFrame::stringByEvaluatingJavaScriptInScriptWorld(IWebScriptWorld* iWorld, JSObjectRef globalObjectRef, BSTR script, BSTR* evaluationResult)
1985 {
1986     if (!evaluationResult)
1987         return E_POINTER;
1988     *evaluationResult = 0;
1989
1990     if (!iWorld)
1991         return E_POINTER;
1992
1993     COMPtr<WebScriptWorld> world(Query, iWorld);
1994     if (!world)
1995         return E_INVALIDARG;
1996
1997     Frame* coreFrame = core(this);
1998     String string = String(script, SysStringLen(script));
1999
2000     // Start off with some guess at a frame and a global object, we'll try to do better...!
2001     JSDOMWindow* anyWorldGlobalObject = coreFrame->script().globalObject(mainThreadNormalWorld());
2002
2003     // The global object is probably a shell object? - if so, we know how to use this!
2004     JSC::JSObject* globalObjectObj = toJS(globalObjectRef);
2005     if (!strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell"))
2006         anyWorldGlobalObject = static_cast<JSDOMWindowShell*>(globalObjectObj)->window();
2007
2008     // Get the frame frome the global object we've settled on.
2009     Frame* frame = anyWorldGlobalObject->wrapped().frame();
2010     ASSERT(frame->document());
2011     JSValue result = frame->script().executeScriptInWorld(world->world(), string, true);
2012
2013     if (!frame) // In case the script removed our frame from the page.
2014         return S_OK;
2015
2016     // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
2017     // If you don't like it, use -[WebScriptObject evaluateWebScript:] or 
2018     // JSEvaluateScript instead, since they have less surprising semantics.
2019     if (!result || !result.isBoolean() && !result.isString() && !result.isNumber())
2020         return S_OK;
2021
2022     JSC::ExecState* exec = anyWorldGlobalObject->globalExec();
2023     JSC::JSLockHolder lock(exec);
2024     String resultString = result.toWTFString(exec);
2025     *evaluationResult = BString(resultString).release();
2026
2027     return S_OK;
2028 }
2029
2030 void WebFrame::unmarkAllMisspellings()
2031 {
2032     Frame* coreFrame = core(this);
2033     for (Frame* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
2034         Document *doc = frame->document();
2035         if (!doc)
2036             return;
2037
2038         doc->markers().removeMarkers(DocumentMarker::Spelling);
2039     }
2040 }
2041
2042 void WebFrame::unmarkAllBadGrammar()
2043 {
2044     Frame* coreFrame = core(this);
2045     for (Frame* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
2046         Document *doc = frame->document();
2047         if (!doc)
2048             return;
2049
2050         doc->markers().removeMarkers(DocumentMarker::Grammar);
2051     }
2052 }
2053
2054 WebView* WebFrame::webView() const
2055 {
2056     return d->webView;
2057 }
2058
2059 void WebFrame::setWebView(WebView* webView)
2060 {
2061     d->webView = webView;
2062 }
2063
2064 COMPtr<IAccessible> WebFrame::accessible() const
2065 {
2066     Frame* coreFrame = core(this);
2067     ASSERT(coreFrame);
2068
2069     Document* currentDocument = coreFrame->document();
2070     if (!currentDocument)
2071         m_accessible = 0;
2072     else if (!m_accessible || m_accessible->document() != currentDocument) {
2073         // Either we've never had a wrapper for this frame's top-level Document,
2074         // the Document renderer was destroyed and its wrapper was detached, or
2075         // the previous Document is in the page cache, and the current document
2076         // needs to be wrapped.
2077         m_accessible = new AccessibleDocument(currentDocument, webView()->viewWindow());
2078     }
2079     return m_accessible.get();
2080 }
2081
2082 void WebFrame::updateBackground()
2083 {
2084     Color backgroundColor = webView()->transparent() ? Color::transparent : Color::white;
2085     Frame* coreFrame = core(this);
2086
2087     if (!coreFrame || !coreFrame->view())
2088         return;
2089
2090     coreFrame->view()->updateBackgroundRecursively(backgroundColor, webView()->transparent());
2091 }
2092
2093 // IWebFrame2
2094 HRESULT WebFrame::isMainFrame(_Out_ BOOL* value)
2095 {
2096     if (!value)
2097         return E_POINTER;
2098
2099     Frame* coreFrame = core(this);
2100     *value = coreFrame->isMainFrame();
2101
2102     return S_OK;
2103 }