| /* |
| * Copyright (C) 2006-2007, 2009, 2014-2015 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "WebKitDLL.h" |
| #include "DOMCoreClasses.h" |
| |
| #include "DOMCSSClasses.h" |
| #include "DOMEventsClasses.h" |
| #include "DOMHTMLClasses.h" |
| #include "WebKitGraphics.h" |
| #include <WebCore/AddEventListenerOptions.h> |
| #include <WebCore/Attr.h> |
| #include <WebCore/BString.h> |
| #include <WebCore/COMPtr.h> |
| #include <WebCore/DOMWindow.h> |
| #include <WebCore/Document.h> |
| #include <WebCore/DragImage.h> |
| #include <WebCore/Element.h> |
| #include <WebCore/Event.h> |
| #include <WebCore/Font.h> |
| #include <WebCore/FontCascade.h> |
| #include <WebCore/Frame.h> |
| #include <WebCore/HTMLCollection.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/NamedNodeMap.h> |
| #include <WebCore/NodeList.h> |
| #include <WebCore/Range.h> |
| #include <WebCore/RenderElement.h> |
| #include <WebCore/RenderTreeAsText.h> |
| #include <WebCore/ScrollIntoViewOptions.h> |
| #include <WebCore/SimpleRange.h> |
| #include <WebCore/StyledElement.h> |
| #include <initguid.h> |
| #include <wtf/text/win/WCharStringExtras.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 WTF::AtomString; |
| using WebCore::BString; |
| using WebCore::Element; |
| using WebCore::ExceptionCode; |
| using WebCore::Frame; |
| using WebCore::IntRect; |
| using WTF::String; |
| |
| // DOMObject - IUnknown ------------------------------------------------------- |
| |
| HRESULT DOMObject::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject) |
| { |
| if (!ppvObject) |
| return E_POINTER; |
| *ppvObject = nullptr; |
| if (IsEqualGUID(riid, IID_IDOMObject)) |
| *ppvObject = static_cast<IDOMObject*>(this); |
| else |
| return WebScriptObject::QueryInterface(riid, ppvObject); |
| |
| AddRef(); |
| return S_OK; |
| } |
| |
| // DOMNode - IUnknown --------------------------------------------------------- |
| |
| HRESULT DOMNode::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject) |
| { |
| if (!ppvObject) |
| return E_POINTER; |
| *ppvObject = nullptr; |
| if (IsEqualGUID(riid, IID_IDOMNode)) |
| *ppvObject = static_cast<IDOMNode*>(this); |
| else if (IsEqualGUID(riid, __uuidof(DOMNode))) |
| *ppvObject = static_cast<DOMNode*>(this); |
| else if (IsEqualGUID(riid, __uuidof(IDOMEventTarget))) |
| *ppvObject = static_cast<IDOMEventTarget*>(this); |
| else |
| return DOMObject::QueryInterface(riid, ppvObject); |
| |
| AddRef(); |
| return S_OK; |
| } |
| |
| // DOMNode -------------------------------------------------------------------- |
| |
| HRESULT DOMNode::nodeName(__deref_opt_out BSTR* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_node) |
| return E_FAIL; |
| |
| *result = BString(m_node->nodeName()).release(); |
| return S_OK; |
| } |
| |
| HRESULT DOMNode::nodeValue(__deref_opt_out BSTR* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_node) |
| return E_FAIL; |
| WTF::String nodeValueStr = m_node->nodeValue(); |
| *result = BString(nodeValueStr).release(); |
| if (nodeValueStr.length() && !*result) |
| return E_OUTOFMEMORY; |
| return S_OK; |
| } |
| |
| HRESULT DOMNode::setNodeValue(_In_ BSTR /*value*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::nodeType(_Out_ unsigned short* /*result*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::parentNode(_COM_Outptr_opt_ IDOMNode** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_node || !m_node->parentNode()) |
| return E_FAIL; |
| *result = DOMNode::createInstance(m_node->parentNode()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| HRESULT DOMNode::childNodes(_COM_Outptr_opt_ IDOMNodeList** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| 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 DOMNode::firstChild(_COM_Outptr_opt_ IDOMNode** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::lastChild(_COM_Outptr_opt_ IDOMNode** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::previousSibling(_COM_Outptr_opt_ IDOMNode** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::nextSibling(_COM_Outptr_opt_ IDOMNode** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_node) |
| return E_FAIL; |
| *result = DOMNode::createInstance(m_node->nextSibling()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| HRESULT DOMNode::attributes(_COM_Outptr_opt_ IDOMNamedNodeMap** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_node) |
| return E_FAIL; |
| *result = DOMNamedNodeMap::createInstance(m_node->attributes()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| HRESULT DOMNode::ownerDocument(_COM_Outptr_opt_ IDOMDocument** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_node) |
| return E_FAIL; |
| *result = DOMDocument::createInstance(m_node->ownerDocument()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| HRESULT DOMNode::insertBefore(_In_opt_ IDOMNode* newChild, _In_opt_ IDOMNode* refChild, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| if (!result) |
| return E_POINTER; |
| |
| *result = nullptr; |
| |
| if (!m_node) |
| return E_FAIL; |
| |
| COMPtr<DOMNode> newChildNode(Query, newChild); |
| if (!newChildNode) |
| return E_FAIL; |
| |
| COMPtr<DOMNode> refChildNode(Query, refChild); |
| |
| if (m_node->insertBefore(*newChildNode->node(), refChildNode ? refChildNode->node() : nullptr).hasException()) |
| return E_FAIL; |
| |
| *result = newChild; |
| (*result)->AddRef(); |
| return S_OK; |
| } |
| |
| HRESULT DOMNode::replaceChild(_In_opt_ IDOMNode* /*newChild*/, _In_opt_ IDOMNode* /*oldChild*/, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::removeChild(_In_opt_ IDOMNode* oldChild, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| if (!result) |
| return E_POINTER; |
| |
| *result = nullptr; |
| |
| if (!m_node) |
| return E_FAIL; |
| |
| COMPtr<DOMNode> oldChildNode(Query, oldChild); |
| if (!oldChildNode) |
| return E_FAIL; |
| |
| if (m_node->removeChild(*oldChildNode->node()).hasException()) |
| return E_FAIL; |
| |
| *result = oldChild; |
| (*result)->AddRef(); |
| return S_OK; |
| } |
| |
| HRESULT DOMNode::appendChild(_In_opt_ IDOMNode* /*oldChild*/, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::hasChildNodes(_Out_ BOOL* /*result*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::cloneNode(BOOL /*deep*/, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::normalize() |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::isSupported(_In_ BSTR /*feature*/, _In_ BSTR /*version*/, _Out_ BOOL* /*result*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::namespaceURI(__deref_opt_out BSTR* result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::prefix(__deref_opt_out BSTR* result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::setPrefix(_In_ BSTR /*prefix*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::localName(__deref_opt_out BSTR* result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::hasAttributes(_Out_ BOOL* /*result*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::isSameNode(_In_opt_ IDOMNode* other, _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 DOMNode::isEqualNode(_In_opt_ IDOMNode* /*other*/, _Out_ BOOL* /*result*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNode::textContent(__deref_opt_out BSTR* result) |
| { |
| if (!result) |
| return E_POINTER; |
| |
| *result = BString(m_node->textContent()).release(); |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMNode::setTextContent(_In_ BSTR /*text*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| // DOMNode - IDOMEventTarget -------------------------------------------------- |
| |
| HRESULT DOMNode::addEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener* listener, BOOL useCapture) |
| { |
| auto webListener = WebEventListener::create(listener); |
| m_node->addEventListener(AtomString(type), WTFMove(webListener), useCapture); |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMNode::removeEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener* listener, BOOL useCapture) |
| { |
| if (!listener || !type) |
| return E_POINTER; |
| if (!m_node) |
| return E_FAIL; |
| auto webListener = WebEventListener::create(listener); |
| m_node->removeEventListener(AtomString(type), webListener, useCapture); |
| return S_OK; |
| } |
| |
| HRESULT DOMNode::dispatchEvent(_In_opt_ IDOMEvent* evt, _Out_ BOOL* result) |
| { |
| if (!evt || !result) |
| return E_POINTER; |
| if (!m_node) |
| return E_FAIL; |
| |
| COMPtr<DOMEvent> domEvent; |
| HRESULT hr = evt->QueryInterface(IID_DOMEvent, (void**) &domEvent); |
| if (FAILED(hr)) |
| return hr; |
| |
| if (!domEvent->coreEvent()) |
| return E_FAIL; |
| |
| auto dispatchResult = m_node->dispatchEventForBindings(*domEvent->coreEvent()); |
| if (dispatchResult.hasException()) |
| return E_FAIL; |
| |
| *result = dispatchResult.releaseReturnValue(); |
| return S_OK; |
| } |
| |
| // DOMNode - DOMNode ---------------------------------------------------------- |
| |
| DOMNode::DOMNode(WebCore::Node* n) |
| { |
| if (n) |
| n->ref(); |
| |
| m_node = n; |
| } |
| |
| DOMNode::~DOMNode() |
| { |
| if (m_node) |
| m_node->deref(); |
| } |
| |
| IDOMNode* DOMNode::createInstance(WebCore::Node* n) |
| { |
| if (!n) |
| return nullptr; |
| |
| HRESULT hr = S_OK; |
| IDOMNode* domNode = nullptr; |
| 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 nullptr; |
| |
| return domNode; |
| } |
| |
| // DOMNodeList - IUnknown ----------------------------------------------------- |
| |
| HRESULT DOMNodeList::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject) |
| { |
| if (!ppvObject) |
| return E_POINTER; |
| *ppvObject = nullptr; |
| if (IsEqualGUID(riid, IID_IDOMNodeList)) |
| *ppvObject = static_cast<IDOMNodeList*>(this); |
| else |
| return DOMObject::QueryInterface(riid, ppvObject); |
| |
| AddRef(); |
| return S_OK; |
| } |
| |
| // IDOMNodeList --------------------------------------------------------------- |
| |
| HRESULT DOMNodeList::item(UINT index, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| 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 DOMNodeList::length(_Out_ UINT* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_nodeList) |
| return E_FAIL; |
| *result = m_nodeList->length(); |
| return S_OK; |
| } |
| |
| // DOMNodeList - DOMNodeList -------------------------------------------------- |
| |
| DOMNodeList::DOMNodeList(WebCore::NodeList* l) |
| { |
| if (l) |
| l->ref(); |
| |
| m_nodeList = l; |
| } |
| |
| DOMNodeList::~DOMNodeList() |
| { |
| if (m_nodeList) |
| m_nodeList->deref(); |
| } |
| |
| IDOMNodeList* DOMNodeList::createInstance(WebCore::NodeList* l) |
| { |
| if (!l) |
| return nullptr; |
| |
| IDOMNodeList* domNodeList = nullptr; |
| DOMNodeList* newNodeList = new DOMNodeList(l); |
| if (FAILED(newNodeList->QueryInterface(IID_IDOMNodeList, (void**)&domNodeList))) |
| return nullptr; |
| |
| return domNodeList; |
| } |
| |
| // DOMDocument - IUnknown ----------------------------------------------------- |
| |
| HRESULT DOMDocument::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject) |
| { |
| if (!ppvObject) |
| return E_POINTER; |
| *ppvObject = nullptr; |
| 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 DOMDocument::doctype(_COM_Outptr_opt_ IDOMDocumentType** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::implementation(_COM_Outptr_opt_ IDOMImplementation** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::documentElement(_COM_Outptr_opt_ IDOMElement** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = DOMElement::createInstance(m_document->documentElement()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| HRESULT DOMDocument::createElement(_In_ BSTR tagName, _COM_Outptr_opt_ IDOMElement** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_document) |
| return E_FAIL; |
| |
| AtomString tagNameString(tagName); |
| auto createElementResult = m_document->createElementForBindings(tagNameString); |
| if (createElementResult.hasException()) |
| return E_FAIL; |
| *result = DOMElement::createInstance(createElementResult.releaseReturnValue().ptr()); |
| return S_OK; |
| } |
| |
| HRESULT DOMDocument::createDocumentFragment(_COM_Outptr_opt_ IDOMDocumentFragment** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT STDMETHODCALLTYPE DOMDocument::createTextNode(_In_ BSTR /*data*/, _COM_Outptr_opt_ IDOMText** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::createComment(_In_ BSTR /*data*/, _COM_Outptr_opt_ IDOMComment** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::createCDATASection(_In_ BSTR /*data*/, _COM_Outptr_opt_ IDOMCDATASection** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::createProcessingInstruction(_In_ BSTR /*target*/, _In_ BSTR /*data*/, _COM_Outptr_opt_ IDOMProcessingInstruction** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::createAttribute(_In_ BSTR /*name*/, _COM_Outptr_opt_ IDOMAttr** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::createEntityReference(_In_ BSTR /*name*/, _COM_Outptr_opt_ IDOMEntityReference** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::getElementsByTagName(_In_ BSTR tagName, _COM_Outptr_opt_ IDOMNodeList** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_document) |
| return E_FAIL; |
| |
| AtomString tagNameString(tagName); |
| RefPtr<WebCore::NodeList> elements; |
| if (!tagNameString.isNull()) |
| elements = m_document->getElementsByTagName(tagNameString); |
| *result = DOMNodeList::createInstance(elements.get()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| HRESULT DOMDocument::importNode(_In_opt_ IDOMNode* /*importedNode*/, BOOL /*deep*/, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::createElementNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*qualifiedName*/, _COM_Outptr_opt_ IDOMElement** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::createAttributeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*qualifiedName*/, _COM_Outptr_opt_ IDOMAttr** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMDocument::getElementsByTagNameNS(_In_ BSTR namespaceURI, _In_ BSTR localName, _COM_Outptr_opt_ IDOMNodeList** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_document) |
| return E_FAIL; |
| |
| AtomString namespaceURIString(namespaceURI); |
| AtomString localNameString(localName); |
| RefPtr<WebCore::NodeList> elements; |
| if (!localNameString.isNull()) |
| elements = m_document->getElementsByTagNameNS(namespaceURIString, localNameString); |
| *result = DOMNodeList::createInstance(elements.get()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| HRESULT DOMDocument::getElementById(_In_ BSTR elementId, _COM_Outptr_opt_ IDOMElement** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| 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 DOMDocument::getComputedStyle(_In_opt_ IDOMElement* elt, _In_ BSTR pseudoElt, _COM_Outptr_opt_ IDOMCSSStyleDeclaration** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!elt) |
| return E_POINTER; |
| |
| COMPtr<DOMElement> domEle; |
| HRESULT hr = elt->QueryInterface(IID_DOMElement, (void**)&domEle); |
| if (FAILED(hr)) |
| return hr; |
| Element* element = domEle->element(); |
| if (!element) |
| return E_FAIL; |
| |
| auto* dv = m_document->domWindow(); |
| String pseudoEltString(pseudoElt); |
| |
| if (!dv) |
| return E_FAIL; |
| |
| *result = DOMCSSStyleDeclaration::createInstance(dv->getComputedStyle(*element, pseudoEltString.impl()).ptr()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| // DOMDocument - IDOMDocumentEvent -------------------------------------------- |
| |
| HRESULT DOMDocument::createEvent(_In_ BSTR eventType, _COM_Outptr_opt_ IDOMEvent** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| |
| String eventTypeString(eventType, SysStringLen(eventType)); |
| auto createEventResult = m_document->createEvent(eventTypeString); |
| if (createEventResult.hasException()) |
| return E_FAIL; |
| *result = DOMEvent::createInstance(createEventResult.releaseReturnValue()); |
| return S_OK; |
| } |
| |
| // DOMDocument - DOMDocument -------------------------------------------------- |
| |
| DOMDocument::DOMDocument(WebCore::Document* d) |
| : DOMNode(d) |
| , m_document(d) |
| { |
| } |
| |
| DOMDocument::~DOMDocument() |
| { |
| } |
| |
| IDOMDocument* DOMDocument::createInstance(WebCore::Document* d) |
| { |
| if (!d) |
| return nullptr; |
| |
| HRESULT hr; |
| IDOMDocument* domDocument = nullptr; |
| |
| 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 nullptr; |
| |
| return domDocument; |
| } |
| |
| // DOMWindow - IUnknown ------------------------------------------------------ |
| |
| HRESULT DOMWindow::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject) |
| { |
| if (!ppvObject) |
| return E_POINTER; |
| *ppvObject = nullptr; |
| if (IsEqualGUID(riid, IID_IDOMWindow)) |
| *ppvObject = static_cast<IDOMWindow*>(this); |
| else if (IsEqualGUID(riid, IID_IDOMEventTarget)) |
| *ppvObject = static_cast<IDOMEventTarget*>(this); |
| else |
| return DOMObject::QueryInterface(riid, ppvObject); |
| |
| AddRef(); |
| return S_OK; |
| } |
| |
| // DOMWindow - IDOMWindow ------------------------------------------------------ |
| |
| HRESULT DOMWindow::document(_COM_Outptr_opt_ IDOMDocument** result) |
| { |
| if (!result) { |
| ASSERT_NOT_REACHED(); |
| return E_POINTER; |
| } |
| |
| *result = DOMDocument::createInstance(m_window->document()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| HRESULT DOMWindow::getComputedStyle(_In_opt_ IDOMElement* element, _In_ BSTR pseudoElement) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMWindow::getMatchedCSSRules(_In_opt_ IDOMElement* element, _In_ BSTR pseudoElement, BOOL authorOnly, _COM_Outptr_opt_ IDOMCSSRuleList** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMWindow::devicePixelRatio(_Out_ double* result) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| // DOMWindow - IDOMEventTarget ------------------------------------------------------ |
| |
| HRESULT DOMWindow::addEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener* listener, BOOL useCapture) |
| { |
| if (!type || !listener) |
| return E_POINTER; |
| if (!m_window) |
| return E_FAIL; |
| auto webListener = WebEventListener::create(listener); |
| m_window->addEventListener(AtomString(type), WTFMove(webListener), useCapture); |
| return S_OK; |
| } |
| |
| HRESULT DOMWindow::removeEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener* listener, BOOL useCapture) |
| { |
| if (!type || !listener) |
| return E_POINTER; |
| if (!m_window) |
| return E_FAIL; |
| auto webListener = WebEventListener::create(listener); |
| m_window->removeEventListener(AtomString(type), webListener, useCapture); |
| return S_OK; |
| } |
| |
| HRESULT DOMWindow::dispatchEvent(_In_opt_ IDOMEvent* evt, _Out_ BOOL* result) |
| { |
| if (!result || !evt) |
| return E_POINTER; |
| if (!m_window) |
| return E_FAIL; |
| |
| COMPtr<DOMEvent> domEvent; |
| HRESULT hr = evt->QueryInterface(IID_DOMEvent, (void**) &domEvent); |
| if (FAILED(hr)) |
| return hr; |
| |
| if (!domEvent->coreEvent()) |
| return E_FAIL; |
| |
| auto dispatchResult = m_window->dispatchEventForBindings(*domEvent->coreEvent()); |
| if (dispatchResult.hasException()) |
| return E_FAIL; |
| |
| *result = dispatchResult.releaseReturnValue(); |
| return S_OK; |
| } |
| |
| |
| // DOMWindow - DOMWindow -------------------------------------------------- |
| |
| DOMWindow::DOMWindow(WebCore::DOMWindow* w) |
| : m_window(w) |
| { |
| m_window->ref(); |
| } |
| |
| DOMWindow::~DOMWindow() |
| { |
| m_window->deref(); |
| } |
| |
| IDOMWindow* DOMWindow::createInstance(WebCore::DOMWindow* w) |
| { |
| if (!w) |
| return nullptr; |
| |
| DOMWindow* newWindow = new DOMWindow(w); |
| |
| IDOMWindow* domWindow = nullptr; |
| HRESULT hr = newWindow->QueryInterface(IID_IDOMWindow, reinterpret_cast<void**>(&domWindow)); |
| |
| if (FAILED(hr)) |
| return nullptr; |
| |
| return domWindow; |
| } |
| |
| // DOMElement - IUnknown ------------------------------------------------------ |
| |
| HRESULT DOMElement::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject) |
| { |
| if (!ppvObject) |
| return E_POINTER; |
| *ppvObject = nullptr; |
| 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 DOMElement::boundingBox(_Out_ LPRECT rect) |
| { |
| if (!rect) |
| return E_POINTER; |
| |
| ::SetRectEmpty(rect); |
| |
| if (!m_element) |
| return E_FAIL; |
| |
| WebCore::RenderElement *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 DOMElement::lineBoxRects(__inout_ecount_full(cRects) RECT* /*rects*/, int cRects) |
| { |
| return E_NOTIMPL; |
| } |
| |
| // IDOMElement ---------------------------------------------------------------- |
| |
| HRESULT DOMElement::tagName(__deref_opt_out BSTR* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = BString(m_element->tagName()).release(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::getAttribute(_In_ BSTR name, __deref_opt_out BSTR* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!m_element) |
| return E_FAIL; |
| WTF::AtomString nameString(name, SysStringLen(name)); |
| WTF::String& attrValueString = (WTF::String&) m_element->getAttribute(nameString); |
| *result = BString(attrValueString).release(); |
| if (attrValueString.length() && !*result) |
| return E_OUTOFMEMORY; |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::setAttribute(_In_ BSTR name, _In_ BSTR value) |
| { |
| if (!m_element) |
| return E_FAIL; |
| |
| WTF::AtomString nameString(name, SysStringLen(name)); |
| WTF::AtomString valueString(value, SysStringLen(value)); |
| auto result = m_element->setAttribute(nameString, valueString); |
| return result.hasException() ? E_FAIL : S_OK; |
| } |
| |
| HRESULT DOMElement::removeAttribute(_In_ BSTR /*name*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::getAttributeNode(_In_ BSTR /*name*/, _COM_Outptr_opt_ IDOMAttr** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::setAttributeNode(_In_opt_ IDOMAttr* /*newAttr*/, _COM_Outptr_opt_ IDOMAttr** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::removeAttributeNode(_In_opt_ IDOMAttr* /*oldAttr*/, _COM_Outptr_opt_ IDOMAttr** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::getElementsByTagName(_In_ BSTR /*name*/, _COM_Outptr_opt_ IDOMNodeList** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::getAttributeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*localName*/, __deref_opt_out BSTR* result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::setAttributeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*qualifiedName*/, _In_ BSTR /*value*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::removeAttributeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*localName*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::getAttributeNodeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*localName*/, _COM_Outptr_opt_ IDOMAttr** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::setAttributeNodeNS(_In_opt_ IDOMAttr* /*newAttr*/, _COM_Outptr_opt_ IDOMAttr** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::getElementsByTagNameNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*localName*/, _COM_Outptr_opt_ IDOMNodeList** result) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::hasAttribute(_In_ BSTR /*name*/, _Out_ BOOL* /*result*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::hasAttributeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*localName*/, _Out_ BOOL* /*result*/) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::focus() |
| { |
| if (!m_element) |
| return E_FAIL; |
| m_element->focus(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::blur() |
| { |
| if (!m_element) |
| return E_FAIL; |
| m_element->blur(); |
| return S_OK; |
| } |
| |
| // IDOMElementPrivate --------------------------------------------------------- |
| |
| HRESULT DOMElement::coreElement(__deref_opt_out void **element) |
| { |
| if (!m_element) |
| return E_FAIL; |
| *element = (void*) m_element; |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::isEqual(_In_opt_ IDOMElement* other, _Out_ BOOL* result) |
| { |
| if (!result) |
| return E_POINTER; |
| |
| *result = FALSE; |
| |
| if (!other) |
| 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 DOMElement::isFocused(_Out_ BOOL* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = FALSE; |
| if (!m_element) |
| return E_FAIL; |
| |
| if (m_element->document().focusedElement() == m_element) |
| *result = TRUE; |
| else |
| *result = FALSE; |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::innerText(__deref_opt_out BSTR* result) |
| { |
| if (!result) { |
| ASSERT_NOT_REACHED(); |
| return E_POINTER; |
| } |
| |
| *result = nullptr; |
| |
| if (!m_element) { |
| ASSERT_NOT_REACHED(); |
| return E_FAIL; |
| } |
| |
| *result = BString(m_element->innerText()).release(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::font(_Out_ WebFontDescription* webFontDescription) |
| { |
| if (!webFontDescription) { |
| ASSERT_NOT_REACHED(); |
| return E_POINTER; |
| } |
| |
| ASSERT(m_element); |
| |
| WebCore::RenderElement* renderer = m_element->renderer(); |
| if (!renderer) |
| return E_FAIL; |
| |
| auto fontDescription = renderer->style().fontCascade().fontDescription(); |
| AtomString family = fontDescription.firstFamily(); |
| |
| // FIXME: This leaks. Delete this whole function to get rid of the leak. |
| UChar* familyCharactersBuffer = new UChar[family.length()]; |
| StringView(family.string()).getCharactersWithUpconvert(familyCharactersBuffer); |
| |
| webFontDescription->family = wcharFrom(familyCharactersBuffer); |
| webFontDescription->familyLength = family.length(); |
| webFontDescription->size = fontDescription.computedSize(); |
| webFontDescription->bold = isFontWeightBold(fontDescription.weight()); |
| webFontDescription->italic = isItalic(fontDescription.italic()); |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::renderedImage(__deref_opt_out HBITMAP* image) |
| { |
| if (!image) { |
| ASSERT_NOT_REACHED(); |
| return E_POINTER; |
| } |
| *image = nullptr; |
| |
| ASSERT(m_element); |
| |
| Frame* frame = m_element->document().frame(); |
| if (!frame) |
| return E_FAIL; |
| |
| *image = createDragImageForNode(*frame, *m_element); |
| if (!*image) |
| return E_FAIL; |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::markerTextForListItem(__deref_opt_out BSTR* markerText) |
| { |
| if (!markerText) |
| return E_POINTER; |
| |
| ASSERT(m_element); |
| |
| *markerText = BString(WebCore::markerTextForListItem(m_element)).release(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::shadowPseudoId(__deref_opt_out BSTR* result) |
| { |
| if (!result) |
| return E_POINTER; |
| |
| ASSERT(m_element); |
| |
| *result = BString(m_element->shadowPseudoId().string()).release(); |
| return S_OK; |
| } |
| |
| // IDOMElementCSSInlineStyle -------------------------------------------------- |
| |
| HRESULT DOMElement::style(_COM_Outptr_opt_ IDOMCSSStyleDeclaration** result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| if (!is<WebCore::StyledElement>(m_element)) |
| return E_FAIL; |
| |
| *result = DOMCSSStyleDeclaration::createInstance(&downcast<WebCore::StyledElement>(*m_element).cssomStyle()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| // IDOMElementExtensions ------------------------------------------------------ |
| |
| HRESULT DOMElement::offsetLeft(_Out_ int* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = m_element->offsetLeft(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::offsetTop(_Out_ int* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = m_element->offsetTop(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::offsetWidth(_Out_ int* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = m_element->offsetWidth(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::offsetHeight(_Out_ int* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = m_element->offsetHeight(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::offsetParent(_COM_Outptr_opt_ IDOMElement** result) |
| { |
| // FIXME |
| ASSERT_NOT_REACHED(); |
| if (!result) |
| return E_POINTER; |
| *result = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::clientWidth(_Out_ int* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = m_element->clientWidth(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::clientHeight(_Out_ int* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = m_element->clientHeight(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::scrollLeft(_Out_ int* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = m_element->scrollLeft(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::setScrollLeft(int /*newScrollLeft*/) |
| { |
| // FIXME |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::scrollTop(_Out_ int* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = m_element->scrollTop(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::setScrollTop(int /*newScrollTop*/) |
| { |
| // FIXME |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMElement::scrollWidth(_Out_ int* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = m_element->scrollWidth(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::scrollHeight(_Out_ int* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = 0; |
| if (!m_element) |
| return E_FAIL; |
| |
| *result = m_element->scrollHeight(); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::scrollIntoView(BOOL alignWithTop) |
| { |
| if (!m_element) |
| return E_FAIL; |
| |
| m_element->scrollIntoView(!!alignWithTop); |
| return S_OK; |
| } |
| |
| HRESULT DOMElement::scrollIntoViewIfNeeded(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 nullptr; |
| |
| HRESULT hr; |
| IDOMElement* domElement = nullptr; |
| |
| if (is<WebCore::HTMLFormElement>(*e)) { |
| 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 (is<WebCore::HTMLInputElement>(*e)) { |
| DOMHTMLInputElement* newElement = new DOMHTMLInputElement(e); |
| hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); |
| } else if (is<WebCore::HTMLOptionElement>(*e)) { |
| 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 (is<WebCore::HTMLTextAreaElement>(*e)) { |
| 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 nullptr; |
| |
| return domElement; |
| } |
| |
| // DOMRange - IUnknown ----------------------------------------------------- |
| |
| HRESULT DOMRange::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject) |
| { |
| if (!ppvObject) |
| return E_POINTER; |
| *ppvObject = nullptr; |
| if (IsEqualGUID(riid, IID_IDOMRange)) |
| *ppvObject = static_cast<IDOMRange*>(this); |
| else |
| return DOMObject::QueryInterface(riid, ppvObject); |
| |
| AddRef(); |
| return S_OK; |
| } |
| |
| // DOMRange ----------------------------------------------------------------- |
| |
| DOMRange::DOMRange(WebCore::Range* e) |
| : m_range(e) |
| { |
| m_range->ref(); |
| } |
| |
| DOMRange::~DOMRange() |
| { |
| m_range->deref(); |
| } |
| |
| IDOMRange* DOMRange::createInstance(WebCore::Range* range) |
| { |
| if (!range) |
| return nullptr; |
| |
| DOMRange* newRange = new DOMRange(range); |
| |
| IDOMRange* domRange = nullptr; |
| if (FAILED(newRange->QueryInterface(IID_IDOMRange, reinterpret_cast<void**>(&domRange)))) |
| return nullptr; |
| |
| return newRange; |
| } |
| |
| IDOMRange* DOMRange::createInstance(const std::optional<WebCore::SimpleRange>& range) |
| { |
| return createInstance(createLiveRange(range).get()); |
| } |
| |
| HRESULT DOMRange::startContainer(_COM_Outptr_opt_ IDOMNode** node) |
| { |
| if (!node) |
| return E_POINTER; |
| *node = nullptr; |
| if (!m_range) |
| return E_UNEXPECTED; |
| |
| *node = DOMNode::createInstance(&m_range->startContainer()); |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMRange::startOffset(_Out_ int* offset) |
| { |
| if (!offset) |
| return E_POINTER; |
| *offset = 0; |
| if (!m_range) |
| return E_UNEXPECTED; |
| |
| *offset = m_range->startOffset(); |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMRange::endContainer(_COM_Outptr_opt_ IDOMNode** node) |
| { |
| if (!node) |
| return E_POINTER; |
| *node = nullptr; |
| if (!m_range) |
| return E_UNEXPECTED; |
| |
| *node = DOMNode::createInstance(&m_range->endContainer()); |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMRange::endOffset(_Out_ int* offset) |
| { |
| if (!offset) |
| return E_POINTER; |
| *offset = 0; |
| if (!m_range) |
| return E_UNEXPECTED; |
| |
| *offset = m_range->endOffset(); |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMRange::collapsed(_Out_ BOOL* result) |
| { |
| if (!result) |
| return E_POINTER; |
| *result = FALSE; |
| if (!m_range) |
| return E_UNEXPECTED; |
| |
| *result = m_range->collapsed(); |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMRange::commonAncestorContainer(_COM_Outptr_opt_ IDOMNode** container) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!container) |
| return E_POINTER; |
| *container = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::setStart(_In_opt_ IDOMNode* refNode, int offset) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::setEnd(_In_opt_ IDOMNode* refNode, int offset) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::setStartBefore(_In_opt_ IDOMNode* refNode) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::setStartAfter(_In_opt_ IDOMNode* refNode) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::setEndBefore(_In_opt_ IDOMNode* refNode) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::setEndAfter(_In_opt_ IDOMNode* refNode) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::collapse(BOOL toStart) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::selectNode(_In_opt_ IDOMNode* refNode) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::selectNodeContents(_In_opt_ IDOMNode* refNode) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::compareBoundaryPoints(unsigned short how, _In_opt_ IDOMRange* sourceRange) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::deleteContents() |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::extractContents(_COM_Outptr_opt_ IDOMDocumentFragment** fragment) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!fragment) |
| return E_POINTER; |
| *fragment = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::cloneContents(_COM_Outptr_opt_ IDOMDocumentFragment** fragment) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!fragment) |
| return E_POINTER; |
| *fragment = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::insertNode(_In_opt_ IDOMNode* newNode) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::surroundContents(_In_opt_ IDOMNode* newParent) |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::cloneRange(_COM_Outptr_opt_ IDOMRange** range) |
| { |
| ASSERT_NOT_REACHED(); |
| if (!range) |
| return E_POINTER; |
| *range = nullptr; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMRange::toString(__deref_opt_out BSTR* str) |
| { |
| if (!str) |
| return E_POINTER; |
| *str = nullptr; |
| if (!m_range) |
| return E_UNEXPECTED; |
| |
| *str = BString(m_range->toString()).release(); |
| |
| return S_OK; |
| } |
| |
| HRESULT DOMRange::detach() |
| { |
| ASSERT_NOT_REACHED(); |
| return E_NOTIMPL; |
| } |
| |
| DOMNamedNodeMap::DOMNamedNodeMap(WebCore::NamedNodeMap* nodeMap) |
| : m_nodeMap(nodeMap) |
| { |
| m_nodeMap->ref(); |
| } |
| |
| DOMNamedNodeMap::~DOMNamedNodeMap() |
| { |
| m_nodeMap->deref(); |
| } |
| |
| IDOMNamedNodeMap* DOMNamedNodeMap::createInstance(WebCore::NamedNodeMap* nodeMap) |
| { |
| if (!nodeMap) |
| return nullptr; |
| |
| DOMNamedNodeMap* namedNodeMap = new DOMNamedNodeMap(nodeMap); |
| |
| IDOMNamedNodeMap* domNamedNodeMap = nullptr; |
| if (FAILED(namedNodeMap->QueryInterface(IID_IDOMNamedNodeMap, reinterpret_cast<void**>(&domNamedNodeMap)))) |
| return nullptr; |
| |
| return namedNodeMap; |
| } |
| |
| HRESULT DOMNamedNodeMap::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject) |
| { |
| *ppvObject = nullptr; |
| if (IsEqualGUID(riid, IID_IDOMNamedNodeMap)) |
| *ppvObject = static_cast<IDOMNamedNodeMap*>(this); |
| else |
| return DOMObject::QueryInterface(riid, ppvObject); |
| |
| AddRef(); |
| return S_OK; |
| } |
| |
| HRESULT DOMNamedNodeMap::getNamedItem(_In_ BSTR name, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNamedNodeMap::setNamedItem(_In_opt_ IDOMNode* arg, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNamedNodeMap::removeNamedItem(_In_ BSTR name, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNamedNodeMap::item(_In_ UINT index, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| if (!result) |
| return E_POINTER; |
| |
| if (!m_nodeMap) |
| return E_FAIL; |
| |
| *result = DOMNode::createInstance(m_nodeMap->item(index).get()); |
| return *result ? S_OK : E_FAIL; |
| } |
| |
| HRESULT DOMNamedNodeMap::length(_Out_opt_ UINT* result) |
| { |
| if (!result) |
| return E_POINTER; |
| |
| *result = m_nodeMap->length(); |
| return S_OK; |
| } |
| |
| HRESULT DOMNamedNodeMap::getNamedItemNS(_In_ BSTR namespaceURI, _In_ BSTR localName, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNamedNodeMap::setNamedItemNS(_In_opt_ IDOMNode* arg, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| return E_NOTIMPL; |
| } |
| |
| HRESULT DOMNamedNodeMap::removeNamedItemNS(_In_ BSTR namespaceURI, _In_ BSTR localName, _COM_Outptr_opt_ IDOMNode** result) |
| { |
| return E_NOTIMPL; |
| } |