DOMHTMLClasses.cpp   [plain text]


/*
 * Copyright (C) 2006-2007, 2009, 2015 Apple Inc. 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 "DOMHTMLClasses.h"
#include "WebFrame.h"

#include <WebCore/BString.h>
#include <WebCore/COMPtr.h>
#include <WebCore/Document.h>
#include <WebCore/Element.h>
#include <WebCore/FrameView.h>
#include <WebCore/HTMLCollection.h>
#include <WebCore/HTMLDocument.h>
#include <WebCore/HTMLFormElement.h>
#include <WebCore/HTMLIFrameElement.h>
#include <WebCore/HTMLInputElement.h>
#include <WebCore/HTMLNames.h>
#include <WebCore/HTMLOptionElement.h>
#include <WebCore/HTMLOptionsCollection.h>
#include <WebCore/HTMLSelectElement.h>
#include <WebCore/HTMLTextAreaElement.h>
#include <WebCore/IntRect.h>
#include <WebCore/RenderObject.h>
#include <WebCore/RenderTextControl.h>

using namespace WebCore;
using namespace HTMLNames;

// DOMHTMLCollection

DOMHTMLCollection::DOMHTMLCollection(WebCore::HTMLCollection* c)
: m_collection(c)
{
}

IDOMHTMLCollection* DOMHTMLCollection::createInstance(WebCore::HTMLCollection* c)
{
    if (!c)
        return 0;

    IDOMHTMLCollection* htmlCollection = 0;
    DOMHTMLCollection* newCollection = new DOMHTMLCollection(c);
    if (FAILED(newCollection->QueryInterface(IID_IDOMHTMLCollection, (void**)&htmlCollection))) {
        delete newCollection;
        return 0;
    }

    return htmlCollection;
}

// DOMHTMLCollection - IUnknown -----------------------------------------------

HRESULT DOMHTMLCollection::QueryInterface(_In_ REFIID riid, _COM_Outptr_  void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IDOMHTMLCollection))
        *ppvObject = static_cast<IDOMHTMLCollection*>(this);
    else
        return DOMObject::QueryInterface(riid, ppvObject);

    AddRef();
    return S_OK;
}

// DOMHTMLCollection ----------------------------------------------------------

HRESULT DOMHTMLCollection::length(_Out_ UINT* result)
{
    if (!result)
        return E_POINTER;
    *result = 0;
    if (!m_collection)
        return E_POINTER;

    *result = m_collection->length();
    return S_OK;
}

HRESULT DOMHTMLCollection::item(UINT index, _COM_Outptr_opt_ IDOMNode** node)
{
    if (!node)
        return E_POINTER;
    *node = nullptr;
    if (!m_collection)
        return E_POINTER;

    *node = DOMNode::createInstance(m_collection->item(index));
    return *node ? S_OK : E_FAIL;
}

HRESULT DOMHTMLCollection::namedItem(_In_ BSTR /*name*/, _COM_Outptr_opt_ IDOMNode** node)
{
    ASSERT_NOT_REACHED();
    if (!node)
        return E_POINTER;
    *node = nullptr;
    return E_NOTIMPL;
}

// DOMHTMLOptionsCollection - IUnknown ----------------------------------------

HRESULT DOMHTMLOptionsCollection::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IDOMHTMLOptionsCollection))
        *ppvObject = static_cast<IDOMHTMLOptionsCollection*>(this);
    else
        return DOMObject::QueryInterface(riid, ppvObject);

    AddRef();
    return S_OK;
}

// DOMHTMLOptionsCollection ---------------------------------------------------

DOMHTMLOptionsCollection::DOMHTMLOptionsCollection(WebCore::HTMLOptionsCollection* collection)
    : m_collection(collection)
{
}

IDOMHTMLOptionsCollection* DOMHTMLOptionsCollection::createInstance(WebCore::HTMLOptionsCollection* collection)
{
    if (!collection)
        return nullptr;

    IDOMHTMLOptionsCollection* optionsCollection = nullptr;
    DOMHTMLOptionsCollection* newCollection = new DOMHTMLOptionsCollection(collection);
    if (FAILED(newCollection->QueryInterface(IID_IDOMHTMLOptionsCollection, (void**)&optionsCollection))) {
        delete newCollection;
        return nullptr;
    }

    return optionsCollection;
}

