--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WebKit/win/DOMCoreClasses.cpp Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,1379 @@
+/*
+ * 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>
+#include <WebCore/RenderTreeAsText.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)
+{
+ if (!result)
+ return E_POINTER;
+ *result = 0;
+ if (!m_node)
+ return E_FAIL;
+ *result = DOMNode::createInstance(m_node->nextSibling());
+ return *result ? S_OK : E_FAIL;
+}
+
+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)
+{
+ if (!result)
+ return E_POINTER;
+
+ *result = 0;
+
+ if (!m_node)
+ return E_FAIL;
+
+ COMPtr<DOMNode> newChildNode(Query, newChild);
+ if (!newChildNode)
+ return E_FAIL;
+
+ COMPtr<DOMNode> refChildNode(Query, refChild);
+
+ ExceptionCode ec;
+ if (!m_node->insertBefore(newChildNode->node(), refChildNode ? refChildNode->node() : 0, ec))
+ return E_FAIL;
+
+ *result = newChild;
+ (*result)->AddRef();
+ return S_OK;
+}
+
+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)
+{
+ if (!result)
+ return E_POINTER;
+
+ *result = 0;
+
+ if (!m_node)
+ return E_FAIL;
+
+ COMPtr<DOMNode> oldChildNode(Query, oldChild);
+ if (!oldChildNode)
+ return E_FAIL;
+
+ ExceptionCode ec;
+ if (!m_node->removeChild(oldChildNode->node(), ec))
+ return E_FAIL;
+
+ *result = oldChild;
+ (*result)->AddRef();
+ return S_OK;
+}
+
+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;
+}
+
+HRESULT STDMETHODCALLTYPE DOMElement::markerTextForListItem(
+ /* [retval][out] */ BSTR* markerText)
+{
+ if (!markerText)
+ return E_POINTER;
+
+ ASSERT(m_element);
+
+ *markerText = BString(WebCore::markerTextForListItem(m_element)).release();
+ 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(iframeTag)) {
+ DOMHTMLIFrameElement* newElement = new DOMHTMLIFrameElement(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(optionTag)) {
+ DOMHTMLOptionElement* newElement = new DOMHTMLOptionElement(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(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;
+}