/*
 * Copyright (C) 2006-2009, 2011, 2013-2015 Apple Inc. All rights reserved.
 * Copyright (C) Research In Motion Limited 2009. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#include "WebKitDLL.h"
#include "WebFrame.h"

#include "CFDictionaryPropertyBag.h"
#include "COMPropertyBag.h"
#include "DOMCoreClasses.h"
#include "MarshallingHelpers.h"
#include "WebActionPropertyBag.h"
#include "WebChromeClient.h"
#include "WebDataSource.h"
#include "WebDocumentLoader.h"
#include "WebDownload.h"
#include "WebEditorClient.h"
#include "WebError.h"
#include "WebFrameLoaderClient.h"
#include "WebFramePolicyListener.h"
#include "WebHistory.h"
#include "WebHistoryItem.h"
#include "WebKit.h"
#include "WebKitStatisticsPrivate.h"
#include "WebMutableURLRequest.h"
#include "WebNotificationCenter.h"
#include "WebScriptWorld.h"
#include "WebURLResponse.h"
#include "WebView.h"
#include <JavaScriptCore/APICast.h>
#include <JavaScriptCore/HeapInlines.h>
#include <JavaScriptCore/JSCJSValue.h>
#include <JavaScriptCore/JSLock.h>
#include <JavaScriptCore/JSObject.h>
#include <WebCore/BString.h>
#include <WebCore/COMPtr.h>
#include <WebCore/DOMWindow.h>
#include <WebCore/Document.h>
#include <WebCore/DocumentLoader.h>
#include <WebCore/DocumentMarkerController.h>
#include <WebCore/Editor.h>
#include <WebCore/Event.h>
#include <WebCore/EventHandler.h>
#include <WebCore/FormState.h>
#include <WebCore/Frame.h>
#include <WebCore/FrameLoadRequest.h>
#include <WebCore/FrameLoader.h>
#include <WebCore/FrameTree.h>
#include <WebCore/FrameView.h>
#include <WebCore/FrameWin.h>
#include <WebCore/GDIObjectCounter.h>
#include <WebCore/GraphicsContext.h>
#include <WebCore/GraphicsContextWin.h>
#include <WebCore/HTMLFormControlElement.h>
#include <WebCore/HTMLFormElement.h>
#include <WebCore/HTMLFrameOwnerElement.h>
#include <WebCore/HTMLInputElement.h>
#include <WebCore/HTMLNames.h>
#include <WebCore/HTMLPlugInElement.h>
#include <WebCore/HistoryItem.h>
#include <WebCore/JSDOMBinding.h>
#include <WebCore/JSDOMWindow.h>
#include <WebCore/KeyboardEvent.h>
#include <WebCore/MIMETypeRegistry.h>
#include <WebCore/MemoryCache.h>
#include <WebCore/MouseRelatedEvent.h>
#include <WebCore/NotImplemented.h>
#include <WebCore/Page.h>
#include <WebCore/PlatformKeyboardEvent.h>
#include <WebCore/PluginData.h>
#include <WebCore/PolicyChecker.h>
#include <WebCore/PrintContext.h>
#include <WebCore/RenderLayerCompositor.h>
#include <WebCore/RenderTreeAsText.h>
#include <WebCore/RenderView.h>
#include <WebCore/ResourceHandle.h>
#include <WebCore/ResourceLoader.h>
#include <WebCore/ResourceRequest.h>
#include <WebCore/ScriptController.h>
#include <WebCore/SecurityOrigin.h>
#include <WebCore/Settings.h>
#include <WebCore/TextIterator.h>
#include <wtf/MathExtras.h>

#if USE(CG)
#include <CoreGraphics/CoreGraphics.h>
#elif USE(CAIRO)
#include <WebCore/GraphicsContextCairo.h>
#include <cairo-win32.h>
#endif

#if USE(CG)
// CG SPI used for printing
extern "C" {
    CGAffineTransform CGContextGetBaseCTM(CGContextRef c); 
    void CGContextSetBaseCTM(CGContextRef c, CGAffineTransform m); 
}
#endif

using namespace WebCore;
using namespace HTMLNames;

using JSC::JSGlobalObject;
using JSC::JSLock;
using JSC::JSValue;

#define FLASH_REDRAW 0


// By imaging to a width a little wider than the available pixels,
// thin pages will be scaled down a little, matching the way they
// print in IE and Camino. This lets them use fewer sheets than they
// would otherwise, which is presumably why other browsers do this.
// Wide pages will be scaled down more than this.
const float PrintingMinimumShrinkFactor = 1.25f;

// This number determines how small we are willing to reduce the page content
// in order to accommodate the widest line. If the page would have to be
// reduced smaller to make the widest line fit, we just clip instead (this
// behavior matches MacIE and Mozilla, at least)
const float PrintingMaximumShrinkFactor = 2.0f;

//-----------------------------------------------------------------------------
// Helpers to convert from WebCore to WebKit type
WebFrame* kit(Frame* frame)
{
    if (!frame)
        return nullptr;

    // FIXME: Doesn't this need to be aware of EmptyFrameLoaderClient?
    FrameLoaderClient& frameLoaderClient = frame->loader().client();
    return static_cast<WebFrameLoaderClient&>(frameLoaderClient).webFrame();
}

Frame* core(WebFrame* webFrame)
{
    if (!webFrame)
        return nullptr;
    return webFrame->impl();
}

// 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
Frame* core(const WebFrame* webFrame)
{
    if (!webFrame)
        return nullptr;
    return const_cast<WebFrame*>(webFrame)->impl();
}

//-----------------------------------------------------------------------------

static Element* elementFromDOMElement(IDOMElement* element)
{
    if (!element)
        return nullptr;

    COMPtr<IDOMElementPrivate> elePriv;
    HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
    if (SUCCEEDED(hr)) {
        Element* ele;
        hr = elePriv->coreElement((void**)&ele);
        if (SUCCEEDED(hr))
            return ele;
    }
    return 0;
}

static HTMLFormElement *formElementFromDOMElement(IDOMElement *element)
{
    if (!element)
        return nullptr;

    IDOMElementPrivate* elePriv;
    HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
    if (SUCCEEDED(hr)) {
        Element* ele;
        hr = elePriv->coreElement((void**)&ele);
        elePriv->Release();
        if (SUCCEEDED(hr) && is<HTMLFormElement>(ele))
            return downcast<HTMLFormElement>(ele);
    }
    return nullptr;
}

static HTMLInputElement* inputElementFromDOMElement(IDOMElement* element)
{
    if (!element)
        return nullptr;

    IDOMElementPrivate* elePriv;
    HRESULT hr = element->QueryInterface(IID_IDOMElementPrivate, (void**) &elePriv);
    if (SUCCEEDED(hr)) {
        Element* ele;
        hr = elePriv->coreElement((void**)&ele);
        elePriv->Release();
        if (SUCCEEDED(hr) && is<HTMLInputElement>(ele))
            return downcast<HTMLInputElement>(ele);
    }
    return nullptr;
}

// WebFramePrivate ------------------------------------------------------------

class WebFrame::WebFramePrivate {
public:
    WebFramePrivate() 
    {
    }

    ~WebFramePrivate() { }
    FrameView* frameView() { return frame ? frame->view() : nullptr; }

    Frame* frame { nullptr };
    WebView* webView { nullptr };
};

// WebFrame ----------------------------------------------------------------

WebFrame::WebFrame()
    : d(new WebFrame::WebFramePrivate)
{
    WebFrameCount++;
    gClassCount++;
    gClassNameCount().add("WebFrame"_s);
}

WebFrame::~WebFrame()
{
    delete d;
    WebFrameCount--;
    gClassCount--;
    gClassNameCount().remove("WebFrame"_s);
}

WebFrame* WebFrame::createInstance()
{
    WebFrame* instance = new WebFrame();
    instance->AddRef();
    return instance;
}

HRESULT WebFrame::setAllowsScrolling(BOOL flag)
{
    if (Frame* frame = core(this))
        if (FrameView* view = frame->view())
            view->setCanHaveScrollbars(!!flag);

    return S_OK;
}

HRESULT WebFrame::allowsScrolling(_Out_ BOOL* flag)
{
    if (!flag)
        return E_POINTER;

    *flag = FALSE;

    if (Frame* frame = core(this)) {
        if (FrameView* view = frame->view())
            *flag = view->canHaveScrollbars();
    }

    return S_OK;
}

HRESULT WebFrame::setIsDisconnected(BOOL flag)
{
    ASSERT_NOT_REACHED();
    return E_FAIL;
}

HRESULT WebFrame::setExcludeFromTextSearch(BOOL flag)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

HRESULT WebFrame::reloadFromOrigin()
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    coreFrame->loader().reload(WebCore::ReloadOption::FromOrigin);
    return S_OK;
}

HRESULT WebFrame::paintDocumentRectToContext(RECT rect, _In_ HDC deviceContext)
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    FrameView* view = coreFrame->view();
    if (!view)
        return E_FAIL;

    // We can't paint with a layout still pending.
    view->updateLayoutAndStyleIfNeededRecursive();

    GraphicsContextWin gc(deviceContext);
    gc.save();
    LONG width = rect.right - rect.left;
    LONG height = rect.bottom - rect.top;
    FloatRect dirtyRect;
    dirtyRect.setWidth(width);
    dirtyRect.setHeight(height);
    gc.clip(dirtyRect);
    gc.translate(-rect.left, -rect.top);
    float scaleFactor = webView()->deviceScaleFactor();
    gc.scale(WebCore::FloatSize(scaleFactor, scaleFactor));
    view->paintContents(gc, rect);
    gc.restore();

    return S_OK;
}

HRESULT WebFrame::paintScrollViewRectToContextAtPoint(RECT rect, POINT pt, _In_ HDC deviceContext)
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    FrameView* view = coreFrame->view();
    if (!view)
        return E_FAIL;

    // We can't paint with a layout still pending.
    view->updateLayoutAndStyleIfNeededRecursive();

    GraphicsContextWin gc(deviceContext);
    gc.save();
    IntRect dirtyRect(rect);
    dirtyRect.move(-pt.x, -pt.y);
    float scaleFactor = webView()->deviceScaleFactor();
    gc.scale(WebCore::FloatSize(scaleFactor, scaleFactor));
    view->paint(gc, dirtyRect);
    gc.restore();

    return S_OK;
}

// IUnknown -------------------------------------------------------------------

HRESULT WebFrame::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, __uuidof(WebFrame)))
        *ppvObject = this;
    else if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IWebFrame2*>(this);
    else if (IsEqualGUID(riid, IID_IWebFrame))
        *ppvObject = static_cast<IWebFrame2*>(this);
    else if (IsEqualGUID(riid, IID_IWebFrame2))
        *ppvObject = static_cast<IWebFrame2*>(this);
    else if (IsEqualGUID(riid, IID_IWebFramePrivate))
        *ppvObject = static_cast<IWebFramePrivate*>(this);
    else if (IsEqualGUID(riid, IID_IWebDocumentText))
        *ppvObject = static_cast<IWebDocumentText*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

ULONG WebFrame::AddRef()
{
    return ++m_refCount;
}

ULONG WebFrame::Release()
{
    ULONG newRef = --m_refCount;
    if (!newRef)
        delete(this);

    return newRef;
}

// IWebFrame -------------------------------------------------------------------

HRESULT WebFrame::name(_Deref_opt_out_ BSTR* frameName)
{
    if (!frameName) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *frameName = nullptr;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    *frameName = BString(coreFrame->tree().uniqueName()).release();
    return S_OK;
}

HRESULT WebFrame::webView(_COM_Outptr_opt_ IWebView** view)
{
    if (!view)
        return E_POINTER;
    *view = nullptr;
    if (!d->webView)
        return E_FAIL;
    *view = d->webView;
    (*view)->AddRef();
    return S_OK;
}

HRESULT WebFrame::frameView(_COM_Outptr_opt_ IWebFrameView** view)
{
    ASSERT_NOT_REACHED();
    if (!view)
        return E_POINTER;
    *view = nullptr;
    return E_NOTIMPL;
}

HRESULT WebFrame::DOMDocument(_COM_Outptr_opt_ IDOMDocument** result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *result = nullptr;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    if (Document* document = coreFrame->document())
        *result = DOMDocument::createInstance(document);

    return *result ? S_OK : E_FAIL;
}


HRESULT WebFrame::DOMWindow(_COM_Outptr_opt_ IDOMWindow** window)
{
    if (!window) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *window = nullptr;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    if (WebCore::DOMWindow* coreWindow = coreFrame->document()->domWindow())
        *window = ::DOMWindow::createInstance(coreWindow);

    return *window ? S_OK : E_FAIL;
}

HRESULT WebFrame::frameElement(_COM_Outptr_opt_ IDOMHTMLElement** frameElement)
{
    if (!frameElement)
        return E_POINTER;

    *frameElement = nullptr;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    COMPtr<IDOMElement> domElement(AdoptCOM, DOMElement::createInstance(coreFrame->ownerElement()));
    COMPtr<IDOMHTMLElement> htmlElement(Query, domElement);
    if (!htmlElement)
        return E_FAIL;
    return htmlElement.copyRefTo(frameElement);
}

HRESULT WebFrame::currentForm(_COM_Outptr_opt_ IDOMElement** currentForm)
{
    if (!currentForm) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *currentForm = nullptr;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    if (HTMLFormElement* formElement = coreFrame->selection().currentForm())
        *currentForm = DOMElement::createInstance(formElement);

    return *currentForm ? S_OK : E_FAIL;
}

JSGlobalContextRef WebFrame::globalContext()
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return nullptr;

    return toGlobalRef(coreFrame->script().globalObject(mainThreadNormalWorld()));
}

JSGlobalContextRef WebFrame::globalContextForScriptWorld(IWebScriptWorld* iWorld)
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return 0;

    COMPtr<WebScriptWorld> world(Query, iWorld);
    if (!world)
        return 0;

    return toGlobalRef(coreFrame->script().globalObject(world->world()));
}

HRESULT WebFrame::loadRequest(_In_opt_ IWebURLRequest* request)
{
    if (!request)
        return S_OK;

    COMPtr<WebMutableURLRequest> requestImpl;

    HRESULT hr = request->QueryInterface(&requestImpl);
    if (FAILED(hr))
        return hr;
 
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    coreFrame->loader().load(FrameLoadRequest(*coreFrame, requestImpl->resourceRequest()));
    return S_OK;
}

void WebFrame::loadData(Ref<WebCore::FragmentedSharedBuffer>&& data, BSTR mimeType, BSTR textEncodingName, BSTR baseURL, BSTR failingURL)
{
    String mimeTypeString(mimeType, SysStringLen(mimeType));
    if (!mimeType)
        mimeTypeString = "text/html"_s;

    String encodingString(textEncodingName, SysStringLen(textEncodingName));

    // FIXME: We should really be using MarshallingHelpers::BSTRToKURL here,
    // but that would turn a null BSTR into a null URL, and we crash inside of
    // WebCore if we use a null URL in constructing the ResourceRequest.
    URL baseCoreURL { String(baseURL ? baseURL : L"", SysStringLen(baseURL)) };

    URL failingCoreURL = MarshallingHelpers::BSTRToKURL(failingURL);

    ResourceRequest request(baseCoreURL);
    ResourceResponse response(URL(), mimeTypeString, data->size(), encodingString);
    SubstituteData substituteData(WTFMove(data), failingCoreURL, response, SubstituteData::SessionHistoryVisibility::Hidden);

    // This method is only called from IWebFrame methods, so don't ASSERT that the Frame pointer isn't null.
    if (Frame* coreFrame = core(this))
        coreFrame->loader().load(FrameLoadRequest(*coreFrame, request, substituteData));
}

HRESULT WebFrame::loadData(_In_opt_ IStream* data, _In_ BSTR mimeType, _In_ BSTR textEncodingName, _In_ BSTR url)
{
    SharedBufferBuilder sharedBuffer;

    STATSTG stat;
    if (SUCCEEDED(data->Stat(&stat, STATFLAG_NONAME))) {
        if (!stat.cbSize.HighPart && stat.cbSize.LowPart) {
            Vector<char> dataBuffer(stat.cbSize.LowPart);
            ULONG read;
            // FIXME: this does a needless copy, would be better to read right into the FragmentedSharedBuffer
            // or adopt the Vector or something.
            if (SUCCEEDED(data->Read(dataBuffer.data(), static_cast<ULONG>(dataBuffer.size()), &read)))
                sharedBuffer.append(dataBuffer.data(), static_cast<int>(dataBuffer.size()));
        }
    }

    loadData(sharedBuffer.take(), mimeType, textEncodingName, url, nullptr);
    return S_OK;
}

HRESULT WebFrame::loadPlainTextString(_In_ BSTR plainText, _In_ BSTR url)
{
    auto sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(plainText), sizeof(UChar) * SysStringLen(plainText));
    BString plainTextMimeType(TEXT("text/plain"), 10);
    BString utf16Encoding(TEXT("utf-16"), 6);
    loadData(WTFMove(sharedBuffer), plainTextMimeType, utf16Encoding, url, nullptr);
    return S_OK;
}

void WebFrame::loadHTMLString(_In_ BSTR htmlString, _In_ BSTR baseURL, _In_ BSTR unreachableURL)
{
    auto sharedBuffer = SharedBuffer::create(reinterpret_cast<char*>(htmlString), sizeof(UChar) * SysStringLen(htmlString));
    BString utf16Encoding(TEXT("utf-16"), 6);
    loadData(WTFMove(sharedBuffer), 0, utf16Encoding, baseURL, unreachableURL);
}

HRESULT WebFrame::loadHTMLString(_In_ BSTR htmlString, _In_ BSTR baseURL)
{
    loadHTMLString(htmlString, baseURL, nullptr);
    return S_OK;
}

HRESULT WebFrame::loadAlternateHTMLString(_In_ BSTR str, _In_ BSTR baseURL, _In_ BSTR unreachableURL)
{
    loadHTMLString(str, baseURL, unreachableURL);
    return S_OK;
}

HRESULT WebFrame::loadArchive(_In_opt_ IWebArchive* /*archive*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

static inline WebDataSource* getWebDataSource(DocumentLoader* loader)
{
    return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : nullptr;
}

HRESULT WebFrame::dataSource(_COM_Outptr_opt_ IWebDataSource** source)
{
    if (!source) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *source = nullptr;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    WebDataSource* webDataSource = getWebDataSource(coreFrame->loader().documentLoader());

    *source = webDataSource;

    if (webDataSource)
        webDataSource->AddRef(); 

    return *source ? S_OK : E_FAIL;
}

HRESULT WebFrame::provisionalDataSource(_COM_Outptr_opt_ IWebDataSource** source)
{
    if (!source) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *source = nullptr;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    WebDataSource* webDataSource = getWebDataSource(coreFrame->loader().provisionalDocumentLoader());

    *source = webDataSource;

    if (webDataSource)
        webDataSource->AddRef(); 

    return *source ? S_OK : E_FAIL;
}

URL WebFrame::url() const
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return URL();

    return coreFrame->document()->url();
}

HRESULT WebFrame::stopLoading()
{
    if (Frame* coreFrame = core(this))
        coreFrame->loader().stopAllLoaders();
    return S_OK;
}

HRESULT WebFrame::reload()
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    coreFrame->loader().reload();
    return S_OK;
}

HRESULT WebFrame::findFrameNamed(_In_ BSTR name, _COM_Outptr_opt_ IWebFrame** frame)
{
    if (!frame) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *frame = nullptr;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    Frame* foundFrame = coreFrame->tree().find(AtomString(name, SysStringLen(name)), *coreFrame);
    if (!foundFrame)
        return S_OK;

    WebFrame* foundWebFrame = kit(foundFrame);
    if (!foundWebFrame)
        return E_FAIL;

    return foundWebFrame->QueryInterface(IID_IWebFrame, (void**)frame);
}

HRESULT WebFrame::parentFrame(_COM_Outptr_opt_ IWebFrame** frame)
{
    if (!frame)
        return E_POINTER;

    *frame = nullptr;

    HRESULT hr = S_OK;
    if (Frame* coreFrame = core(this))
        if (WebFrame* webFrame = kit(coreFrame->tree().parent()))
            hr = webFrame->QueryInterface(IID_IWebFrame, (void**) frame);

    return hr;
}

class EnumChildFrames final : public IEnumVARIANT
{
public:
    EnumChildFrames(Frame* f)
        : m_frame(f), m_curChild(f ? f->tree().firstChild() : nullptr)
    {
    }

    virtual HRESULT STDMETHODCALLTYPE QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
    {
        *ppvObject = nullptr;
        if (IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IEnumVARIANT))
            *ppvObject = this;
        else
            return E_NOINTERFACE;

        AddRef();
        return S_OK;
    }

    virtual ULONG STDMETHODCALLTYPE AddRef()
    {
        return ++m_refCount;
    }

    virtual ULONG STDMETHODCALLTYPE Release()
    {
        ULONG newRef = --m_refCount;
        if (!newRef)
            delete(this);
        return newRef;
    }

    virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
    {
        if (pCeltFetched)
            *pCeltFetched = 0;
        if (!rgVar)
            return E_POINTER;
        ::VariantInit(rgVar);
        if (!celt || celt > 1)
            return S_FALSE;
        if (!m_frame || !m_curChild)
            return S_FALSE;

        WebFrame* webFrame = kit(m_curChild);
        IUnknown* unknown;
        HRESULT hr = webFrame->QueryInterface(IID_IUnknown, (void**)&unknown);
        if (FAILED(hr))
            return hr;

        V_VT(rgVar) = VT_UNKNOWN;
        V_UNKNOWN(rgVar) = unknown;

        m_curChild = m_curChild->tree().nextSibling();
        if (pCeltFetched)
            *pCeltFetched = 1;
        return S_OK;
    }

    virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
    {
        if (!m_frame)
            return S_FALSE;
        for (unsigned i = 0; i < celt && m_curChild; i++)
            m_curChild = m_curChild->tree().nextSibling();
        return m_curChild ? S_OK : S_FALSE;
    }

    virtual HRESULT STDMETHODCALLTYPE Reset(void)
    {
        if (!m_frame)
            return S_FALSE;
        m_curChild = m_frame->tree().firstChild();
        return S_OK;
    }

    virtual HRESULT STDMETHODCALLTYPE Clone(IEnumVARIANT**)
    {
        return E_NOTIMPL;
    }

private:
    ULONG m_refCount { 1 };
    Frame* m_frame;
    Frame* m_curChild;
};

HRESULT WebFrame::childFrames(_COM_Outptr_opt_ IEnumVARIANT** enumFrames)
{
    if (!enumFrames)
        return E_POINTER;

    *enumFrames = new EnumChildFrames(core(this));
    return S_OK;
}

// IWebFramePrivate ------------------------------------------------------

enum WebRenderTreeAsTextOption {
    WebRenderTreeAsTextShowAllLayers           = 1 << 0,
    WebRenderTreeAsTextShowLayerNesting        = 1 << 1,
    WebRenderTreeAsTextShowCompositedLayers    = 1 << 2,
    WebRenderTreeAsTextShowOverflow            = 1 << 3,
    WebRenderTreeAsTextShowSVGGeometry         = 1 << 4,
    WebRenderTreeAsTextShowLayerFragments      = 1 << 5
};

typedef unsigned WebRenderTreeAsTextOptions;

static OptionSet<RenderAsTextFlag> toRenderAsTextFlags(WebRenderTreeAsTextOptions options)
{
    OptionSet<RenderAsTextFlag> flags;

    if (options & WebRenderTreeAsTextShowAllLayers)
        flags.add(RenderAsTextFlag::ShowAllLayers);
    if (options & WebRenderTreeAsTextShowLayerNesting)
        flags.add(RenderAsTextFlag::ShowLayerNesting);
    if (options & WebRenderTreeAsTextShowCompositedLayers)
        flags.add(RenderAsTextFlag::ShowCompositedLayers);
    if (options & WebRenderTreeAsTextShowOverflow)
        flags.add(RenderAsTextFlag::ShowOverflow);
    if (options & WebRenderTreeAsTextShowSVGGeometry)
        flags.add(RenderAsTextFlag::ShowSVGGeometry);
    if (options & WebRenderTreeAsTextShowLayerFragments)
        flags.add(RenderAsTextFlag::ShowLayerFragments);

    return flags;
}

HRESULT WebFrame::renderTreeAsExternalRepresentation(unsigned options, _Deref_opt_out_ BSTR* result)
{
    if (!result)
        return E_POINTER;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    *result = BString(externalRepresentation(coreFrame, toRenderAsTextFlags(options))).release();
    return S_OK;
}

HRESULT WebFrame::renderTreeAsExternalRepresentationForPrinting(_Deref_opt_out_ BSTR* result)
{
    if (!result)
        return E_POINTER;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    *result = BString(externalRepresentation(coreFrame, { RenderAsTextFlag::PrintingMode })).release();
    return S_OK;
}

HRESULT WebFrame::pageNumberForElementById(_In_ BSTR id, float pageWidthInPixels, float pageHeightInPixels, _Out_ int* pageNumber)
{
    // TODO: Please remove this function if not needed as this is LTC specific function
    // and has been moved to Internals.
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

HRESULT WebFrame::numberOfPages(float pageWidthInPixels, float pageHeightInPixels, _Out_ int* pageCount)
{
    // TODO: Please remove this function if not needed as this is LTC specific function
    // and has been moved to Internals.
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

HRESULT WebFrame::scrollOffset(_Out_ SIZE* offset)
{
    if (!offset) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    FrameView* view = coreFrame->view();
    if (!view)
        return E_FAIL;

    *offset = toIntSize(view->scrollPosition());
    return S_OK;
}

HRESULT WebFrame::layout()
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    FrameView* view = coreFrame->view();
    if (!view)
        return E_FAIL;

    view->layoutContext().layout();
    return S_OK;
}

HRESULT WebFrame::firstLayoutDone(_Out_ BOOL* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *result = FALSE;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    *result = coreFrame->loader().stateMachine().firstLayoutDone();
    return S_OK;
}

HRESULT WebFrame::pendingFrameUnloadEventCount(_Out_ UINT* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *result = 0;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    *result = coreFrame->document()->domWindow()->pendingUnloadEventListeners();
    return S_OK;
}

HRESULT WebFrame::hasSpellingMarker(UINT from, UINT length, BOOL* result)
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;
    *result = coreFrame->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
    return S_OK;
}

HRESULT WebFrame::clearOpener()
{
    HRESULT hr = S_OK;
    if (Frame* coreFrame = core(this))
        coreFrame->loader().setOpener(nullptr);

    return hr;
}

HRESULT WebFrame::setTextDirection(_In_ BSTR direction)
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    String directionString(direction, SysStringLen(direction));
    if (directionString == "auto")
        coreFrame->editor().setBaseWritingDirection(WritingDirection::Natural);
    else if (directionString == "ltr")
        coreFrame->editor().setBaseWritingDirection(WritingDirection::LeftToRight);
    else if (directionString == "rtl")
        coreFrame->editor().setBaseWritingDirection(WritingDirection::RightToLeft);
    return S_OK;
}

// IWebDocumentText -----------------------------------------------------------

HRESULT WebFrame::supportsTextEncoding(_Out_ BOOL* result)
{
    *result = FALSE;
    return E_NOTIMPL;
}

HRESULT WebFrame::selectedString(_Deref_opt_out_ BSTR* result)
{
    if (!result)
        return E_POINTER;
    *result = nullptr;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    String text = coreFrame->displayStringModifiedByEncoding(coreFrame->editor().selectedText());

    *result = BString(text).release();
    return S_OK;
}

HRESULT WebFrame::selectAll()
{
    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    if (!coreFrame->editor().command("SelectAll"_s).execute())
        return E_FAIL;

    return S_OK;
}

HRESULT WebFrame::deselectAll()
{
    return E_NOTIMPL;
}

// WebFrame ---------------------------------------------------------------

Ref<Frame> WebFrame::createSubframeWithOwnerElement(IWebView* webView, Page* page, HTMLFrameOwnerElement* ownerElement)
{
    webView->QueryInterface(&d->webView);
    d->webView->Release(); // don't hold the extra ref

    HWND viewWindow;
    d->webView->viewWindow(&viewWindow);

    this->AddRef(); // We release this ref in frameLoaderDestroyed()
    auto frame = Frame::create(page, ownerElement, makeUniqueRef<WebFrameLoaderClient>(this));
    d->frame = frame.ptr();
    return frame;
}

void WebFrame::initWithWebView(IWebView* webView, Page* page)
{
    webView->QueryInterface(&d->webView);
    d->webView->Release(); // don't hold the extra ref

    HWND viewWindow;
    d->webView->viewWindow(&viewWindow);

    this->AddRef(); // We release this ref in frameLoaderDestroyed()
    d->frame = &page->mainFrame();
}

Frame* WebFrame::impl()
{
    return d->frame;
}

void WebFrame::invalidate()
{
    Frame* coreFrame = core(this);
    ASSERT(coreFrame);

    if (Document* document = coreFrame->document())
        document->resolveStyle(WebCore::Document::ResolveStyleType::Rebuild);
}

HRESULT WebFrame::inViewSourceMode(BOOL* flag)
{
    return E_NOTIMPL;
}

HRESULT WebFrame::setInViewSourceMode(BOOL flag)
{
    return E_NOTIMPL;
}

HRESULT WebFrame::elementWithName(BSTR name, IDOMElement* form, IDOMElement** element)
{
    if (!form)
        return E_INVALIDARG;

    HTMLFormElement* formElement = formElementFromDOMElement(form);
    if (formElement) {
        AtomString targetName((UChar*)name, SysStringLen(name));
        for (auto& associatedElement : formElement->copyAssociatedElementsVector()) {
            if (!is<HTMLFormControlElement>(associatedElement))
                continue;
            auto& elt = downcast<HTMLFormControlElement>(associatedElement.get());
            // Skip option elements, other duds.
            if (elt.name() == targetName) {
                *element = DOMElement::createInstance(&elt);
                return S_OK;
            }
        }
    }
    return E_FAIL;
}

HRESULT WebFrame::formForElement(IDOMElement* element, IDOMElement** form)
{
    if (!element)
        return E_INVALIDARG;

    HTMLInputElement *inputElement = inputElementFromDOMElement(element);
    if (!inputElement)
        return E_FAIL;

    HTMLFormElement *formElement = inputElement->form();
    if (!formElement)
        return E_FAIL;

    *form = DOMElement::createInstance(formElement);
    return S_OK;
}

HRESULT WebFrame::elementDoesAutoComplete(_In_opt_ IDOMElement *element, _Out_ BOOL* result)
{
    *result = false;
    if (!element)
        return E_INVALIDARG;

    HTMLInputElement *inputElement = inputElementFromDOMElement(element);
    if (!inputElement)
        *result = false;
    else
        *result = inputElement->isTextField() && !inputElement->isPasswordField() && inputElement->shouldAutocomplete();

    return S_OK;
}

HRESULT WebFrame::visibleContentRect(_Out_ RECT* rect)
{
    if (!rect)
        return E_POINTER;
    SetRectEmpty(rect);

    Frame* frame = core(this);
    if (!frame)
        return E_UNEXPECTED;

    FrameView* view = frame->view();
    if (!view)
        return E_FAIL;

    *rect = view->visibleContentRect();
    return S_OK;
}

HRESULT WebFrame::isDisplayingStandaloneImage(_Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;

    *result = FALSE;

    Frame* frame = core(this);
    if (!frame)
        return E_UNEXPECTED;

    Document* document = frame->document();
    *result = document && document->isImageDocument();
    return S_OK;
}

HRESULT WebFrame::allowsFollowingLink(_In_ BSTR url, _Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;

    *result = TRUE;

    Frame* frame = core(this);
    if (!frame)
        return E_UNEXPECTED;

    *result = frame->document()->securityOrigin().canDisplay(MarshallingHelpers::BSTRToKURL(url));
    return S_OK;
}

HRESULT WebFrame::controlsInForm(IDOMElement* form, IDOMElement** controls, int* cControls)
{
    if (!form)
        return E_INVALIDARG;

    HTMLFormElement* formElement = formElementFromDOMElement(form);
    if (!formElement)
        return E_FAIL;

    auto elements = formElement->copyAssociatedElementsVector();
    int inCount = *cControls;
    int count = (int) elements.size();
    *cControls = count;
    if (!controls)
        return S_OK;
    if (inCount < count)
        return E_FAIL;

    *cControls = 0;
    for (auto& element : elements) {
        if (element->isEnumeratable()) {
            // Skip option elements, other duds.
            controls[*cControls] = DOMElement::createInstance(&element->asHTMLElement());
            (*cControls)++;
        }
    }
    return S_OK;
}

HRESULT WebFrame::elementIsPassword(IDOMElement *element, bool *result)
{
    HTMLInputElement* inputElement = inputElementFromDOMElement(element);
    *result = inputElement && inputElement->isPasswordField();
    return S_OK;
}

HRESULT WebFrame::searchForLabelsBeforeElement(const BSTR* labels, unsigned cLabels, IDOMElement* beforeElement, unsigned* outResultDistance, BOOL* outResultIsInCellAbove, BSTR* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    if (outResultDistance)
        *outResultDistance = 0;
    if (outResultIsInCellAbove)
        *outResultIsInCellAbove = FALSE;
    *result = 0;

    if (!cLabels)
        return S_OK;
    if (cLabels < 1)
        return E_INVALIDARG;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    Vector<String> labelStrings(cLabels);
    for (int i=0; i<cLabels; i++)
        labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
    Element *coreElement = elementFromDOMElement(beforeElement);
    if (!coreElement)
        return E_FAIL;

    size_t resultDistance;
    bool resultIsInCellAbove;
    String label = coreFrame->searchForLabelsBeforeElement(labelStrings, coreElement, &resultDistance, &resultIsInCellAbove);
    
    *result = BString(label).release();
    if (label.length() && !*result)
        return E_OUTOFMEMORY;
    if (outResultDistance)
        *outResultDistance = resultDistance;
    if (outResultIsInCellAbove)
        *outResultIsInCellAbove = resultIsInCellAbove;

    return S_OK;
}

HRESULT WebFrame::matchLabelsAgainstElement(const BSTR* labels, int cLabels, IDOMElement* againstElement, BSTR* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *result = 0;

    if (!cLabels)
        return S_OK;
    if (cLabels < 1)
        return E_INVALIDARG;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    Vector<String> labelStrings(cLabels);
    for (int i=0; i<cLabels; i++)
        labelStrings[i] = String(labels[i], SysStringLen(labels[i]));
    Element *coreElement = elementFromDOMElement(againstElement);
    if (!coreElement)
        return E_FAIL;

    String label = coreFrame->matchLabelsAgainstElement(labelStrings, coreElement);
    
    *result = BString(label).release();
    if (label.length() && !*result)
        return E_OUTOFMEMORY;
    return S_OK;
}

HRESULT WebFrame::canProvideDocumentSource(bool* result)
{
    HRESULT hr = S_OK;
    *result = false;

    COMPtr<IWebDataSource> dataSource;
    hr = WebFrame::dataSource(&dataSource);
    if (FAILED(hr))
        return hr;

    COMPtr<IWebURLResponse> urlResponse;
    hr = dataSource->response(&urlResponse);
    if (SUCCEEDED(hr) && urlResponse) {
        BString mimeTypeBStr;
        if (SUCCEEDED(urlResponse->MIMEType(&mimeTypeBStr))) {
            String mimeType(mimeTypeBStr, SysStringLen(mimeTypeBStr));
            *result = mimeType == "text/html" || WebCore::MIMETypeRegistry::isXMLMIMEType(mimeType);
        }
    }
    return hr;
}

HRESULT WebFrame::layerTreeAsText(_Deref_out_opt_ BSTR* result)
{
    if (!result)
        return E_POINTER;
    *result = nullptr;

    Frame* frame = core(this);
    if (!frame)
        return E_UNEXPECTED;

    String text = frame->contentRenderer()->compositor().layerTreeAsText();
    *result = BString(text).release();
    return S_OK;
}

void WebFrame::frameLoaderDestroyed()
{
    // The FrameLoader going away is equivalent to the Frame going away,
    // so we now need to clear our frame pointer.
    d->frame = 0;

    this->Release();
}

static IntRect printerRect(HDC printDC)
{
    return IntRect(0, 0, 
                   GetDeviceCaps(printDC, PHYSICALWIDTH)  - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETX),
                   GetDeviceCaps(printDC, PHYSICALHEIGHT) - 2 * GetDeviceCaps(printDC, PHYSICALOFFSETY));
}

void WebFrame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSizeOrNot adjustViewSize)
{
    Frame* coreFrame = core(this);
    ASSERT(coreFrame);
    coreFrame->setPrinting(printing, pageSize, originalPageSize, maximumShrinkRatio, adjustViewSize ? AdjustViewSize : DoNotAdjustViewSize);
}

HRESULT WebFrame::setInPrintingMode(BOOL value, _In_ HDC printDC)
{
    if (m_inPrintingMode == !!value)
        return S_OK;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    if (!coreFrame->document())
        return E_FAIL;

    m_inPrintingMode = !!value;

    // If we are a frameset just print with the layout we have onscreen, otherwise relayout
    // according to the paper size
    FloatSize minLayoutSize(0.0, 0.0);
    FloatSize originalPageSize(0.0, 0.0);
    if (m_inPrintingMode && !coreFrame->document()->isFrameSet()) {
        if (!printDC) {
            ASSERT_NOT_REACHED();
            return E_POINTER;
        }

        const int desiredPixelsPerInch = 72;
        IntRect printRect = printerRect(printDC);
        int paperHorizontalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSX);
        int paperVerticalPixelsPerInch = ::GetDeviceCaps(printDC, LOGPIXELSY);
        int paperWidth = printRect.width() * desiredPixelsPerInch / paperHorizontalPixelsPerInch;
        int paperHeight = printRect.height() * desiredPixelsPerInch / paperVerticalPixelsPerInch;
        originalPageSize = FloatSize(paperWidth, paperHeight);
        Frame* coreFrame = core(this);
        minLayoutSize = coreFrame->resizePageRectsKeepingRatio(originalPageSize, FloatSize(paperWidth * PrintingMinimumShrinkFactor, paperHeight * PrintingMinimumShrinkFactor));
    }

    setPrinting(m_inPrintingMode, minLayoutSize, originalPageSize, PrintingMaximumShrinkFactor / PrintingMinimumShrinkFactor, AdjustViewSize);

    if (!m_inPrintingMode)
        m_pageRects.clear();

    return S_OK;
}

void WebFrame::headerAndFooterHeights(float* headerHeight, float* footerHeight)
{
    if (headerHeight)
        *headerHeight = 0;
    if (footerHeight)
        *footerHeight = 0;
    float height = 0;
    COMPtr<IWebUIDelegate> ui;
    if (FAILED(d->webView->uiDelegate(&ui)))
        return;
    if (headerHeight && SUCCEEDED(ui->webViewHeaderHeight(d->webView, &height)))
        *headerHeight = height;
    if (footerHeight && SUCCEEDED(ui->webViewFooterHeight(d->webView, &height)))
        *footerHeight = height;
}

IntRect WebFrame::printerMarginRect(HDC printDC)
{
    IntRect emptyRect(0, 0, 0, 0);

    COMPtr<IWebUIDelegate> ui;
    if (FAILED(d->webView->uiDelegate(&ui)))
        return emptyRect;

    RECT rect;
    if (FAILED(ui->webViewPrintingMarginRect(d->webView, &rect)))
        return emptyRect;

    rect.left = MulDiv(rect.left, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
    rect.top = MulDiv(rect.top, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);
    rect.right = MulDiv(rect.right, ::GetDeviceCaps(printDC, LOGPIXELSX), 1000);
    rect.bottom = MulDiv(rect.bottom, ::GetDeviceCaps(printDC, LOGPIXELSY), 1000);

    return IntRect(rect.left, rect.top, (rect.right - rect.left), rect.bottom - rect.top);
}

const Vector<WebCore::IntRect>& WebFrame::computePageRects(HDC printDC)
{
    ASSERT(m_inPrintingMode);
    
    Frame* coreFrame = core(this);
    ASSERT(coreFrame);
    ASSERT(coreFrame->document());

    if (!printDC)
        return m_pageRects;

    // adjust the page rect by the header and footer
    float headerHeight = 0, footerHeight = 0;
    headerAndFooterHeights(&headerHeight, &footerHeight);
    IntRect pageRect = printerRect(printDC);
    IntRect marginRect = printerMarginRect(printDC);
    IntRect adjustedRect = IntRect(
        pageRect.x() + marginRect.x(),
        pageRect.y() + marginRect.y(),
        pageRect.width() - marginRect.x() - marginRect.maxX(),
        pageRect.height() - marginRect.y() - marginRect.maxY());

    computePageRectsForFrame(coreFrame, adjustedRect, headerHeight, footerHeight, 1.0,m_pageRects, m_pageHeight);
    
    return m_pageRects;
}

HRESULT WebFrame::getPrintedPageCount(_In_ HDC printDC, _Out_ UINT *pageCount)
{
    if (!pageCount || !printDC) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    *pageCount = 0;

    if (!m_inPrintingMode) {
        ASSERT_NOT_REACHED();
        return E_FAIL;
    }

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    if (!coreFrame->document())
        return E_FAIL;

    const Vector<IntRect>& pages = computePageRects(printDC);
    *pageCount = (UINT) pages.size();
    
    return S_OK;
}

#if USE(CG)
void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
{
    int x = pageRect.x();
    int y = 0;
    RECT headerRect = {x, y, x+pageRect.width(), y+static_cast<int>(headerHeight)};
    ui->drawHeaderInRect(d->webView, &headerRect, reinterpret_cast<ULONG_PTR>(pctx));
}

void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight)
{
    int x = pageRect.x();
    int y = std::max((int)headerHeight+pageRect.height(), m_pageHeight-static_cast<int>(footerHeight));
    RECT footerRect = {x, y, x+pageRect.width(), y+static_cast<int>(footerHeight)};
    ui->drawFooterInRect(d->webView, &footerRect, reinterpret_cast<ULONG_PTR>(pctx), page + 1, pageCount);
}

void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext& spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount)
{
    Frame* coreFrame = core(this);

    IntRect pageRect = m_pageRects[page];

    CGContextSaveGState(pctx);

    IntRect printRect = printerRect(printDC);
    CGRect mediaBox = CGRectMake(CGFloat(0),
                                 CGFloat(0),
                                 CGFloat(printRect.width()),
                                 CGFloat(printRect.height()));

    CGContextBeginPage(pctx, &mediaBox);

    CGFloat scale = static_cast<float>(mediaBox.size.width)/static_cast<float>(pageRect.width());
    CGAffineTransform ctm = CGContextGetBaseCTM(pctx);
    ctm = CGAffineTransformScale(ctm, -scale, -scale);
    ctm = CGAffineTransformTranslate(ctm, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight)); // reserves space for header
    CGContextScaleCTM(pctx, scale, scale);
    CGContextTranslateCTM(pctx, CGFloat(-pageRect.x()), CGFloat(-pageRect.y()+headerHeight));   // reserves space for header
    CGContextSetBaseCTM(pctx, ctm);

    coreFrame->view()->paintContents(spoolCtx, pageRect);

    CGContextTranslateCTM(pctx, CGFloat(pageRect.x()), CGFloat(pageRect.y())-headerHeight);

    if (headerHeight)
        drawHeader(pctx, ui, pageRect, headerHeight);

    if (footerHeight)
        drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight);

    CGContextEndPage(pctx);
    CGContextRestoreGState(pctx);
}
#elif USE(CAIRO)
static float scaleFactor(HDC printDC, const IntRect& marginRect, const IntRect& pageRect)
{
    const IntRect& printRect = printerRect(printDC);

    IntRect adjustedRect = IntRect(
        printRect.x() + marginRect.x(),
        printRect.y() + marginRect.y(),
        printRect.width() - marginRect.x() - marginRect.maxX(),
        printRect.height() - marginRect.y() - marginRect.maxY());

    float scale = static_cast<float>(adjustedRect.width()) / static_cast<float>(pageRect.width());
    if (!scale)
       scale = 1.0;

    return scale;
}

static HDC hdcFromContext(PlatformGraphicsContext* pctx)
{
    return cairo_win32_surface_get_dc(cairo_get_target(pctx->cr()));
}

void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
{
    HDC hdc = hdcFromContext(pctx);

    int x = pageRect.x();
    int y = 0;
    RECT headerRect = {x, y, x + pageRect.width(), y + static_cast<int>(headerHeight)};

    ui->drawHeaderInRect(d->webView, &headerRect, reinterpret_cast<ULONG_PTR>(hdc));
}

void WebFrame::drawFooter(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, UINT page, UINT pageCount, float headerHeight, float footerHeight)
{
    HDC hdc = hdcFromContext(pctx);
    
    int x = pageRect.x();
    int y = std::max(static_cast<int>(headerHeight) + pageRect.height(), m_pageHeight  -static_cast<int>(footerHeight));
    RECT footerRect = {x, y, x + pageRect.width(), y + static_cast<int>(footerHeight)};

    ui->drawFooterInRect(d->webView, &footerRect, reinterpret_cast<ULONG_PTR>(hdc), page+1, pageCount);
}

static XFORM buildXFORMFromCairo(HDC targetDC, cairo_t* previewContext)
{
    XFORM scaled;
    GetWorldTransform(targetDC, &scaled);

    cairo_matrix_t ctm;
    cairo_get_matrix(previewContext, &ctm);    
        
    // Scale to the preview screen bounds
    scaled.eM11 = ctm.xx;
    scaled.eM22 = ctm.yy;

    return scaled;
}

void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext& spoolCtx, HDC printDC, IWebUIDelegate* ui, float headerHeight, float footerHeight, UINT page, UINT pageCount)
{
    Frame* coreFrame = core(this);

    const IntRect& pageRect = m_pageRects[page];
    const IntRect& marginRect = printerMarginRect(printDC);

    // In preview, the printDC is a placeholder, so just always use the HDC backing the graphics context.
    HDC hdc = hdcFromContext(pctx);

    spoolCtx.save();
    
    XFORM original, scaled;
    GetWorldTransform(hdc, &original);
    
    cairo_t* cr = pctx->cr();
    bool preview = (hdc != printDC);
    if (preview) {
        // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo will
        // draw correctly.  We need to retain the correct preview scale here for use when the Cairo
        // drawing completes so that we can scale our GDI-based header/footer calls. This is a
        // workaround for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
        scaled = buildXFORMFromCairo(hdc, cr);
    }

    float scale = scaleFactor(printDC, marginRect, pageRect);
    
    IntRect cairoMarginRect(marginRect);
    cairoMarginRect.scale(1 / scale);

    // We cannot scale the display HDC because the print surface also scales fonts,
    // resulting in invalid printing (and print preview)
    cairo_scale(cr, scale, scale);
    cairo_translate(cr, cairoMarginRect.x(), cairoMarginRect.y() + headerHeight);

    // Modify Cairo (only) to account for page position.
    cairo_translate(cr, -pageRect.x(), -pageRect.y());
    coreFrame->view()->paintContents(spoolCtx, pageRect);
    cairo_translate(cr, pageRect.x(), pageRect.y());
    
    if (preview) {
        // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo would
        // draw correctly.  We need to rescale the HDC to the correct preview scale so our GDI-based
        // header/footer calls will draw properly.  This is a workaround for a bug in Cairo.
        // (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
        SetWorldTransform(hdc, &scaled);
    }
    
    XFORM xform = TransformationMatrix().translate(marginRect.x(), marginRect.y()).scale(scale);
    ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
   
    if (headerHeight)
        drawHeader(pctx, ui, pageRect, headerHeight);
    
    if (footerHeight)
        drawFooter(pctx, ui, pageRect, page, pageCount, headerHeight, footerHeight);

    SetWorldTransform(hdc, &original);

    cairo_show_page(cr);
    ASSERT(!cairo_status(cr));
    spoolCtx.restore();
}

static void setCairoTransformToPreviewHDC(cairo_t* previewCtx, HDC previewDC)
{
    XFORM passedCTM;
    GetWorldTransform(previewDC, &passedCTM);

    // Reset HDC WorldTransform to unscaled state.  Scaling must be
    // done in Cairo to avoid drawing errors.
    XFORM unscaledCTM = passedCTM;
    unscaledCTM.eM11 = 1.0;
    unscaledCTM.eM22 = 1.0;
        
    SetWorldTransform(previewDC, &unscaledCTM);

    // Make the Cairo transform match the information passed to WebKit
    // in the HDC's WorldTransform.
    cairo_matrix_t ctm = { passedCTM.eM11, passedCTM.eM12, passedCTM.eM21,
                           passedCTM.eM22, passedCTM.eDx, passedCTM.eDy };

    cairo_set_matrix(previewCtx, &ctm);    
}

#endif

HRESULT WebFrame::spoolPages(HDC printDC, UINT startPage, UINT endPage, void* ctx)
{
#if USE(CG)
    if (!printDC || !ctx) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }
#elif USE(CAIRO)
    if (!printDC) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }
    
    HDC targetDC = (ctx) ? (HDC)ctx : printDC;

    cairo_surface_t* printSurface = 0;
    if (ctx)
        printSurface = cairo_win32_surface_create(targetDC); // in-memory
    else
        printSurface = cairo_win32_printing_surface_create(targetDC); // metafile
    
    cairo_t* cr = cairo_create(printSurface);
    if (!cr) {
        cairo_surface_destroy(printSurface);    
        return E_FAIL;
    }

    GraphicsContextCairo platformContext(cr);
    PlatformGraphicsContext* pctx = &platformContext;
    cairo_destroy(cr);

    if (ctx) {
        // If this is a preview, the Windows HDC was sent with scaling information.
        // Retrieve it and reset it so that it draws properly.  This is a workaround
        // for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
        setCairoTransformToPreviewHDC(cr, targetDC);
    }
    
    cairo_surface_set_fallback_resolution(printSurface, 72.0, 72.0);
#endif

    if (!m_inPrintingMode) {
        ASSERT_NOT_REACHED();
        return E_FAIL;
    }

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    if (!coreFrame->document())
        return E_FAIL;

    UINT pageCount = (UINT) m_pageRects.size();
#if USE(CG)
    PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)ctx;
#endif

    if (!pageCount || startPage > pageCount) {
        ASSERT_NOT_REACHED();
        return E_FAIL;
    }

    if (startPage > 0)
        startPage--;

    if (endPage == 0)
        endPage = pageCount;

    COMPtr<IWebUIDelegate> ui;
    if (FAILED(d->webView->uiDelegate(&ui)))
        return E_FAIL;

    float headerHeight = 0, footerHeight = 0;
    headerAndFooterHeights(&headerHeight, &footerHeight);
#if USE(CG) || USE(CAIRO)
    GraphicsContextWin spoolCtx(pctx);

    for (UINT ii = startPage; ii < endPage; ii++)
        spoolPage(pctx, spoolCtx, printDC, ui.get(), headerHeight, footerHeight, ii, pageCount);
#endif

#if USE(CAIRO)
    cairo_surface_finish(printSurface);
    ASSERT(!cairo_surface_status(printSurface));
    cairo_surface_destroy(printSurface);
#endif

    return S_OK;
}

HRESULT WebFrame::isFrameSet(_Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;

    *result = FALSE;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    if (!coreFrame->document())
        return E_FAIL;

    *result = coreFrame->document()->isFrameSet() ? TRUE : FALSE;
    return S_OK;
}

HRESULT WebFrame::string(_Deref_opt_out_ BSTR* result)
{
    if (!result)
        return E_POINTER;

    *result = nullptr;

    auto* frame = core(this);
    if (!frame)
        return E_UNEXPECTED;

    auto* document = frame->document();
    if (!document)
        return E_FAIL;

    *result = BString(plainText(makeRangeSelectingNodeContents(*document))).release();
    return S_OK;
}

HRESULT WebFrame::size(_Out_ SIZE* size)
{
    if (!size)
        return E_POINTER;
    size->cx = size->cy = 0;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;
    FrameView* view = coreFrame->view();
    if (!view)
        return E_FAIL;
    size->cx = view->width();
    size->cy = view->height();
    return S_OK;
}

HRESULT WebFrame::hasScrollBars(_Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;
    *result = FALSE;

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    FrameView* view = coreFrame->view();
    if (!view)
        return E_FAIL;

    if (view->horizontalScrollbar() || view->verticalScrollbar())
        *result = TRUE;

    return S_OK;
}

HRESULT WebFrame::contentBounds(_Out_ RECT* result)
{
    if (!result)
        return E_POINTER;
    ::SetRectEmpty(result);

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    FrameView* view = coreFrame->view();
    if (!view)
        return E_FAIL;

    result->bottom = view->contentsHeight();
    result->right = view->contentsWidth();
    return S_OK;
}

HRESULT WebFrame::frameBounds(_Out_ RECT* result)
{
    if (!result)
        return E_POINTER;
    ::SetRectEmpty(result);

    Frame* coreFrame = core(this);
    if (!coreFrame)
        return E_UNEXPECTED;

    FrameView* view = coreFrame->view();
    if (!view)
        return E_FAIL;

    FloatRect bounds = view->visibleContentRectIncludingScrollbars();
    result->bottom = (LONG) bounds.height();
    result->right = (LONG) bounds.width();
    return S_OK;
}

HRESULT WebFrame::isDescendantOfFrame(_In_opt_ IWebFrame* ancestor, _Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;
    *result = FALSE;

    Frame* coreFrame = core(this);
    COMPtr<WebFrame> ancestorWebFrame(Query, ancestor);
    if (!ancestorWebFrame)
        return S_OK;

    *result = (coreFrame && coreFrame->tree().isDescendantOf(core(ancestorWebFrame.get()))) ? TRUE : FALSE;
    return S_OK;
}

HRESULT WebFrame::stringByEvaluatingJavaScriptInScriptWorld(IWebScriptWorld* iWorld, JSObjectRef globalObjectRef, BSTR script, BSTR* evaluationResult)
{
    if (!evaluationResult)
        return E_POINTER;
    *evaluationResult = 0;

    if (!iWorld)
        return E_POINTER;

    COMPtr<WebScriptWorld> world(Query, iWorld);
    if (!world)
        return E_INVALIDARG;

    Frame* coreFrame = core(this);
    String string = String(script, SysStringLen(script));

    // Start off with some guess at a frame and a global object, we'll try to do better...!
    JSDOMWindow* anyWorldGlobalObject = coreFrame->script().globalObject(mainThreadNormalWorld());

    // The global object is probably a proxy object? - if so, we know how to use this!
    JSC::JSObject* globalObjectObj = toJS(globalObjectRef);
    auto& vm = globalObjectObj->vm();
    if (globalObjectObj->inherits<JSWindowProxy>())
        anyWorldGlobalObject = JSC::jsDynamicCast<JSDOMWindow*>(static_cast<JSWindowProxy*>(globalObjectObj)->window());

    if (!anyWorldGlobalObject)
        return E_INVALIDARG;

    // Get the frame frome the global object we've settled on.
    Frame* frame = anyWorldGlobalObject->wrapped().frame();
    ASSERT(frame->document());
    JSValue result = frame->script().executeScriptInWorldIgnoringException(world->world(), string, true);

    if (!frame) // In case the script removed our frame from the page.
        return S_OK;

    // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
    // If you don't like it, use -[WebScriptObject evaluateWebScript:] or 
    // JSEvaluateScript instead, since they have less surprising semantics.
    if (!result || (!result.isBoolean() && !result.isString() && !result.isNumber()))
        return S_OK;

    JSC::JSGlobalObject* lexicalGlobalObject = anyWorldGlobalObject;
    JSC::JSLockHolder lock(lexicalGlobalObject);
    String resultString = result.toWTFString(lexicalGlobalObject);
    *evaluationResult = BString(resultString).release();

    return S_OK;
}

void WebFrame::unmarkAllMisspellings()
{
    Frame* coreFrame = core(this);
    for (Frame* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
        Document *doc = frame->document();
        if (!doc)
            return;

        doc->markers().removeMarkers(DocumentMarker::Spelling);
    }
}

void WebFrame::unmarkAllBadGrammar()
{
    Frame* coreFrame = core(this);
    for (Frame* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
        Document *doc = frame->document();
        if (!doc)
            return;

        doc->markers().removeMarkers(DocumentMarker::Grammar);
    }
}

WebView* WebFrame::webView() const
{
    return d->webView;
}

void WebFrame::setWebView(WebView* webView)
{
    d->webView = webView;
}

COMPtr<IAccessible> WebFrame::accessible() const
{
    Frame* coreFrame = core(this);
    ASSERT(coreFrame);

    Document* currentDocument = coreFrame->document();
    if (!currentDocument)
        m_accessible = 0;
    else if (!m_accessible || m_accessible->document() != currentDocument) {
        // Either we've never had a wrapper for this frame's top-level Document,
        // the Document renderer was destroyed and its wrapper was detached, or
        // the previous Document is in the back/forward cache, and the current document
        // needs to be wrapped.
        m_accessible = new AccessibleDocument(currentDocument, webView()->viewWindow());
    }
    return m_accessible.get();
}

void WebFrame::updateBackground()
{
    Frame* coreFrame = core(this);

    if (!coreFrame || !coreFrame->view())
        return;

    std::optional<Color> backgroundColor;
    if (webView()->transparent())
        backgroundColor = Color(Color::transparentBlack);
    coreFrame->view()->updateBackgroundRecursively(backgroundColor);
}

// IWebFrame2
HRESULT WebFrame::isMainFrame(_Out_ BOOL* value)
{
    if (!value)
        return E_POINTER;

    Frame* coreFrame = core(this);
    *value = coreFrame->isMainFrame();

    return S_OK;
}