HRESULT DOMHTMLOptionsCollection::length(_Out_ unsigned* result)
{
    if (!result)
        return E_POINTER;

    *result = m_collection->length();
    return S_OK;
}

HRESULT DOMHTMLOptionsCollection::setLength(unsigned /*length*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

HRESULT DOMHTMLOptionsCollection::item(unsigned index, _COM_Outptr_opt_ IDOMNode** result)
{
    if (!result)
        return E_POINTER;

    *result = DOMNode::createInstance(m_collection->item(index));

    return *result ? S_OK : E_FAIL;
}

HRESULT DOMHTMLOptionsCollection::namedItem(_In_ BSTR /*name*/, _COM_Outptr_opt_ IDOMNode** result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}

// DOMHTMLDocument - IUnknown -------------------------------------------------

HRESULT DOMHTMLDocument::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IDOMHTMLDocument))
        *ppvObject = static_cast<IDOMHTMLDocument*>(this);
    else
        return DOMDocument::QueryInterface(riid, ppvObject);

    AddRef();
    return S_OK;
}

// DOMHTMLDocument ------------------------------------------------------------

HRESULT DOMHTMLDocument::title(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;

    *result = nullptr;

    if (!m_document || !m_document->isHTMLDocument())
        return E_FAIL;

    *result = BString(m_document->title()).release();
    return S_OK;
}
    
HRESULT DOMHTMLDocument::setTitle(_In_ BSTR /*title*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::referrer(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;

    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::domain(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;

    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::URL(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;

    *result = BString(downcast<HTMLDocument>(*m_document).url()).release();
    return S_OK;
}
    
HRESULT DOMHTMLDocument::body(_COM_Outptr_opt_ IDOMHTMLElement** bodyElement)
{
    if (!bodyElement)
        return E_POINTER;

    *bodyElement = nullptr;
    if (!is<HTMLDocument>(m_document))
        return E_FAIL;

    HTMLDocument& htmlDoc = downcast<HTMLDocument>(*m_document);
    COMPtr<IDOMElement> domElement;
    domElement.adoptRef(DOMHTMLElement::createInstance(htmlDoc.bodyOrFrameset()));
    if (domElement)
        return domElement->QueryInterface(IID_IDOMHTMLElement, (void**) bodyElement);
    return E_FAIL;
}
    
HRESULT DOMHTMLDocument::setBody(_In_opt_ IDOMHTMLElement* /*body*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::images(_COM_Outptr_opt_ IDOMHTMLCollection** collection)
{
    ASSERT_NOT_REACHED();
    if (!collection)
        return E_POINTER;
    *collection = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::applets(_COM_Outptr_opt_ IDOMHTMLCollection** collection)
{
    ASSERT_NOT_REACHED();
    if (!collection)
        return E_POINTER;
    *collection = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::links(_COM_Outptr_opt_ IDOMHTMLCollection** collection)
{
    ASSERT_NOT_REACHED();
    if (!collection)
        return E_POINTER;
    *collection = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::forms(_COM_Outptr_opt_ IDOMHTMLCollection** collection)
{
    if (!collection)
        return E_POINTER;
    *collection = nullptr;
    if (!is<HTMLDocument>(m_document))
        return E_FAIL;

    HTMLDocument& htmlDoc = downcast<HTMLDocument>(*m_document);
    RefPtr<HTMLCollection> forms = htmlDoc.forms();
    *collection = DOMHTMLCollection::createInstance(forms.get());
    return S_OK;
}
    
HRESULT DOMHTMLDocument::anchors(_COM_Outptr_opt_ IDOMHTMLCollection** collection)
{
    ASSERT_NOT_REACHED();
    if (!collection)
        return E_POINTER;
    *collection = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::cookie(__deref_opt_out BSTR* cookie)
{
    ASSERT_NOT_REACHED();
    if (!cookie)
        return E_POINTER;
    *cookie = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::setCookie(_In_ BSTR /*cookie*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::open()
{
    if (!m_document)
        return E_FAIL;

    m_document->open();
    return S_OK;
}
    
HRESULT DOMHTMLDocument::close()
{
    if (!m_document)
        return E_FAIL;

    m_document->close();
    return S_OK;
}
    
HRESULT DOMHTMLDocument::write(_In_ BSTR text)
{
    if (!m_document)
        return E_FAIL;

    m_document->write(nullptr, { String { text } });
    return S_OK;
}
    
HRESULT DOMHTMLDocument::writeln(_In_ BSTR text)
{
    if (!m_document)
        return E_FAIL;

    m_document->writeln(nullptr, { String { text } });
    return S_OK;
}
    
HRESULT DOMHTMLDocument::getElementById_(_In_ BSTR /*elementId*/, _COM_Outptr_opt_ IDOMElement** element)
{
    ASSERT_NOT_REACHED();
    if (!element)
        return E_POINTER;
    *element = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLDocument::getElementsByName(_In_ BSTR /*elementName*/, _COM_Outptr_opt_ IDOMNodeList** nodeList)
{
    ASSERT_NOT_REACHED();
    if (!nodeList)
        return E_POINTER;
    *nodeList = nullptr;
    return E_NOTIMPL;
}

// DOMHTMLElement - IUnknown --------------------------------------------------

HRESULT DOMHTMLElement::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IDOMHTMLElement))
        *ppvObject = static_cast<IDOMHTMLElement*>(this);
    else
        return DOMElement::QueryInterface(riid, ppvObject);

    AddRef();
    return S_OK;
}

