/* * Copyright (C) 2006, 2007, 2009 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 COMPUTER, 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 COMPUTER, 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 "config.h" #include "WebKitDLL.h" #include "DOMCoreClasses.h" #include "COMPtr.h" #include "DOMCSSClasses.h" #include "DOMEventsClasses.h" #include "DOMHTMLClasses.h" #include "WebKitGraphics.h" #pragma warning(push, 0) #include <WebCore/BString.h> #include <WebCore/DOMWindow.h> #include <WebCore/Document.h> #include <WebCore/Element.h> #include <WebCore/Frame.h> #include <WebCore/SimpleFontData.h> #include <WebCore/HTMLFormElement.h> #include <WebCore/HTMLInputElement.h> #include <WebCore/HTMLNames.h> #include <WebCore/HTMLOptionElement.h> #include <WebCore/HTMLSelectElement.h> #include <WebCore/HTMLTextAreaElement.h> #include <WebCore/NodeList.h> #include <WebCore/RenderObject.h> #pragma warning(pop) #include <initguid.h> // {3B0C0EFF-478B-4b0b-8290-D2321E08E23E} DEFINE_GUID(IID_DOMElement, 0x3b0c0eff, 0x478b, 0x4b0b, 0x82, 0x90, 0xd2, 0x32, 0x1e, 0x8, 0xe2, 0x3e); // Our normal style is just to say "using namespace WebCore" rather than having // individual using directives for each type from that namespace. But // "DOMObject" exists both in the WebCore namespace and unnamespaced in this // file, which leads to ambiguities if we say "using namespace WebCore". using namespace WebCore::HTMLNames; using WebCore::AtomicString; using WebCore::BString; using WebCore::Element; using WebCore::ExceptionCode; using WebCore::FontDescription; using WebCore::Frame; using WebCore::IntRect; using WebCore::String; // DOMObject - IUnknown ------------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMObject::QueryInterface(REFIID riid, void** ppvObject) { *ppvObject = 0; if (IsEqualGUID(riid, IID_IDOMObject)) *ppvObject = static_cast<IDOMObject*>(this); else return WebScriptObject::QueryInterface(riid, ppvObject); AddRef(); return S_OK; } // DOMNode - IUnknown --------------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMNode::QueryInterface(REFIID riid, void** ppvObject) { *ppvObject = 0; if (IsEqualGUID(riid, IID_IDOMNode)) *ppvObject = static_cast<IDOMNode*>(this); else if (IsEqualGUID(riid, __uuidof(DOMNode))) *ppvObject = static_cast<DOMNode*>(this); else return DOMObject::QueryInterface(riid, ppvObject); AddRef(); return S_OK; } // DOMNode -------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMNode::nodeName( /* [retval][out] */ BSTR* result) { if (!result) return E_POINTER; if (!m_node) return E_FAIL; *result = BString(m_node->nodeName()).release(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMNode::nodeValue( /* [retval][out] */ BSTR* result) { if (!m_node) return E_FAIL; WebCore::String nodeValueStr = m_node->nodeValue(); *result = SysAllocStringLen(nodeValueStr.characters(), nodeValueStr.length()); if (nodeValueStr.length() && !*result) return E_OUTOFMEMORY; return S_OK; } HRESULT STDMETHODCALLTYPE DOMNode::setNodeValue( /* [in] */ BSTR /*value*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::nodeType( /* [retval][out] */ unsigned short* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::parentNode( /* [retval][out] */ IDOMNode** result) { *result = 0; if (!m_node || !m_node->parentNode()) return E_FAIL; *result = DOMNode::createInstance(m_node->parentNode()); return *result ? S_OK : E_FAIL; } HRESULT STDMETHODCALLTYPE DOMNode::childNodes( /* [retval][out] */ IDOMNodeList** result) { if (!m_node) return E_FAIL; if (!result) return E_POINTER; *result = DOMNodeList::createInstance(m_node->childNodes().get()); return *result ? S_OK : E_FAIL; } HRESULT STDMETHODCALLTYPE DOMNode::firstChild( /* [retval][out] */ IDOMNode** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::lastChild( /* [retval][out] */ IDOMNode** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::previousSibling( /* [retval][out] */ IDOMNode** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::nextSibling( /* [retval][out] */ IDOMNode** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::attributes( /* [retval][out] */ IDOMNamedNodeMap** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::ownerDocument( /* [retval][out] */ IDOMDocument** result) { if (!result) return E_POINTER; *result = 0; if (!m_node) return E_FAIL; *result = DOMDocument::createInstance(m_node->ownerDocument()); return *result ? S_OK : E_FAIL; } HRESULT STDMETHODCALLTYPE DOMNode::insertBefore( /* [in] */ IDOMNode* /*newChild*/, /* [in] */ IDOMNode* /*refChild*/, /* [retval][out] */ IDOMNode** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::replaceChild( /* [in] */ IDOMNode* /*newChild*/, /* [in] */ IDOMNode* /*oldChild*/, /* [retval][out] */ IDOMNode** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::removeChild( /* [in] */ IDOMNode* /*oldChild*/, /* [retval][out] */ IDOMNode** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::appendChild( /* [in] */ IDOMNode* /*oldChild*/, /* [retval][out] */ IDOMNode** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::hasChildNodes( /* [retval][out] */ BOOL* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::cloneNode( /* [in] */ BOOL /*deep*/, /* [retval][out] */ IDOMNode** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::normalize( void) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::isSupported( /* [in] */ BSTR /*feature*/, /* [in] */ BSTR /*version*/, /* [retval][out] */ BOOL* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::namespaceURI( /* [retval][out] */ BSTR* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::prefix( /* [retval][out] */ BSTR* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::setPrefix( /* [in] */ BSTR /*prefix*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::localName( /* [retval][out] */ BSTR* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::hasAttributes( /* [retval][out] */ BOOL* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::isSameNode( /* [in] */ IDOMNode* other, /* [retval][out] */ BOOL* result) { if (!result) { ASSERT_NOT_REACHED(); return E_POINTER; } *result = FALSE; if (!other) return E_POINTER; COMPtr<DOMNode> domOther; HRESULT hr = other->QueryInterface(__uuidof(DOMNode), (void**)&domOther); if (FAILED(hr)) return hr; *result = m_node->isSameNode(domOther->node()) ? TRUE : FALSE; return S_OK; } HRESULT STDMETHODCALLTYPE DOMNode::isEqualNode( /* [in] */ IDOMNode* /*other*/, /* [retval][out] */ BOOL* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::textContent( /* [retval][out] */ BSTR* result) { if (!result) return E_POINTER; *result = BString(m_node->textContent()).release(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMNode::setTextContent( /* [in] */ BSTR /*text*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } // DOMNode - IDOMEventTarget -------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMNode::addEventListener( /* [in] */ BSTR /*type*/, /* [in] */ IDOMEventListener* /*listener*/, /* [in] */ BOOL /*useCapture*/) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::removeEventListener( /* [in] */ BSTR /*type*/, /* [in] */ IDOMEventListener* /*listener*/, /* [in] */ BOOL /*useCapture*/) { return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMNode::dispatchEvent( /* [in] */ IDOMEvent* evt, /* [retval][out] */ BOOL* result) { if (!m_node || !evt) return E_FAIL; #if 0 // FIXME - raise dom exceptions if (![self _node]->isEventTargetNode()) WebCore::raiseDOMException(DOM_NOT_SUPPORTED_ERR); #endif COMPtr<DOMEvent> domEvent; HRESULT hr = evt->QueryInterface(IID_DOMEvent, (void**) &domEvent); if (FAILED(hr)) return hr; WebCore::ExceptionCode ec = 0; *result = m_node->dispatchEvent(domEvent->coreEvent(), ec) ? TRUE : FALSE; #if 0 // FIXME - raise dom exceptions WebCore::raiseOnDOMError(ec); #endif return S_OK; } // DOMNode - DOMNode ---------------------------------------------------------- DOMNode::DOMNode(WebCore::Node* n) : m_node(0) { if (n) n->ref(); m_node = n; } DOMNode::~DOMNode() { if (m_node) m_node->deref(); } IDOMNode* DOMNode::createInstance(WebCore::Node* n) { if (!n) return 0; HRESULT hr = S_OK; IDOMNode* domNode = 0; WebCore::Node::NodeType nodeType = n->nodeType(); switch (nodeType) { case WebCore::Node::ELEMENT_NODE: { IDOMElement* newElement = DOMElement::createInstance(static_cast<WebCore::Element*>(n)); if (newElement) { hr = newElement->QueryInterface(IID_IDOMNode, (void**)&domNode); newElement->Release(); } } break; case WebCore::Node::DOCUMENT_NODE: { IDOMDocument* newDocument = DOMDocument::createInstance(n->document()); if (newDocument) { hr = newDocument->QueryInterface(IID_IDOMNode, (void**)&domNode); newDocument->Release(); } } break; default: { DOMNode* newNode = new DOMNode(n); hr = newNode->QueryInterface(IID_IDOMNode, (void**)&domNode); } break; } if (FAILED(hr)) return 0; return domNode; } // DOMNodeList - IUnknown ----------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMNodeList::QueryInterface(REFIID riid, void** ppvObject) { *ppvObject = 0; if (IsEqualGUID(riid, IID_IDOMNodeList)) *ppvObject = static_cast<IDOMNodeList*>(this); else return DOMObject::QueryInterface(riid, ppvObject); AddRef(); return S_OK; } // IDOMNodeList --------------------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMNodeList::item( /* [in] */ UINT index, /* [retval][out] */ IDOMNode **result) { *result = 0; if (!m_nodeList) return E_FAIL; WebCore::Node* itemNode = m_nodeList->item(index); if (!itemNode) return E_FAIL; *result = DOMNode::createInstance(itemNode); return *result ? S_OK : E_FAIL; } HRESULT STDMETHODCALLTYPE DOMNodeList::length( /* [retval][out] */ UINT *result) { *result = 0; if (!m_nodeList) return E_FAIL; *result = m_nodeList->length(); return S_OK; } // DOMNodeList - DOMNodeList -------------------------------------------------- DOMNodeList::DOMNodeList(WebCore::NodeList* l) : m_nodeList(0) { if (l) l->ref(); m_nodeList = l; } DOMNodeList::~DOMNodeList() { if (m_nodeList) m_nodeList->deref(); } IDOMNodeList* DOMNodeList::createInstance(WebCore::NodeList* l) { if (!l) return 0; IDOMNodeList* domNodeList = 0; DOMNodeList* newNodeList = new DOMNodeList(l); if (FAILED(newNodeList->QueryInterface(IID_IDOMNodeList, (void**)&domNodeList))) return 0; return domNodeList; } // DOMDocument - IUnknown ----------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMDocument::QueryInterface(REFIID riid, void** ppvObject) { *ppvObject = 0; if (IsEqualGUID(riid, IID_IDOMDocument)) *ppvObject = static_cast<IDOMDocument*>(this); else if (IsEqualGUID(riid, IID_IDOMViewCSS)) *ppvObject = static_cast<IDOMViewCSS*>(this); else if (IsEqualGUID(riid, IID_IDOMDocumentEvent)) *ppvObject = static_cast<IDOMDocumentEvent*>(this); else return DOMNode::QueryInterface(riid, ppvObject); AddRef(); return S_OK; } // DOMDocument ---------------------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMDocument::doctype( /* [retval][out] */ IDOMDocumentType** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::implementation( /* [retval][out] */ IDOMImplementation** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::documentElement( /* [retval][out] */ IDOMElement** result) { *result = DOMElement::createInstance(m_document->documentElement()); return *result ? S_OK : E_FAIL; } HRESULT STDMETHODCALLTYPE DOMDocument::createElement( /* [in] */ BSTR tagName, /* [retval][out] */ IDOMElement** result) { if (!m_document) return E_FAIL; String tagNameString(tagName); ExceptionCode ec; *result = DOMElement::createInstance(m_document->createElement(tagNameString, ec).get()); return *result ? S_OK : E_FAIL; } HRESULT STDMETHODCALLTYPE DOMDocument::createDocumentFragment( /* [retval][out] */ IDOMDocumentFragment** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::createTextNode( /* [in] */ BSTR /*data*/, /* [retval][out] */ IDOMText** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::createComment( /* [in] */ BSTR /*data*/, /* [retval][out] */ IDOMComment** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::createCDATASection( /* [in] */ BSTR /*data*/, /* [retval][out] */ IDOMCDATASection** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::createProcessingInstruction( /* [in] */ BSTR /*target*/, /* [in] */ BSTR /*data*/, /* [retval][out] */ IDOMProcessingInstruction** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::createAttribute( /* [in] */ BSTR /*name*/, /* [retval][out] */ IDOMAttr** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::createEntityReference( /* [in] */ BSTR /*name*/, /* [retval][out] */ IDOMEntityReference** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::getElementsByTagName( /* [in] */ BSTR tagName, /* [retval][out] */ IDOMNodeList** result) { if (!m_document) return E_FAIL; String tagNameString(tagName); *result = DOMNodeList::createInstance(m_document->getElementsByTagName(tagNameString).get()); return *result ? S_OK : E_FAIL; } HRESULT STDMETHODCALLTYPE DOMDocument::importNode( /* [in] */ IDOMNode* /*importedNode*/, /* [in] */ BOOL /*deep*/, /* [retval][out] */ IDOMNode** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::createElementNS( /* [in] */ BSTR /*namespaceURI*/, /* [in] */ BSTR /*qualifiedName*/, /* [retval][out] */ IDOMElement** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::createAttributeNS( /* [in] */ BSTR /*namespaceURI*/, /* [in] */ BSTR /*qualifiedName*/, /* [retval][out] */ IDOMAttr** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMDocument::getElementsByTagNameNS( /* [in] */ BSTR namespaceURI, /* [in] */ BSTR localName, /* [retval][out] */ IDOMNodeList** result) { if (!m_document) return E_FAIL; String namespaceURIString(namespaceURI); String localNameString(localName); *result = DOMNodeList::createInstance(m_document->getElementsByTagNameNS(namespaceURIString, localNameString).get()); return *result ? S_OK : E_FAIL; } HRESULT STDMETHODCALLTYPE DOMDocument::getElementById( /* [in] */ BSTR elementId, /* [retval][out] */ IDOMElement** result) { if (!m_document) return E_FAIL; String idString(elementId); *result = DOMElement::createInstance(m_document->getElementById(idString)); return *result ? S_OK : E_FAIL; } // DOMDocument - IDOMViewCSS -------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMDocument::getComputedStyle( /* [in] */ IDOMElement* elt, /* [in] */ BSTR pseudoElt, /* [retval][out] */ IDOMCSSStyleDeclaration** result) { if (!elt || !result) return E_POINTER; COMPtr<DOMElement> domEle; HRESULT hr = elt->QueryInterface(IID_DOMElement, (void**)&domEle); if (FAILED(hr)) return hr; Element* element = domEle->element(); WebCore::DOMWindow* dv = m_document->defaultView(); String pseudoEltString(pseudoElt); if (!dv) return E_FAIL; *result = DOMCSSStyleDeclaration::createInstance(dv->getComputedStyle(element, pseudoEltString.impl()).get()); return *result ? S_OK : E_FAIL; } // DOMDocument - IDOMDocumentEvent -------------------------------------------- HRESULT STDMETHODCALLTYPE DOMDocument::createEvent( /* [in] */ BSTR eventType, /* [retval][out] */ IDOMEvent **result) { String eventTypeString(eventType, SysStringLen(eventType)); WebCore::ExceptionCode ec = 0; *result = DOMEvent::createInstance(m_document->createEvent(eventTypeString, ec)); return *result ? S_OK : E_FAIL; } // DOMDocument - DOMDocument -------------------------------------------------- DOMDocument::DOMDocument(WebCore::Document* d) : DOMNode(d) , m_document(d) { } DOMDocument::~DOMDocument() { } IDOMDocument* DOMDocument::createInstance(WebCore::Document* d) { if (!d) return 0; HRESULT hr; IDOMDocument* domDocument = 0; if (d->isHTMLDocument()) { DOMHTMLDocument* newDocument = new DOMHTMLDocument(d); hr = newDocument->QueryInterface(IID_IDOMDocument, (void**)&domDocument); } else { DOMDocument* newDocument = new DOMDocument(d); hr = newDocument->QueryInterface(IID_IDOMDocument, (void**)&domDocument); } if (FAILED(hr)) return 0; return domDocument; } // DOMElement - IUnknown ------------------------------------------------------ HRESULT STDMETHODCALLTYPE DOMElement::QueryInterface(REFIID riid, void** ppvObject) { *ppvObject = 0; if (IsEqualGUID(riid, IID_IDOMElement)) *ppvObject = static_cast<IDOMElement*>(this); else if (IsEqualGUID(riid, IID_DOMElement)) *ppvObject = static_cast<DOMElement*>(this); else if (IsEqualGUID(riid, IID_IDOMElementPrivate)) *ppvObject = static_cast<IDOMElementPrivate*>(this); else if (IsEqualGUID(riid, IID_IDOMNodeExtensions)) *ppvObject = static_cast<IDOMNodeExtensions*>(this); else if (IsEqualGUID(riid, IID_IDOMElementCSSInlineStyle)) *ppvObject = static_cast<IDOMElementCSSInlineStyle*>(this); else if (IsEqualGUID(riid, IID_IDOMElementExtensions)) *ppvObject = static_cast<IDOMElementExtensions*>(this); else return DOMNode::QueryInterface(riid, ppvObject); AddRef(); return S_OK; } // DOMElement - IDOMNodeExtensions--------------------------------------------- HRESULT STDMETHODCALLTYPE DOMElement::boundingBox( /* [retval][out] */ LPRECT rect) { ::SetRectEmpty(rect); if (!m_element) return E_FAIL; WebCore::RenderObject *renderer = m_element->renderer(); if (renderer) { IntRect boundsIntRect = renderer->absoluteBoundingBoxRect(); rect->left = boundsIntRect.x(); rect->top = boundsIntRect.y(); rect->right = boundsIntRect.x() + boundsIntRect.width(); rect->bottom = boundsIntRect.y() + boundsIntRect.height(); } return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::lineBoxRects( /* [size_is][in] */ RECT* /*rects*/, /* [in] */ int /*cRects*/) { return E_NOTIMPL; } // IDOMElement ---------------------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMElement::tagName( /* [retval][out] */ BSTR* result) { if (!m_element) return E_FAIL; if (!result) return E_POINTER; *result = BString(m_element->tagName()).release(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::getAttribute( /* [in] */ BSTR name, /* [retval][out] */ BSTR* result) { if (!m_element) return E_FAIL; WebCore::String nameString(name, SysStringLen(name)); WebCore::String& attrValueString = (WebCore::String&) m_element->getAttribute(nameString); *result = SysAllocStringLen(attrValueString.characters(), attrValueString.length()); if (attrValueString.length() && !*result) return E_OUTOFMEMORY; return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::setAttribute( /* [in] */ BSTR name, /* [in] */ BSTR value) { if (!m_element) return E_FAIL; WebCore::String nameString(name, SysStringLen(name)); WebCore::String valueString(value, SysStringLen(value)); WebCore::ExceptionCode ec = 0; m_element->setAttribute(nameString, valueString, ec); return ec ? E_FAIL : S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::removeAttribute( /* [in] */ BSTR /*name*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNode( /* [in] */ BSTR /*name*/, /* [retval][out] */ IDOMAttr** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNode( /* [in] */ IDOMAttr* /*newAttr*/, /* [retval][out] */ IDOMAttr** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::removeAttributeNode( /* [in] */ IDOMAttr* /*oldAttr*/, /* [retval][out] */ IDOMAttr** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::getElementsByTagName( /* [in] */ BSTR /*name*/, /* [retval][out] */ IDOMNodeList** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNS( /* [in] */ BSTR /*namespaceURI*/, /* [in] */ BSTR /*localName*/, /* [retval][out] */ BSTR* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNS( /* [in] */ BSTR /*namespaceURI*/, /* [in] */ BSTR /*qualifiedName*/, /* [in] */ BSTR /*value*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::removeAttributeNS( /* [in] */ BSTR /*namespaceURI*/, /* [in] */ BSTR /*localName*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNodeNS( /* [in] */ BSTR /*namespaceURI*/, /* [in] */ BSTR /*localName*/, /* [retval][out] */ IDOMAttr** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNodeNS( /* [in] */ IDOMAttr* /*newAttr*/, /* [retval][out] */ IDOMAttr** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::getElementsByTagNameNS( /* [in] */ BSTR /*namespaceURI*/, /* [in] */ BSTR /*localName*/, /* [retval][out] */ IDOMNodeList** /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::hasAttribute( /* [in] */ BSTR /*name*/, /* [retval][out] */ BOOL* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::hasAttributeNS( /* [in] */ BSTR /*namespaceURI*/, /* [in] */ BSTR /*localName*/, /* [retval][out] */ BOOL* /*result*/) { ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::focus( void) { if (!m_element) return E_FAIL; m_element->focus(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::blur( void) { if (!m_element) return E_FAIL; m_element->blur(); return S_OK; } // IDOMElementPrivate --------------------------------------------------------- HRESULT DOMElement::coreElement(void **element) { if (!m_element) return E_FAIL; *element = (void*) m_element; return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::isEqual( /* [in] */ IDOMElement *other, /* [retval][out] */ BOOL *result) { *result = FALSE; if (!other || !result) return E_POINTER; IDOMElementPrivate* otherPriv; HRESULT hr = other->QueryInterface(IID_IDOMElementPrivate, (void**) &otherPriv); if (FAILED(hr)) return hr; void* otherCoreEle; hr = otherPriv->coreElement(&otherCoreEle); otherPriv->Release(); if (FAILED(hr)) return hr; *result = (otherCoreEle == (void*)m_element) ? TRUE : FALSE; return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::isFocused( /* [retval][out] */ BOOL *result) { if (!m_element) return E_FAIL; if (m_element->document()->focusedNode() == m_element) *result = TRUE; else *result = FALSE; return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::innerText( /* [retval][out] */ BSTR* result) { if (!result) { ASSERT_NOT_REACHED(); return E_POINTER; } if (!m_element) { ASSERT_NOT_REACHED(); return E_FAIL; } *result = BString(m_element->innerText()).release(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::font(WebFontDescription* webFontDescription) { if (!webFontDescription) { ASSERT_NOT_REACHED(); return E_POINTER; } ASSERT(m_element); WebCore::RenderObject* renderer = m_element->renderer(); if (!renderer) return E_FAIL; FontDescription fontDescription = renderer->style()->font().fontDescription(); AtomicString family = fontDescription.family().family(); webFontDescription->family = family.characters(); webFontDescription->familyLength = family.length(); webFontDescription->size = fontDescription.computedSize(); webFontDescription->bold = fontDescription.weight() >= WebCore::FontWeight600; webFontDescription->italic = fontDescription.italic(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::renderedImage(HBITMAP* image) { if (!image) { ASSERT_NOT_REACHED(); return E_POINTER; } *image = 0; ASSERT(m_element); Frame* frame = m_element->document()->frame(); if (!frame) return E_FAIL; *image = frame->nodeImage(m_element); if (!*image) return E_FAIL; return S_OK; } // IDOMElementCSSInlineStyle -------------------------------------------------- HRESULT STDMETHODCALLTYPE DOMElement::style( /* [retval][out] */ IDOMCSSStyleDeclaration** result) { if (!result) return E_POINTER; if (!m_element) return E_FAIL; WebCore::CSSStyleDeclaration* style = m_element->style(); if (!style) return E_FAIL; *result = DOMCSSStyleDeclaration::createInstance(style); return *result ? S_OK : E_FAIL; } // IDOMElementExtensions ------------------------------------------------------ HRESULT STDMETHODCALLTYPE DOMElement::offsetLeft( /* [retval][out] */ int* result) { if (!m_element) return E_FAIL; *result = m_element->offsetLeft(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::offsetTop( /* [retval][out] */ int* result) { if (!m_element) return E_FAIL; *result = m_element->offsetTop(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::offsetWidth( /* [retval][out] */ int* result) { if (!m_element) return E_FAIL; *result = m_element->offsetWidth(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::offsetHeight( /* [retval][out] */ int* result) { if (!m_element) return E_FAIL; *result = m_element->offsetHeight(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::offsetParent( /* [retval][out] */ IDOMElement** /*result*/) { // FIXME ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::clientWidth( /* [retval][out] */ int* result) { if (!m_element) return E_FAIL; *result = m_element->clientWidth(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::clientHeight( /* [retval][out] */ int* result) { if (!m_element) return E_FAIL; *result = m_element->clientHeight(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::scrollLeft( /* [retval][out] */ int* result) { if (!m_element) return E_FAIL; *result = m_element->scrollLeft(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::setScrollLeft( /* [in] */ int /*newScrollLeft*/) { // FIXME ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::scrollTop( /* [retval][out] */ int* result) { if (!m_element) return E_FAIL; *result = m_element->scrollTop(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::setScrollTop( /* [in] */ int /*newScrollTop*/) { // FIXME ASSERT_NOT_REACHED(); return E_NOTIMPL; } HRESULT STDMETHODCALLTYPE DOMElement::scrollWidth( /* [retval][out] */ int* result) { if (!m_element) return E_FAIL; *result = m_element->scrollWidth(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::scrollHeight( /* [retval][out] */ int* result) { if (!m_element) return E_FAIL; *result = m_element->scrollHeight(); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::scrollIntoView( /* [in] */ BOOL alignWithTop) { if (!m_element) return E_FAIL; m_element->scrollIntoView(!!alignWithTop); return S_OK; } HRESULT STDMETHODCALLTYPE DOMElement::scrollIntoViewIfNeeded( /* [in] */ BOOL centerIfNeeded) { if (!m_element) return E_FAIL; m_element->scrollIntoViewIfNeeded(!!centerIfNeeded); return S_OK; } // DOMElement ----------------------------------------------------------------- DOMElement::DOMElement(WebCore::Element* e) : DOMNode(e) , m_element(e) { } DOMElement::~DOMElement() { } IDOMElement* DOMElement::createInstance(WebCore::Element* e) { if (!e) return 0; HRESULT hr; IDOMElement* domElement = 0; if (e->hasTagName(formTag)) { DOMHTMLFormElement* newElement = new DOMHTMLFormElement(e); hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); } else if (e->hasTagName(selectTag)) { DOMHTMLSelectElement* newElement = new DOMHTMLSelectElement(e); hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); } else if (e->hasTagName(optionTag)) { DOMHTMLOptionElement* newElement = new DOMHTMLOptionElement(e); hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); } else if (e->hasTagName(inputTag)) { DOMHTMLInputElement* newElement = new DOMHTMLInputElement(e); hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); } else if (e->hasTagName(textareaTag)) { DOMHTMLTextAreaElement* newElement = new DOMHTMLTextAreaElement(e); hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); } else if (e->isHTMLElement()) { DOMHTMLElement* newElement = new DOMHTMLElement(e); hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); } else { DOMElement* newElement = new DOMElement(e); hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); } if (FAILED(hr)) return 0; return domElement; }