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