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