Home | History | Annotate | Download | only in win
      1 /*
      2  * Copyright (C) 2006, 2007, 2009 Apple Inc.  All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "WebKitDLL.h"
     28 #include "DOMCoreClasses.h"
     29 
     30 #include "DOMCSSClasses.h"
     31 #include "DOMEventsClasses.h"
     32 #include "DOMHTMLClasses.h"
     33 #include "WebKitGraphics.h"
     34 
     35 #include <WebCore/BString.h>
     36 #include <WebCore/COMPtr.h>
     37 #include <WebCore/DOMWindow.h>
     38 #include <WebCore/Document.h>
     39 #include <WebCore/Element.h>
     40 #include <WebCore/Frame.h>
     41 #include <WebCore/SimpleFontData.h>
     42 #include <WebCore/HTMLFormElement.h>
     43 #include <WebCore/HTMLInputElement.h>
     44 #include <WebCore/HTMLNames.h>
     45 #include <WebCore/HTMLOptionElement.h>
     46 #include <WebCore/HTMLSelectElement.h>
     47 #include <WebCore/HTMLTextAreaElement.h>
     48 #include <WebCore/NodeList.h>
     49 #include <WebCore/RenderObject.h>
     50 #include <WebCore/RenderTreeAsText.h>
     51 
     52 #include <initguid.h>
     53 // {3B0C0EFF-478B-4b0b-8290-D2321E08E23E}
     54 DEFINE_GUID(IID_DOMElement, 0x3b0c0eff, 0x478b, 0x4b0b, 0x82, 0x90, 0xd2, 0x32, 0x1e, 0x8, 0xe2, 0x3e);
     55 
     56 // Our normal style is just to say "using namespace WebCore" rather than having
     57 // individual using directives for each type from that namespace. But
     58 // "DOMObject" exists both in the WebCore namespace and unnamespaced in this
     59 // file, which leads to ambiguities if we say "using namespace WebCore".
     60 using namespace WebCore::HTMLNames;
     61 using WTF::AtomicString;
     62 using WebCore::BString;
     63 using WebCore::Element;
     64 using WebCore::ExceptionCode;
     65 using WebCore::FontDescription;
     66 using WebCore::Frame;
     67 using WebCore::IntRect;
     68 using WTF::String;
     69 
     70 // DOMObject - IUnknown -------------------------------------------------------
     71 
     72 HRESULT STDMETHODCALLTYPE DOMObject::QueryInterface(REFIID riid, void** ppvObject)
     73 {
     74     *ppvObject = 0;
     75     if (IsEqualGUID(riid, IID_IDOMObject))
     76         *ppvObject = static_cast<IDOMObject*>(this);
     77     else
     78         return WebScriptObject::QueryInterface(riid, ppvObject);
     79 
     80     AddRef();
     81     return S_OK;
     82 }
     83 
     84 // DOMNode - IUnknown ---------------------------------------------------------
     85 
     86 HRESULT STDMETHODCALLTYPE DOMNode::QueryInterface(REFIID riid, void** ppvObject)
     87 {
     88     *ppvObject = 0;
     89     if (IsEqualGUID(riid, IID_IDOMNode))
     90         *ppvObject = static_cast<IDOMNode*>(this);
     91     else if (IsEqualGUID(riid, __uuidof(DOMNode)))
     92         *ppvObject = static_cast<DOMNode*>(this);
     93     else
     94         return DOMObject::QueryInterface(riid, ppvObject);
     95 
     96     AddRef();
     97     return S_OK;
     98 }
     99 
    100 // DOMNode --------------------------------------------------------------------
    101 
    102 HRESULT STDMETHODCALLTYPE DOMNode::nodeName(
    103     /* [retval][out] */ BSTR* result)
    104 {
    105     if (!result)
    106         return E_POINTER;
    107 
    108     if (!m_node)
    109         return E_FAIL;
    110 
    111     *result = BString(m_node->nodeName()).release();
    112     return S_OK;
    113 }
    114 
    115 HRESULT STDMETHODCALLTYPE DOMNode::nodeValue(
    116     /* [retval][out] */ BSTR* result)
    117 {
    118     if (!m_node)
    119         return E_FAIL;
    120     WTF::String nodeValueStr = m_node->nodeValue();
    121     *result = SysAllocStringLen(nodeValueStr.characters(), nodeValueStr.length());
    122     if (nodeValueStr.length() && !*result)
    123         return E_OUTOFMEMORY;
    124     return S_OK;
    125 }
    126 
    127 HRESULT STDMETHODCALLTYPE DOMNode::setNodeValue(
    128     /* [in] */ BSTR /*value*/)
    129 {
    130     ASSERT_NOT_REACHED();
    131     return E_NOTIMPL;
    132 }
    133 
    134 HRESULT STDMETHODCALLTYPE DOMNode::nodeType(
    135     /* [retval][out] */ unsigned short* /*result*/)
    136 {
    137     ASSERT_NOT_REACHED();
    138     return E_NOTIMPL;
    139 }
    140 
    141 HRESULT STDMETHODCALLTYPE DOMNode::parentNode(
    142     /* [retval][out] */ IDOMNode** result)
    143 {
    144     *result = 0;
    145     if (!m_node || !m_node->parentNode())
    146         return E_FAIL;
    147     *result = DOMNode::createInstance(m_node->parentNode());
    148     return *result ? S_OK : E_FAIL;
    149 }
    150 
    151 HRESULT STDMETHODCALLTYPE DOMNode::childNodes(
    152     /* [retval][out] */ IDOMNodeList** result)
    153 {
    154     if (!m_node)
    155         return E_FAIL;
    156 
    157     if (!result)
    158         return E_POINTER;
    159 
    160     *result = DOMNodeList::createInstance(m_node->childNodes().get());
    161     return *result ? S_OK : E_FAIL;
    162 }
    163 
    164 HRESULT STDMETHODCALLTYPE DOMNode::firstChild(
    165     /* [retval][out] */ IDOMNode** /*result*/)
    166 {
    167     ASSERT_NOT_REACHED();
    168     return E_NOTIMPL;
    169 }
    170 
    171 HRESULT STDMETHODCALLTYPE DOMNode::lastChild(
    172     /* [retval][out] */ IDOMNode** /*result*/)
    173 {
    174     ASSERT_NOT_REACHED();
    175     return E_NOTIMPL;
    176 }
    177 
    178 HRESULT STDMETHODCALLTYPE DOMNode::previousSibling(
    179     /* [retval][out] */ IDOMNode** /*result*/)
    180 {
    181     ASSERT_NOT_REACHED();
    182     return E_NOTIMPL;
    183 }
    184 
    185 HRESULT STDMETHODCALLTYPE DOMNode::nextSibling(
    186     /* [retval][out] */ IDOMNode** result)
    187 {
    188     if (!result)
    189         return E_POINTER;
    190     *result = 0;
    191     if (!m_node)
    192         return E_FAIL;
    193     *result = DOMNode::createInstance(m_node->nextSibling());
    194     return *result ? S_OK : E_FAIL;
    195 }
    196 
    197 HRESULT STDMETHODCALLTYPE DOMNode::attributes(
    198     /* [retval][out] */ IDOMNamedNodeMap** /*result*/)
    199 {
    200     ASSERT_NOT_REACHED();
    201     return E_NOTIMPL;
    202 }
    203 
    204 HRESULT STDMETHODCALLTYPE DOMNode::ownerDocument(
    205     /* [retval][out] */ IDOMDocument** result)
    206 {
    207     if (!result)
    208         return E_POINTER;
    209     *result = 0;
    210     if (!m_node)
    211         return E_FAIL;
    212     *result = DOMDocument::createInstance(m_node->ownerDocument());
    213     return *result ? S_OK : E_FAIL;
    214 }
    215 
    216 HRESULT STDMETHODCALLTYPE DOMNode::insertBefore(
    217     /* [in] */ IDOMNode* newChild,
    218     /* [in] */ IDOMNode* refChild,
    219     /* [retval][out] */ IDOMNode** result)
    220 {
    221     if (!result)
    222         return E_POINTER;
    223 
    224     *result = 0;
    225 
    226     if (!m_node)
    227         return E_FAIL;
    228 
    229     COMPtr<DOMNode> newChildNode(Query, newChild);
    230     if (!newChildNode)
    231         return E_FAIL;
    232 
    233     COMPtr<DOMNode> refChildNode(Query, refChild);
    234 
    235     ExceptionCode ec;
    236     if (!m_node->insertBefore(newChildNode->node(), refChildNode ? refChildNode->node() : 0, ec))
    237         return E_FAIL;
    238 
    239     *result = newChild;
    240     (*result)->AddRef();
    241     return S_OK;
    242 }
    243 
    244 HRESULT STDMETHODCALLTYPE DOMNode::replaceChild(
    245     /* [in] */ IDOMNode* /*newChild*/,
    246     /* [in] */ IDOMNode* /*oldChild*/,
    247     /* [retval][out] */ IDOMNode** /*result*/)
    248 {
    249     ASSERT_NOT_REACHED();
    250     return E_NOTIMPL;
    251 }
    252 
    253 HRESULT STDMETHODCALLTYPE DOMNode::removeChild(
    254     /* [in] */ IDOMNode* oldChild,
    255     /* [retval][out] */ IDOMNode** result)
    256 {
    257     if (!result)
    258         return E_POINTER;
    259 
    260     *result = 0;
    261 
    262     if (!m_node)
    263         return E_FAIL;
    264 
    265     COMPtr<DOMNode> oldChildNode(Query, oldChild);
    266     if (!oldChildNode)
    267         return E_FAIL;
    268 
    269     ExceptionCode ec;
    270     if (!m_node->removeChild(oldChildNode->node(), ec))
    271         return E_FAIL;
    272 
    273     *result = oldChild;
    274     (*result)->AddRef();
    275     return S_OK;
    276 }
    277 
    278 HRESULT STDMETHODCALLTYPE DOMNode::appendChild(
    279     /* [in] */ IDOMNode* /*oldChild*/,
    280     /* [retval][out] */ IDOMNode** /*result*/)
    281 {
    282     ASSERT_NOT_REACHED();
    283     return E_NOTIMPL;
    284 }
    285 
    286 HRESULT STDMETHODCALLTYPE DOMNode::hasChildNodes(
    287     /* [retval][out] */ BOOL* /*result*/)
    288 {
    289     ASSERT_NOT_REACHED();
    290     return E_NOTIMPL;
    291 }
    292 
    293 HRESULT STDMETHODCALLTYPE DOMNode::cloneNode(
    294     /* [in] */ BOOL /*deep*/,
    295     /* [retval][out] */ IDOMNode** /*result*/)
    296 {
    297     ASSERT_NOT_REACHED();
    298     return E_NOTIMPL;
    299 }
    300 
    301 HRESULT STDMETHODCALLTYPE DOMNode::normalize( void)
    302 {
    303     ASSERT_NOT_REACHED();
    304     return E_NOTIMPL;
    305 }
    306 
    307 HRESULT STDMETHODCALLTYPE DOMNode::isSupported(
    308     /* [in] */ BSTR /*feature*/,
    309     /* [in] */ BSTR /*version*/,
    310     /* [retval][out] */ BOOL* /*result*/)
    311 {
    312     ASSERT_NOT_REACHED();
    313     return E_NOTIMPL;
    314 }
    315 
    316 HRESULT STDMETHODCALLTYPE DOMNode::namespaceURI(
    317     /* [retval][out] */ BSTR* /*result*/)
    318 {
    319     ASSERT_NOT_REACHED();
    320     return E_NOTIMPL;
    321 }
    322 
    323 HRESULT STDMETHODCALLTYPE DOMNode::prefix(
    324     /* [retval][out] */ BSTR* /*result*/)
    325 {
    326     ASSERT_NOT_REACHED();
    327     return E_NOTIMPL;
    328 }
    329 
    330 HRESULT STDMETHODCALLTYPE DOMNode::setPrefix(
    331     /* [in] */ BSTR /*prefix*/)
    332 {
    333     ASSERT_NOT_REACHED();
    334     return E_NOTIMPL;
    335 }
    336 
    337 HRESULT STDMETHODCALLTYPE DOMNode::localName(
    338     /* [retval][out] */ BSTR* /*result*/)
    339 {
    340     ASSERT_NOT_REACHED();
    341     return E_NOTIMPL;
    342 }
    343 
    344 HRESULT STDMETHODCALLTYPE DOMNode::hasAttributes(
    345     /* [retval][out] */ BOOL* /*result*/)
    346 {
    347     ASSERT_NOT_REACHED();
    348     return E_NOTIMPL;
    349 }
    350 
    351 HRESULT STDMETHODCALLTYPE DOMNode::isSameNode(
    352     /* [in] */ IDOMNode* other,
    353     /* [retval][out] */ BOOL* result)
    354 {
    355     if (!result) {
    356         ASSERT_NOT_REACHED();
    357         return E_POINTER;
    358     }
    359 
    360     *result = FALSE;
    361 
    362     if (!other)
    363         return E_POINTER;
    364 
    365     COMPtr<DOMNode> domOther;
    366     HRESULT hr = other->QueryInterface(__uuidof(DOMNode), (void**)&domOther);
    367     if (FAILED(hr))
    368         return hr;
    369 
    370     *result = m_node->isSameNode(domOther->node()) ? TRUE : FALSE;
    371     return S_OK;
    372 }
    373 
    374 HRESULT STDMETHODCALLTYPE DOMNode::isEqualNode(
    375     /* [in] */ IDOMNode* /*other*/,
    376     /* [retval][out] */ BOOL* /*result*/)
    377 {
    378     ASSERT_NOT_REACHED();
    379     return E_NOTIMPL;
    380 }
    381 
    382 HRESULT STDMETHODCALLTYPE DOMNode::textContent(
    383     /* [retval][out] */ BSTR* result)
    384 {
    385     if (!result)
    386         return E_POINTER;
    387 
    388     *result = BString(m_node->textContent()).release();
    389 
    390     return S_OK;
    391 }
    392 
    393 HRESULT STDMETHODCALLTYPE DOMNode::setTextContent(
    394     /* [in] */ BSTR /*text*/)
    395 {
    396     ASSERT_NOT_REACHED();
    397     return E_NOTIMPL;
    398 }
    399 
    400 // DOMNode - IDOMEventTarget --------------------------------------------------
    401 
    402 HRESULT STDMETHODCALLTYPE DOMNode::addEventListener(
    403     /* [in] */ BSTR /*type*/,
    404     /* [in] */ IDOMEventListener* /*listener*/,
    405     /* [in] */ BOOL /*useCapture*/)
    406 {
    407     return E_NOTIMPL;
    408 }
    409 
    410 HRESULT STDMETHODCALLTYPE DOMNode::removeEventListener(
    411     /* [in] */ BSTR /*type*/,
    412     /* [in] */ IDOMEventListener* /*listener*/,
    413     /* [in] */ BOOL /*useCapture*/)
    414 {
    415     return E_NOTIMPL;
    416 }
    417 
    418 HRESULT STDMETHODCALLTYPE DOMNode::dispatchEvent(
    419     /* [in] */ IDOMEvent* evt,
    420     /* [retval][out] */ BOOL* result)
    421 {
    422     if (!m_node || !evt)
    423         return E_FAIL;
    424 
    425 #if 0   // FIXME - raise dom exceptions
    426     if (![self _node]->isEventTargetNode())
    427         WebCore::raiseDOMException(DOM_NOT_SUPPORTED_ERR);
    428 #endif
    429 
    430     COMPtr<DOMEvent> domEvent;
    431     HRESULT hr = evt->QueryInterface(IID_DOMEvent, (void**) &domEvent);
    432     if (FAILED(hr))
    433         return hr;
    434 
    435     WebCore::ExceptionCode ec = 0;
    436     *result = m_node->dispatchEvent(domEvent->coreEvent(), ec) ? TRUE : FALSE;
    437 #if 0   // FIXME - raise dom exceptions
    438     WebCore::raiseOnDOMError(ec);
    439 #endif
    440     return S_OK;
    441 }
    442 
    443 // DOMNode - DOMNode ----------------------------------------------------------
    444 
    445 DOMNode::DOMNode(WebCore::Node* n)
    446 : m_node(0)
    447 {
    448     if (n)
    449         n->ref();
    450 
    451     m_node = n;
    452 }
    453 
    454 DOMNode::~DOMNode()
    455 {
    456     if (m_node)
    457         m_node->deref();
    458 }
    459 
    460 IDOMNode* DOMNode::createInstance(WebCore::Node* n)
    461 {
    462     if (!n)
    463         return 0;
    464 
    465     HRESULT hr = S_OK;
    466     IDOMNode* domNode = 0;
    467     WebCore::Node::NodeType nodeType = n->nodeType();
    468 
    469     switch (nodeType) {
    470         case WebCore::Node::ELEMENT_NODE:
    471         {
    472             IDOMElement* newElement = DOMElement::createInstance(static_cast<WebCore::Element*>(n));
    473             if (newElement) {
    474                 hr = newElement->QueryInterface(IID_IDOMNode, (void**)&domNode);
    475                 newElement->Release();
    476             }
    477         }
    478         break;
    479         case WebCore::Node::DOCUMENT_NODE:
    480         {
    481             IDOMDocument* newDocument = DOMDocument::createInstance(n->document());
    482             if (newDocument) {
    483                 hr = newDocument->QueryInterface(IID_IDOMNode, (void**)&domNode);
    484                 newDocument->Release();
    485             }
    486         }
    487         break;
    488         default:
    489         {
    490             DOMNode* newNode = new DOMNode(n);
    491             hr = newNode->QueryInterface(IID_IDOMNode, (void**)&domNode);
    492         }
    493         break;
    494     }
    495 
    496     if (FAILED(hr))
    497         return 0;
    498 
    499     return domNode;
    500 }
    501 
    502 // DOMNodeList - IUnknown -----------------------------------------------------
    503 
    504 HRESULT STDMETHODCALLTYPE DOMNodeList::QueryInterface(REFIID riid, void** ppvObject)
    505 {
    506     *ppvObject = 0;
    507     if (IsEqualGUID(riid, IID_IDOMNodeList))
    508         *ppvObject = static_cast<IDOMNodeList*>(this);
    509     else
    510         return DOMObject::QueryInterface(riid, ppvObject);
    511 
    512     AddRef();
    513     return S_OK;
    514 }
    515 
    516 // IDOMNodeList ---------------------------------------------------------------
    517 
    518 HRESULT STDMETHODCALLTYPE DOMNodeList::item(
    519     /* [in] */ UINT index,
    520     /* [retval][out] */ IDOMNode **result)
    521 {
    522     *result = 0;
    523     if (!m_nodeList)
    524         return E_FAIL;
    525 
    526     WebCore::Node* itemNode = m_nodeList->item(index);
    527     if (!itemNode)
    528         return E_FAIL;
    529 
    530     *result = DOMNode::createInstance(itemNode);
    531     return *result ? S_OK : E_FAIL;
    532 }
    533 
    534 HRESULT STDMETHODCALLTYPE DOMNodeList::length(
    535         /* [retval][out] */ UINT *result)
    536 {
    537     *result = 0;
    538     if (!m_nodeList)
    539         return E_FAIL;
    540     *result = m_nodeList->length();
    541     return S_OK;
    542 }
    543 
    544 // DOMNodeList - DOMNodeList --------------------------------------------------
    545 
    546 DOMNodeList::DOMNodeList(WebCore::NodeList* l)
    547 : m_nodeList(0)
    548 {
    549     if (l)
    550         l->ref();
    551 
    552     m_nodeList = l;
    553 }
    554 
    555 DOMNodeList::~DOMNodeList()
    556 {
    557     if (m_nodeList)
    558         m_nodeList->deref();
    559 }
    560 
    561 IDOMNodeList* DOMNodeList::createInstance(WebCore::NodeList* l)
    562 {
    563     if (!l)
    564         return 0;
    565 
    566     IDOMNodeList* domNodeList = 0;
    567     DOMNodeList* newNodeList = new DOMNodeList(l);
    568     if (FAILED(newNodeList->QueryInterface(IID_IDOMNodeList, (void**)&domNodeList)))
    569         return 0;
    570 
    571     return domNodeList;
    572 }
    573 
    574 // DOMDocument - IUnknown -----------------------------------------------------
    575 
    576 HRESULT STDMETHODCALLTYPE DOMDocument::QueryInterface(REFIID riid, void** ppvObject)
    577 {
    578     *ppvObject = 0;
    579     if (IsEqualGUID(riid, IID_IDOMDocument))
    580         *ppvObject = static_cast<IDOMDocument*>(this);
    581     else if (IsEqualGUID(riid, IID_IDOMViewCSS))
    582         *ppvObject = static_cast<IDOMViewCSS*>(this);
    583     else if (IsEqualGUID(riid, IID_IDOMDocumentEvent))
    584         *ppvObject = static_cast<IDOMDocumentEvent*>(this);
    585     else
    586         return DOMNode::QueryInterface(riid, ppvObject);
    587 
    588     AddRef();
    589     return S_OK;
    590 }
    591 
    592 // DOMDocument ----------------------------------------------------------------
    593 
    594 HRESULT STDMETHODCALLTYPE DOMDocument::doctype(
    595     /* [retval][out] */ IDOMDocumentType** /*result*/)
    596 {
    597     ASSERT_NOT_REACHED();
    598     return E_NOTIMPL;
    599 }
    600 
    601 HRESULT STDMETHODCALLTYPE DOMDocument::implementation(
    602     /* [retval][out] */ IDOMImplementation** /*result*/)
    603 {
    604     ASSERT_NOT_REACHED();
    605     return E_NOTIMPL;
    606 }
    607 
    608 HRESULT STDMETHODCALLTYPE DOMDocument::documentElement(
    609     /* [retval][out] */ IDOMElement** result)
    610 {
    611     *result = DOMElement::createInstance(m_document->documentElement());
    612     return *result ? S_OK : E_FAIL;
    613 }
    614 
    615 HRESULT STDMETHODCALLTYPE DOMDocument::createElement(
    616     /* [in] */ BSTR tagName,
    617     /* [retval][out] */ IDOMElement** result)
    618 {
    619     if (!m_document)
    620         return E_FAIL;
    621 
    622     String tagNameString(tagName);
    623     ExceptionCode ec;
    624     *result = DOMElement::createInstance(m_document->createElement(tagNameString, ec).get());
    625     return *result ? S_OK : E_FAIL;
    626 }
    627 
    628 HRESULT STDMETHODCALLTYPE DOMDocument::createDocumentFragment(
    629     /* [retval][out] */ IDOMDocumentFragment** /*result*/)
    630 {
    631     ASSERT_NOT_REACHED();
    632     return E_NOTIMPL;
    633 }
    634 
    635 HRESULT STDMETHODCALLTYPE DOMDocument::createTextNode(
    636     /* [in] */ BSTR /*data*/,
    637     /* [retval][out] */ IDOMText** /*result*/)
    638 {
    639     ASSERT_NOT_REACHED();
    640     return E_NOTIMPL;
    641 }
    642 
    643 HRESULT STDMETHODCALLTYPE DOMDocument::createComment(
    644     /* [in] */ BSTR /*data*/,
    645     /* [retval][out] */ IDOMComment** /*result*/)
    646 {
    647     ASSERT_NOT_REACHED();
    648     return E_NOTIMPL;
    649 }
    650 
    651 HRESULT STDMETHODCALLTYPE DOMDocument::createCDATASection(
    652     /* [in] */ BSTR /*data*/,
    653     /* [retval][out] */ IDOMCDATASection** /*result*/)
    654 {
    655     ASSERT_NOT_REACHED();
    656     return E_NOTIMPL;
    657 }
    658 
    659 HRESULT STDMETHODCALLTYPE DOMDocument::createProcessingInstruction(
    660     /* [in] */ BSTR /*target*/,
    661     /* [in] */ BSTR /*data*/,
    662     /* [retval][out] */ IDOMProcessingInstruction** /*result*/)
    663 {
    664     ASSERT_NOT_REACHED();
    665     return E_NOTIMPL;
    666 }
    667 
    668 HRESULT STDMETHODCALLTYPE DOMDocument::createAttribute(
    669     /* [in] */ BSTR /*name*/,
    670     /* [retval][out] */ IDOMAttr** /*result*/)
    671 {
    672     ASSERT_NOT_REACHED();
    673     return E_NOTIMPL;
    674 }
    675 
    676 HRESULT STDMETHODCALLTYPE DOMDocument::createEntityReference(
    677     /* [in] */ BSTR /*name*/,
    678     /* [retval][out] */ IDOMEntityReference** /*result*/)
    679 {
    680     ASSERT_NOT_REACHED();
    681     return E_NOTIMPL;
    682 }
    683 
    684 HRESULT STDMETHODCALLTYPE DOMDocument::getElementsByTagName(
    685     /* [in] */ BSTR tagName,
    686     /* [retval][out] */ IDOMNodeList** result)
    687 {
    688     if (!m_document)
    689         return E_FAIL;
    690 
    691     String tagNameString(tagName);
    692     *result = DOMNodeList::createInstance(m_document->getElementsByTagName(tagNameString).get());
    693     return *result ? S_OK : E_FAIL;
    694 }
    695 
    696 HRESULT STDMETHODCALLTYPE DOMDocument::importNode(
    697     /* [in] */ IDOMNode* /*importedNode*/,
    698     /* [in] */ BOOL /*deep*/,
    699     /* [retval][out] */ IDOMNode** /*result*/)
    700 {
    701     ASSERT_NOT_REACHED();
    702     return E_NOTIMPL;
    703 }
    704 
    705 HRESULT STDMETHODCALLTYPE DOMDocument::createElementNS(
    706     /* [in] */ BSTR /*namespaceURI*/,
    707     /* [in] */ BSTR /*qualifiedName*/,
    708     /* [retval][out] */ IDOMElement** /*result*/)
    709 {
    710     ASSERT_NOT_REACHED();
    711     return E_NOTIMPL;
    712 }
    713 
    714 HRESULT STDMETHODCALLTYPE DOMDocument::createAttributeNS(
    715     /* [in] */ BSTR /*namespaceURI*/,
    716     /* [in] */ BSTR /*qualifiedName*/,
    717     /* [retval][out] */ IDOMAttr** /*result*/)
    718 {
    719     ASSERT_NOT_REACHED();
    720     return E_NOTIMPL;
    721 }
    722 
    723 HRESULT STDMETHODCALLTYPE DOMDocument::getElementsByTagNameNS(
    724     /* [in] */ BSTR namespaceURI,
    725     /* [in] */ BSTR localName,
    726     /* [retval][out] */ IDOMNodeList** result)
    727 {
    728     if (!m_document)
    729         return E_FAIL;
    730 
    731     String namespaceURIString(namespaceURI);
    732     String localNameString(localName);
    733     *result = DOMNodeList::createInstance(m_document->getElementsByTagNameNS(namespaceURIString, localNameString).get());
    734     return *result ? S_OK : E_FAIL;
    735 }
    736 
    737 HRESULT STDMETHODCALLTYPE DOMDocument::getElementById(
    738     /* [in] */ BSTR elementId,
    739     /* [retval][out] */ IDOMElement** result)
    740 {
    741     if (!m_document)
    742         return E_FAIL;
    743 
    744     String idString(elementId);
    745     *result = DOMElement::createInstance(m_document->getElementById(idString));
    746     return *result ? S_OK : E_FAIL;
    747 }
    748 
    749 // DOMDocument - IDOMViewCSS --------------------------------------------------
    750 
    751 HRESULT STDMETHODCALLTYPE DOMDocument::getComputedStyle(
    752     /* [in] */ IDOMElement* elt,
    753     /* [in] */ BSTR pseudoElt,
    754     /* [retval][out] */ IDOMCSSStyleDeclaration** result)
    755 {
    756     if (!elt || !result)
    757         return E_POINTER;
    758 
    759     COMPtr<DOMElement> domEle;
    760     HRESULT hr = elt->QueryInterface(IID_DOMElement, (void**)&domEle);
    761     if (FAILED(hr))
    762         return hr;
    763     Element* element = domEle->element();
    764 
    765     WebCore::DOMWindow* dv = m_document->defaultView();
    766     String pseudoEltString(pseudoElt);
    767 
    768     if (!dv)
    769         return E_FAIL;
    770 
    771     *result = DOMCSSStyleDeclaration::createInstance(dv->getComputedStyle(element, pseudoEltString.impl()).get());
    772     return *result ? S_OK : E_FAIL;
    773 }
    774 
    775 // DOMDocument - IDOMDocumentEvent --------------------------------------------
    776 
    777 HRESULT STDMETHODCALLTYPE DOMDocument::createEvent(
    778     /* [in] */ BSTR eventType,
    779     /* [retval][out] */ IDOMEvent **result)
    780 {
    781     String eventTypeString(eventType, SysStringLen(eventType));
    782     WebCore::ExceptionCode ec = 0;
    783     *result = DOMEvent::createInstance(m_document->createEvent(eventTypeString, ec));
    784     return *result ? S_OK : E_FAIL;
    785 }
    786 
    787 // DOMDocument - DOMDocument --------------------------------------------------
    788 
    789 DOMDocument::DOMDocument(WebCore::Document* d)
    790 : DOMNode(d)
    791 , m_document(d)
    792 {
    793 }
    794 
    795 DOMDocument::~DOMDocument()
    796 {
    797 }
    798 
    799 IDOMDocument* DOMDocument::createInstance(WebCore::Document* d)
    800 {
    801     if (!d)
    802         return 0;
    803 
    804     HRESULT hr;
    805     IDOMDocument* domDocument = 0;
    806 
    807     if (d->isHTMLDocument()) {
    808         DOMHTMLDocument* newDocument = new DOMHTMLDocument(d);
    809         hr = newDocument->QueryInterface(IID_IDOMDocument, (void**)&domDocument);
    810     } else {
    811         DOMDocument* newDocument = new DOMDocument(d);
    812         hr = newDocument->QueryInterface(IID_IDOMDocument, (void**)&domDocument);
    813     }
    814 
    815     if (FAILED(hr))
    816         return 0;
    817 
    818     return domDocument;
    819 }
    820 
    821 // DOMElement - IUnknown ------------------------------------------------------
    822 
    823 HRESULT STDMETHODCALLTYPE DOMElement::QueryInterface(REFIID riid, void** ppvObject)
    824 {
    825     *ppvObject = 0;
    826     if (IsEqualGUID(riid, IID_IDOMElement))
    827         *ppvObject = static_cast<IDOMElement*>(this);
    828     else if (IsEqualGUID(riid, IID_DOMElement))
    829         *ppvObject = static_cast<DOMElement*>(this);
    830     else if (IsEqualGUID(riid, IID_IDOMElementPrivate))
    831         *ppvObject = static_cast<IDOMElementPrivate*>(this);
    832     else if (IsEqualGUID(riid, IID_IDOMNodeExtensions))
    833         *ppvObject = static_cast<IDOMNodeExtensions*>(this);
    834     else if (IsEqualGUID(riid, IID_IDOMElementCSSInlineStyle))
    835         *ppvObject = static_cast<IDOMElementCSSInlineStyle*>(this);
    836     else if (IsEqualGUID(riid, IID_IDOMElementExtensions))
    837         *ppvObject = static_cast<IDOMElementExtensions*>(this);
    838     else
    839         return DOMNode::QueryInterface(riid, ppvObject);
    840 
    841     AddRef();
    842     return S_OK;
    843 }
    844 
    845 // DOMElement - IDOMNodeExtensions---------------------------------------------
    846 
    847 HRESULT STDMETHODCALLTYPE DOMElement::boundingBox(
    848     /* [retval][out] */ LPRECT rect)
    849 {
    850     ::SetRectEmpty(rect);
    851 
    852     if (!m_element)
    853         return E_FAIL;
    854 
    855     WebCore::RenderObject *renderer = m_element->renderer();
    856     if (renderer) {
    857         IntRect boundsIntRect = renderer->absoluteBoundingBoxRect();
    858         rect->left = boundsIntRect.x();
    859         rect->top = boundsIntRect.y();
    860         rect->right = boundsIntRect.x() + boundsIntRect.width();
    861         rect->bottom = boundsIntRect.y() + boundsIntRect.height();
    862     }
    863 
    864     return S_OK;
    865 }
    866 
    867 HRESULT STDMETHODCALLTYPE DOMElement::lineBoxRects(
    868     /* [size_is][in] */ RECT* /*rects*/,
    869     /* [in] */ int /*cRects*/)
    870 {
    871     return E_NOTIMPL;
    872 }
    873 
    874 // IDOMElement ----------------------------------------------------------------
    875 
    876 HRESULT STDMETHODCALLTYPE DOMElement::tagName(
    877         /* [retval][out] */ BSTR* result)
    878 {
    879     if (!m_element)
    880         return E_FAIL;
    881 
    882     if (!result)
    883         return E_POINTER;
    884 
    885     *result = BString(m_element->tagName()).release();
    886     return S_OK;
    887 }
    888 
    889 HRESULT STDMETHODCALLTYPE DOMElement::getAttribute(
    890         /* [in] */ BSTR name,
    891         /* [retval][out] */ BSTR* result)
    892 {
    893     if (!m_element)
    894         return E_FAIL;
    895     WTF::String nameString(name, SysStringLen(name));
    896     WTF::String& attrValueString = (WTF::String&) m_element->getAttribute(nameString);
    897     *result = SysAllocStringLen(attrValueString.characters(), attrValueString.length());
    898     if (attrValueString.length() && !*result)
    899         return E_OUTOFMEMORY;
    900     return S_OK;
    901 }
    902 
    903 HRESULT STDMETHODCALLTYPE DOMElement::setAttribute(
    904         /* [in] */ BSTR name,
    905         /* [in] */ BSTR value)
    906 {
    907     if (!m_element)
    908         return E_FAIL;
    909 
    910     WTF::String nameString(name, SysStringLen(name));
    911     WTF::String valueString(value, SysStringLen(value));
    912     WebCore::ExceptionCode ec = 0;
    913     m_element->setAttribute(nameString, valueString, ec);
    914     return ec ? E_FAIL : S_OK;
    915 }
    916 
    917 HRESULT STDMETHODCALLTYPE DOMElement::removeAttribute(
    918         /* [in] */ BSTR /*name*/)
    919 {
    920     ASSERT_NOT_REACHED();
    921     return E_NOTIMPL;
    922 }
    923 
    924 HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNode(
    925         /* [in] */ BSTR /*name*/,
    926         /* [retval][out] */ IDOMAttr** /*result*/)
    927 {
    928     ASSERT_NOT_REACHED();
    929     return E_NOTIMPL;
    930 }
    931 
    932 HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNode(
    933         /* [in] */ IDOMAttr* /*newAttr*/,
    934         /* [retval][out] */ IDOMAttr** /*result*/)
    935 {
    936     ASSERT_NOT_REACHED();
    937     return E_NOTIMPL;
    938 }
    939 
    940 HRESULT STDMETHODCALLTYPE DOMElement::removeAttributeNode(
    941         /* [in] */ IDOMAttr* /*oldAttr*/,
    942         /* [retval][out] */ IDOMAttr** /*result*/)
    943 {
    944     ASSERT_NOT_REACHED();
    945     return E_NOTIMPL;
    946 }
    947 
    948 HRESULT STDMETHODCALLTYPE DOMElement::getElementsByTagName(
    949         /* [in] */ BSTR /*name*/,
    950         /* [retval][out] */ IDOMNodeList** /*result*/)
    951 {
    952     ASSERT_NOT_REACHED();
    953     return E_NOTIMPL;
    954 }
    955 
    956 HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNS(
    957         /* [in] */ BSTR /*namespaceURI*/,
    958         /* [in] */ BSTR /*localName*/,
    959         /* [retval][out] */ BSTR* /*result*/)
    960 {
    961     ASSERT_NOT_REACHED();
    962     return E_NOTIMPL;
    963 }
    964 
    965 HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNS(
    966         /* [in] */ BSTR /*namespaceURI*/,
    967         /* [in] */ BSTR /*qualifiedName*/,
    968         /* [in] */ BSTR /*value*/)
    969 {
    970     ASSERT_NOT_REACHED();
    971     return E_NOTIMPL;
    972 }
    973 
    974 HRESULT STDMETHODCALLTYPE DOMElement::removeAttributeNS(
    975         /* [in] */ BSTR /*namespaceURI*/,
    976         /* [in] */ BSTR /*localName*/)
    977 {
    978     ASSERT_NOT_REACHED();
    979     return E_NOTIMPL;
    980 }
    981 
    982 HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNodeNS(
    983         /* [in] */ BSTR /*namespaceURI*/,
    984         /* [in] */ BSTR /*localName*/,
    985         /* [retval][out] */ IDOMAttr** /*result*/)
    986 {
    987     ASSERT_NOT_REACHED();
    988     return E_NOTIMPL;
    989 }
    990 
    991 HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNodeNS(
    992         /* [in] */ IDOMAttr* /*newAttr*/,
    993         /* [retval][out] */ IDOMAttr** /*result*/)
    994 {
    995     ASSERT_NOT_REACHED();
    996     return E_NOTIMPL;
    997 }
    998 
    999 HRESULT STDMETHODCALLTYPE DOMElement::getElementsByTagNameNS(
   1000         /* [in] */ BSTR /*namespaceURI*/,
   1001         /* [in] */ BSTR /*localName*/,
   1002         /* [retval][out] */ IDOMNodeList** /*result*/)
   1003 {
   1004     ASSERT_NOT_REACHED();
   1005     return E_NOTIMPL;
   1006 }
   1007 
   1008 HRESULT STDMETHODCALLTYPE DOMElement::hasAttribute(
   1009         /* [in] */ BSTR /*name*/,
   1010         /* [retval][out] */ BOOL* /*result*/)
   1011 {
   1012     ASSERT_NOT_REACHED();
   1013     return E_NOTIMPL;
   1014 }
   1015 
   1016 HRESULT STDMETHODCALLTYPE DOMElement::hasAttributeNS(
   1017         /* [in] */ BSTR /*namespaceURI*/,
   1018         /* [in] */ BSTR /*localName*/,
   1019         /* [retval][out] */ BOOL* /*result*/)
   1020 {
   1021     ASSERT_NOT_REACHED();
   1022     return E_NOTIMPL;
   1023 }
   1024 
   1025 HRESULT STDMETHODCALLTYPE DOMElement::focus( void)
   1026 {
   1027     if (!m_element)
   1028         return E_FAIL;
   1029     m_element->focus();
   1030     return S_OK;
   1031 }
   1032 
   1033 HRESULT STDMETHODCALLTYPE DOMElement::blur( void)
   1034 {
   1035     if (!m_element)
   1036         return E_FAIL;
   1037     m_element->blur();
   1038     return S_OK;
   1039 }
   1040 
   1041 // IDOMElementPrivate ---------------------------------------------------------
   1042 
   1043 HRESULT DOMElement::coreElement(void **element)
   1044 {
   1045     if (!m_element)
   1046         return E_FAIL;
   1047     *element = (void*) m_element;
   1048     return S_OK;
   1049 }
   1050 
   1051 HRESULT STDMETHODCALLTYPE DOMElement::isEqual(
   1052     /* [in] */ IDOMElement *other,
   1053     /* [retval][out] */ BOOL *result)
   1054 {
   1055     *result = FALSE;
   1056 
   1057     if (!other || !result)
   1058         return E_POINTER;
   1059 
   1060     IDOMElementPrivate* otherPriv;
   1061     HRESULT hr = other->QueryInterface(IID_IDOMElementPrivate, (void**) &otherPriv);
   1062     if (FAILED(hr))
   1063         return hr;
   1064 
   1065     void* otherCoreEle;
   1066     hr = otherPriv->coreElement(&otherCoreEle);
   1067     otherPriv->Release();
   1068     if (FAILED(hr))
   1069         return hr;
   1070 
   1071     *result = (otherCoreEle == (void*)m_element) ? TRUE : FALSE;
   1072     return S_OK;
   1073 }
   1074 
   1075 HRESULT STDMETHODCALLTYPE DOMElement::isFocused(
   1076     /* [retval][out] */ BOOL *result)
   1077 {
   1078     if (!m_element)
   1079         return E_FAIL;
   1080 
   1081     if (m_element->document()->focusedNode() == m_element)
   1082         *result = TRUE;
   1083     else
   1084         *result = FALSE;
   1085 
   1086     return S_OK;
   1087 }
   1088 
   1089 HRESULT STDMETHODCALLTYPE DOMElement::innerText(
   1090     /* [retval][out] */ BSTR* result)
   1091 {
   1092     if (!result) {
   1093         ASSERT_NOT_REACHED();
   1094         return E_POINTER;
   1095     }
   1096 
   1097     if (!m_element) {
   1098         ASSERT_NOT_REACHED();
   1099         return E_FAIL;
   1100     }
   1101 
   1102     *result = BString(m_element->innerText()).release();
   1103     return S_OK;
   1104 }
   1105 
   1106 HRESULT STDMETHODCALLTYPE DOMElement::font(WebFontDescription* webFontDescription)
   1107 {
   1108     if (!webFontDescription) {
   1109         ASSERT_NOT_REACHED();
   1110         return E_POINTER;
   1111     }
   1112 
   1113     ASSERT(m_element);
   1114 
   1115     WebCore::RenderObject* renderer = m_element->renderer();
   1116     if (!renderer)
   1117         return E_FAIL;
   1118 
   1119     FontDescription fontDescription = renderer->style()->font().fontDescription();
   1120     AtomicString family = fontDescription.family().family();
   1121     webFontDescription->family = family.characters();
   1122     webFontDescription->familyLength = family.length();
   1123     webFontDescription->size = fontDescription.computedSize();
   1124     webFontDescription->bold = fontDescription.weight() >= WebCore::FontWeight600;
   1125     webFontDescription->italic = fontDescription.italic();
   1126 
   1127     return S_OK;
   1128 }
   1129 
   1130 HRESULT STDMETHODCALLTYPE DOMElement::renderedImage(HBITMAP* image)
   1131 {
   1132     if (!image) {
   1133         ASSERT_NOT_REACHED();
   1134         return E_POINTER;
   1135     }
   1136     *image = 0;
   1137 
   1138     ASSERT(m_element);
   1139 
   1140     Frame* frame = m_element->document()->frame();
   1141     if (!frame)
   1142         return E_FAIL;
   1143 
   1144     *image = frame->nodeImage(m_element);
   1145     if (!*image)
   1146         return E_FAIL;
   1147 
   1148     return S_OK;
   1149 }
   1150 
   1151 HRESULT STDMETHODCALLTYPE DOMElement::markerTextForListItem(
   1152     /* [retval][out] */ BSTR* markerText)
   1153 {
   1154     if (!markerText)
   1155         return E_POINTER;
   1156 
   1157     ASSERT(m_element);
   1158 
   1159     *markerText = BString(WebCore::markerTextForListItem(m_element)).release();
   1160     return S_OK;
   1161 }
   1162 
   1163 // IDOMElementCSSInlineStyle --------------------------------------------------
   1164 
   1165 HRESULT STDMETHODCALLTYPE DOMElement::style(
   1166     /* [retval][out] */ IDOMCSSStyleDeclaration** result)
   1167 {
   1168     if (!result)
   1169         return E_POINTER;
   1170     if (!m_element)
   1171         return E_FAIL;
   1172 
   1173     WebCore::CSSStyleDeclaration* style = m_element->style();
   1174     if (!style)
   1175         return E_FAIL;
   1176 
   1177     *result = DOMCSSStyleDeclaration::createInstance(style);
   1178     return *result ? S_OK : E_FAIL;
   1179 }
   1180 
   1181 // IDOMElementExtensions ------------------------------------------------------
   1182 
   1183 HRESULT STDMETHODCALLTYPE DOMElement::offsetLeft(
   1184     /* [retval][out] */ int* result)
   1185 {
   1186     if (!m_element)
   1187         return E_FAIL;
   1188 
   1189     *result = m_element->offsetLeft();
   1190     return S_OK;
   1191 }
   1192 
   1193 HRESULT STDMETHODCALLTYPE DOMElement::offsetTop(
   1194     /* [retval][out] */ int* result)
   1195 {
   1196     if (!m_element)
   1197         return E_FAIL;
   1198 
   1199     *result = m_element->offsetTop();
   1200     return S_OK;
   1201 }
   1202 
   1203 HRESULT STDMETHODCALLTYPE DOMElement::offsetWidth(
   1204     /* [retval][out] */ int* result)
   1205 {
   1206     if (!m_element)
   1207         return E_FAIL;
   1208 
   1209     *result = m_element->offsetWidth();
   1210     return S_OK;
   1211 }
   1212 
   1213 HRESULT STDMETHODCALLTYPE DOMElement::offsetHeight(
   1214     /* [retval][out] */ int* result)
   1215 {
   1216     if (!m_element)
   1217         return E_FAIL;
   1218 
   1219     *result = m_element->offsetHeight();
   1220     return S_OK;
   1221 }
   1222 
   1223 HRESULT STDMETHODCALLTYPE DOMElement::offsetParent(
   1224     /* [retval][out] */ IDOMElement** /*result*/)
   1225 {
   1226     // FIXME
   1227     ASSERT_NOT_REACHED();
   1228     return E_NOTIMPL;
   1229 }
   1230 
   1231 HRESULT STDMETHODCALLTYPE DOMElement::clientWidth(
   1232     /* [retval][out] */ int* result)
   1233 {
   1234     if (!m_element)
   1235         return E_FAIL;
   1236 
   1237     *result = m_element->clientWidth();
   1238     return S_OK;
   1239 }
   1240 
   1241 HRESULT STDMETHODCALLTYPE DOMElement::clientHeight(
   1242     /* [retval][out] */ int* result)
   1243 {
   1244     if (!m_element)
   1245         return E_FAIL;
   1246 
   1247     *result = m_element->clientHeight();
   1248     return S_OK;
   1249 }
   1250 
   1251 HRESULT STDMETHODCALLTYPE DOMElement::scrollLeft(
   1252     /* [retval][out] */ int* result)
   1253 {
   1254     if (!m_element)
   1255         return E_FAIL;
   1256 
   1257     *result = m_element->scrollLeft();
   1258     return S_OK;
   1259 }
   1260 
   1261 HRESULT STDMETHODCALLTYPE DOMElement::setScrollLeft(
   1262     /* [in] */ int /*newScrollLeft*/)
   1263 {
   1264     // FIXME
   1265     ASSERT_NOT_REACHED();
   1266     return E_NOTIMPL;
   1267 }
   1268 
   1269 HRESULT STDMETHODCALLTYPE DOMElement::scrollTop(
   1270     /* [retval][out] */ int* result)
   1271 {
   1272     if (!m_element)
   1273         return E_FAIL;
   1274 
   1275     *result = m_element->scrollTop();
   1276     return S_OK;
   1277 }
   1278 
   1279 HRESULT STDMETHODCALLTYPE DOMElement::setScrollTop(
   1280     /* [in] */ int /*newScrollTop*/)
   1281 {
   1282     // FIXME
   1283     ASSERT_NOT_REACHED();
   1284     return E_NOTIMPL;
   1285 }
   1286 
   1287 HRESULT STDMETHODCALLTYPE DOMElement::scrollWidth(
   1288     /* [retval][out] */ int* result)
   1289 {
   1290     if (!m_element)
   1291         return E_FAIL;
   1292 
   1293     *result = m_element->scrollWidth();
   1294     return S_OK;
   1295 }
   1296 
   1297 HRESULT STDMETHODCALLTYPE DOMElement::scrollHeight(
   1298     /* [retval][out] */ int* result)
   1299 {
   1300     if (!m_element)
   1301         return E_FAIL;
   1302 
   1303     *result = m_element->scrollHeight();
   1304     return S_OK;
   1305 }
   1306 
   1307 HRESULT STDMETHODCALLTYPE DOMElement::scrollIntoView(
   1308     /* [in] */ BOOL alignWithTop)
   1309 {
   1310     if (!m_element)
   1311         return E_FAIL;
   1312 
   1313     m_element->scrollIntoView(!!alignWithTop);
   1314     return S_OK;
   1315 }
   1316 
   1317 HRESULT STDMETHODCALLTYPE DOMElement::scrollIntoViewIfNeeded(
   1318     /* [in] */ BOOL centerIfNeeded)
   1319 {
   1320     if (!m_element)
   1321         return E_FAIL;
   1322 
   1323     m_element->scrollIntoViewIfNeeded(!!centerIfNeeded);
   1324     return S_OK;
   1325 }
   1326 
   1327 // DOMElement -----------------------------------------------------------------
   1328 
   1329 DOMElement::DOMElement(WebCore::Element* e)
   1330 : DOMNode(e)
   1331 , m_element(e)
   1332 {
   1333 }
   1334 
   1335 DOMElement::~DOMElement()
   1336 {
   1337 }
   1338 
   1339 IDOMElement* DOMElement::createInstance(WebCore::Element* e)
   1340 {
   1341     if (!e)
   1342         return 0;
   1343 
   1344     HRESULT hr;
   1345     IDOMElement* domElement = 0;
   1346 
   1347     if (e->hasTagName(formTag)) {
   1348         DOMHTMLFormElement* newElement = new DOMHTMLFormElement(e);
   1349         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
   1350     } else if (e->hasTagName(iframeTag)) {
   1351         DOMHTMLIFrameElement* newElement = new DOMHTMLIFrameElement(e);
   1352         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
   1353     } else if (e->hasTagName(inputTag)) {
   1354         DOMHTMLInputElement* newElement = new DOMHTMLInputElement(e);
   1355         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
   1356     } else if (e->hasTagName(optionTag)) {
   1357         DOMHTMLOptionElement* newElement = new DOMHTMLOptionElement(e);
   1358         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
   1359     } else if (e->hasTagName(selectTag)) {
   1360         DOMHTMLSelectElement* newElement = new DOMHTMLSelectElement(e);
   1361         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
   1362     } else if (e->hasTagName(textareaTag)) {
   1363         DOMHTMLTextAreaElement* newElement = new DOMHTMLTextAreaElement(e);
   1364         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
   1365     } else if (e->isHTMLElement()) {
   1366         DOMHTMLElement* newElement = new DOMHTMLElement(e);
   1367         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
   1368     } else {
   1369         DOMElement* newElement = new DOMElement(e);
   1370         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
   1371     }
   1372 
   1373     if (FAILED(hr))
   1374         return 0;
   1375 
   1376     return domElement;
   1377 }
   1378