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