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