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