67030fa4ef1a7fab5f94e66507ac3f70abd4f433
[WebKit-https.git] / WebKit / win / DOMCoreClasses.cpp
1 /*
2  * Copyright (C) 2006, 2007 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 "COMPtr.h"
31 #include "DOMCSSClasses.h"
32 #include "DOMEventsClasses.h"
33 #include "DOMHTMLClasses.h"
34 #pragma warning(push, 0)
35 #include <WebCore/BString.h>
36 #include <WebCore/DOMWindow.h>
37 #include <WebCore/Document.h>
38 #include <WebCore/Element.h>
39 #include <WebCore/HTMLFormElement.h>
40 #include <WebCore/HTMLInputElement.h>
41 #include <WebCore/HTMLNames.h>
42 #include <WebCore/HTMLOptionElement.h>
43 #include <WebCore/HTMLSelectElement.h>
44 #include <WebCore/HTMLTextAreaElement.h>
45 #include <WebCore/NodeList.h>
46 #include <WebCore/RenderObject.h>
47 #pragma warning(pop)
48
49 #include <initguid.h>
50 // {79A193A5-D783-4c73-9AD9-D10678B943DE}
51 DEFINE_GUID(IID_DOMNode, 0x79a193a5, 0xd783, 0x4c73, 0x9a, 0xd9, 0xd1, 0x6, 0x78, 0xb9, 0x43, 0xde);
52 // {3B0C0EFF-478B-4b0b-8290-D2321E08E23E}
53 DEFINE_GUID(IID_DOMElement, 0x3b0c0eff, 0x478b, 0x4b0b, 0x82, 0x90, 0xd2, 0x32, 0x1e, 0x8, 0xe2, 0x3e);
54
55 using namespace WebCore;
56 using namespace HTMLNames;
57
58 // DOMObject - IUnknown -------------------------------------------------------
59
60 HRESULT STDMETHODCALLTYPE DOMObject::QueryInterface(REFIID riid, void** ppvObject)
61 {
62     *ppvObject = 0;
63     if (IsEqualGUID(riid, IID_IDOMObject))
64         *ppvObject = static_cast<IDOMObject*>(this);
65     else
66         return WebScriptObject::QueryInterface(riid, ppvObject);
67
68     AddRef();
69     return S_OK;
70 }
71
72 // DOMNode - IUnknown ---------------------------------------------------------
73
74 HRESULT STDMETHODCALLTYPE DOMNode::QueryInterface(REFIID riid, void** ppvObject)
75 {
76     *ppvObject = 0;
77     if (IsEqualGUID(riid, IID_IDOMNode))
78         *ppvObject = static_cast<IDOMNode*>(this);
79     else if (IsEqualGUID(riid, IID_DOMNode))
80         *ppvObject = static_cast<DOMNode*>(this);
81     else
82         return DOMObject::QueryInterface(riid, ppvObject);
83
84     AddRef();
85     return S_OK;
86 }
87
88 // DOMNode --------------------------------------------------------------------
89
90 HRESULT STDMETHODCALLTYPE DOMNode::nodeName( 
91     /* [retval][out] */ BSTR* /*result*/)
92 {
93     ASSERT_NOT_REACHED();
94     return E_NOTIMPL;
95 }
96
97 HRESULT STDMETHODCALLTYPE DOMNode::nodeValue( 
98     /* [retval][out] */ BSTR* result)
99 {
100     if (!m_node)
101         return E_FAIL;
102     WebCore::String nodeValueStr = m_node->nodeValue();
103     *result = SysAllocStringLen(nodeValueStr.characters(), nodeValueStr.length());
104     if (nodeValueStr.length() && !*result)
105         return E_OUTOFMEMORY;
106     return S_OK;
107 }
108
109 HRESULT STDMETHODCALLTYPE DOMNode::setNodeValue( 
110     /* [in] */ BSTR /*value*/)
111 {
112     ASSERT_NOT_REACHED();
113     return E_NOTIMPL;
114 }
115
116 HRESULT STDMETHODCALLTYPE DOMNode::nodeType( 
117     /* [retval][out] */ unsigned short* /*result*/)
118 {
119     ASSERT_NOT_REACHED();
120     return E_NOTIMPL;
121 }
122
123 HRESULT STDMETHODCALLTYPE DOMNode::parentNode( 
124     /* [retval][out] */ IDOMNode** result)
125 {
126     *result = 0;
127     if (!m_node || !m_node->parentNode())
128         return E_FAIL;
129     *result = DOMNode::createInstance(m_node->parentNode());
130     return S_OK;
131 }
132
133 HRESULT STDMETHODCALLTYPE DOMNode::childNodes( 
134     /* [retval][out] */ IDOMNodeList** /*result*/)
135 {
136     ASSERT_NOT_REACHED();
137     return E_NOTIMPL;
138 }
139
140 HRESULT STDMETHODCALLTYPE DOMNode::firstChild( 
141     /* [retval][out] */ IDOMNode** /*result*/)
142 {
143     ASSERT_NOT_REACHED();
144     return E_NOTIMPL;
145 }
146
147 HRESULT STDMETHODCALLTYPE DOMNode::lastChild( 
148     /* [retval][out] */ IDOMNode** /*result*/)
149 {
150     ASSERT_NOT_REACHED();
151     return E_NOTIMPL;
152 }
153
154 HRESULT STDMETHODCALLTYPE DOMNode::previousSibling( 
155     /* [retval][out] */ IDOMNode** /*result*/)
156 {
157     ASSERT_NOT_REACHED();
158     return E_NOTIMPL;
159 }
160
161 HRESULT STDMETHODCALLTYPE DOMNode::nextSibling( 
162     /* [retval][out] */ IDOMNode** /*result*/)
163 {
164     ASSERT_NOT_REACHED();
165     return E_NOTIMPL;
166 }
167
168 HRESULT STDMETHODCALLTYPE DOMNode::attributes( 
169     /* [retval][out] */ IDOMNamedNodeMap** /*result*/)
170 {
171     ASSERT_NOT_REACHED();
172     return E_NOTIMPL;
173 }
174
175 HRESULT STDMETHODCALLTYPE DOMNode::ownerDocument( 
176     /* [retval][out] */ IDOMDocument** result)
177 {
178     if (!result)
179         return E_POINTER;
180     *result = 0;
181     if (!m_node)
182         return E_FAIL;
183     *result = DOMDocument::createInstance(m_node->ownerDocument());
184     return S_OK;
185 }
186
187 HRESULT STDMETHODCALLTYPE DOMNode::insertBefore( 
188     /* [in] */ IDOMNode* /*newChild*/,
189     /* [in] */ IDOMNode* /*refChild*/,
190     /* [retval][out] */ IDOMNode** /*result*/)
191 {
192     ASSERT_NOT_REACHED();
193     return E_NOTIMPL;
194 }
195
196 HRESULT STDMETHODCALLTYPE DOMNode::replaceChild( 
197     /* [in] */ IDOMNode* /*newChild*/,
198     /* [in] */ IDOMNode* /*oldChild*/,
199     /* [retval][out] */ IDOMNode** /*result*/)
200 {
201     ASSERT_NOT_REACHED();
202     return E_NOTIMPL;
203 }
204
205 HRESULT STDMETHODCALLTYPE DOMNode::removeChild( 
206     /* [in] */ IDOMNode* /*oldChild*/,
207     /* [retval][out] */ IDOMNode** /*result*/)
208 {
209     ASSERT_NOT_REACHED();
210     return E_NOTIMPL;
211 }
212
213 HRESULT STDMETHODCALLTYPE DOMNode::appendChild( 
214     /* [in] */ IDOMNode* /*oldChild*/,
215     /* [retval][out] */ IDOMNode** /*result*/)
216 {
217     ASSERT_NOT_REACHED();
218     return E_NOTIMPL;
219 }
220
221 HRESULT STDMETHODCALLTYPE DOMNode::hasChildNodes( 
222     /* [retval][out] */ BOOL* /*result*/)
223 {
224     ASSERT_NOT_REACHED();
225     return E_NOTIMPL;
226 }
227
228 HRESULT STDMETHODCALLTYPE DOMNode::cloneNode( 
229     /* [in] */ BOOL /*deep*/,
230     /* [retval][out] */ IDOMNode** /*result*/)
231 {
232     ASSERT_NOT_REACHED();
233     return E_NOTIMPL;
234 }
235
236 HRESULT STDMETHODCALLTYPE DOMNode::normalize( void)
237 {
238     ASSERT_NOT_REACHED();
239     return E_NOTIMPL;
240 }
241
242 HRESULT STDMETHODCALLTYPE DOMNode::isSupported( 
243     /* [in] */ BSTR /*feature*/,
244     /* [in] */ BSTR /*version*/,
245     /* [retval][out] */ BOOL* /*result*/)
246 {
247     ASSERT_NOT_REACHED();
248     return E_NOTIMPL;
249 }
250
251 HRESULT STDMETHODCALLTYPE DOMNode::namespaceURI( 
252     /* [retval][out] */ BSTR* /*result*/)
253 {
254     ASSERT_NOT_REACHED();
255     return E_NOTIMPL;
256 }
257
258 HRESULT STDMETHODCALLTYPE DOMNode::prefix( 
259     /* [retval][out] */ BSTR* /*result*/)
260 {
261     ASSERT_NOT_REACHED();
262     return E_NOTIMPL;
263 }
264
265 HRESULT STDMETHODCALLTYPE DOMNode::setPrefix( 
266     /* [in] */ BSTR /*prefix*/)
267 {
268     ASSERT_NOT_REACHED();
269     return E_NOTIMPL;
270 }
271
272 HRESULT STDMETHODCALLTYPE DOMNode::localName( 
273     /* [retval][out] */ BSTR* /*result*/)
274 {
275     ASSERT_NOT_REACHED();
276     return E_NOTIMPL;
277 }
278
279 HRESULT STDMETHODCALLTYPE DOMNode::hasAttributes( 
280     /* [retval][out] */ BOOL* /*result*/)
281 {
282     ASSERT_NOT_REACHED();
283     return E_NOTIMPL;
284 }
285
286 HRESULT STDMETHODCALLTYPE DOMNode::isSameNode( 
287     /* [in] */ IDOMNode* other,
288     /* [retval][out] */ BOOL* result)
289 {
290     if (!result) {
291         ASSERT_NOT_REACHED();
292         return E_POINTER;
293     }
294
295     *result = FALSE;
296
297     if (!other)
298         return E_POINTER;
299
300     COMPtr<DOMNode> domOther;
301     HRESULT hr = other->QueryInterface(IID_DOMNode, (void**)&domOther);
302     if (FAILED(hr))
303         return hr;
304
305     *result = m_node->isSameNode(domOther->node()) ? TRUE : FALSE;
306     return S_OK;
307 }
308
309 HRESULT STDMETHODCALLTYPE DOMNode::isEqualNode( 
310     /* [in] */ IDOMNode* /*other*/,
311     /* [retval][out] */ BOOL* /*result*/)
312 {
313     ASSERT_NOT_REACHED();
314     return E_NOTIMPL;
315 }
316
317 HRESULT STDMETHODCALLTYPE DOMNode::textContent( 
318     /* [retval][out] */ BSTR* result)
319 {
320     if (!result)
321         return E_POINTER;
322
323     *result = BString(m_node->textContent()).release();
324
325     return S_OK;
326 }
327
328 HRESULT STDMETHODCALLTYPE DOMNode::setTextContent( 
329     /* [in] */ BSTR /*text*/)
330 {
331     ASSERT_NOT_REACHED();
332     return E_NOTIMPL;
333 }
334
335 // DOMNode - IDOMEventTarget --------------------------------------------------
336
337 HRESULT STDMETHODCALLTYPE DOMNode::addEventListener( 
338     /* [in] */ BSTR /*type*/,
339     /* [in] */ IDOMEventListener* /*listener*/,
340     /* [in] */ BOOL /*useCapture*/)
341 {
342     return E_NOTIMPL;
343 }
344
345 HRESULT STDMETHODCALLTYPE DOMNode::removeEventListener( 
346     /* [in] */ BSTR /*type*/,
347     /* [in] */ IDOMEventListener* /*listener*/,
348     /* [in] */ BOOL /*useCapture*/)
349 {
350     return E_NOTIMPL;
351 }
352
353 HRESULT STDMETHODCALLTYPE DOMNode::dispatchEvent( 
354     /* [in] */ IDOMEvent* evt,
355     /* [retval][out] */ BOOL* result)
356 {
357     if (!m_node || !evt)
358         return E_FAIL;
359
360 #if 0   // FIXME - raise dom exceptions
361     if (![self _node]->isEventTargetNode())
362         WebCore::raiseDOMException(DOM_NOT_SUPPORTED_ERR);
363 #endif
364
365     COMPtr<DOMEvent> domEvent;
366     HRESULT hr = evt->QueryInterface(IID_DOMEvent, (void**) &domEvent);
367     if (FAILED(hr))
368         return hr;
369
370     WebCore::ExceptionCode ec = 0;
371     *result = WebCore::EventTargetNodeCast(m_node)->dispatchEvent(domEvent->coreEvent(), ec) ? TRUE : FALSE;
372 #if 0   // FIXME - raise dom exceptions
373     WebCore::raiseOnDOMError(ec);
374 #endif
375     return S_OK;
376 }
377
378 // DOMNode - DOMNode ----------------------------------------------------------
379
380 DOMNode::DOMNode(WebCore::Node* n)
381 : m_node(0)
382 {
383     if (n)
384         n->ref();
385
386     m_node = n;
387 }
388
389 DOMNode::~DOMNode()
390 {
391     if (m_node)
392         m_node->deref();
393 }
394
395 IDOMNode* DOMNode::createInstance(WebCore::Node* n)
396 {
397     if (!n)
398         return 0;
399
400     HRESULT hr = S_OK;
401     IDOMNode* domNode = 0;
402     WebCore::Node::NodeType nodeType = n->nodeType();
403
404     switch (nodeType) {
405         case WebCore::Node::ELEMENT_NODE: 
406         {
407             IDOMElement* newElement = DOMElement::createInstance(static_cast<WebCore::Element*>(n));
408             if (newElement) {
409                 hr = newElement->QueryInterface(IID_IDOMNode, (void**)&domNode);
410                 newElement->Release();
411             }
412         }
413         break;
414         case WebCore::Node::DOCUMENT_NODE:
415         {
416             IDOMDocument* newDocument = DOMDocument::createInstance(n->document());
417             if (newDocument) {
418                 hr = newDocument->QueryInterface(IID_IDOMNode, (void**)&domNode);
419                 newDocument->Release();
420             }
421         }
422         break;
423         default:
424         {
425             DOMNode* newNode = new DOMNode(n);
426             hr = newNode->QueryInterface(IID_IDOMNode, (void**)&domNode);
427         }
428         break;
429     }
430
431     if (FAILED(hr))
432         return 0;
433
434     return domNode;
435 }
436
437 // DOMNodeList - IUnknown -----------------------------------------------------
438
439 HRESULT STDMETHODCALLTYPE DOMNodeList::QueryInterface(REFIID riid, void** ppvObject)
440 {
441     *ppvObject = 0;
442     if (IsEqualGUID(riid, IID_IDOMNodeList))
443         *ppvObject = static_cast<IDOMNodeList*>(this);
444     else
445         return DOMObject::QueryInterface(riid, ppvObject);
446
447     AddRef();
448     return S_OK;
449 }
450
451 // IDOMNodeList ---------------------------------------------------------------
452
453 HRESULT STDMETHODCALLTYPE DOMNodeList::item( 
454     /* [in] */ UINT index,
455     /* [retval][out] */ IDOMNode **result)
456 {
457     *result = 0;
458     if (!m_nodeList)
459         return E_FAIL;
460
461     WebCore::Node* itemNode = m_nodeList->item(index);
462     if (!itemNode)
463         return E_FAIL;
464
465     *result = DOMNode::createInstance(itemNode);
466     if (!(*result))
467         return E_FAIL;
468     return S_OK;
469 }
470
471 HRESULT STDMETHODCALLTYPE DOMNodeList::length( 
472         /* [retval][out] */ UINT *result)
473 {
474     *result = 0;
475     if (!m_nodeList)
476         return E_FAIL;
477     *result = m_nodeList->length();
478     return S_OK;
479 }
480
481 // DOMNodeList - DOMNodeList --------------------------------------------------
482
483 DOMNodeList::DOMNodeList(WebCore::NodeList* l)
484 : m_nodeList(0)
485 {
486     if (l)
487         l->ref();
488
489     m_nodeList = l;
490 }
491
492 DOMNodeList::~DOMNodeList()
493 {
494     if (m_nodeList)
495         m_nodeList->deref();
496 }
497
498 IDOMNodeList* DOMNodeList::createInstance(WebCore::NodeList* l)
499 {
500     if (!l)
501         return 0;
502
503     IDOMNodeList* domNodeList = 0;
504     DOMNodeList* newNodeList = new DOMNodeList(l);
505     if (FAILED(newNodeList->QueryInterface(IID_IDOMNodeList, (void**)&domNodeList)))
506         return 0;
507
508     return domNodeList;
509 }
510
511 // DOMDocument - IUnknown -----------------------------------------------------
512
513 HRESULT STDMETHODCALLTYPE DOMDocument::QueryInterface(REFIID riid, void** ppvObject)
514 {
515     *ppvObject = 0;
516     if (IsEqualGUID(riid, IID_IDOMDocument))
517         *ppvObject = static_cast<IDOMDocument*>(this);
518     else if (IsEqualGUID(riid, IID_IDOMViewCSS))
519         *ppvObject = static_cast<IDOMViewCSS*>(this);
520     else if (IsEqualGUID(riid, IID_IDOMDocumentEvent))
521         *ppvObject = static_cast<IDOMDocumentEvent*>(this);
522     else
523         return DOMNode::QueryInterface(riid, ppvObject);
524
525     AddRef();
526     return S_OK;
527 }
528
529 // DOMDocument ----------------------------------------------------------------
530
531 HRESULT STDMETHODCALLTYPE DOMDocument::doctype( 
532     /* [retval][out] */ IDOMDocumentType** /*result*/)
533 {
534     ASSERT_NOT_REACHED();
535     return E_NOTIMPL;
536 }
537
538 HRESULT STDMETHODCALLTYPE DOMDocument::implementation( 
539     /* [retval][out] */ IDOMImplementation** /*result*/)
540 {
541     ASSERT_NOT_REACHED();
542     return E_NOTIMPL;
543 }
544
545 HRESULT STDMETHODCALLTYPE DOMDocument::documentElement( 
546     /* [retval][out] */ IDOMElement** result)
547 {
548     *result = DOMElement::createInstance(m_document->documentElement());
549     return S_OK;
550 }
551
552 HRESULT STDMETHODCALLTYPE DOMDocument::createElement( 
553     /* [in] */ BSTR tagName,
554     /* [retval][out] */ IDOMElement** result)
555 {
556     if (!m_document)
557         return E_FAIL;
558
559     String tagNameString(tagName);
560     ExceptionCode ec;
561     *result = DOMElement::createInstance(m_document->createElement(tagNameString, ec).get());
562     if (!(*result))
563         return E_FAIL;
564     return S_OK;    
565 }
566
567 HRESULT STDMETHODCALLTYPE DOMDocument::createDocumentFragment( 
568     /* [retval][out] */ IDOMDocumentFragment** /*result*/)
569 {
570     ASSERT_NOT_REACHED();
571     return E_NOTIMPL;
572 }
573
574 HRESULT STDMETHODCALLTYPE DOMDocument::createTextNode( 
575     /* [in] */ BSTR /*data*/,
576     /* [retval][out] */ IDOMText** /*result*/)
577 {
578     ASSERT_NOT_REACHED();
579     return E_NOTIMPL;
580 }
581
582 HRESULT STDMETHODCALLTYPE DOMDocument::createComment( 
583     /* [in] */ BSTR /*data*/,
584     /* [retval][out] */ IDOMComment** /*result*/)
585 {
586     ASSERT_NOT_REACHED();
587     return E_NOTIMPL;
588 }
589
590 HRESULT STDMETHODCALLTYPE DOMDocument::createCDATASection( 
591     /* [in] */ BSTR /*data*/,
592     /* [retval][out] */ IDOMCDATASection** /*result*/)
593 {
594     ASSERT_NOT_REACHED();
595     return E_NOTIMPL;
596 }
597
598 HRESULT STDMETHODCALLTYPE DOMDocument::createProcessingInstruction( 
599     /* [in] */ BSTR /*target*/,
600     /* [in] */ BSTR /*data*/,
601     /* [retval][out] */ IDOMProcessingInstruction** /*result*/)
602 {
603     ASSERT_NOT_REACHED();
604     return E_NOTIMPL;
605 }
606
607 HRESULT STDMETHODCALLTYPE DOMDocument::createAttribute( 
608     /* [in] */ BSTR /*name*/,
609     /* [retval][out] */ IDOMAttr** /*result*/)
610 {
611     ASSERT_NOT_REACHED();
612     return E_NOTIMPL;
613 }
614
615 HRESULT STDMETHODCALLTYPE DOMDocument::createEntityReference( 
616     /* [in] */ BSTR /*name*/,
617     /* [retval][out] */ IDOMEntityReference** /*result*/)
618 {
619     ASSERT_NOT_REACHED();
620     return E_NOTIMPL;
621 }
622
623 HRESULT STDMETHODCALLTYPE DOMDocument::getElementsByTagName( 
624     /* [in] */ BSTR tagName,
625     /* [retval][out] */ IDOMNodeList** result)
626 {
627     if (!m_document)
628         return E_FAIL;
629
630     String tagNameString(tagName);
631     *result = DOMNodeList::createInstance(m_document->getElementsByTagName(tagNameString).get());
632     if (!(*result))
633         return E_FAIL;
634     return S_OK;
635 }
636
637 HRESULT STDMETHODCALLTYPE DOMDocument::importNode( 
638     /* [in] */ IDOMNode* /*importedNode*/,
639     /* [in] */ BOOL /*deep*/,
640     /* [retval][out] */ IDOMNode** /*result*/)
641 {
642     ASSERT_NOT_REACHED();
643     return E_NOTIMPL;
644 }
645
646 HRESULT STDMETHODCALLTYPE DOMDocument::createElementNS( 
647     /* [in] */ BSTR /*namespaceURI*/,
648     /* [in] */ BSTR /*qualifiedName*/,
649     /* [retval][out] */ IDOMElement** /*result*/)
650 {
651     ASSERT_NOT_REACHED();
652     return E_NOTIMPL;
653 }
654
655 HRESULT STDMETHODCALLTYPE DOMDocument::createAttributeNS( 
656     /* [in] */ BSTR /*namespaceURI*/,
657     /* [in] */ BSTR /*qualifiedName*/,
658     /* [retval][out] */ IDOMAttr** /*result*/)
659 {
660     ASSERT_NOT_REACHED();
661     return E_NOTIMPL;
662 }
663
664 HRESULT STDMETHODCALLTYPE DOMDocument::getElementsByTagNameNS( 
665     /* [in] */ BSTR namespaceURI,
666     /* [in] */ BSTR localName,
667     /* [retval][out] */ IDOMNodeList** result)
668 {
669     if (!m_document)
670         return E_FAIL;
671
672     String namespaceURIString(namespaceURI);
673     String localNameString(localName);
674     *result = DOMNodeList::createInstance(m_document->getElementsByTagNameNS(namespaceURIString, localNameString).get());
675     if (!(*result))
676         return E_FAIL;
677     return S_OK;
678 }
679
680 HRESULT STDMETHODCALLTYPE DOMDocument::getElementById( 
681     /* [in] */ BSTR /*elementId*/,
682     /* [retval][out] */ IDOMElement** /*result*/)
683 {
684     ASSERT_NOT_REACHED();
685     return E_NOTIMPL;
686 }
687
688 // DOMDocument - IDOMViewCSS --------------------------------------------------
689
690 HRESULT STDMETHODCALLTYPE DOMDocument::getComputedStyle( 
691     /* [in] */ IDOMElement* elt,
692     /* [in] */ BSTR pseudoElt,
693     /* [retval][out] */ IDOMCSSStyleDeclaration** result)
694 {
695     if (!elt || !result)
696         return E_POINTER;
697
698     COMPtr<DOMElement> domEle;
699     HRESULT hr = elt->QueryInterface(IID_DOMElement, (void**)&domEle);
700     if (FAILED(hr))
701         return hr;
702     Element* element = domEle->element();
703
704     WebCore::DOMWindow* dv = m_document->defaultView();
705     String pseudoEltString(pseudoElt);
706     
707     if (!dv)
708         return E_FAIL;
709     
710     *result = DOMCSSStyleDeclaration::createInstance(dv->getComputedStyle(element, pseudoEltString.impl()).get());
711     return S_OK;
712 }
713
714 // DOMDocument - IDOMDocumentEvent --------------------------------------------
715
716 HRESULT STDMETHODCALLTYPE DOMDocument::createEvent( 
717     /* [in] */ BSTR eventType,
718     /* [retval][out] */ IDOMEvent **result)
719 {
720     String eventTypeString(eventType, SysStringLen(eventType));
721     WebCore::ExceptionCode ec = 0;
722     *result = DOMEvent::createInstance(m_document->createEvent(eventTypeString, ec));
723     return S_OK;
724 }
725
726 // DOMDocument - DOMDocument --------------------------------------------------
727
728 DOMDocument::DOMDocument(WebCore::Document* d)
729 : DOMNode(d)
730 , m_document(d)
731 {
732 }
733
734 DOMDocument::~DOMDocument()
735 {
736 }
737
738 IDOMDocument* DOMDocument::createInstance(WebCore::Document* d)
739 {
740     if (!d)
741         return 0;
742
743     HRESULT hr;
744     IDOMDocument* domDocument = 0;
745
746     if (d->isHTMLDocument()) {
747         DOMHTMLDocument* newDocument = new DOMHTMLDocument(d);
748         hr = newDocument->QueryInterface(IID_IDOMDocument, (void**)&domDocument);
749     } else {
750         DOMDocument* newDocument = new DOMDocument(d);
751         hr = newDocument->QueryInterface(IID_IDOMDocument, (void**)&domDocument);
752     }
753
754     if (FAILED(hr))
755         return 0;
756
757     return domDocument;
758 }
759
760 // DOMElement - IUnknown ------------------------------------------------------
761
762 HRESULT STDMETHODCALLTYPE DOMElement::QueryInterface(REFIID riid, void** ppvObject)
763 {
764     *ppvObject = 0;
765     if (IsEqualGUID(riid, IID_IDOMElement))
766         *ppvObject = static_cast<IDOMElement*>(this);
767     else if (IsEqualGUID(riid, IID_DOMElement))
768         *ppvObject = static_cast<DOMElement*>(this);
769     else if (IsEqualGUID(riid, IID_IDOMElementPrivate))
770         *ppvObject = static_cast<IDOMElementPrivate*>(this);
771     else if (IsEqualGUID(riid, IID_IDOMNodeExtensions))
772         *ppvObject = static_cast<IDOMNodeExtensions*>(this);
773     else if (IsEqualGUID(riid, IID_IDOMElementCSSInlineStyle))
774         *ppvObject = static_cast<IDOMElementCSSInlineStyle*>(this);
775     else if (IsEqualGUID(riid, IID_IDOMElementExtensions))
776         *ppvObject = static_cast<IDOMElementExtensions*>(this);
777     else
778         return DOMNode::QueryInterface(riid, ppvObject);
779
780     AddRef();
781     return S_OK;
782 }
783
784 // DOMElement - IDOMNodeExtensions---------------------------------------------
785
786 HRESULT STDMETHODCALLTYPE DOMElement::boundingBox( 
787     /* [retval][out] */ LPRECT rect)
788 {
789     ::SetRectEmpty(rect);
790
791     if (!m_element)
792         return E_FAIL;
793
794     WebCore::RenderObject *renderer = m_element->renderer();
795     if (renderer) {
796         IntRect boundsIntRect = renderer->absoluteBoundingBoxRect();
797         rect->left = boundsIntRect.x();
798         rect->top = boundsIntRect.y();
799         rect->right = boundsIntRect.x() + boundsIntRect.width();
800         rect->bottom = boundsIntRect.y() + boundsIntRect.height();
801     }
802
803     return S_OK;
804 }
805
806 HRESULT STDMETHODCALLTYPE DOMElement::lineBoxRects( 
807     /* [size_is][in] */ RECT* /*rects*/,
808     /* [in] */ int /*cRects*/)
809 {
810     return E_NOTIMPL;
811 }
812
813 // IDOMElement ----------------------------------------------------------------
814
815 HRESULT STDMETHODCALLTYPE DOMElement::tagName( 
816         /* [retval][out] */ BSTR* /*result*/)
817 {
818     ASSERT_NOT_REACHED();
819     return E_NOTIMPL;
820 }
821     
822 HRESULT STDMETHODCALLTYPE DOMElement::getAttribute( 
823         /* [in] */ BSTR name,
824         /* [retval][out] */ BSTR* result)
825 {
826     if (!m_element)
827         return E_FAIL;
828     WebCore::String nameString(name, SysStringLen(name));
829     WebCore::String& attrValueString = (WebCore::String&) m_element->getAttribute(nameString);
830     *result = SysAllocStringLen(attrValueString.characters(), attrValueString.length());
831     if (attrValueString.length() && !*result)
832         return E_OUTOFMEMORY;
833     return S_OK;
834 }
835     
836 HRESULT STDMETHODCALLTYPE DOMElement::setAttribute( 
837         /* [in] */ BSTR name,
838         /* [in] */ BSTR value)
839 {
840     if (!m_element)
841         return E_FAIL;
842
843     WebCore::String nameString(name, SysStringLen(name));
844     WebCore::String valueString(value, SysStringLen(value));
845     WebCore::ExceptionCode ec = 0;
846     m_element->setAttribute(nameString, valueString, ec);
847     return ec ? E_FAIL : S_OK;
848 }
849     
850 HRESULT STDMETHODCALLTYPE DOMElement::removeAttribute( 
851         /* [in] */ BSTR /*name*/)
852 {
853     ASSERT_NOT_REACHED();
854     return E_NOTIMPL;
855 }
856     
857 HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNode( 
858         /* [in] */ BSTR /*name*/,
859         /* [retval][out] */ IDOMAttr** /*result*/)
860 {
861     ASSERT_NOT_REACHED();
862     return E_NOTIMPL;
863 }
864     
865 HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNode( 
866         /* [in] */ IDOMAttr* /*newAttr*/,
867         /* [retval][out] */ IDOMAttr** /*result*/)
868 {
869     ASSERT_NOT_REACHED();
870     return E_NOTIMPL;
871 }
872     
873 HRESULT STDMETHODCALLTYPE DOMElement::removeAttributeNode( 
874         /* [in] */ IDOMAttr* /*oldAttr*/,
875         /* [retval][out] */ IDOMAttr** /*result*/)
876 {
877     ASSERT_NOT_REACHED();
878     return E_NOTIMPL;
879 }
880     
881 HRESULT STDMETHODCALLTYPE DOMElement::getElementsByTagName( 
882         /* [in] */ BSTR /*name*/,
883         /* [retval][out] */ IDOMNodeList** /*result*/)
884 {
885     ASSERT_NOT_REACHED();
886     return E_NOTIMPL;
887 }
888     
889 HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNS( 
890         /* [in] */ BSTR /*namespaceURI*/,
891         /* [in] */ BSTR /*localName*/,
892         /* [retval][out] */ BSTR* /*result*/)
893 {
894     ASSERT_NOT_REACHED();
895     return E_NOTIMPL;
896 }
897     
898 HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNS( 
899         /* [in] */ BSTR /*namespaceURI*/,
900         /* [in] */ BSTR /*qualifiedName*/,
901         /* [in] */ BSTR /*value*/)
902 {
903     ASSERT_NOT_REACHED();
904     return E_NOTIMPL;
905 }
906     
907 HRESULT STDMETHODCALLTYPE DOMElement::removeAttributeNS( 
908         /* [in] */ BSTR /*namespaceURI*/,
909         /* [in] */ BSTR /*localName*/)
910 {
911     ASSERT_NOT_REACHED();
912     return E_NOTIMPL;
913 }
914     
915 HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNodeNS( 
916         /* [in] */ BSTR /*namespaceURI*/,
917         /* [in] */ BSTR /*localName*/,
918         /* [retval][out] */ IDOMAttr** /*result*/)
919 {
920     ASSERT_NOT_REACHED();
921     return E_NOTIMPL;
922 }
923     
924 HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNodeNS( 
925         /* [in] */ IDOMAttr* /*newAttr*/,
926         /* [retval][out] */ IDOMAttr** /*result*/)
927 {
928     ASSERT_NOT_REACHED();
929     return E_NOTIMPL;
930 }
931     
932 HRESULT STDMETHODCALLTYPE DOMElement::getElementsByTagNameNS( 
933         /* [in] */ BSTR /*namespaceURI*/,
934         /* [in] */ BSTR /*localName*/,
935         /* [retval][out] */ IDOMNodeList** /*result*/)
936 {
937     ASSERT_NOT_REACHED();
938     return E_NOTIMPL;
939 }
940     
941 HRESULT STDMETHODCALLTYPE DOMElement::hasAttribute( 
942         /* [in] */ BSTR /*name*/,
943         /* [retval][out] */ BOOL* /*result*/)
944 {
945     ASSERT_NOT_REACHED();
946     return E_NOTIMPL;
947 }
948     
949 HRESULT STDMETHODCALLTYPE DOMElement::hasAttributeNS( 
950         /* [in] */ BSTR /*namespaceURI*/,
951         /* [in] */ BSTR /*localName*/,
952         /* [retval][out] */ BOOL* /*result*/)
953 {
954     ASSERT_NOT_REACHED();
955     return E_NOTIMPL;
956 }
957
958 HRESULT STDMETHODCALLTYPE DOMElement::focus( void)
959 {
960     if (!m_element)
961         return E_FAIL;
962     m_element->focus();
963     return S_OK;
964 }
965
966 HRESULT STDMETHODCALLTYPE DOMElement::blur( void)
967 {
968     if (!m_element)
969         return E_FAIL;
970     m_element->blur();
971     return S_OK;
972 }
973
974 // IDOMElementPrivate ---------------------------------------------------------
975
976 HRESULT DOMElement::coreElement(void **element)
977 {
978     if (!m_element)
979         return E_FAIL;
980     *element = (void*) m_element;
981     return S_OK;
982 }
983
984 HRESULT STDMETHODCALLTYPE DOMElement::isEqual( 
985     /* [in] */ IDOMElement *other,
986     /* [retval][out] */ BOOL *result)
987 {
988     *result = FALSE;
989
990     if (!other || !result)
991         return E_POINTER;
992
993     IDOMElementPrivate* otherPriv;
994     HRESULT hr = other->QueryInterface(IID_IDOMElementPrivate, (void**) &otherPriv);
995     if (FAILED(hr))
996         return hr;
997     
998     void* otherCoreEle;
999     hr = otherPriv->coreElement(&otherCoreEle);
1000     otherPriv->Release();
1001     if (FAILED(hr))
1002         return hr;
1003
1004     *result = (otherCoreEle == (void*)m_element) ? TRUE : FALSE;
1005     return S_OK;
1006 }
1007
1008 HRESULT STDMETHODCALLTYPE DOMElement::isFocused( 
1009     /* [retval][out] */ BOOL *result)
1010 {
1011     if (!m_element)
1012         return E_FAIL;
1013
1014     if (m_element->document()->focusedNode() == m_element)
1015         *result = TRUE;
1016     else
1017         *result = FALSE;
1018
1019     return S_OK;
1020 }
1021
1022 HRESULT STDMETHODCALLTYPE DOMElement::innerText(
1023     /* [retval][out] */ BSTR* result)
1024 {
1025     if (!result) {
1026         ASSERT_NOT_REACHED();
1027         return E_POINTER;
1028     }
1029
1030     if (!m_element) {
1031         ASSERT_NOT_REACHED();
1032         return E_FAIL;
1033     }
1034
1035     *result = BString(m_element->innerText()).release();
1036     return S_OK;
1037 }
1038
1039 // IDOMElementCSSInlineStyle --------------------------------------------------
1040
1041 HRESULT STDMETHODCALLTYPE DOMElement::style( 
1042     /* [retval][out] */ IDOMCSSStyleDeclaration** result)
1043 {
1044     if (!result)
1045         return E_POINTER;
1046     if (!m_element)
1047         return E_FAIL;
1048
1049     WebCore::CSSStyleDeclaration* style = m_element->style();
1050     if (!style)
1051         return E_FAIL;
1052
1053     *result = DOMCSSStyleDeclaration::createInstance(style);
1054     return S_OK;
1055 }
1056
1057 // IDOMElementExtensions ------------------------------------------------------
1058
1059 HRESULT STDMETHODCALLTYPE DOMElement::offsetLeft( 
1060     /* [retval][out] */ int* result)
1061 {
1062     if (!m_element)
1063         return E_FAIL;
1064
1065     *result = m_element->offsetLeft();
1066     return S_OK;
1067 }
1068
1069 HRESULT STDMETHODCALLTYPE DOMElement::offsetTop( 
1070     /* [retval][out] */ int* result)
1071 {
1072     if (!m_element)
1073         return E_FAIL;
1074
1075     *result = m_element->offsetTop();
1076     return S_OK;
1077 }
1078
1079 HRESULT STDMETHODCALLTYPE DOMElement::offsetWidth( 
1080     /* [retval][out] */ int* result)
1081 {
1082     if (!m_element)
1083         return E_FAIL;
1084
1085     *result = m_element->offsetWidth();
1086     return S_OK;
1087 }
1088
1089 HRESULT STDMETHODCALLTYPE DOMElement::offsetHeight( 
1090     /* [retval][out] */ int* result)
1091 {
1092     if (!m_element)
1093         return E_FAIL;
1094
1095     *result = m_element->offsetHeight();
1096     return S_OK;
1097 }
1098
1099 HRESULT STDMETHODCALLTYPE DOMElement::offsetParent( 
1100     /* [retval][out] */ IDOMElement** /*result*/)
1101 {
1102     // FIXME
1103     ASSERT_NOT_REACHED();
1104     return E_NOTIMPL;
1105 }
1106
1107 HRESULT STDMETHODCALLTYPE DOMElement::clientWidth( 
1108     /* [retval][out] */ int* result)
1109 {
1110     if (!m_element)
1111         return E_FAIL;
1112
1113     *result = m_element->clientWidth();
1114     return S_OK;
1115 }
1116
1117 HRESULT STDMETHODCALLTYPE DOMElement::clientHeight( 
1118     /* [retval][out] */ int* result)
1119 {
1120     if (!m_element)
1121         return E_FAIL;
1122
1123     *result = m_element->clientHeight();
1124     return S_OK;
1125 }
1126
1127 HRESULT STDMETHODCALLTYPE DOMElement::scrollLeft( 
1128     /* [retval][out] */ int* result)
1129 {
1130     if (!m_element)
1131         return E_FAIL;
1132
1133     *result = m_element->scrollLeft();
1134     return S_OK;
1135 }
1136
1137 HRESULT STDMETHODCALLTYPE DOMElement::setScrollLeft( 
1138     /* [in] */ int /*newScrollLeft*/)
1139 {
1140     // FIXME
1141     ASSERT_NOT_REACHED();
1142     return E_NOTIMPL;
1143 }
1144
1145 HRESULT STDMETHODCALLTYPE DOMElement::scrollTop( 
1146     /* [retval][out] */ int* result)
1147 {
1148     if (!m_element)
1149         return E_FAIL;
1150
1151     *result = m_element->scrollTop();
1152     return S_OK;
1153 }
1154
1155 HRESULT STDMETHODCALLTYPE DOMElement::setScrollTop( 
1156     /* [in] */ int /*newScrollTop*/)
1157 {
1158     // FIXME
1159     ASSERT_NOT_REACHED();
1160     return E_NOTIMPL;
1161 }
1162
1163 HRESULT STDMETHODCALLTYPE DOMElement::scrollWidth( 
1164     /* [retval][out] */ int* result)
1165 {
1166     if (!m_element)
1167         return E_FAIL;
1168
1169     *result = m_element->scrollWidth();
1170     return S_OK;
1171 }
1172
1173 HRESULT STDMETHODCALLTYPE DOMElement::scrollHeight( 
1174     /* [retval][out] */ int* result)
1175 {
1176     if (!m_element)
1177         return E_FAIL;
1178
1179     *result = m_element->scrollHeight();
1180     return S_OK;
1181 }
1182
1183 HRESULT STDMETHODCALLTYPE DOMElement::scrollIntoView( 
1184     /* [in] */ BOOL alignWithTop)
1185 {
1186     if (!m_element)
1187         return E_FAIL;
1188
1189     m_element->scrollIntoView(!!alignWithTop);
1190     return S_OK;
1191 }
1192
1193 HRESULT STDMETHODCALLTYPE DOMElement::scrollIntoViewIfNeeded( 
1194     /* [in] */ BOOL centerIfNeeded)
1195 {
1196     if (!m_element)
1197         return E_FAIL;
1198
1199     m_element->scrollIntoViewIfNeeded(!!centerIfNeeded);
1200     return S_OK;
1201 }
1202
1203 // DOMElement -----------------------------------------------------------------
1204
1205 DOMElement::DOMElement(WebCore::Element* e)
1206 : DOMNode(e)
1207 , m_element(e)
1208 {
1209 }
1210
1211 DOMElement::~DOMElement()
1212 {
1213 }
1214
1215 IDOMElement* DOMElement::createInstance(WebCore::Element* e)
1216 {
1217     if (!e)
1218         return 0;
1219
1220     HRESULT hr;
1221     IDOMElement* domElement = 0;
1222
1223     if (e->hasTagName(formTag)) {
1224         DOMHTMLFormElement* newElement = new DOMHTMLFormElement(e);
1225         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1226     } else if (e->hasTagName(selectTag)) {
1227         DOMHTMLSelectElement* newElement = new DOMHTMLSelectElement(e);
1228         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1229     } else if (e->hasTagName(optionTag)) {
1230         DOMHTMLOptionElement* newElement = new DOMHTMLOptionElement(e);
1231         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1232     } else if (e->hasTagName(inputTag)) {
1233         DOMHTMLInputElement* newElement = new DOMHTMLInputElement(e);
1234         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1235     } else if (e->hasTagName(textareaTag)) {
1236         DOMHTMLTextAreaElement* newElement = new DOMHTMLTextAreaElement(e);
1237         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1238     } else if (e->isHTMLElement()) {
1239         DOMHTMLElement* newElement = new DOMHTMLElement(e);
1240         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1241     } else {
1242         DOMElement* newElement = new DOMElement(e);
1243         hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement);
1244     }
1245
1246     if (FAILED(hr))
1247         return 0;
1248
1249     return domElement;
1250 }