5df783862cc91c85a3b5a6b3f5426696131a83b3
[WebKit-https.git] / Source / WebKit / win / DOMCoreClasses.cpp
1 /*
2  * Copyright (C) 2006-2007, 2009, 2014-2015 Apple Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "WebKitDLL.h"
27 #include "DOMCoreClasses.h"
28
29 #include "DOMCSSClasses.h"
30 #include "DOMEventsClasses.h"
31 #include "DOMHTMLClasses.h"
32 #include "WebKitGraphics.h"
33
34 #include <WebCore/BString.h>
35 #include <WebCore/COMPtr.h>
36 #include <WebCore/DOMWindow.h>
37 #include <WebCore/Document.h>
38 #include <WebCore/DragImage.h>
39 #include <WebCore/Element.h>
40 #include <WebCore/Event.h>
41 #include <WebCore/Font.h>
42 #include <WebCore/FontCascade.h>
43 #include <WebCore/Frame.h>
44 #include <WebCore/HTMLCollection.h>
45 #include <WebCore/HTMLFormElement.h>
46 #include <WebCore/HTMLInputElement.h>
47 #include <WebCore/HTMLNames.h>
48 #include <WebCore/HTMLOptionElement.h>
49 #include <WebCore/HTMLSelectElement.h>
50 #include <WebCore/HTMLTextAreaElement.h>
51 #include <WebCore/NamedNodeMap.h>
52 #include <WebCore/NodeList.h>
53 #include <WebCore/Range.h>
54 #include <WebCore/RenderElement.h>
55 #include <WebCore/RenderTreeAsText.h>
56
57 #include <initguid.h>
58 // {3B0C0EFF-478B-4b0b-8290-D2321E08E23E}
59 DEFINE_GUID(IID_DOMElement, 0x3b0c0eff, 0x478b, 0x4b0b, 0x82, 0x90, 0xd2, 0x32, 0x1e, 0x8, 0xe2, 0x3e);
60
61 // Our normal style is just to say "using namespace WebCore" rather than having
62 // individual using directives for each type from that namespace. But
63 // "DOMObject" exists both in the WebCore namespace and unnamespaced in this
64 // file, which leads to ambiguities if we say "using namespace WebCore".
65 using namespace WebCore::HTMLNames;
66 using WTF::AtomicString;
67 using WebCore::BString;
68 using WebCore::Element;
69 using WebCore::ExceptionCode;
70 using WebCore::Frame;
71 using WebCore::IntRect;
72 using WTF::String;
73
74 // DOMObject - IUnknown -------------------------------------------------------
75
76 HRESULT DOMObject::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
77 {
78     if (!ppvObject)
79         return E_POINTER;
80     *ppvObject = nullptr;
81     if (IsEqualGUID(riid, IID_IDOMObject))
82         *ppvObject = static_cast<IDOMObject*>(this);
83     else
84         return WebScriptObject::QueryInterface(riid, ppvObject);
85
86     AddRef();
87     return S_OK;
88 }
89
90 // DOMNode - IUnknown ---------------------------------------------------------
91
92 HRESULT DOMNode::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
93 {
94     if (!ppvObject)
95         return E_POINTER;
96     *ppvObject = nullptr;
97     if (IsEqualGUID(riid, IID_IDOMNode))
98         *ppvObject = static_cast<IDOMNode*>(this);
99     else if (IsEqualGUID(riid, __uuidof(DOMNode)))
100         *ppvObject = static_cast<DOMNode*>(this);
101     else if (IsEqualGUID(riid, __uuidof(IDOMEventTarget)))
102         *ppvObject = static_cast<IDOMEventTarget*>(this);
103     else
104         return DOMObject::QueryInterface(riid, ppvObject);
105
106     AddRef();
107     return S_OK;
108 }
109
110 // DOMNode --------------------------------------------------------------------
111
112 HRESULT DOMNode::nodeName(__deref_opt_out BSTR* result)
113 {
114     if (!result)
115         return E_POINTER;
116     *result = nullptr;
117     if (!m_node)
118         return E_FAIL;
119
120     *result = BString(m_node->nodeName()).release();
121     return S_OK;
122 }
123
124 HRESULT DOMNode::nodeValue(__deref_opt_out BSTR* result)
125 {
126     if (!result)
127         return E_POINTER;
128     *result = nullptr;
129     if (!m_node)
130         return E_FAIL;
131     WTF::String nodeValueStr = m_node->nodeValue();
132     *result = BString(nodeValueStr).release();
133     if (nodeValueStr.length() && !*result)
134         return E_OUTOFMEMORY;
135     return S_OK;
136 }
137
138 HRESULT DOMNode::setNodeValue(_In_ BSTR /*value*/)
139 {
140     ASSERT_NOT_REACHED();
141     return E_NOTIMPL;
142 }
143
144 HRESULT DOMNode::nodeType(_Out_ unsigned short* /*result*/)
145 {
146     ASSERT_NOT_REACHED();
147     return E_NOTIMPL;
148 }
149
150 HRESULT DOMNode::parentNode(_COM_Outptr_opt_ IDOMNode** result)
151 {
152     if (!result)
153         return E_POINTER;
154     *result = nullptr;
155     if (!m_node || !m_node->parentNode())
156         return E_FAIL;
157     *result = DOMNode::createInstance(m_node->parentNode());
158     return *result ? S_OK : E_FAIL;
159 }
160
161 HRESULT DOMNode::childNodes(_COM_Outptr_opt_ IDOMNodeList** result)
162 {
163     if (!result)
164         return E_POINTER;
165     *result = nullptr;
166     if (!m_node)
167         return E_FAIL;
168
169     if (!result)
170         return E_POINTER;
171
172     *result = DOMNodeList::createInstance(m_node->childNodes().get());
173     return *result ? S_OK : E_FAIL;
174 }
175
176 HRESULT DOMNode::firstChild(_COM_Outptr_opt_ IDOMNode** result)
177 {
178     ASSERT_NOT_REACHED();
179     if (!result)
180         return E_POINTER;
181     *result = nullptr;
182     return E_NOTIMPL;
183 }
184
185 HRESULT DOMNode::lastChild(_COM_Outptr_opt_ IDOMNode** result)
186 {
187     ASSERT_NOT_REACHED();
188     if (!result)
189         return E_POINTER;
190     *result = nullptr;
191     return E_NOTIMPL;
192 }
193
194 HRESULT DOMNode::previousSibling(_COM_Outptr_opt_ IDOMNode** result)
195 {
196     ASSERT_NOT_REACHED();
197     if (!result)
198         return E_POINTER;
199     *result = nullptr;
200     return E_NOTIMPL;
201 }
202
203 HRESULT DOMNode::nextSibling(_COM_Outptr_opt_ IDOMNode** result)
204 {
205     if (!result)
206         return E_POINTER;
207     *result = nullptr;
208     if (!m_node)
209         return E_FAIL;
210     *result = DOMNode::createInstance(m_node->nextSibling());
211     return *result ? S_OK : E_FAIL;
212 }
213
214 HRESULT DOMNode::attributes(_COM_Outptr_opt_ IDOMNamedNodeMap** result)
215 {
216     if (!result)
217         return E_POINTER;
218     *result = nullptr;
219     if (!m_node)
220         return E_FAIL;
221     *result = DOMNamedNodeMap::createInstance(m_node->attributes());
222     return *result ? S_OK : E_FAIL;
223 }
224
225 HRESULT DOMNode::ownerDocument(_COM_Outptr_opt_ IDOMDocument** result)
226 {
227     if (!result)
228         return E_POINTER;
229     *result = nullptr;
230     if (!m_node)
231         return E_FAIL;
232     *result = DOMDocument::createInstance(m_node->ownerDocument());
233     return *result ? S_OK : E_FAIL;
234 }
235
236 HRESULT DOMNode::insertBefore(_In_opt_ IDOMNode* newChild, _In_opt_ IDOMNode* refChild, _COM_Outptr_opt_ IDOMNode** result)
237 {
238     if (!result)
239         return E_POINTER;
240
241     *result = nullptr;
242
243     if (!m_node)
244         return E_FAIL;
245
246     COMPtr<DOMNode> newChildNode(Query, newChild);
247     if (!newChildNode)
248         return E_FAIL;
249
250     COMPtr<DOMNode> refChildNode(Query, refChild);
251
252     ExceptionCode ec;
253     if (!m_node->insertBefore(*newChildNode->node(), refChildNode ? refChildNode->node() : nullptr, ec))
254         return E_FAIL;
255
256     *result = newChild;
257     (*result)->AddRef();
258     return S_OK;
259 }
260
261 HRESULT DOMNode::replaceChild(_In_opt_ IDOMNode* /*newChild*/, _In_opt_ IDOMNode* /*oldChild*/, _COM_Outptr_opt_ IDOMNode** result)
262 {
263     ASSERT_NOT_REACHED();
264     if (!result)
265         return E_POINTER;
266     *result = nullptr;
267     return E_NOTIMPL;
268 }
269
270 HRESULT DOMNode::removeChild(_In_opt_ IDOMNode* oldChild, _COM_Outptr_opt_ IDOMNode** result)
271 {
272     if (!result)
273         return E_POINTER;
274
275     *result = nullptr;
276
277     if (!m_node)
278         return E_FAIL;
279
280     COMPtr<DOMNode> oldChildNode(Query, oldChild);
281     if (!oldChildNode)
282         return E_FAIL;
283
284     ExceptionCode ec;
285     if (!m_node->removeChild(*oldChildNode->node(), ec))
286         return E_FAIL;
287
288     *result = oldChild;
289     (*result)->AddRef();
290     return S_OK;
291 }
292
293 HRESULT DOMNode::appendChild(_In_opt_ IDOMNode* /*oldChild*/, _COM_Outptr_opt_ IDOMNode** result)
294 {
295     ASSERT_NOT_REACHED();
296     if (!result)
297         return E_POINTER;
298     *result = nullptr;
299     return E_NOTIMPL;
300 }
301
302 HRESULT DOMNode::hasChildNodes(_Out_ BOOL* /*result*/)
303 {
304     ASSERT_NOT_REACHED();
305     return E_NOTIMPL;
306 }
307
308 HRESULT DOMNode::cloneNode(BOOL /*deep*/, _COM_Outptr_opt_ IDOMNode** result)
309 {
310     ASSERT_NOT_REACHED();
311     if (!result)
312         return E_POINTER;
313     *result = nullptr;
314     return E_NOTIMPL;
315 }
316
317 HRESULT DOMNode::normalize()
318 {
319     ASSERT_NOT_REACHED();
320     return E_NOTIMPL;
321 }
322
323 HRESULT DOMNode::isSupported(_In_ BSTR /*feature*/, _In_ BSTR /*version*/, _Out_ BOOL* /*result*/)
324 {
325     ASSERT_NOT_REACHED();
326     return E_NOTIMPL;
327 }
328
329 HRESULT DOMNode::namespaceURI(__deref_opt_out BSTR* result)
330 {
331     ASSERT_NOT_REACHED();
332     if (!result)
333         return E_POINTER;
334     *result = nullptr;
335     return E_NOTIMPL;
336 }
337
338 HRESULT DOMNode::prefix(__deref_opt_out BSTR* result)
339 {
340     ASSERT_NOT_REACHED();
341     if (!result)
342         return E_POINTER;
343     *result = nullptr;
344     return E_NOTIMPL;
345 }
346
347 HRESULT DOMNode::setPrefix(_In_ BSTR /*prefix*/)
348 {
349     ASSERT_NOT_REACHED();
350     return E_NOTIMPL;
351 }
352
353 HRESULT DOMNode::localName(__deref_opt_out BSTR* result)
354 {
355     ASSERT_NOT_REACHED();
356     if (!result)
357         return E_POINTER;
358     *result = nullptr;
359     return E_NOTIMPL;
360 }
361
362 HRESULT DOMNode::hasAttributes(_Out_ BOOL* /*result*/)
363 {
364     ASSERT_NOT_REACHED();
365     return E_NOTIMPL;
366 }
367
368 HRESULT DOMNode::isSameNode(_In_opt_ IDOMNode* other, _Out_ BOOL* result)
369 {
370     if (!result) {
371         ASSERT_NOT_REACHED();
372         return E_POINTER;
373     }
374
375     *result = FALSE;
376
377     if (!other)
378         return E_POINTER;
379
380     COMPtr<DOMNode> domOther;
381     HRESULT hr = other->QueryInterface(__uuidof(DOMNode), (void**)&domOther);
382     if (FAILED(hr))
383         return hr;
384
385     *result = m_node->isSameNode(domOther->node()) ? TRUE : FALSE;
386     return S_OK;
387 }
388
389 HRESULT DOMNode::isEqualNode(_In_opt_ IDOMNode* /*other*/, _Out_ BOOL* /*result*/)
390 {
391     ASSERT_NOT_REACHED();
392     return E_NOTIMPL;
393 }
394
395 HRESULT DOMNode::textContent(__deref_opt_out BSTR* result)
396 {
397     if (!result)
398         return E_POINTER;
399
400     *result = BString(m_node->textContent()).release();
401
402     return S_OK;
403 }
404
405 HRESULT DOMNode::setTextContent(_In_ BSTR /*text*/)
406 {
407     ASSERT_NOT_REACHED();
408     return E_NOTIMPL;
409 }
410
411 // DOMNode - IDOMEventTarget --------------------------------------------------
412
413 HRESULT DOMNode::addEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener* listener, BOOL useCapture)
414 {
415     RefPtr<WebEventListener> webListener = WebEventListener::create(listener);
416     m_node->addEventListener(type, webListener, useCapture);
417
418     return S_OK;
419 }
420
421 HRESULT DOMNode::removeEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener* listener, BOOL useCapture)
422 {
423     if (!listener || !type)
424         return E_POINTER;
425     if (!m_node)
426         return E_FAIL;
427     RefPtr<WebEventListener> webListener = WebEventListener::create(listener);
428     m_node->removeEventListener(type, webListener.get(), useCapture);
429     return S_OK;
430 }
431
432 HRESULT DOMNode::dispatchEvent(_In_opt_ IDOMEvent* evt, _Out_ BOOL* result)
433 {
434     if (!evt || !result)
435         return E_POINTER;
436     if (!m_node)
437         return E_FAIL;
438
439     COMPtr<DOMEvent> domEvent;
440     HRESULT hr = evt->QueryInterface(IID_DOMEvent, (void**) &domEvent);
441     if (FAILED(hr))
442         return hr;
443
444     WebCore::ExceptionCode ec = 0;
445     *result = m_node->dispatchEventForBindings(domEvent->coreEvent(), ec) ? TRUE : FALSE;
446     return ec ? E_FAIL : S_OK;
447 }
448
449 // DOMNode - DOMNode ----------------------------------------------------------
450
451 DOMNode::DOMNode(WebCore::Node* n)
452 {
453     if (n)
454         n->ref();
455
456     m_node = n;
457 }
458
459 DOMNode::~DOMNode()
460 {
461     if (m_node)
462         m_node->deref();
463 }
464
465 IDOMNode* DOMNode::createInstance(WebCore::Node* n)
466 {
467     if (!n)
468         return nullptr;
469
470     HRESULT hr = S_OK;
471     IDOMNode* domNode = nullptr;
472     WebCore::Node::NodeType nodeType = n->nodeType();
473
474     switch (nodeType) {
475         case WebCore::Node::ELEMENT_NODE: 
476         {
477             IDOMElement* newElement = DOMElement::createInstance(static_cast<WebCore::Element*>(n));
478             if (newElement) {
479                 hr = newElement->QueryInterface(IID_IDOMNode, (void**)&domNode);
480                 newElement->Release();
481             }
482         }
483         break;
484         case WebCore::Node::DOCUMENT_NODE:
485         {
486             IDOMDocument* newDocument = DOMDocument::createInstance(&n->document());
487             if (newDocument) {
488                 hr = newDocument->QueryInterface(IID_IDOMNode, (void**)&domNode);
489                 newDocument->Release();
490             }
491         }
492         break;
493         default:
494         {
495             DOMNode* newNode = new DOMNode(n);
496             hr = newNode->QueryInterface(IID_IDOMNode, (void**)&domNode);
497         }
498         break;
499     }
500
501     if (FAILED(hr))
502         return nullptr;
503
504     return domNode;
505 }
506
507 // DOMNodeList - IUnknown -----------------------------------------------------
508
509 HRESULT DOMNodeList::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
510 {
511     if (!ppvObject)
512         return E_POINTER;
513     *ppvObject = nullptr;
514     if (IsEqualGUID(riid, IID_IDOMNodeList))
515         *ppvObject = static_cast<IDOMNodeList*>(this);
516     else
517         return DOMObject::QueryInterface(riid, ppvObject);
518
519     AddRef();
520     return S_OK;
521 }
522
523 // IDOMNodeList ---------------------------------------------------------------
524
525 HRESULT DOMNodeList::item(UINT index, _COM_Outptr_opt_ IDOMNode** result)
526 {
527     if (!result)
528         return E_POINTER;
529     *result = nullptr;
530     if (!m_nodeList)
531         return E_FAIL;
532
533     WebCore::Node* itemNode = m_nodeList->item(index);
534     if (!itemNode)
535         return E_FAIL;
536
537     *result = DOMNode::createInstance(itemNode);
538     return *result ? S_OK : E_FAIL;
539 }
540
541 HRESULT DOMNodeList::length(_Out_ UINT* result)
542 {
543     if (!result)
544         return E_POINTER;
545     *result = 0;
546     if (!m_nodeList)
547         return E_FAIL;
548     *result = m_nodeList->length();
549     return S_OK;
550 }
551
552 // DOMNodeList - DOMNodeList --------------------------------------------------
553
554 DOMNodeList::DOMNodeList(WebCore::NodeList* l)
555 {
556     if (l)
557         l->ref();
558
559     m_nodeList = l;
560 }
561
562 DOMNodeList::~DOMNodeList()
563 {
564     if (m_nodeList)
565         m_nodeList->deref();
566 }
567
568 IDOMNodeList* DOMNodeList::createInstance(WebCore::NodeList* l)
569 {
570     if (!l)
571         return nullptr;
572
573     IDOMNodeList* domNodeList = nullptr;
574     DOMNodeList* newNodeList = new DOMNodeList(l);
575     if (FAILED(newNodeList->QueryInterface(IID_IDOMNodeList, (void**)&domNodeList)))
576         return nullptr;
577
578     return domNodeList;
579 }
580
581 // DOMDocument - IUnknown -----------------------------------------------------
582
583 HRESULT DOMDocument::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
584 {
585     if (!ppvObject)
586         return E_POINTER;
587     *ppvObject = nullptr;
588     if (IsEqualGUID(riid, IID_IDOMDocument))
589         *ppvObject = static_cast<IDOMDocument*>(this);
590     else if (IsEqualGUID(riid, IID_IDOMViewCSS))
591         *ppvObject = static_cast<IDOMViewCSS*>(this);
592     else if (IsEqualGUID(riid, IID_IDOMDocumentEvent))
593         *ppvObject = static_cast<IDOMDocumentEvent*>(this);
594     else
595         return DOMNode::QueryInterface(riid, ppvObject);
596
597     AddRef();
598     return S_OK;
599 }
600
601 // DOMDocument ----------------------------------------------------------------
602
603 HRESULT DOMDocument::doctype(_COM_Outptr_opt_ IDOMDocumentType** result)
604 {
605     ASSERT_NOT_REACHED();
606     if (!result)
607         return E_POINTER;
608     *result = nullptr;
609     return E_NOTIMPL;
610 }
611
612 HRESULT DOMDocument::implementation(_COM_Outptr_opt_ IDOMImplementation** result)
613 {
614     ASSERT_NOT_REACHED();
615     if (!result)
616         return E_POINTER;
617     *result = nullptr;
618     return E_NOTIMPL;
619 }
620
621 HRESULT DOMDocument::documentElement(_COM_Outptr_opt_ IDOMElement** result)
622 {
623     if (!result)
624         return E_POINTER;
625     *result = DOMElement::createInstance(m_document->documentElement());
626     return *result ? S_OK : E_FAIL;
627 }
628
629 HRESULT DOMDocument::createElement(_In_ BSTR tagName, _COM_Outptr_opt_ IDOMElement** result)
630 {
631     if (!result)
632         return E_POINTER;
633     *result = nullptr;
634     if (!m_document)
635         return E_FAIL;
636
637     String tagNameString(tagName);
638     ExceptionCode ec;
639     *result = DOMElement::createInstance(m_document->createElementForBindings(tagNameString, ec).get());
640     return *result ? S_OK : E_FAIL;
641 }
642
643 HRESULT DOMDocument::createDocumentFragment(_COM_Outptr_opt_ IDOMDocumentFragment** result)
644 {
645     ASSERT_NOT_REACHED();
646     if (!result)
647         return E_POINTER;
648     *result = nullptr;
649     return E_NOTIMPL;
650 }
651
652 HRESULT STDMETHODCALLTYPE DOMDocument::createTextNode(_In_ BSTR /*data*/, _COM_Outptr_opt_ IDOMText** result)
653 {
654     ASSERT_NOT_REACHED();
655     if (!result)
656         return E_POINTER;
657     *result = nullptr;
658     return E_NOTIMPL;
659 }
660
661 HRESULT DOMDocument::createComment(_In_ BSTR /*data*/, _COM_Outptr_opt_ IDOMComment** result)
662 {
663     ASSERT_NOT_REACHED();
664     if (!result)
665         return E_POINTER;
666     *result = nullptr;
667     return E_NOTIMPL;
668 }
669
670 HRESULT DOMDocument::createCDATASection(_In_ BSTR /*data*/, _COM_Outptr_opt_ IDOMCDATASection** result)
671 {
672     ASSERT_NOT_REACHED();
673     if (!result)
674         return E_POINTER;
675     *result = nullptr;
676     return E_NOTIMPL;
677 }
678
679 HRESULT DOMDocument::createProcessingInstruction(_In_ BSTR /*target*/, _In_ BSTR /*data*/, _COM_Outptr_opt_ IDOMProcessingInstruction** result)
680 {
681     ASSERT_NOT_REACHED();
682     if (!result)
683         return E_POINTER;
684     *result = nullptr;
685     return E_NOTIMPL;
686 }
687
688 HRESULT DOMDocument::createAttribute(_In_ BSTR /*name*/, _COM_Outptr_opt_ IDOMAttr** result)
689 {
690     ASSERT_NOT_REACHED();
691     if (!result)
692         return E_POINTER;
693     *result = nullptr;
694     return E_NOTIMPL;
695 }
696
697 HRESULT DOMDocument::createEntityReference(_In_ BSTR /*name*/, _COM_Outptr_opt_ IDOMEntityReference** result)
698 {
699     ASSERT_NOT_REACHED();
700     if (!result)
701         return E_POINTER;
702     *result = nullptr;
703     return E_NOTIMPL;
704 }
705
706 HRESULT DOMDocument::getElementsByTagName(_In_ BSTR tagName, _COM_Outptr_opt_ IDOMNodeList** result)
707 {
708     if (!result)
709         return E_POINTER;
710     *result = nullptr;
711     if (!m_document)
712         return E_FAIL;
713
714     String tagNameString(tagName);
715     RefPtr<WebCore::NodeList> elements;
716     if (!tagNameString.isNull())
717         elements = m_document->getElementsByTagName(tagNameString);
718     *result = DOMNodeList::createInstance(elements.get());
719     return *result ? S_OK : E_FAIL;
720 }
721
722 HRESULT DOMDocument::importNode(_In_opt_ IDOMNode* /*importedNode*/, BOOL /*deep*/, _COM_Outptr_opt_ IDOMNode** result)
723 {
724     ASSERT_NOT_REACHED();
725     if (!result)
726         return E_POINTER;
727     *result = nullptr;
728     return E_NOTIMPL;
729 }
730
731 HRESULT DOMDocument::createElementNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*qualifiedName*/, _COM_Outptr_opt_ IDOMElement** result)
732 {
733     ASSERT_NOT_REACHED();
734     if (!result)
735         return E_POINTER;
736     *result = nullptr;
737     return E_NOTIMPL;
738 }
739
740 HRESULT DOMDocument::createAttributeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*qualifiedName*/, _COM_Outptr_opt_ IDOMAttr** result)
741 {
742     ASSERT_NOT_REACHED();
743     if (!result)
744         return E_POINTER;
745     *result = nullptr;
746     return E_NOTIMPL;
747 }
748
749 HRESULT DOMDocument::getElementsByTagNameNS(_In_ BSTR namespaceURI, _In_ BSTR localName, _COM_Outptr_opt_ IDOMNodeList** result)
750 {
751     if (!result)
752         return E_POINTER;
753     *result = nullptr;
754     if (!m_document)
755         return E_FAIL;
756
757     String namespaceURIString(namespaceURI);
758     String localNameString(localName);
759     RefPtr<WebCore::NodeList> elements;
760     if (!localNameString.isNull())
761         elements = m_document->getElementsByTagNameNS(namespaceURIString, localNameString);
762     *result = DOMNodeList::createInstance(elements.get());
763     return *result ? S_OK : E_FAIL;
764 }
765
766 HRESULT DOMDocument::getElementById(_In_ BSTR elementId, _COM_Outptr_opt_ IDOMElement** result)
767 {
768     if (!result)
769         return E_POINTER;
770     *result = nullptr;
771     if (!m_document)
772         return E_FAIL;
773
774     String idString(elementId);
775     *result = DOMElement::createInstance(m_document->getElementById(idString));
776     return *result ? S_OK : E_FAIL;
777 }
778
779 // DOMDocument - IDOMViewCSS --------------------------------------------------
780
781 HRESULT DOMDocument::getComputedStyle(_In_opt_ IDOMElement* elt, _In_ BSTR pseudoElt, _COM_Outptr_opt_ IDOMCSSStyleDeclaration** result)
782 {
783     if (!result)
784         return E_POINTER;
785     *result = nullptr;
786     if (!elt)
787         return E_POINTER;
788
789     COMPtr<DOMElement> domEle;
790     HRESULT hr = elt->QueryInterface(IID_DOMElement, (void**)&domEle);
791     if (FAILED(hr))
792         return hr;
793     Element* element = domEle->element();
794
795     WebCore::DOMWindow* dv = m_document->defaultView();
796     String pseudoEltString(pseudoElt);
797     
798     if (!dv)
799         return E_FAIL;
800     
801     *result = DOMCSSStyleDeclaration::createInstance(dv->getComputedStyle(element, pseudoEltString.impl()).get());
802     return *result ? S_OK : E_FAIL;
803 }
804
805 // DOMDocument - IDOMDocumentEvent --------------------------------------------
806
807 HRESULT DOMDocument::createEvent(_In_ BSTR eventType, _COM_Outptr_opt_ IDOMEvent** result)
808 {
809     if (!result)
810         return E_POINTER;
811     *result = nullptr;
812
813     String eventTypeString(eventType, SysStringLen(eventType));
814     WebCore::ExceptionCode ec = 0;
815     *result = DOMEvent::createInstance(m_document->createEvent(eventTypeString, ec));
816     return *result ? S_OK : E_FAIL;
817 }
818
819 // DOMDocument - DOMDocument --------------------------------------------------
820
821 DOMDocument::DOMDocument(WebCore::Document* d)
822     : DOMNode(d)
823     , m_document(d)
824 {
825 }
826
827 DOMDocument::~DOMDocument()
828 {
829 }
830
831 IDOMDocument* DOMDocument::createInstance(WebCore::Document* d)
832 {
833     if (!d)
834         return nullptr;
835
836     HRESULT hr;
837     IDOMDocument* domDocument = nullptr;
838
839     if (d->isHTMLDocument()) {
840         DOMHTMLDocument* newDocument = new DOMHTMLDocument(d);
841         hr = newDocument->QueryInterface(IID_IDOMDocument, (void**)&domDocument);
842     } else {
843         DOMDocument* newDocument = new DOMDocument(d);
844         hr = newDocument->QueryInterface(IID_IDOMDocument, (void**)&domDocument);
845     }
846
847     if (FAILED(hr))
848         return nullptr;
849
850     return domDocument;
851 }
852
853 // DOMWindow - IUnknown ------------------------------------------------------
854
855 HRESULT DOMWindow::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
856 {
857     if (!ppvObject)
858         return E_POINTER;
859     *ppvObject = nullptr;
860     if (IsEqualGUID(riid, IID_IDOMWindow))
861         *ppvObject = static_cast<IDOMWindow*>(this);
862     else if (IsEqualGUID(riid, IID_IDOMEventTarget))
863         *ppvObject = static_cast<IDOMEventTarget*>(this);
864     else
865         return DOMObject::QueryInterface(riid, ppvObject);
866
867     AddRef();
868     return S_OK;
869 }
870
871 // DOMWindow - IDOMWindow ------------------------------------------------------
872
873 HRESULT DOMWindow::document(_COM_Outptr_opt_ IDOMDocument** result)
874 {
875     if (!result) {
876         ASSERT_NOT_REACHED();
877         return E_POINTER;
878     }
879
880     *result = DOMDocument::createInstance(m_window->document());
881     return *result ? S_OK : E_FAIL;
882 }
883
884 HRESULT DOMWindow::getComputedStyle(_In_opt_ IDOMElement* element, _In_ BSTR pseudoElement)
885 {
886     ASSERT_NOT_REACHED();
887     return E_NOTIMPL;
888 }
889
890 HRESULT DOMWindow::getMatchedCSSRules(_In_opt_ IDOMElement* element, _In_ BSTR pseudoElement, BOOL authorOnly, _COM_Outptr_opt_ IDOMCSSRuleList** result)
891 {
892     ASSERT_NOT_REACHED();
893     if (!result)
894         return E_POINTER;
895     *result = nullptr;
896     return E_NOTIMPL;
897 }
898
899 HRESULT DOMWindow::devicePixelRatio(_Out_ double* result)
900 {
901     ASSERT_NOT_REACHED();
902     return E_NOTIMPL;
903 }
904
905 // DOMWindow - IDOMEventTarget ------------------------------------------------------
906
907 HRESULT DOMWindow::addEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener* listener, BOOL useCapture)
908 {
909     if (!type || !listener)
910         return E_POINTER;
911     if (!m_window)
912         return E_FAIL;
913     RefPtr<WebEventListener> webListener = WebEventListener::create(listener);
914     m_window->addEventListener(type, webListener, useCapture);
915     return S_OK;
916 }
917
918 HRESULT DOMWindow::removeEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener* listener, BOOL useCapture)
919 {
920     if (!type || !listener)
921         return E_POINTER;
922     if (!m_window)
923         return E_FAIL;
924     RefPtr<WebEventListener> webListener = WebEventListener::create(listener);
925     m_window->removeEventListener(type, webListener.get(), useCapture);
926     return S_OK;
927 }
928
929 HRESULT DOMWindow::dispatchEvent(_In_opt_ IDOMEvent* evt, _Out_ BOOL* result)
930 {
931     if (!result || !evt)
932         return E_POINTER;
933     if (!m_window)
934         return E_FAIL;
935
936     COMPtr<DOMEvent> domEvent;
937     HRESULT hr = evt->QueryInterface(IID_DOMEvent, (void**) &domEvent);
938     if (FAILED(hr))
939         return hr;
940
941     WebCore::ExceptionCode ec = 0;
942     *result = m_window->dispatchEventForBindings(domEvent->coreEvent(), ec) ? TRUE : FALSE;
943     return ec ? E_FAIL : S_OK;
944 }
945
946
947 // DOMWindow - DOMWindow --------------------------------------------------
948
949 DOMWindow::DOMWindow(WebCore::DOMWindow* w)
950     : m_window(w)
951 {
952 }
953
954 DOMWindow::~DOMWindow()
955 {
956 }
957
958 IDOMWindow* DOMWindow::createInstance(WebCore::DOMWindow* w)
959 {
960     if (!w)
961         return nullptr;
962
963     DOMWindow* newWindow = new DOMWindow(w);
964
965     IDOMWindow* domWindow = nullptr;
966     HRESULT hr = newWindow->QueryInterface(IID_IDOMWindow, reinterpret_cast<void**>(&domWindow));
967
968     if (FAILED(hr))
969         return nullptr;
970
971     return domWindow;
972 }
973
974 // DOMElement - IUnknown ------------------------------------------------------
975
976 HRESULT DOMElement::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
977 {
978     if (!ppvObject)
979         return E_POINTER;
980     *ppvObject = nullptr;
981     if (IsEqualGUID(riid, IID_IDOMElement))
982         *ppvObject = static_cast<IDOMElement*>(this);
983     else if (IsEqualGUID(riid, IID_DOMElement))
984         *ppvObject = static_cast<DOMElement*>(this);
985     else if (IsEqualGUID(riid, IID_IDOMElementPrivate))
986         *ppvObject = static_cast<IDOMElementPrivate*>(this);
987     else if (IsEqualGUID(riid, IID_IDOMNodeExtensions))
988         *ppvObject = static_cast<IDOMNodeExtensions*>(this);
989     else if (IsEqualGUID(riid, IID_IDOMElementCSSInlineStyle))
990         *ppvObject = static_cast<IDOMElementCSSInlineStyle*>(this);
991     else if (IsEqualGUID(riid, IID_IDOMElementExtensions))
992         *ppvObject = static_cast<IDOMElementExtensions*>(this);
993     else
994         return DOMNode::QueryInterface(riid, ppvObject);
995
996     AddRef();
997     return S_OK;
998 }
999
1000 // DOMElement - IDOMNodeExtensions---------------------------------------------
1001
1002 HRESULT DOMElement::boundingBox(_Out_ LPRECT rect)
1003 {
1004     if (!rect)
1005         return E_POINTER;
1006
1007     ::SetRectEmpty(rect);
1008
1009     if (!m_element)
1010         return E_FAIL;
1011
1012     WebCore::RenderElement *renderer = m_element->renderer();
1013     if (renderer) {
1014         IntRect boundsIntRect = renderer->absoluteBoundingBoxRect();
1015         rect->left = boundsIntRect.x();
1016         rect->top = boundsIntRect.y();
1017         rect->right = boundsIntRect.x() + boundsIntRect.width();
1018         rect->bottom = boundsIntRect.y() + boundsIntRect.height();
1019     }
1020
1021     return S_OK;
1022 }
1023
1024 HRESULT DOMElement::lineBoxRects(__inout_ecount_full(cRects) RECT* /*rects*/, int cRects)
1025 {
1026     return E_NOTIMPL;
1027 }
1028
1029 // IDOMElement ----------------------------------------------------------------
1030
1031 HRESULT DOMElement::tagName(__deref_opt_out BSTR* result)
1032 {
1033     if (!result)
1034         return E_POINTER;
1035     *result = nullptr;
1036     if (!m_element)
1037         return E_FAIL;
1038
1039     *result = BString(m_element->tagName()).release();
1040     return S_OK;
1041 }
1042     
1043 HRESULT DOMElement::getAttribute(_In_ BSTR name, __deref_opt_out BSTR* result)
1044 {
1045     if (!result)
1046         return E_POINTER;
1047     *result = nullptr;
1048     if (!m_element)
1049         return E_FAIL;
1050     WTF::String nameString(name, SysStringLen(name));
1051     WTF::String& attrValueString = (WTF::String&) m_element->getAttribute(nameString);
1052     *result = BString(attrValueString).release();
1053     if (attrValueString.length() && !*result)
1054         return E_OUTOFMEMORY;
1055     return S_OK;
1056 }
1057     
1058 HRESULT DOMElement::setAttribute(_In_ BSTR name, _In_ BSTR value)
1059 {
1060     if (!m_element)
1061         return E_FAIL;
1062
1063     WTF::String nameString(name, SysStringLen(name));
1064     WTF::String valueString(value, SysStringLen(value));
1065     WebCore::ExceptionCode ec = 0;
1066     m_element->setAttribute(nameString, valueString, ec);
1067     return ec ? E_FAIL : S_OK;
1068 }
1069     
1070 HRESULT DOMElement::removeAttribute(_In_ BSTR /*name*/)
1071 {
1072     ASSERT_NOT_REACHED();
1073     return E_NOTIMPL;
1074 }
1075     
1076 HRESULT DOMElement::getAttributeNode(_In_ BSTR /*name*/, _COM_Outptr_opt_ IDOMAttr** result)
1077 {
1078     ASSERT_NOT_REACHED();
1079     if (!result)
1080         return E_POINTER;
1081     *result = nullptr;
1082     return E_NOTIMPL;
1083 }
1084     
1085 HRESULT DOMElement::setAttributeNode(_In_opt_ IDOMAttr* /*newAttr*/, _COM_Outptr_opt_ IDOMAttr** result)
1086 {
1087     ASSERT_NOT_REACHED();
1088     if (!result)
1089         return E_POINTER;
1090     *result = nullptr;
1091     return E_NOTIMPL;
1092 }
1093     
1094 HRESULT DOMElement::removeAttributeNode(_In_opt_ IDOMAttr* /*oldAttr*/, _COM_Outptr_opt_ IDOMAttr** result)
1095 {
1096     ASSERT_NOT_REACHED();
1097     if (!result)
1098         return E_POINTER;
1099     *result = nullptr;
1100     return E_NOTIMPL;
1101 }
1102     
1103 HRESULT DOMElement::getElementsByTagName(_In_ BSTR /*name*/, _COM_Outptr_opt_ IDOMNodeList** result)
1104 {
1105     ASSERT_NOT_REACHED();
1106     if (!result)
1107         return E_POINTER;
1108     *result = nullptr;
1109     return E_NOTIMPL;
1110 }
1111     
1112 HRESULT DOMElement::getAttributeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*localName*/, __deref_opt_out BSTR* result)
1113 {
1114     ASSERT_NOT_REACHED();
1115     if (!result)
1116         return E_POINTER;
1117     *result = nullptr;
1118     return E_NOTIMPL;
1119 }
1120     
1121 HRESULT DOMElement::setAttributeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*qualifiedName*/, _In_ BSTR /*value*/)
1122 {
1123     ASSERT_NOT_REACHED();
1124     return E_NOTIMPL;
1125 }
1126     
1127 HRESULT DOMElement::removeAttributeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*localName*/)
1128 {
1129     ASSERT_NOT_REACHED();
1130     return E_NOTIMPL;
1131 }
1132     
1133 HRESULT DOMElement::getAttributeNodeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*localName*/, _COM_Outptr_opt_ IDOMAttr** result)
1134 {
1135     ASSERT_NOT_REACHED();
1136     if (!result)
1137         return E_POINTER;
1138     *result = nullptr;
1139     return E_NOTIMPL;
1140 }
1141     
1142 HRESULT DOMElement::setAttributeNodeNS(_In_opt_ IDOMAttr* /*newAttr*/, _COM_Outptr_opt_ IDOMAttr** result)
1143 {
1144     ASSERT_NOT_REACHED();
1145     if (!result)
1146         return E_POINTER;
1147     *result = nullptr;
1148     return E_NOTIMPL;
1149 }
1150     
1151 HRESULT DOMElement::getElementsByTagNameNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*localName*/, _COM_Outptr_opt_ IDOMNodeList** result)
1152 {
1153     ASSERT_NOT_REACHED();
1154     if (!result)
1155         return E_POINTER;
1156     *result = nullptr;
1157     return E_NOTIMPL;
1158 }
1159     
1160 HRESULT DOMElement::hasAttribute(_In_ BSTR /*name*/, _Out_ BOOL* /*result*/)
1161 {
1162     ASSERT_NOT_REACHED();
1163     return E_NOTIMPL;
1164 }
1165     
1166 HRESULT DOMElement::hasAttributeNS(_In_ BSTR /*namespaceURI*/, _In_ BSTR /*localName*/, _Out_ BOOL* /*result*/)
1167 {
1168     ASSERT_NOT_REACHED();
1169     return E_NOTIMPL;
1170 }
1171
1172 HRESULT DOMElement::focus()
1173 {
1174     if (!m_element)
1175         return E_FAIL;
1176     m_element->focus();
1177     return S_OK;
1178 }
1179
1180 HRESULT DOMElement::blur()
1181 {
1182     if (!m_element)
1183         return E_FAIL;
1184     m_element->blur();
1185     return S_OK;
1186 }
1187
1188 // IDOMElementPrivate ---------------------------------------------------------
1189
1190 HRESULT DOMElement::coreElement(__deref_opt_out void **element)
1191 {
1192     if (!m_element)
1193         return E_FAIL;
1194     *element = (void*) m_element;
1195     return S_OK;
1196 }
1197
1198 HRESULT DOMElement::isEqual(_In_opt_ IDOMElement* other, _Out_ BOOL* result)
1199 {
1200     if (!result)
1201         return E_POINTER;
1202
1203     *result = FALSE;
1204
1205     if (!other)
1206         return E_POINTER;
1207
1208     IDOMElementPrivate* otherPriv;
1209     HRESULT hr = other->QueryInterface(IID_IDOMElementPrivate, (void**) &otherPriv);
1210     if (FAILED(hr))
1211         return hr;
1212     
1213     void* otherCoreEle;
1214     hr = otherPriv->coreElement(&otherCoreEle);
1215     otherPriv->Release();
1216     if (FAILED(hr))
1217         return hr;
1218
1219     *result = (otherCoreEle == (void*)m_element) ? TRUE : FALSE;
1220     return S_OK;
1221 }
1222
1223 HRESULT DOMElement::isFocused(_Out_ BOOL* result)
1224 {
1225     if (!result)
1226         return E_POINTER;
1227     *result = FALSE;
1228     if (!m_element)
1229         return E_FAIL;
1230
1231     if (m_element->document().focusedElement() == m_element)
1232         *result = TRUE;
1233     else
1234         *result = FALSE;
1235
1236     return S_OK;
1237 }
1238
1239 HRESULT DOMElement::innerText(__deref_opt_out BSTR* result)
1240 {
1241     if (!result) {
1242         ASSERT_NOT_REACHED();
1243         return E_POINTER;
1244     }
1245
1246     *result = nullptr;
1247
1248     if (!m_element) {
1249         ASSERT_NOT_REACHED();
1250         return E_FAIL;
1251     }
1252
1253     *result = BString(m_element->innerText()).release();
1254     return S_OK;
1255 }
1256
1257 HRESULT DOMElement::font(_Out_ WebFontDescription* webFontDescription)
1258 {
1259     if (!webFontDescription) {
1260         ASSERT_NOT_REACHED();
1261         return E_POINTER;
1262     }
1263
1264     ASSERT(m_element);
1265
1266     WebCore::RenderElement* renderer = m_element->renderer();
1267     if (!renderer)
1268         return E_FAIL;
1269
1270     auto fontDescription = renderer->style().fontCascade().fontDescription();
1271     AtomicString family = fontDescription.firstFamily();
1272
1273     // FIXME: This leaks. Delete this whole function to get rid of the leak.
1274     UChar* familyCharactersBuffer = new UChar[family.length()];
1275     StringView(family.string()).getCharactersWithUpconvert(familyCharactersBuffer);
1276
1277     webFontDescription->family = familyCharactersBuffer;
1278     webFontDescription->familyLength = family.length();
1279     webFontDescription->size = fontDescription.computedSize();
1280     webFontDescription->bold = fontDescription.weight() >= WebCore::FontWeight600;
1281     webFontDescription->italic = fontDescription.italic();
1282
1283     return S_OK;
1284 }
1285
1286 HRESULT DOMElement::renderedImage(__deref_opt_out HBITMAP* image)
1287 {
1288     if (!image) {
1289         ASSERT_NOT_REACHED();
1290         return E_POINTER;
1291     }
1292     *image = nullptr;
1293
1294     ASSERT(m_element);
1295
1296     Frame* frame = m_element->document().frame();
1297     if (!frame)
1298         return E_FAIL;
1299
1300     *image = createDragImageForNode(*frame, *m_element);
1301     if (!*image)
1302         return E_FAIL;
1303
1304     return S_OK;
1305 }
1306
1307 HRESULT DOMElement::markerTextForListItem(__deref_opt_out BSTR* markerText)
1308 {
1309     if (!markerText)
1310         return E_POINTER;
1311
1312     ASSERT(m_element);
1313
1314     *markerText = BString(WebCore::markerTextForListItem(m_element)).release();
1315     return S_OK;
1316 }
1317
1318 HRESULT DOMElement::shadowPseudoId(__deref_opt_out BSTR* result)
1319 {
1320     if (!result)
1321         return E_POINTER;
1322
1323     ASSERT(m_element);
1324
1325     *result = BString(m_element->shadowPseudoId().string()).release();
1326     return S_OK;
1327 }
1328
1329 // IDOMElementCSSInlineStyle --------------------------------------------------
1330
1331 HRESULT DOMElement::style(_COM_Outptr_opt_ IDOMCSSStyleDeclaration** result)
1332 {
1333     if (!result)
1334         return E_POINTER;
1335     *result = nullptr;
1336     if (!m_element)
1337         return E_FAIL;
1338
1339     WebCore::CSSStyleDeclaration* style = m_element->cssomStyle();
1340     if (!style)
1341         return E_FAIL;
1342
1343     *result = DOMCSSStyleDeclaration::createInstance(style);
1344     return *result ? S_OK : E_FAIL;
1345 }
1346
1347 // IDOMElementExtensions ------------------------------------------------------
1348
1349 HRESULT DOMElement::offsetLeft(_Out_ int* result)
1350 {
1351     if (!result)
1352         return E_POINTER;
1353     *result = 0;
1354     if (!m_element)
1355         return E_FAIL;
1356
1357     *result = m_element->offsetLeft();
1358     return S_OK;
1359 }
1360
1361 HRESULT DOMElement::offsetTop(_Out_ int* result)
1362 {
1363     if (!result)
1364         return E_POINTER;
1365     *result = 0;
1366     if (!m_element)
1367         return E_FAIL;
1368
1369     *result = m_element->offsetTop();
1370     return S_OK;
1371 }
1372
1373 HRESULT DOMElement::offsetWidth(_Out_ int* result)
1374 {
1375     if (!result)
1376         return E_POINTER;
1377     *result = 0;
1378     if (!m_element)
1379         return E_FAIL;
1380
1381     *result = m_element->offsetWidth();
1382     return S_OK;
1383 }
1384
1385 HRESULT DOMElement::offsetHeight(_Out_ int* result)
1386 {
1387     if (!result)
1388         return E_POINTER;
1389     *result = 0;
1390     if (!m_element)
1391         return E_FAIL;
1392
1393     *result = m_element->offsetHeight();
1394     return S_OK;
1395 }
1396
1397 HRESULT DOMElement::offsetParent(_COM_Outptr_opt_ IDOMElement** result)
1398 {
1399     // FIXME
1400     ASSERT_NOT_REACHED();
1401     if (!result)
1402         return E_POINTER;
1403     *result = nullptr;
1404     return E_NOTIMPL;
1405 }
1406
1407 HRESULT DOMElement::clientWidth(_Out_ int* result)
1408 {
1409     if (!result)
1410         return E_POINTER;
1411     *result = 0;
1412     if (!m_element)
1413         return E_FAIL;
1414
1415     *result = m_element->clientWidth();
1416     return S_OK;
1417 }
1418
1419 HRESULT DOMElement::clientHeight(_Out_ int* result)
1420 {
1421     if (!result)
1422         return E_POINTER;
1423     *result = 0;
1424     if (!m_element)
1425         return E_FAIL;
1426
1427     *result = m_element->clientHeight();
1428     return S_OK;
1429 }
1430
1431 HRESULT DOMElement::scrollLeft(_Out_ int* result)
1432 {
1433     if (!result)
1434         return E_POINTER;
1435     *result = 0;
1436     if (!m_element)
1437         return E_FAIL;
1438
1439     *result = m_element->scrollLeft();
1440     return S_OK;
1441 }
1442
1443 HRESULT DOMElement::setScrollLeft(int /*newScrollLeft*/)
1444 {
1445     // FIXME
1446     ASSERT_NOT_REACHED();
1447     return E_NOTIMPL;
1448 }
1449
1450 HRESULT DOMElement::scrollTop(_Out_ int* result)
1451 {
1452     if (!result)
1453         return E_POINTER;
1454     *result = 0;
1455     if (!m_element)
1456         return E_FAIL;
1457
1458     *result = m_element->scrollTop();
1459     return S_OK;
1460 }
1461
1462 HRESULT DOMElement::setScrollTop(int /*newScrollTop*/)
1463 {
1464     // FIXME
1465     ASSERT_NOT_REACHED();
1466     return E_NOTIMPL;
1467 }
1468
1469 HRESULT DOMElement::scrollWidth(_Out_ int* result)
1470 {
1471     if (!result)
1472         return E_POINTER;
1473     *result = 0;
1474     if (!m_element)
1475         return E_FAIL;
1476
1477     *result = m_element->scrollWidth();
1478     return S_OK;
1479 }
1480
1481 HRESULT DOMElement::scrollHeight(_Out_ int* result)
1482 {
1483     if (!result)
1484         return E_POINTER;
1485     *result = 0;
1486     if (!m_element)
1487         return E_FAIL;
1488
1489     *result = m_element->scrollHeight();
1490     return S_OK;
1491 }
1492
1493 HRESULT DOMElement::scrollIntoView(BOOL alignWithTop)
1494 {
1495     if (!m_element)
1496         return E_FAIL;
1497
1498     m_element->scrollIntoView(!!alignWithTop);
1499     return S_OK;
1500 }
1501
1502 HRESULT DOMElement::scrollIntoViewIfNeeded(BOOL centerIfNeeded)
1503 {
1504     if (!m_element)
1505         return E_FAIL;
1506
1507     m_element->scrollIntoViewIfNeeded(!!centerIfNeeded);
1508     return S_OK;
1509 }
1510
1511 // DOMElement -----------------------------------------------------------------
1512
1513 DOMElement::DOMElement(WebCore::Element* e)
1514     : DOMNode(e)
1515     , m_element(e)
1516 {
1517 }
1518
1519 DOMElement::~DOMElement()
1520 {
1521 }
1522
1523 IDOMElement* DOMElement::createInstance(WebCore::Element* e)
1524 {
1525     if (!e)
1526         return nullptr;
1527
1528     HRESULT hr;
1529     IDOMElement* domElement = nullptr;
1530
1531     if (is<WebCore::HTMLFormElement>(*e)) {
1532         DOMHTMLFormElement* newElement = new DOMHTMLFormElement(e);
1533         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1534     } else if (e->hasTagName(iframeTag)) {
1535         DOMHTMLIFrameElement* newElement = new DOMHTMLIFrameElement(e);
1536         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1537     } else if (is<WebCore::HTMLInputElement>(*e)) {
1538         DOMHTMLInputElement* newElement = new DOMHTMLInputElement(e);
1539         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1540     } else if (is<WebCore::HTMLOptionElement>(*e)) {
1541         DOMHTMLOptionElement* newElement = new DOMHTMLOptionElement(e);
1542         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1543     } else if (e->hasTagName(selectTag)) {
1544         DOMHTMLSelectElement* newElement = new DOMHTMLSelectElement(e);
1545         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1546     } else if (is<WebCore::HTMLTextAreaElement>(*e)) {
1547         DOMHTMLTextAreaElement* newElement = new DOMHTMLTextAreaElement(e);
1548         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1549     } else if (e->isHTMLElement()) {
1550         DOMHTMLElement* newElement = new DOMHTMLElement(e);
1551         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1552     } else {
1553         DOMElement* newElement = new DOMElement(e);
1554         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1555     }
1556
1557     if (FAILED(hr))
1558         return nullptr;
1559
1560     return domElement;
1561 }
1562
1563 // DOMRange - IUnknown -----------------------------------------------------
1564
1565 HRESULT DOMRange::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
1566 {
1567     if (!ppvObject)
1568         return E_POINTER;
1569     *ppvObject = nullptr;
1570     if (IsEqualGUID(riid, IID_IDOMRange))
1571         *ppvObject = static_cast<IDOMRange*>(this);
1572     else
1573         return DOMObject::QueryInterface(riid, ppvObject);
1574
1575     AddRef();
1576     return S_OK;
1577 }
1578
1579 // DOMRange ----------------------------------------------------------------- 
1580
1581 DOMRange::DOMRange(WebCore::Range* e)
1582     : m_range(e)
1583 {
1584 }
1585
1586 DOMRange::~DOMRange()
1587 {
1588 }
1589
1590 IDOMRange* DOMRange::createInstance(WebCore::Range* range)
1591 {
1592     if (!range)
1593         return nullptr;
1594
1595     DOMRange* newRange = new DOMRange(range);
1596
1597     IDOMRange* domRange = nullptr;
1598     if (FAILED(newRange->QueryInterface(IID_IDOMRange, reinterpret_cast<void**>(&domRange))))
1599         return nullptr;
1600
1601     return newRange;
1602 }
1603
1604 HRESULT DOMRange::startContainer(_COM_Outptr_opt_ IDOMNode** node)
1605 {
1606     if (!node)
1607         return E_POINTER;
1608     *node = nullptr;
1609     if (!m_range)
1610         return E_UNEXPECTED;
1611
1612     *node = DOMNode::createInstance(&m_range->startContainer());
1613
1614     return S_OK;
1615 }
1616
1617 HRESULT DOMRange::startOffset(_Out_ int* offset)
1618 {
1619     if (!offset)
1620         return E_POINTER;
1621     *offset = 0;
1622     if (!m_range)
1623         return E_UNEXPECTED;
1624
1625     *offset = m_range->startOffset();
1626
1627     return S_OK;
1628 }
1629
1630 HRESULT DOMRange::endContainer(_COM_Outptr_opt_ IDOMNode** node)
1631 {
1632     if (!node)
1633         return E_POINTER;
1634     *node = nullptr;
1635     if (!m_range)
1636         return E_UNEXPECTED;
1637
1638     *node = DOMNode::createInstance(&m_range->endContainer());
1639
1640     return S_OK;
1641 }
1642
1643 HRESULT DOMRange::endOffset(_Out_ int* offset)
1644 {
1645     if (!offset)
1646         return E_POINTER;
1647     *offset = 0;
1648     if (!m_range)
1649         return E_UNEXPECTED;
1650
1651     *offset = m_range->endOffset();
1652
1653     return S_OK;
1654 }
1655
1656 HRESULT DOMRange::collapsed(_Out_ BOOL* result)
1657 {
1658     if (!result)
1659         return E_POINTER;
1660     *result = FALSE;
1661     if (!m_range)
1662         return E_UNEXPECTED;
1663
1664     *result = m_range->collapsed();
1665
1666     return S_OK;
1667 }
1668
1669 HRESULT DOMRange::commonAncestorContainer(_COM_Outptr_opt_ IDOMNode** container)
1670 {
1671     ASSERT_NOT_REACHED();
1672     if (!container)
1673         return E_POINTER;
1674     *container = nullptr;
1675     return E_NOTIMPL;
1676 }
1677
1678 HRESULT DOMRange::setStart(_In_opt_ IDOMNode* refNode, int offset)
1679 {
1680     ASSERT_NOT_REACHED();
1681     return E_NOTIMPL;
1682 }
1683
1684 HRESULT DOMRange::setEnd(_In_opt_ IDOMNode* refNode, int offset)
1685 {
1686     ASSERT_NOT_REACHED();
1687     return E_NOTIMPL;
1688 }
1689
1690 HRESULT DOMRange::setStartBefore(_In_opt_ IDOMNode* refNode)
1691 {
1692     ASSERT_NOT_REACHED();
1693     return E_NOTIMPL;
1694 }
1695
1696 HRESULT DOMRange::setStartAfter(_In_opt_ IDOMNode* refNode)
1697 {
1698     ASSERT_NOT_REACHED();
1699     return E_NOTIMPL;
1700 }
1701
1702 HRESULT DOMRange::setEndBefore(_In_opt_  IDOMNode* refNode)
1703 {
1704     ASSERT_NOT_REACHED();
1705     return E_NOTIMPL;
1706 }
1707
1708 HRESULT DOMRange::setEndAfter(_In_opt_  IDOMNode* refNode)
1709 {
1710     ASSERT_NOT_REACHED();
1711     return E_NOTIMPL;
1712 }
1713
1714 HRESULT DOMRange::collapse(BOOL toStart)
1715 {
1716     ASSERT_NOT_REACHED();
1717     return E_NOTIMPL;
1718 }
1719
1720 HRESULT DOMRange::selectNode(_In_opt_ IDOMNode* refNode)
1721 {
1722     ASSERT_NOT_REACHED();
1723     return E_NOTIMPL;
1724 }
1725
1726 HRESULT DOMRange::selectNodeContents(_In_opt_ IDOMNode* refNode)
1727 {
1728     ASSERT_NOT_REACHED();
1729     return E_NOTIMPL;
1730 }
1731
1732 HRESULT DOMRange::compareBoundaryPoints(unsigned short how, _In_opt_ IDOMRange* sourceRange)
1733 {
1734     ASSERT_NOT_REACHED();
1735     return E_NOTIMPL;
1736 }
1737
1738 HRESULT DOMRange::deleteContents()
1739 {
1740     ASSERT_NOT_REACHED();
1741     return E_NOTIMPL;
1742 }
1743
1744 HRESULT DOMRange::extractContents(_COM_Outptr_opt_ IDOMDocumentFragment** fragment)
1745 {
1746     ASSERT_NOT_REACHED();
1747     if (!fragment)
1748         return E_POINTER;
1749     *fragment = nullptr;
1750     return E_NOTIMPL;
1751 }
1752
1753 HRESULT DOMRange::cloneContents(_COM_Outptr_opt_ IDOMDocumentFragment** fragment)
1754 {
1755     ASSERT_NOT_REACHED();
1756     if (!fragment)
1757         return E_POINTER;
1758     *fragment = nullptr;
1759     return E_NOTIMPL;
1760 }
1761
1762 HRESULT DOMRange::insertNode(_In_opt_ IDOMNode* newNode)
1763 {
1764     ASSERT_NOT_REACHED();
1765     return E_NOTIMPL;
1766 }
1767
1768 HRESULT DOMRange::surroundContents(_In_opt_ IDOMNode* newParent)
1769 {
1770     ASSERT_NOT_REACHED();
1771     return E_NOTIMPL;
1772 }
1773
1774 HRESULT DOMRange::cloneRange(_COM_Outptr_opt_ IDOMRange** range)
1775 {
1776     ASSERT_NOT_REACHED();
1777     if (!range)
1778         return E_POINTER;
1779     *range = nullptr;
1780     return E_NOTIMPL;
1781 }
1782
1783 HRESULT DOMRange::toString(__deref_opt_out BSTR* str)
1784 {
1785     if (!str)
1786         return E_POINTER;
1787     *str = nullptr;
1788     if (!m_range)
1789         return E_UNEXPECTED;
1790
1791     *str = BString(m_range->toString()).release();
1792
1793     return S_OK;
1794 }
1795
1796 HRESULT DOMRange::detach()
1797 {
1798     ASSERT_NOT_REACHED();
1799     return E_NOTIMPL;
1800 }
1801
1802 DOMNamedNodeMap::DOMNamedNodeMap(WebCore::NamedNodeMap* nodeMap)
1803     : m_nodeMap(nodeMap)
1804 {
1805 }
1806
1807 DOMNamedNodeMap::~DOMNamedNodeMap()
1808 {
1809 }
1810
1811 IDOMNamedNodeMap* DOMNamedNodeMap::createInstance(WebCore::NamedNodeMap* nodeMap)
1812 {
1813     if (!nodeMap)
1814         return nullptr;
1815
1816     DOMNamedNodeMap* namedNodeMap = new DOMNamedNodeMap(nodeMap);
1817
1818     IDOMNamedNodeMap* domNamedNodeMap = nullptr;
1819     if (FAILED(namedNodeMap->QueryInterface(IID_IDOMNamedNodeMap, reinterpret_cast<void**>(&domNamedNodeMap))))
1820         return nullptr;
1821
1822     return namedNodeMap;
1823 }
1824
1825 HRESULT DOMNamedNodeMap::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject)
1826 {
1827     *ppvObject = nullptr;
1828     if (IsEqualGUID(riid, IID_IDOMNamedNodeMap))
1829         *ppvObject = static_cast<IDOMNamedNodeMap*>(this);
1830     else
1831         return DOMObject::QueryInterface(riid, ppvObject);
1832
1833     AddRef();
1834     return S_OK;
1835 }
1836
1837 HRESULT DOMNamedNodeMap::getNamedItem(_In_ BSTR name, _COM_Outptr_opt_ IDOMNode** result)
1838 {
1839     return E_NOTIMPL;
1840 }
1841
1842 HRESULT DOMNamedNodeMap::setNamedItem(_In_opt_ IDOMNode* arg, _COM_Outptr_opt_ IDOMNode** result)
1843 {
1844     return E_NOTIMPL;
1845 }
1846
1847 HRESULT DOMNamedNodeMap::removeNamedItem(_In_ BSTR name, _COM_Outptr_opt_ IDOMNode** result)
1848 {
1849     return E_NOTIMPL;
1850 }
1851
1852 HRESULT DOMNamedNodeMap::item(_In_ UINT index, _COM_Outptr_opt_ IDOMNode** result)
1853 {
1854     if (!result)
1855         return E_POINTER;
1856     
1857     if (!m_nodeMap)
1858         return E_FAIL;
1859
1860     *result = DOMNode::createInstance(m_nodeMap->item(index).get());
1861     return *result ? S_OK : E_FAIL;
1862 }
1863
1864 HRESULT DOMNamedNodeMap::length(_Out_opt_ UINT* result)
1865 {
1866     if (!result)
1867         return E_POINTER;
1868
1869     *result = m_nodeMap->length();
1870     return S_OK;
1871 }
1872
1873 HRESULT DOMNamedNodeMap::getNamedItemNS(_In_ BSTR namespaceURI, _In_ BSTR localName, _COM_Outptr_opt_ IDOMNode** result)
1874 {
1875     return E_NOTIMPL;
1876 }
1877
1878 HRESULT DOMNamedNodeMap::setNamedItemNS(_In_opt_ IDOMNode* arg, _COM_Outptr_opt_ IDOMNode** result)
1879 {
1880     return E_NOTIMPL;
1881 }
1882
1883 HRESULT DOMNamedNodeMap::removeNamedItemNS(_In_ BSTR namespaceURI, _In_ BSTR localName, _COM_Outptr_opt_ IDOMNode** result)
1884 {
1885     return E_NOTIMPL;
1886 }