// DOMHTMLElement -------------------------------------------------------------

HRESULT DOMHTMLElement::idName(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;

    ASSERT(is<HTMLElement>(m_element));
    String idString = downcast<HTMLElement>(m_element)->attributeWithoutSynchronization(idAttr);
    *result = BString(idString).release();
    return S_OK;
}
    
HRESULT DOMHTMLElement::setIdName(_In_ BSTR /*idName*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLElement::title(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLElement::setTitle(_In_ BSTR /*title*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLElement::lang(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLElement::setLang(_In_ BSTR /*lang*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLElement::dir(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLElement::setDir(_In_ BSTR /*dir*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLElement::className(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLElement::setClassName(_In_ BSTR /*className*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

HRESULT DOMHTMLElement::innerHTML(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;
    String innerHtmlString = downcast<HTMLElement>(m_element)->innerHTML();
    *result = BString(innerHtmlString).release();
    return S_OK;
}
        
HRESULT DOMHTMLElement::setInnerHTML(_In_ BSTR html)
{
    ASSERT(is<HTMLElement>(m_element));
    HTMLElement* htmlElement = downcast<HTMLElement>(m_element);
    String htmlString(html, SysStringLen(html));
    htmlElement->setInnerHTML(htmlString);
    return S_OK;
}
        
HRESULT DOMHTMLElement::innerText(__deref_opt_out BSTR* result)
{
    ASSERT(is<HTMLElement>(m_element));
    if (!result)
        return E_POINTER;
    WTF::String innerTextString = downcast<HTMLElement>(m_element)->innerText();
    *result = BString(innerTextString).release();
    return S_OK;
}
        
HRESULT DOMHTMLElement::setInnerText(_In_ BSTR text)
{
    ASSERT(is<HTMLElement>(m_element));
    HTMLElement* htmlElement = downcast<HTMLElement>(m_element);
    WTF::String textString(text, SysStringLen(text));
    htmlElement->setInnerText(textString);
    return S_OK;
}

// DOMHTMLFormElement - IUnknown ----------------------------------------------

HRESULT DOMHTMLFormElement::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IDOMHTMLFormElement))
        *ppvObject = static_cast<IDOMHTMLFormElement*>(this);
    else
        return DOMHTMLElement::QueryInterface(riid, ppvObject);

    AddRef();
    return S_OK;
}

// DOMHTMLFormElement ---------------------------------------------------------

HRESULT DOMHTMLFormElement::elements(_COM_Outptr_opt_ IDOMHTMLCollection** result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::length(_Out_ int* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::name(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::setName(_In_ BSTR /*name*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::acceptCharset(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::setAcceptCharset(_In_ BSTR /*acceptCharset*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::action(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;
    ASSERT(is<HTMLFormElement>(m_element));
    WTF::String actionString = downcast<HTMLFormElement>(*m_element).action();
    *result = BString(actionString).release();
    return S_OK;
}
    
HRESULT DOMHTMLFormElement::setAction(_In_ BSTR /*action*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::encType(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::setEnctype(_In_opt_ BSTR* /*encType*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::method(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;
    ASSERT(is<HTMLFormElement>(m_element));
    WTF::String methodString = downcast<HTMLFormElement>(*m_element).method();
    *result = BString(methodString).release();
    return S_OK;
}
    
HRESULT DOMHTMLFormElement::setMethod(_In_ BSTR /*method*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::target(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::setTarget(_In_ BSTR /*target*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::submit()
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLFormElement::reset()
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

// DOMHTMLSelectElement - IUnknown ----------------------------------------------

HRESULT DOMHTMLSelectElement::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IDOMHTMLSelectElement))
        *ppvObject = static_cast<IDOMHTMLSelectElement*>(this);
    else if (IsEqualGUID(riid, IID_IFormsAutoFillTransitionSelect))
        *ppvObject = static_cast<IFormsAutoFillTransitionSelect*>(this);
    else
        return DOMHTMLElement::QueryInterface(riid, ppvObject);

    AddRef();
    return S_OK;
}

// DOMHTMLSelectElement -------------------------------------------------------

HRESULT DOMHTMLSelectElement::type(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::selectedIndex(_Out_ int* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::setSelectedIndx(int /*selectedIndex*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::value(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::setValue(_In_ BSTR /*value*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::length(_Out_ int* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::form(_COM_Outptr_opt_ IDOMHTMLFormElement** result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::options(_COM_Outptr_opt_ IDOMHTMLOptionsCollection** result)
{
    if (!result)
        return E_POINTER;

    ASSERT(m_element);
    HTMLSelectElement& selectElement = downcast<HTMLSelectElement>(*m_element);

    *result = nullptr;
    RefPtr<HTMLOptionsCollection> options = selectElement.options();
    *result = DOMHTMLOptionsCollection::createInstance(options.get());
    return S_OK;
}
    
HRESULT DOMHTMLSelectElement::disabled(_Out_ BOOL* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::setDisabled(BOOL /*disabled*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::multiple(_Out_ BOOL* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::setMultiple(BOOL /*multiple*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::name(__deref_opt_out BSTR* result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::setName(_In_ BSTR /*name*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::size(_Out_ int* /*size*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::setSize(int /*size*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::tabIndex(_Out_ int* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::setTabIndex(int /*tabIndex*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::add(_In_opt_ IDOMHTMLElement* /*element*/, _In_opt_ IDOMHTMLElement* /*before*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLSelectElement::remove(int /*index*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
// DOMHTMLSelectElement - IFormsAutoFillTransitionSelect ----------------------

HRESULT DOMHTMLSelectElement::activateItemAtIndex(int index)
{
    ASSERT(m_element);
    HTMLSelectElement& selectElement = downcast<HTMLSelectElement>(*m_element);

    if (index >= selectElement.length())
        return E_FAIL;

    selectElement.setSelectedIndex(index);
    return S_OK;
}

// DOMHTMLOptionElement - IUnknown --------------------------------------------

HRESULT DOMHTMLOptionElement::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IDOMHTMLOptionElement))
        *ppvObject = static_cast<IDOMHTMLOptionElement*>(this);
    else
        return DOMHTMLElement::QueryInterface(riid, ppvObject);

    AddRef();
    return S_OK;
}

// DOMHTMLOptionElement -------------------------------------------------------

HRESULT DOMHTMLOptionElement::form(_COM_Outptr_opt_ IDOMHTMLFormElement** result)
{
    ASSERT_NOT_REACHED();
    if (!result)
        return E_POINTER;
    *result = nullptr;
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLOptionElement::defaultSelected(_Out_ BOOL* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLOptionElement::setDefaultSelected(BOOL /*defaultSelected*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLOptionElement::text(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;

    *result = nullptr;

    ASSERT(is<HTMLOptionElement>(m_element));
    HTMLOptionElement& optionElement = downcast<HTMLOptionElement>(*m_element);

    *result = BString(optionElement.text()).release();
    return S_OK;
}
    
HRESULT DOMHTMLOptionElement::index(_Out_ int* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLOptionElement::disabled(_Out_ BOOL* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLOptionElement::setDisabled(BOOL /*disabled*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLOptionElement::label(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;

    *result = nullptr;

    ASSERT(is<HTMLOptionElement>(m_element));
    HTMLOptionElement& optionElement = downcast<HTMLOptionElement>(*m_element);

    *result = BString(optionElement.label()).release();
    return S_OK;
}
    
HRESULT DOMHTMLOptionElement::setLabel(_In_ BSTR /*label*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLOptionElement::selected(_Out_ BOOL* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLOptionElement::setSelected(BOOL /*selected*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLOptionElement::value(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLOptionElement::setValue(_In_ BSTR /*value*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

// DOMHTMLInputElement - IUnknown ----------------------------------------------

HRESULT DOMHTMLInputElement::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IDOMHTMLInputElement))
        *ppvObject = static_cast<IDOMHTMLInputElement*>(this);
    else if (IsEqualGUID(riid, IID_IFormsAutoFillTransition))
        *ppvObject = static_cast<IFormsAutoFillTransition*>(this);
    else if (IsEqualGUID(riid, IID_IFormPromptAdditions))
        *ppvObject = static_cast<IFormPromptAdditions*>(this);    
    else
        return DOMHTMLElement::QueryInterface(riid, ppvObject);

    AddRef();
    return S_OK;
}

// DOMHTMLInputElement --------------------------------------------------------

HRESULT DOMHTMLInputElement::defaultValue(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setDefaultValue(_In_ BSTR /*val*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::defaultChecked(_Out_ BOOL* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setDefaultChecked(_In_ BSTR /*checked*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::form(_COM_Outptr_opt_ IDOMHTMLElement** result)
{
    if (!result)
        return E_POINTER;
    *result = nullptr;
    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    COMPtr<IDOMElement> domElement;
    domElement.adoptRef(DOMHTMLElement::createInstance(inputElement.form()));
    if (domElement)
        return domElement->QueryInterface(IID_IDOMHTMLElement, (void**) result);
    return E_FAIL;
}
    
HRESULT DOMHTMLInputElement::accept(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setAccept(_In_ BSTR /*accept*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::accessKey(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setAccessKey(_In_ BSTR /*key*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::align(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setAlign(_In_ BSTR /*align*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::alt(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setAlt(_In_ BSTR /*alt*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::checked(_Out_ BOOL* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setChecked(BOOL /*checked*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::disabled(_Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;

    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    *result = inputElement.isDisabledFormControl() ? TRUE : FALSE;
    return S_OK;
}
    
HRESULT DOMHTMLInputElement::setDisabled(BOOL /*disabled*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::maxLength(_Out_ int* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setMaxLength(int /*maxLength*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::name(__deref_opt_out BSTR* /*name*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setName(_In_ BSTR /*name*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::readOnly(_Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;

    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    *result = inputElement.isReadOnly() ? TRUE : FALSE;
    return S_OK;
}
    
HRESULT DOMHTMLInputElement::setReadOnly(BOOL /*readOnly*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::size(_Out_ unsigned* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setSize(unsigned /*size*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::src(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setSrc(_In_ BSTR /*src*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::tabIndex(_Out_ int* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setTabIndex(int /*tabIndex*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::type(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setType(_In_ BSTR type)
{
    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    WTF::String typeString(type, SysStringLen(type));
    inputElement.setType(typeString);
    return S_OK;
}
    
HRESULT DOMHTMLInputElement::useMap(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::setUseMap(_In_ BSTR /*useMap*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLInputElement::value(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;

    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    WTF::String valueString = inputElement.value();
    *result = BString(valueString).release();
    if (valueString.length() && !*result)
        return E_OUTOFMEMORY;
    return S_OK;
}
    
HRESULT DOMHTMLInputElement::setValue(_In_ BSTR value)
{
    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    inputElement.setValue(String((UChar*) value, SysStringLen(value)));
    return S_OK;
}

HRESULT DOMHTMLInputElement::setValueForUser(_In_ BSTR value)
{
    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    inputElement.setValueForUser(String(static_cast<UChar*>(value), SysStringLen(value)));
    return S_OK;
}

HRESULT DOMHTMLInputElement::select()
{
    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    inputElement.select();
    return S_OK;
}
    
HRESULT DOMHTMLInputElement::click()
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}

HRESULT DOMHTMLInputElement::setSelectionStart(long start)
{
    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    inputElement.setSelectionStart(start);
    return S_OK;
}

HRESULT DOMHTMLInputElement::selectionStart(_Out_ long *start)
{
    if (!start)
        return E_POINTER;

    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    *start = inputElement.selectionStart();
    return S_OK;
}

HRESULT DOMHTMLInputElement::setSelectionEnd(long end)
{
    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    inputElement.setSelectionEnd(end);
    return S_OK;
}

HRESULT DOMHTMLInputElement::selectionEnd(_Out_ long *end)
{
    if (!end)
        return E_POINTER;

    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    *end = inputElement.selectionEnd();
    return S_OK;
}

// DOMHTMLInputElement -- IFormsAutoFillTransition ----------------------------

HRESULT DOMHTMLInputElement::isTextField(_Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;

    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    *result = inputElement.isTextField() ? TRUE : FALSE;
    return S_OK;
}

HRESULT DOMHTMLInputElement::rectOnScreen(_Out_ LPRECT rect)
{
    if (!rect)
        return E_POINTER;
    ASSERT(is<HTMLInputElement>(m_element));
    rect->left = rect->top = rect->right = rect->bottom = 0;
    RenderObject* renderer = m_element->renderer();
    FrameView* view = m_element->document().view();
    if (!renderer || !view)
        return E_FAIL;

    IntRect coreRect = view->contentsToScreen(renderer->absoluteBoundingBoxRect());
    rect->left = coreRect.x();
    rect->top = coreRect.y();
    rect->right = coreRect.maxX();
    rect->bottom = coreRect.maxY();

    return S_OK;
}

HRESULT DOMHTMLInputElement::replaceCharactersInRange(int startTarget, int endTarget, _In_ BSTR replacementString, int index)
{
    if (!replacementString)
        return E_POINTER;

    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);

    String newValue = inputElement.value();
    String webCoreReplacementString(static_cast<UChar*>(replacementString), SysStringLen(replacementString));
    newValue.replace(startTarget, endTarget - startTarget, webCoreReplacementString);
    inputElement.setValue(newValue);
    inputElement.setSelectionRange(index, newValue.length());

    return S_OK;
}

HRESULT DOMHTMLInputElement::selectedRange(_Out_ int* start, _Out_ int* end)
{
    if (!start || !end)
        return E_POINTER;

    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    *start = inputElement.selectionStart();
    *end = inputElement.selectionEnd();
    return S_OK;
}

HRESULT DOMHTMLInputElement::setAutofilled(BOOL filled)
{
    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    inputElement.setAutoFilled(!!filled);
    return S_OK;
}

HRESULT DOMHTMLInputElement::isAutofilled(_Out_ BOOL* result)
{
    if (!result)
        return E_POINTER;

    ASSERT(is<HTMLInputElement>(m_element));
    HTMLInputElement& inputElement = downcast<HTMLInputElement>(*m_element);
    *result = inputElement.isAutoFilled() ? TRUE : FALSE;
    return S_OK;
}

// DOMHTMLInputElement -- IFormPromptAdditions ------------------------------------

HRESULT DOMHTMLInputElement::isUserEdited(_Out_ BOOL *result)
{
    if (!result)
        return E_POINTER;

    *result = FALSE;
    ASSERT(is<HTMLInputElement>(m_element));
    BOOL textField = FALSE;
    if (FAILED(isTextField(&textField)) || !textField)
        return S_OK;
    if (downcast<HTMLInputElement>(*m_element).lastChangeWasUserEdit())
        *result = TRUE;
    return S_OK;
}

// DOMHTMLTextAreaElement - IUnknown ----------------------------------------------

HRESULT DOMHTMLTextAreaElement::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IDOMHTMLTextAreaElement))
        *ppvObject = static_cast<IDOMHTMLTextAreaElement*>(this);
    else if (IsEqualGUID(riid, IID_IFormPromptAdditions))
        *ppvObject = static_cast<IFormPromptAdditions*>(this);    
    else
        return DOMHTMLElement::QueryInterface(riid, ppvObject);

    AddRef();
    return S_OK;
}

// DOMHTMLTextAreaElement -----------------------------------------------------

HRESULT DOMHTMLTextAreaElement::defaultValue(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::setDefaultValue(_In_ BSTR /*val*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::form(_COM_Outptr_opt_ IDOMHTMLElement** result)
{
    if (!result)
        return E_POINTER;
    *result = nullptr;
    ASSERT(is<HTMLTextAreaElement>(m_element));
    HTMLTextAreaElement& textareaElement = downcast<HTMLTextAreaElement>(*m_element);
    COMPtr<IDOMElement> domElement;
    domElement.adoptRef(DOMHTMLElement::createInstance(textareaElement.form()));
    if (domElement)
        return domElement->QueryInterface(IID_IDOMHTMLElement, (void**) result);
    return E_FAIL;
}
    
HRESULT DOMHTMLTextAreaElement::accessKey(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::setAccessKey(_In_ BSTR /*key*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::cols(_Out_ int* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::setCols(int /*cols*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::disabled(_Out_ BOOL* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::setDisabled(BOOL /*disabled*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::name(__deref_opt_out BSTR* /*name*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::setName(_In_ BSTR /*name*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::readOnly(_Out_ BOOL* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::setReadOnly(BOOL /*readOnly*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::rows(_Out_ int* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::setRows(int /*rows*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::tabIndex(_Out_ int* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::setTabIndex(int /*tabIndex*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::type(__deref_opt_out BSTR* /*result*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT DOMHTMLTextAreaElement::value(__deref_opt_out BSTR* result)
{
    if (!result)
        return E_POINTER;

    ASSERT(is<HTMLTextAreaElement>(m_element));
    HTMLTextAreaElement& textareaElement = downcast<HTMLTextAreaElement>(*m_element);
    WTF::String valueString = textareaElement.value();
    *result = BString(valueString).release();
    if (valueString.length() && !*result)
        return E_OUTOFMEMORY;
    return S_OK;
}
    
HRESULT DOMHTMLTextAreaElement::setValue(_In_ BSTR value)
{
    ASSERT(is<HTMLTextAreaElement>(m_element));
    HTMLTextAreaElement& textareaElement = downcast<HTMLTextAreaElement>(*m_element);
    textareaElement.setValue(String((UChar*) value, SysStringLen(value)));
    return S_OK;
}
    
HRESULT DOMHTMLTextAreaElement::select()
{
    ASSERT(is<HTMLTextAreaElement>(m_element));
    HTMLTextAreaElement& textareaElement = downcast<HTMLTextAreaElement>(*m_element);
    textareaElement.select();
    return S_OK;
}

// DOMHTMLTextAreaElement -- IFormPromptAdditions ------------------------------------

HRESULT DOMHTMLTextAreaElement::isUserEdited(_Out_ BOOL *result)
{
    if (!result)
        return E_POINTER;

    *result = FALSE;
    ASSERT(is<HTMLTextAreaElement>(m_element));
    if (downcast<HTMLTextAreaElement>(*m_element).lastChangeWasUserEdit())
        *result = TRUE;
    return S_OK;
}

// DOMHTMLIFrameElement - IUnknown --------------------------------------------------

HRESULT DOMHTMLIFrameElement::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;
    *ppvObject = nullptr;
    if (IsEqualGUID(riid, IID_IDOMHTMLIFrameElement))
        *ppvObject = static_cast<IDOMHTMLIFrameElement*>(this);
    else
        return DOMHTMLElement::QueryInterface(riid, ppvObject);

    AddRef();
    return S_OK;
}

// DOMHTMLIFrameElement -------------------------------------------------------------

HRESULT DOMHTMLIFrameElement::contentFrame(_COM_Outptr_opt_ IWebFrame** result)
{
    if (!result)
        return E_POINTER;
    *result = nullptr;
    ASSERT(m_element);
    HTMLIFrameElement& iFrameElement = downcast<HTMLIFrameElement>(*m_element);
    COMPtr<IWebFrame> webFrame = kit(iFrameElement.contentFrame());
    if (!webFrame)
        return E_FAIL;
    return webFrame.copyRefTo(result);
}