mshtml: Moved creating new element to separated function.
[wine] / dlls / mshtml / htmlelem.c
1 /*
2  * Copyright 2006 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19
20 #include <stdarg.h>
21
22 #define COBJMACROS
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "winreg.h"
28 #include "ole2.h"
29 #include "shlwapi.h"
30
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
33
34 #include "mshtml_private.h"
35 #include "htmlevent.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38
39 #define HTMLELEM_THIS(iface) DEFINE_THIS(HTMLElement, HTMLElement, iface)
40
41 HRESULT create_nselem(HTMLDocumentNode *doc, const WCHAR *tag, nsIDOMHTMLElement **ret)
42 {
43     nsIDOMElement *nselem;
44     nsAString tag_str;
45     nsresult nsres;
46
47     if(!doc->basedoc.nsdoc) {
48         WARN("NULL nsdoc\n");
49         return E_UNEXPECTED;
50     }
51
52     nsAString_Init(&tag_str, tag);
53     nsres = nsIDOMDocument_CreateElement(doc->basedoc.nsdoc, &tag_str, &nselem);
54     nsAString_Finish(&tag_str);
55     if(NS_FAILED(nsres)) {
56         ERR("CreateElement failed: %08x\n", nsres);
57         return E_FAIL;
58     }
59
60     nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLElement, (void**)ret);
61     nsIDOMElement_Release(nselem);
62     if(NS_FAILED(nsres)) {
63         ERR("Could not get nsIDOMHTMLElement iface: %08x\n", nsres);
64         return E_FAIL;
65     }
66
67     return S_OK;
68 }
69
70 #define HTMLELEM_NODE_THIS(iface) DEFINE_THIS2(HTMLElement, node, iface)
71
72 static HRESULT WINAPI HTMLElement_QueryInterface(IHTMLElement *iface,
73                                                  REFIID riid, void **ppv)
74 {
75     HTMLElement *This = HTMLELEM_THIS(iface);
76
77     return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->node), riid, ppv);
78 }
79
80 static ULONG WINAPI HTMLElement_AddRef(IHTMLElement *iface)
81 {
82     HTMLElement *This = HTMLELEM_THIS(iface);
83
84     return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->node));
85 }
86
87 static ULONG WINAPI HTMLElement_Release(IHTMLElement *iface)
88 {
89     HTMLElement *This = HTMLELEM_THIS(iface);
90
91     return IHTMLDOMNode_Release(HTMLDOMNODE(&This->node));
92 }
93
94 static HRESULT WINAPI HTMLElement_GetTypeInfoCount(IHTMLElement *iface, UINT *pctinfo)
95 {
96     HTMLElement *This = HTMLELEM_THIS(iface);
97     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->node.dispex), pctinfo);
98 }
99
100 static HRESULT WINAPI HTMLElement_GetTypeInfo(IHTMLElement *iface, UINT iTInfo,
101                                               LCID lcid, ITypeInfo **ppTInfo)
102 {
103     HTMLElement *This = HTMLELEM_THIS(iface);
104     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->node.dispex), iTInfo, lcid, ppTInfo);
105 }
106
107 static HRESULT WINAPI HTMLElement_GetIDsOfNames(IHTMLElement *iface, REFIID riid,
108                                                 LPOLESTR *rgszNames, UINT cNames,
109                                                 LCID lcid, DISPID *rgDispId)
110 {
111     HTMLElement *This = HTMLELEM_THIS(iface);
112     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->node.dispex), riid, rgszNames, cNames, lcid, rgDispId);
113 }
114
115 static HRESULT WINAPI HTMLElement_Invoke(IHTMLElement *iface, DISPID dispIdMember,
116                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
117                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
118 {
119     HTMLElement *This = HTMLELEM_THIS(iface);
120     return IDispatchEx_Invoke(DISPATCHEX(&This->node.dispex), dispIdMember, riid, lcid,
121             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
122 }
123
124 static HRESULT WINAPI HTMLElement_setAttribute(IHTMLElement *iface, BSTR strAttributeName,
125                                                VARIANT AttributeValue, LONG lFlags)
126 {
127     HTMLElement *This = HTMLELEM_THIS(iface);
128     HRESULT hres;
129     DISPID dispid, dispidNamed = DISPID_PROPERTYPUT;
130     DISPPARAMS dispParams;
131     EXCEPINFO excep;
132
133     TRACE("(%p)->(%s . %08x)\n", This, debugstr_w(strAttributeName), lFlags);
134
135     hres = IDispatchEx_GetDispID(DISPATCHEX(&This->node.dispex), strAttributeName,
136             fdexNameCaseInsensitive | fdexNameEnsure, &dispid);
137     if(FAILED(hres))
138         return hres;
139
140     dispParams.cArgs = 1;
141     dispParams.cNamedArgs = 1;
142     dispParams.rgdispidNamedArgs = &dispidNamed;
143     dispParams.rgvarg = &AttributeValue;
144
145     hres = IDispatchEx_InvokeEx(DISPATCHEX(&This->node.dispex), dispid,
146             LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dispParams,
147             NULL, &excep, NULL);
148     return hres;
149 }
150
151 static HRESULT WINAPI HTMLElement_getAttribute(IHTMLElement *iface, BSTR strAttributeName,
152                                                LONG lFlags, VARIANT *AttributeValue)
153 {
154     HTMLElement *This = HTMLELEM_THIS(iface);
155     DISPID dispid;
156     HRESULT hres;
157     DISPPARAMS dispParams = {NULL, NULL, 0, 0};
158     EXCEPINFO excep;
159
160     TRACE("(%p)->(%s %08x %p)\n", This, debugstr_w(strAttributeName), lFlags, AttributeValue);
161
162     hres = IDispatchEx_GetDispID(DISPATCHEX(&This->node.dispex), strAttributeName,
163             fdexNameCaseInsensitive, &dispid);
164     if(hres == DISP_E_UNKNOWNNAME) {
165         V_VT(AttributeValue) = VT_NULL;
166         return S_OK;
167     }
168
169     if(FAILED(hres)) {
170         V_VT(AttributeValue) = VT_NULL;
171         return hres;
172     }
173
174     hres = IDispatchEx_InvokeEx(DISPATCHEX(&This->node.dispex), dispid,
175             LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dispParams,
176             AttributeValue, &excep, NULL);
177
178     return hres;
179 }
180
181 static HRESULT WINAPI HTMLElement_removeAttribute(IHTMLElement *iface, BSTR strAttributeName,
182                                                   LONG lFlags, VARIANT_BOOL *pfSuccess)
183 {
184     HTMLElement *This = HTMLELEM_THIS(iface);
185     FIXME("(%p)->()\n", This);
186     return E_NOTIMPL;
187 }
188
189 static HRESULT WINAPI HTMLElement_put_className(IHTMLElement *iface, BSTR v)
190 {
191     HTMLElement *This = HTMLELEM_THIS(iface);
192     nsAString classname_str;
193     nsresult nsres;
194
195     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
196
197     if(!This->nselem) {
198         FIXME("NULL nselem\n");
199         return E_NOTIMPL;
200     }
201
202     nsAString_Init(&classname_str, v);
203     nsres = nsIDOMHTMLElement_SetClassName(This->nselem, &classname_str);
204     nsAString_Finish(&classname_str);
205     if(NS_FAILED(nsres))
206         ERR("SetClassName failed: %08x\n", nsres);
207
208     return S_OK;
209 }
210
211 static HRESULT WINAPI HTMLElement_get_className(IHTMLElement *iface, BSTR *p)
212 {
213     HTMLElement *This = HTMLELEM_THIS(iface);
214     nsAString class_str;
215     nsresult nsres;
216     HRESULT hres = S_OK;
217
218     TRACE("(%p)->(%p)\n", This, p);
219
220     if(!This->nselem) {
221         FIXME("NULL nselem\n");
222         return E_NOTIMPL;
223     }
224
225     nsAString_Init(&class_str, NULL);
226     nsres = nsIDOMHTMLElement_GetClassName(This->nselem, &class_str);
227
228     if(NS_SUCCEEDED(nsres)) {
229         const PRUnichar *class;
230         nsAString_GetData(&class_str, &class);
231         *p = *class ? SysAllocString(class) : NULL;
232     }else {
233         ERR("GetClassName failed: %08x\n", nsres);
234         hres = E_FAIL;
235     }
236
237     nsAString_Finish(&class_str);
238
239     TRACE("className=%s\n", debugstr_w(*p));
240     return hres;
241 }
242
243 static HRESULT WINAPI HTMLElement_put_id(IHTMLElement *iface, BSTR v)
244 {
245     HTMLElement *This = HTMLELEM_THIS(iface);
246     nsAString id_str;
247     nsresult nsres;
248
249     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
250
251     if(!This->nselem) {
252         FIXME("nselem == NULL\n");
253         return S_OK;
254     }
255
256     nsAString_Init(&id_str, v);
257     nsres = nsIDOMHTMLElement_SetId(This->nselem, &id_str);
258     nsAString_Finish(&id_str);
259     if(NS_FAILED(nsres))
260         ERR("SetId failed: %08x\n", nsres);
261
262     return S_OK;
263 }
264
265 static HRESULT WINAPI HTMLElement_get_id(IHTMLElement *iface, BSTR *p)
266 {
267     HTMLElement *This = HTMLELEM_THIS(iface);
268     const PRUnichar *id;
269     nsAString id_str;
270     nsresult nsres;
271
272     TRACE("(%p)->(%p)\n", This, p);
273
274     *p = NULL;
275
276     if(!This->nselem)
277         return S_OK;
278
279     nsAString_Init(&id_str, NULL);
280     nsres = nsIDOMHTMLElement_GetId(This->nselem, &id_str);
281     nsAString_GetData(&id_str, &id);
282
283     if(NS_FAILED(nsres))
284         ERR("GetId failed: %08x\n", nsres);
285     else if(*id)
286         *p = SysAllocString(id);
287
288     nsAString_Finish(&id_str);
289     return S_OK;
290 }
291
292 static HRESULT WINAPI HTMLElement_get_tagName(IHTMLElement *iface, BSTR *p)
293 {
294     HTMLElement *This = HTMLELEM_THIS(iface);
295     const PRUnichar *tag;
296     nsAString tag_str;
297     nsresult nsres;
298
299     TRACE("(%p)->(%p)\n", This, p);
300
301     if(!This->nselem) {
302         static const WCHAR comment_tagW[] = {'!',0};
303
304         WARN("NULL nselem, assuming comment\n");
305
306         *p = SysAllocString(comment_tagW);
307         return S_OK;
308     }
309
310     nsAString_Init(&tag_str, NULL);
311     nsres = nsIDOMHTMLElement_GetTagName(This->nselem, &tag_str);
312     if(NS_SUCCEEDED(nsres)) {
313         nsAString_GetData(&tag_str, &tag);
314         *p = SysAllocString(tag);
315     }else {
316         ERR("GetTagName failed: %08x\n", nsres);
317         *p = NULL;
318     }
319     nsAString_Finish(&tag_str);
320
321     return S_OK;
322 }
323
324 static HRESULT WINAPI HTMLElement_get_parentElement(IHTMLElement *iface, IHTMLElement **p)
325 {
326     HTMLElement *This = HTMLELEM_THIS(iface);
327     IHTMLDOMNode *node;
328     HRESULT hres;
329
330     TRACE("(%p)->(%p)\n", This, p);
331
332     hres = IHTMLDOMNode_get_parentNode(HTMLDOMNODE(&This->node), &node);
333     if(FAILED(hres))
334         return hres;
335
336     hres = IHTMLDOMNode_QueryInterface(node, &IID_IHTMLElement, (void**)p);
337     IHTMLDOMNode_Release(node);
338     if(FAILED(hres))
339         *p = NULL;
340
341     return S_OK;
342 }
343
344 static HRESULT WINAPI HTMLElement_get_style(IHTMLElement *iface, IHTMLStyle **p)
345 {
346     HTMLElement *This = HTMLELEM_THIS(iface);
347     nsIDOMElementCSSInlineStyle *nselemstyle;
348     nsIDOMCSSStyleDeclaration *nsstyle;
349     nsresult nsres;
350
351     TRACE("(%p)->(%p)\n", This, p);
352
353     if(!This->nselem) {
354         FIXME("NULL nselem\n");
355         return E_NOTIMPL;
356     }
357
358     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMElementCSSInlineStyle,
359                                              (void**)&nselemstyle);
360     if(NS_FAILED(nsres)) {
361         ERR("Coud not get nsIDOMCSSStyleDeclaration interface: %08x\n", nsres);
362         return E_FAIL;
363     }
364
365     nsres = nsIDOMElementCSSInlineStyle_GetStyle(nselemstyle, &nsstyle);
366     nsIDOMElementCSSInlineStyle_Release(nselemstyle);
367     if(NS_FAILED(nsres)) {
368         ERR("GetStyle failed: %08x\n", nsres);
369         return E_FAIL;
370     }
371
372     /* FIXME: Store style instead of creating a new instance in each call */
373     *p = HTMLStyle_Create(nsstyle);
374
375     nsIDOMCSSStyleDeclaration_Release(nsstyle);
376     return S_OK;
377 }
378
379 static HRESULT WINAPI HTMLElement_put_onhelp(IHTMLElement *iface, VARIANT v)
380 {
381     HTMLElement *This = HTMLELEM_THIS(iface);
382     FIXME("(%p)->()\n", This);
383     return E_NOTIMPL;
384 }
385
386 static HRESULT WINAPI HTMLElement_get_onhelp(IHTMLElement *iface, VARIANT *p)
387 {
388     HTMLElement *This = HTMLELEM_THIS(iface);
389     FIXME("(%p)->(%p)\n", This, p);
390     return E_NOTIMPL;
391 }
392
393 static HRESULT WINAPI HTMLElement_put_onclick(IHTMLElement *iface, VARIANT v)
394 {
395     HTMLElement *This = HTMLELEM_THIS(iface);
396
397     TRACE("(%p)->()\n", This);
398
399     return set_node_event(&This->node, EVENTID_CLICK, &v);
400 }
401
402 static HRESULT WINAPI HTMLElement_get_onclick(IHTMLElement *iface, VARIANT *p)
403 {
404     HTMLElement *This = HTMLELEM_THIS(iface);
405
406     TRACE("(%p)->(%p)\n", This, p);
407
408     return get_node_event(&This->node, EVENTID_CLICK, p);
409 }
410
411 static HRESULT WINAPI HTMLElement_put_ondblclick(IHTMLElement *iface, VARIANT v)
412 {
413     HTMLElement *This = HTMLELEM_THIS(iface);
414
415     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
416
417     return set_node_event(&This->node, EVENTID_DBLCLICK, &v);
418 }
419
420 static HRESULT WINAPI HTMLElement_get_ondblclick(IHTMLElement *iface, VARIANT *p)
421 {
422     HTMLElement *This = HTMLELEM_THIS(iface);
423
424     TRACE("(%p)->(%p)\n", This, p);
425
426     return get_node_event(&This->node, EVENTID_DBLCLICK, p);
427 }
428
429 static HRESULT WINAPI HTMLElement_put_onkeydown(IHTMLElement *iface, VARIANT v)
430 {
431     HTMLElement *This = HTMLELEM_THIS(iface);
432
433     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
434
435     return set_node_event(&This->node, EVENTID_KEYDOWN, &v);
436 }
437
438 static HRESULT WINAPI HTMLElement_get_onkeydown(IHTMLElement *iface, VARIANT *p)
439 {
440     HTMLElement *This = HTMLELEM_THIS(iface);
441
442     TRACE("(%p)->(%p)\n", This, p);
443
444     return get_node_event(&This->node, EVENTID_KEYDOWN, p);
445 }
446
447 static HRESULT WINAPI HTMLElement_put_onkeyup(IHTMLElement *iface, VARIANT v)
448 {
449     HTMLElement *This = HTMLELEM_THIS(iface);
450
451     TRACE("(%p)->()\n", This);
452
453     return set_node_event(&This->node, EVENTID_KEYUP, &v);
454 }
455
456 static HRESULT WINAPI HTMLElement_get_onkeyup(IHTMLElement *iface, VARIANT *p)
457 {
458     HTMLElement *This = HTMLELEM_THIS(iface);
459     FIXME("(%p)->(%p)\n", This, p);
460     return E_NOTIMPL;
461 }
462
463 static HRESULT WINAPI HTMLElement_put_onkeypress(IHTMLElement *iface, VARIANT v)
464 {
465     HTMLElement *This = HTMLELEM_THIS(iface);
466     FIXME("(%p)->()\n", This);
467     return E_NOTIMPL;
468 }
469
470 static HRESULT WINAPI HTMLElement_get_onkeypress(IHTMLElement *iface, VARIANT *p)
471 {
472     HTMLElement *This = HTMLELEM_THIS(iface);
473     FIXME("(%p)->(%p)\n", This, p);
474     return E_NOTIMPL;
475 }
476
477 static HRESULT WINAPI HTMLElement_put_onmouseout(IHTMLElement *iface, VARIANT v)
478 {
479     HTMLElement *This = HTMLELEM_THIS(iface);
480
481     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
482
483     return set_node_event(&This->node, EVENTID_MOUSEOUT, &v);
484 }
485
486 static HRESULT WINAPI HTMLElement_get_onmouseout(IHTMLElement *iface, VARIANT *p)
487 {
488     HTMLElement *This = HTMLELEM_THIS(iface);
489
490     TRACE("(%p)->(%p)\n", This, p);
491
492     return get_node_event(&This->node, EVENTID_MOUSEOUT, p);
493 }
494
495 static HRESULT WINAPI HTMLElement_put_onmouseover(IHTMLElement *iface, VARIANT v)
496 {
497     HTMLElement *This = HTMLELEM_THIS(iface);
498
499     TRACE("(%p)->()\n", This);
500
501     return set_node_event(&This->node, EVENTID_MOUSEOVER, &v);
502 }
503
504 static HRESULT WINAPI HTMLElement_get_onmouseover(IHTMLElement *iface, VARIANT *p)
505 {
506     HTMLElement *This = HTMLELEM_THIS(iface);
507
508     TRACE("(%p)->(%p)\n", This, p);
509
510     return get_node_event(&This->node, EVENTID_MOUSEOVER, p);
511 }
512
513 static HRESULT WINAPI HTMLElement_put_onmousemove(IHTMLElement *iface, VARIANT v)
514 {
515     HTMLElement *This = HTMLELEM_THIS(iface);
516     FIXME("(%p)->()\n", This);
517     return E_NOTIMPL;
518 }
519
520 static HRESULT WINAPI HTMLElement_get_onmousemove(IHTMLElement *iface, VARIANT *p)
521 {
522     HTMLElement *This = HTMLELEM_THIS(iface);
523     FIXME("(%p)->(%p)\n", This, p);
524     return E_NOTIMPL;
525 }
526
527 static HRESULT WINAPI HTMLElement_put_onmousedown(IHTMLElement *iface, VARIANT v)
528 {
529     HTMLElement *This = HTMLELEM_THIS(iface);
530
531     TRACE("(%p)->()\n", This);
532
533     return set_node_event(&This->node, EVENTID_MOUSEDOWN, &v);
534 }
535
536 static HRESULT WINAPI HTMLElement_get_onmousedown(IHTMLElement *iface, VARIANT *p)
537 {
538     HTMLElement *This = HTMLELEM_THIS(iface);
539
540     TRACE("(%p)->(%p)\n", This, p);
541
542     return get_node_event(&This->node, EVENTID_MOUSEDOWN, p);
543 }
544
545 static HRESULT WINAPI HTMLElement_put_onmouseup(IHTMLElement *iface, VARIANT v)
546 {
547     HTMLElement *This = HTMLELEM_THIS(iface);
548
549     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
550
551     return set_node_event(&This->node, EVENTID_MOUSEUP, &v);
552 }
553
554 static HRESULT WINAPI HTMLElement_get_onmouseup(IHTMLElement *iface, VARIANT *p)
555 {
556     HTMLElement *This = HTMLELEM_THIS(iface);
557
558     TRACE("(%p)->(%p)\n", This, p);
559
560     return get_node_event(&This->node, EVENTID_MOUSEUP, p);
561 }
562
563 static HRESULT WINAPI HTMLElement_get_document(IHTMLElement *iface, IDispatch **p)
564 {
565     HTMLElement *This = HTMLELEM_THIS(iface);
566
567     TRACE("(%p)->(%p)\n", This, p);
568
569     if(!p)
570         return E_POINTER;
571
572     *p = (IDispatch*)HTMLDOC(&This->node.doc->basedoc);
573     IDispatch_AddRef(*p);
574
575     return S_OK;
576 }
577
578 static HRESULT WINAPI HTMLElement_put_title(IHTMLElement *iface, BSTR v)
579 {
580     HTMLElement *This = HTMLELEM_THIS(iface);
581     nsAString title_str;
582     nsresult nsres;
583
584     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
585
586     nsAString_Init(&title_str, v);
587     nsres = nsIDOMHTMLElement_SetTitle(This->nselem, &title_str);
588     nsAString_Finish(&title_str);
589     if(NS_FAILED(nsres))
590         ERR("SetTitle failed: %08x\n", nsres);
591
592     return S_OK;
593 }
594
595 static HRESULT WINAPI HTMLElement_get_title(IHTMLElement *iface, BSTR *p)
596 {
597     HTMLElement *This = HTMLELEM_THIS(iface);
598     nsAString title_str;
599     nsresult nsres;
600
601     TRACE("(%p)->(%p)\n", This, p);
602
603     nsAString_Init(&title_str, NULL);
604     nsres = nsIDOMHTMLElement_GetTitle(This->nselem, &title_str);
605     if(NS_SUCCEEDED(nsres)) {
606         const PRUnichar *title;
607
608         nsAString_GetData(&title_str, &title);
609         *p = *title ? SysAllocString(title) : NULL;
610     }else {
611         ERR("GetTitle failed: %08x\n", nsres);
612         return E_FAIL;
613     }
614
615     return S_OK;
616 }
617
618 static HRESULT WINAPI HTMLElement_put_language(IHTMLElement *iface, BSTR v)
619 {
620     HTMLElement *This = HTMLELEM_THIS(iface);
621     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
622     return E_NOTIMPL;
623 }
624
625 static HRESULT WINAPI HTMLElement_get_language(IHTMLElement *iface, BSTR *p)
626 {
627     HTMLElement *This = HTMLELEM_THIS(iface);
628     FIXME("(%p)->(%p)\n", This, p);
629     return E_NOTIMPL;
630 }
631
632 static HRESULT WINAPI HTMLElement_put_onselectstart(IHTMLElement *iface, VARIANT v)
633 {
634     HTMLElement *This = HTMLELEM_THIS(iface);
635
636     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
637
638     return set_node_event(&This->node, EVENTID_SELECTSTART, &v);
639 }
640
641 static HRESULT WINAPI HTMLElement_get_onselectstart(IHTMLElement *iface, VARIANT *p)
642 {
643     HTMLElement *This = HTMLELEM_THIS(iface);
644
645     TRACE("(%p)->(%p)\n", This, p);
646
647     return get_node_event(&This->node, EVENTID_SELECTSTART, p);
648 }
649
650 static HRESULT WINAPI HTMLElement_scrollIntoView(IHTMLElement *iface, VARIANT varargStart)
651 {
652     HTMLElement *This = HTMLELEM_THIS(iface);
653     FIXME("(%p)->()\n", This);
654     return E_NOTIMPL;
655 }
656
657 static HRESULT WINAPI HTMLElement_contains(IHTMLElement *iface, IHTMLElement *pChild,
658                                            VARIANT_BOOL *pfResult)
659 {
660     HTMLElement *This = HTMLELEM_THIS(iface);
661     FIXME("(%p)->(%p %p)\n", This, pChild, pfResult);
662     return E_NOTIMPL;
663 }
664
665 static HRESULT WINAPI HTMLElement_get_sourceIndex(IHTMLElement *iface, LONG *p)
666 {
667     HTMLElement *This = HTMLELEM_THIS(iface);
668     FIXME("(%p)->(%p)\n", This, p);
669     return E_NOTIMPL;
670 }
671
672 static HRESULT WINAPI HTMLElement_get_recordNumber(IHTMLElement *iface, VARIANT *p)
673 {
674     HTMLElement *This = HTMLELEM_THIS(iface);
675     FIXME("(%p)->(%p)\n", This, p);
676     return E_NOTIMPL;
677 }
678
679 static HRESULT WINAPI HTMLElement_put_lang(IHTMLElement *iface, BSTR v)
680 {
681     HTMLElement *This = HTMLELEM_THIS(iface);
682     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
683     return E_NOTIMPL;
684 }
685
686 static HRESULT WINAPI HTMLElement_get_lang(IHTMLElement *iface, BSTR *p)
687 {
688     HTMLElement *This = HTMLELEM_THIS(iface);
689     FIXME("(%p)->(%p)\n", This, p);
690     return E_NOTIMPL;
691 }
692
693 static HRESULT WINAPI HTMLElement_get_offsetLeft(IHTMLElement *iface, LONG *p)
694 {
695     HTMLElement *This = HTMLELEM_THIS(iface);
696     FIXME("(%p)->(%p)\n", This, p);
697     return E_NOTIMPL;
698 }
699
700 static HRESULT WINAPI HTMLElement_get_offsetTop(IHTMLElement *iface, LONG *p)
701 {
702     HTMLElement *This = HTMLELEM_THIS(iface);
703     nsIDOMNSHTMLElement *nselem;
704     PRInt32 top = 0;
705     nsresult nsres;
706
707     TRACE("(%p)->(%p)\n", This, p);
708
709     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
710     if(NS_FAILED(nsres)) {
711         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
712         return E_FAIL;
713     }
714
715     nsres = nsIDOMNSHTMLElement_GetOffsetTop(nselem, &top);
716     nsIDOMNSHTMLElement_Release(nselem);
717     if(NS_FAILED(nsres)) {
718         ERR("GetOffsetTop failed: %08x\n", nsres);
719         return E_FAIL;
720     }
721
722     *p = top;
723     return S_OK;
724 }
725
726 static HRESULT WINAPI HTMLElement_get_offsetWidth(IHTMLElement *iface, LONG *p)
727 {
728     HTMLElement *This = HTMLELEM_THIS(iface);
729     nsIDOMNSHTMLElement *nselem;
730     PRInt32 offset = 0;
731     nsresult nsres;
732
733     TRACE("(%p)->(%p)\n", This, p);
734
735     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
736     if(NS_FAILED(nsres)) {
737         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
738         return E_FAIL;
739     }
740
741     nsres = nsIDOMNSHTMLElement_GetOffsetWidth(nselem, &offset);
742     nsIDOMNSHTMLElement_Release(nselem);
743     if(NS_FAILED(nsres)) {
744         ERR("GetOffsetWidth failed: %08x\n", nsres);
745         return E_FAIL;
746     }
747
748     *p = offset;
749     return S_OK;
750 }
751
752 static HRESULT WINAPI HTMLElement_get_offsetHeight(IHTMLElement *iface, LONG *p)
753 {
754     HTMLElement *This = HTMLELEM_THIS(iface);
755     nsIDOMNSHTMLElement *nselem;
756     PRInt32 offset = 0;
757     nsresult nsres;
758
759     TRACE("(%p)->(%p)\n", This, p);
760
761     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
762     if(NS_FAILED(nsres)) {
763         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
764         return E_FAIL;
765     }
766
767     nsres = nsIDOMNSHTMLElement_GetOffsetHeight(nselem, &offset);
768     nsIDOMNSHTMLElement_Release(nselem);
769     if(NS_FAILED(nsres)) {
770         ERR("GetOffsetHeight failed: %08x\n", nsres);
771         return E_FAIL;
772     }
773
774     *p = offset;
775     return S_OK;
776 }
777
778 static HRESULT WINAPI HTMLElement_get_offsetParent(IHTMLElement *iface, IHTMLElement **p)
779 {
780     HTMLElement *This = HTMLELEM_THIS(iface);
781     FIXME("(%p)->(%p)\n", This, p);
782     return E_NOTIMPL;
783 }
784
785 static HRESULT WINAPI HTMLElement_put_innerHTML(IHTMLElement *iface, BSTR v)
786 {
787     HTMLElement *This = HTMLELEM_THIS(iface);
788     nsIDOMNSHTMLElement *nselem;
789     nsAString html_str;
790     nsresult nsres;
791
792     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
793
794     if(!This->nselem) {
795         FIXME("NULL nselem\n");
796         return E_NOTIMPL;
797     }
798
799     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
800     if(NS_FAILED(nsres)) {
801         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
802         return E_FAIL;
803     }
804
805     nsAString_Init(&html_str, v);
806     nsres = nsIDOMNSHTMLElement_SetInnerHTML(nselem, &html_str);
807     nsAString_Finish(&html_str);
808
809     if(NS_FAILED(nsres)) {
810         FIXME("SetInnerHtml failed %08x\n", nsres);
811         return E_FAIL;
812     }
813
814     return S_OK;
815 }
816
817 static HRESULT WINAPI HTMLElement_get_innerHTML(IHTMLElement *iface, BSTR *p)
818 {
819     HTMLElement *This = HTMLELEM_THIS(iface);
820     nsIDOMNSHTMLElement *nselem;
821     nsAString html_str;
822     nsresult nsres;
823
824     TRACE("(%p)->(%p)\n", This, p);
825
826     if(!This->nselem) {
827         FIXME("NULL nselem\n");
828         return E_NOTIMPL;
829     }
830
831     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
832     if(NS_FAILED(nsres)) {
833         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
834         return E_FAIL;
835     }
836
837     nsAString_Init(&html_str, NULL);
838     nsres = nsIDOMNSHTMLElement_GetInnerHTML(nselem, &html_str);
839     if(NS_SUCCEEDED(nsres)) {
840         const PRUnichar *html;
841
842         nsAString_GetData(&html_str, &html);
843         *p = *html ? SysAllocString(html) : NULL;
844     }else {
845         FIXME("SetInnerHtml failed %08x\n", nsres);
846         *p = NULL;
847     }
848
849     nsAString_Finish(&html_str);
850     return S_OK;
851 }
852
853 static HRESULT WINAPI HTMLElement_put_innerText(IHTMLElement *iface, BSTR v)
854 {
855     HTMLElement *This = HTMLELEM_THIS(iface);
856     nsIDOMNode *nschild, *tmp;
857     nsIDOMText *text_node;
858     nsAString text_str;
859     nsresult nsres;
860
861     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
862
863     while(1) {
864         nsres = nsIDOMHTMLElement_GetLastChild(This->nselem, &nschild);
865         if(NS_FAILED(nsres)) {
866             ERR("GetLastChild failed: %08x\n", nsres);
867             return E_FAIL;
868         }
869         if(!nschild)
870             break;
871
872         nsres = nsIDOMHTMLElement_RemoveChild(This->nselem, nschild, &tmp);
873         nsIDOMNode_Release(nschild);
874         if(NS_FAILED(nsres)) {
875             ERR("RemoveChild failed: %08x\n", nsres);
876             return E_FAIL;
877         }
878         nsIDOMNode_Release(tmp);
879     }
880
881     nsAString_Init(&text_str, v);
882     nsres = nsIDOMHTMLDocument_CreateTextNode(This->node.doc->basedoc.nsdoc, &text_str, &text_node);
883     nsAString_Finish(&text_str);
884     if(NS_FAILED(nsres)) {
885         ERR("CreateTextNode failed: %08x\n", nsres);
886         return E_FAIL;
887     }
888
889     nsres = nsIDOMHTMLElement_AppendChild(This->nselem, (nsIDOMNode*)text_node, &tmp);
890     if(NS_FAILED(nsres)) {
891         ERR("AppendChild failed: %08x\n", nsres);
892         return E_FAIL;
893     }
894
895     nsIDOMNode_Release(tmp);
896     return S_OK;
897 }
898
899 static HRESULT WINAPI HTMLElement_get_innerText(IHTMLElement *iface, BSTR *p)
900 {
901     HTMLElement *This = HTMLELEM_THIS(iface);
902
903     TRACE("(%p)->(%p)\n", This, p);
904
905     return get_node_text(&This->node, p);
906 }
907
908 static HRESULT WINAPI HTMLElement_put_outerHTML(IHTMLElement *iface, BSTR v)
909 {
910     HTMLElement *This = HTMLELEM_THIS(iface);
911     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
912     return E_NOTIMPL;
913 }
914
915 static HRESULT WINAPI HTMLElement_get_outerHTML(IHTMLElement *iface, BSTR *p)
916 {
917     HTMLElement *This = HTMLELEM_THIS(iface);
918     nsAString html_str;
919     HRESULT hres;
920
921     WARN("(%p)->(%p) semi-stub\n", This, p);
922
923     nsAString_Init(&html_str, NULL);
924     hres = nsnode_to_nsstring(This->node.nsnode, &html_str);
925     if(SUCCEEDED(hres)) {
926         const PRUnichar *html;
927
928         nsAString_GetData(&html_str, &html);
929         *p = SysAllocString(html);
930         if(!*p)
931             hres = E_OUTOFMEMORY;
932     }
933
934     nsAString_Finish(&html_str);
935
936     TRACE("ret %s\n", debugstr_w(*p));
937     return S_OK;
938 }
939
940 static HRESULT WINAPI HTMLElement_put_outerText(IHTMLElement *iface, BSTR v)
941 {
942     HTMLElement *This = HTMLELEM_THIS(iface);
943     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
944     return E_NOTIMPL;
945 }
946
947 static HRESULT WINAPI HTMLElement_get_outerText(IHTMLElement *iface, BSTR *p)
948 {
949     HTMLElement *This = HTMLELEM_THIS(iface);
950     FIXME("(%p)->(%p)\n", This, p);
951     return E_NOTIMPL;
952 }
953
954 static HRESULT HTMLElement_InsertAdjacentNode(HTMLElement *This, BSTR where, nsIDOMNode *nsnode)
955 {
956     static const WCHAR wszBeforeBegin[] = {'b','e','f','o','r','e','B','e','g','i','n',0};
957     static const WCHAR wszAfterBegin[] = {'a','f','t','e','r','B','e','g','i','n',0};
958     static const WCHAR wszBeforeEnd[] = {'b','e','f','o','r','e','E','n','d',0};
959     static const WCHAR wszAfterEnd[] = {'a','f','t','e','r','E','n','d',0};
960     nsresult nsres;
961
962     if(!This->nselem) {
963         FIXME("NULL nselem\n");
964         return E_NOTIMPL;
965     }
966
967     if (!strcmpiW(where, wszBeforeBegin))
968     {
969         nsIDOMNode *unused;
970         nsIDOMNode *parent;
971         nsres = nsIDOMNode_GetParentNode(This->nselem, &parent);
972         if (!parent) return E_INVALIDARG;
973         nsres = nsIDOMNode_InsertBefore(parent, nsnode,
974                                         (nsIDOMNode *)This->nselem, &unused);
975         if (unused) nsIDOMNode_Release(unused);
976         nsIDOMNode_Release(parent);
977     }
978     else if (!strcmpiW(where, wszAfterBegin))
979     {
980         nsIDOMNode *unused;
981         nsIDOMNode *first_child;
982         nsIDOMNode_GetFirstChild(This->nselem, &first_child);
983         nsres = nsIDOMNode_InsertBefore(This->nselem, nsnode, first_child, &unused);
984         if (unused) nsIDOMNode_Release(unused);
985         if (first_child) nsIDOMNode_Release(first_child);
986     }
987     else if (!strcmpiW(where, wszBeforeEnd))
988     {
989         nsIDOMNode *unused;
990         nsres = nsIDOMNode_AppendChild(This->nselem, nsnode, &unused);
991         if (unused) nsIDOMNode_Release(unused);
992     }
993     else if (!strcmpiW(where, wszAfterEnd))
994     {
995         nsIDOMNode *unused;
996         nsIDOMNode *next_sibling;
997         nsIDOMNode *parent;
998         nsIDOMNode_GetParentNode(This->nselem, &parent);
999         if (!parent) return E_INVALIDARG;
1000
1001         nsIDOMNode_GetNextSibling(This->nselem, &next_sibling);
1002         if (next_sibling)
1003         {
1004             nsres = nsIDOMNode_InsertBefore(parent, nsnode, next_sibling, &unused);
1005             nsIDOMNode_Release(next_sibling);
1006         }
1007         else
1008             nsres = nsIDOMNode_AppendChild(parent, nsnode, &unused);
1009         nsIDOMNode_Release(parent);
1010         if (unused) nsIDOMNode_Release(unused);
1011     }
1012     else
1013     {
1014         ERR("invalid where: %s\n", debugstr_w(where));
1015         return E_INVALIDARG;
1016     }
1017
1018     if (NS_FAILED(nsres))
1019         return E_FAIL;
1020     else
1021         return S_OK;
1022 }
1023
1024 static HRESULT WINAPI HTMLElement_insertAdjacentHTML(IHTMLElement *iface, BSTR where,
1025                                                      BSTR html)
1026 {
1027     HTMLElement *This = HTMLELEM_THIS(iface);
1028     nsIDOMDocumentRange *nsdocrange;
1029     nsIDOMRange *range;
1030     nsIDOMNSRange *nsrange;
1031     nsIDOMNode *nsnode;
1032     nsAString ns_html;
1033     nsresult nsres;
1034     HRESULT hr;
1035
1036     TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(html));
1037
1038     if(!This->node.doc->basedoc.nsdoc) {
1039         WARN("NULL nsdoc\n");
1040         return E_UNEXPECTED;
1041     }
1042
1043     nsres = nsIDOMDocument_QueryInterface(This->node.doc->basedoc.nsdoc, &IID_nsIDOMDocumentRange, (void **)&nsdocrange);
1044     if(NS_FAILED(nsres))
1045     {
1046         ERR("getting nsIDOMDocumentRange failed: %08x\n", nsres);
1047         return E_FAIL;
1048     }
1049     nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &range);
1050     nsIDOMDocumentRange_Release(nsdocrange);
1051     if(NS_FAILED(nsres))
1052     {
1053         ERR("CreateRange failed: %08x\n", nsres);
1054         return E_FAIL;
1055     }
1056
1057     nsIDOMRange_SetStartBefore(range, (nsIDOMNode *)This->nselem);
1058
1059     nsIDOMRange_QueryInterface(range, &IID_nsIDOMNSRange, (void **)&nsrange);
1060     nsIDOMRange_Release(range);
1061     if(NS_FAILED(nsres))
1062     {
1063         ERR("getting nsIDOMNSRange failed: %08x\n", nsres);
1064         return E_FAIL;
1065     }
1066
1067     nsAString_Init(&ns_html, html);
1068
1069     nsres = nsIDOMNSRange_CreateContextualFragment(nsrange, &ns_html, (nsIDOMDocumentFragment **)&nsnode);
1070     nsIDOMNSRange_Release(nsrange);
1071     nsAString_Finish(&ns_html);
1072
1073     if(NS_FAILED(nsres) || !nsnode)
1074     {
1075         ERR("CreateTextNode failed: %08x\n", nsres);
1076         return E_FAIL;
1077     }
1078
1079     hr = HTMLElement_InsertAdjacentNode(This, where, nsnode);
1080     nsIDOMNode_Release(nsnode);
1081
1082     return hr;
1083 }
1084
1085 static HRESULT WINAPI HTMLElement_insertAdjacentText(IHTMLElement *iface, BSTR where,
1086                                                      BSTR text)
1087 {
1088     HTMLElement *This = HTMLELEM_THIS(iface);
1089     nsIDOMNode *nsnode;
1090     nsAString ns_text;
1091     nsresult nsres;
1092     HRESULT hr;
1093
1094     TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(text));
1095
1096     if(!This->node.doc->basedoc.nsdoc) {
1097         WARN("NULL nsdoc\n");
1098         return E_UNEXPECTED;
1099     }
1100
1101
1102     nsAString_Init(&ns_text, text);
1103     nsres = nsIDOMDocument_CreateTextNode(This->node.doc->basedoc.nsdoc, &ns_text, (nsIDOMText **)&nsnode);
1104     nsAString_Finish(&ns_text);
1105
1106     if(NS_FAILED(nsres) || !nsnode)
1107     {
1108         ERR("CreateTextNode failed: %08x\n", nsres);
1109         return E_FAIL;
1110     }
1111
1112     hr = HTMLElement_InsertAdjacentNode(This, where, nsnode);
1113     nsIDOMNode_Release(nsnode);
1114
1115     return hr;
1116 }
1117
1118 static HRESULT WINAPI HTMLElement_get_parentTextEdit(IHTMLElement *iface, IHTMLElement **p)
1119 {
1120     HTMLElement *This = HTMLELEM_THIS(iface);
1121     FIXME("(%p)->(%p)\n", This, p);
1122     return E_NOTIMPL;
1123 }
1124
1125 static HRESULT WINAPI HTMLElement_get_isTextEdit(IHTMLElement *iface, VARIANT_BOOL *p)
1126 {
1127     HTMLElement *This = HTMLELEM_THIS(iface);
1128     FIXME("(%p)->(%p)\n", This, p);
1129     return E_NOTIMPL;
1130 }
1131
1132 static HRESULT WINAPI HTMLElement_click(IHTMLElement *iface)
1133 {
1134     HTMLElement *This = HTMLELEM_THIS(iface);
1135
1136     TRACE("(%p)\n", This);
1137
1138     return call_event(&This->node, EVENTID_CLICK);
1139 }
1140
1141 static HRESULT WINAPI HTMLElement_get_filters(IHTMLElement *iface,
1142                                               IHTMLFiltersCollection **p)
1143 {
1144     HTMLElement *This = HTMLELEM_THIS(iface);
1145     FIXME("(%p)->(%p)\n", This, p);
1146     return E_NOTIMPL;
1147 }
1148
1149 static HRESULT WINAPI HTMLElement_put_ondragstart(IHTMLElement *iface, VARIANT v)
1150 {
1151     HTMLElement *This = HTMLELEM_THIS(iface);
1152     FIXME("(%p)->()\n", This);
1153     return E_NOTIMPL;
1154 }
1155
1156 static HRESULT WINAPI HTMLElement_get_ondragstart(IHTMLElement *iface, VARIANT *p)
1157 {
1158     HTMLElement *This = HTMLELEM_THIS(iface);
1159     FIXME("(%p)->(%p)\n", This, p);
1160     return E_NOTIMPL;
1161 }
1162
1163 static HRESULT WINAPI HTMLElement_toString(IHTMLElement *iface, BSTR *String)
1164 {
1165     HTMLElement *This = HTMLELEM_THIS(iface);
1166     FIXME("(%p)->(%p)\n", This, String);
1167     return E_NOTIMPL;
1168 }
1169
1170 static HRESULT WINAPI HTMLElement_put_onbeforeupdate(IHTMLElement *iface, VARIANT v)
1171 {
1172     HTMLElement *This = HTMLELEM_THIS(iface);
1173     FIXME("(%p)->()\n", This);
1174     return E_NOTIMPL;
1175 }
1176
1177 static HRESULT WINAPI HTMLElement_get_onbeforeupdate(IHTMLElement *iface, VARIANT *p)
1178 {
1179     HTMLElement *This = HTMLELEM_THIS(iface);
1180     FIXME("(%p)->(%p)\n", This, p);
1181     return E_NOTIMPL;
1182 }
1183
1184 static HRESULT WINAPI HTMLElement_put_onafterupdate(IHTMLElement *iface, VARIANT v)
1185 {
1186     HTMLElement *This = HTMLELEM_THIS(iface);
1187     FIXME("(%p)->()\n", This);
1188     return E_NOTIMPL;
1189 }
1190
1191 static HRESULT WINAPI HTMLElement_get_onafterupdate(IHTMLElement *iface, VARIANT *p)
1192 {
1193     HTMLElement *This = HTMLELEM_THIS(iface);
1194     FIXME("(%p)->(%p)\n", This, p);
1195     return E_NOTIMPL;
1196 }
1197
1198 static HRESULT WINAPI HTMLElement_put_onerrorupdate(IHTMLElement *iface, VARIANT v)
1199 {
1200     HTMLElement *This = HTMLELEM_THIS(iface);
1201     FIXME("(%p)->()\n", This);
1202     return E_NOTIMPL;
1203 }
1204
1205 static HRESULT WINAPI HTMLElement_get_onerrorupdate(IHTMLElement *iface, VARIANT *p)
1206 {
1207     HTMLElement *This = HTMLELEM_THIS(iface);
1208     FIXME("(%p)->(%p)\n", This, p);
1209     return E_NOTIMPL;
1210 }
1211
1212 static HRESULT WINAPI HTMLElement_put_onrowexit(IHTMLElement *iface, VARIANT v)
1213 {
1214     HTMLElement *This = HTMLELEM_THIS(iface);
1215     FIXME("(%p)->()\n", This);
1216     return E_NOTIMPL;
1217 }
1218
1219 static HRESULT WINAPI HTMLElement_get_onrowexit(IHTMLElement *iface, VARIANT *p)
1220 {
1221     HTMLElement *This = HTMLELEM_THIS(iface);
1222     FIXME("(%p)->(%p)\n", This, p);
1223     return E_NOTIMPL;
1224 }
1225
1226 static HRESULT WINAPI HTMLElement_put_onrowenter(IHTMLElement *iface, VARIANT v)
1227 {
1228     HTMLElement *This = HTMLELEM_THIS(iface);
1229     FIXME("(%p)->()\n", This);
1230     return E_NOTIMPL;
1231 }
1232
1233 static HRESULT WINAPI HTMLElement_get_onrowenter(IHTMLElement *iface, VARIANT *p)
1234 {
1235     HTMLElement *This = HTMLELEM_THIS(iface);
1236     FIXME("(%p)->(%p)\n", This, p);
1237     return E_NOTIMPL;
1238 }
1239
1240 static HRESULT WINAPI HTMLElement_put_ondatasetchanged(IHTMLElement *iface, VARIANT v)
1241 {
1242     HTMLElement *This = HTMLELEM_THIS(iface);
1243     FIXME("(%p)->()\n", This);
1244     return E_NOTIMPL;
1245 }
1246
1247 static HRESULT WINAPI HTMLElement_get_ondatasetchanged(IHTMLElement *iface, VARIANT *p)
1248 {
1249     HTMLElement *This = HTMLELEM_THIS(iface);
1250     FIXME("(%p)->(%p)\n", This, p);
1251     return E_NOTIMPL;
1252 }
1253
1254 static HRESULT WINAPI HTMLElement_put_ondataavailable(IHTMLElement *iface, VARIANT v)
1255 {
1256     HTMLElement *This = HTMLELEM_THIS(iface);
1257     FIXME("(%p)->()\n", This);
1258     return E_NOTIMPL;
1259 }
1260
1261 static HRESULT WINAPI HTMLElement_get_ondataavailable(IHTMLElement *iface, VARIANT *p)
1262 {
1263     HTMLElement *This = HTMLELEM_THIS(iface);
1264     FIXME("(%p)->(%p)\n", This, p);
1265     return E_NOTIMPL;
1266 }
1267
1268 static HRESULT WINAPI HTMLElement_put_ondatasetcomplete(IHTMLElement *iface, VARIANT v)
1269 {
1270     HTMLElement *This = HTMLELEM_THIS(iface);
1271     FIXME("(%p)->()\n", This);
1272     return E_NOTIMPL;
1273 }
1274
1275 static HRESULT WINAPI HTMLElement_get_ondatasetcomplete(IHTMLElement *iface, VARIANT *p)
1276 {
1277     HTMLElement *This = HTMLELEM_THIS(iface);
1278     FIXME("(%p)->(%p)\n", This, p);
1279     return E_NOTIMPL;
1280 }
1281
1282 static HRESULT WINAPI HTMLElement_put_onfilterchange(IHTMLElement *iface, VARIANT v)
1283 {
1284     HTMLElement *This = HTMLELEM_THIS(iface);
1285     FIXME("(%p)->()\n", This);
1286     return E_NOTIMPL;
1287 }
1288
1289 static HRESULT WINAPI HTMLElement_get_onfilterchange(IHTMLElement *iface, VARIANT *p)
1290 {
1291     HTMLElement *This = HTMLELEM_THIS(iface);
1292     FIXME("(%p)->(%p)\n", This, p);
1293     return E_NOTIMPL;
1294 }
1295
1296 static HRESULT WINAPI HTMLElement_get_children(IHTMLElement *iface, IDispatch **p)
1297 {
1298     HTMLElement *This = HTMLELEM_THIS(iface);
1299     nsIDOMNodeList *nsnode_list;
1300     nsresult nsres;
1301
1302     TRACE("(%p)->(%p)\n", This, p);
1303
1304     nsres = nsIDOMNode_GetChildNodes(This->node.nsnode, &nsnode_list);
1305     if(NS_FAILED(nsres)) {
1306         ERR("GetChildNodes failed: %08x\n", nsres);
1307         return E_FAIL;
1308     }
1309
1310     *p = (IDispatch*)create_collection_from_nodelist(This->node.doc, (IUnknown*)HTMLELEM(This), nsnode_list);
1311
1312     nsIDOMNodeList_Release(nsnode_list);
1313     return S_OK;
1314 }
1315
1316 static HRESULT WINAPI HTMLElement_get_all(IHTMLElement *iface, IDispatch **p)
1317 {
1318     HTMLElement *This = HTMLELEM_THIS(iface);
1319
1320     TRACE("(%p)->(%p)\n", This, p);
1321
1322     *p = (IDispatch*)create_all_collection(&This->node, FALSE);
1323     return S_OK;
1324 }
1325
1326 #undef HTMLELEM_THIS
1327
1328 static const IHTMLElementVtbl HTMLElementVtbl = {
1329     HTMLElement_QueryInterface,
1330     HTMLElement_AddRef,
1331     HTMLElement_Release,
1332     HTMLElement_GetTypeInfoCount,
1333     HTMLElement_GetTypeInfo,
1334     HTMLElement_GetIDsOfNames,
1335     HTMLElement_Invoke,
1336     HTMLElement_setAttribute,
1337     HTMLElement_getAttribute,
1338     HTMLElement_removeAttribute,
1339     HTMLElement_put_className,
1340     HTMLElement_get_className,
1341     HTMLElement_put_id,
1342     HTMLElement_get_id,
1343     HTMLElement_get_tagName,
1344     HTMLElement_get_parentElement,
1345     HTMLElement_get_style,
1346     HTMLElement_put_onhelp,
1347     HTMLElement_get_onhelp,
1348     HTMLElement_put_onclick,
1349     HTMLElement_get_onclick,
1350     HTMLElement_put_ondblclick,
1351     HTMLElement_get_ondblclick,
1352     HTMLElement_put_onkeydown,
1353     HTMLElement_get_onkeydown,
1354     HTMLElement_put_onkeyup,
1355     HTMLElement_get_onkeyup,
1356     HTMLElement_put_onkeypress,
1357     HTMLElement_get_onkeypress,
1358     HTMLElement_put_onmouseout,
1359     HTMLElement_get_onmouseout,
1360     HTMLElement_put_onmouseover,
1361     HTMLElement_get_onmouseover,
1362     HTMLElement_put_onmousemove,
1363     HTMLElement_get_onmousemove,
1364     HTMLElement_put_onmousedown,
1365     HTMLElement_get_onmousedown,
1366     HTMLElement_put_onmouseup,
1367     HTMLElement_get_onmouseup,
1368     HTMLElement_get_document,
1369     HTMLElement_put_title,
1370     HTMLElement_get_title,
1371     HTMLElement_put_language,
1372     HTMLElement_get_language,
1373     HTMLElement_put_onselectstart,
1374     HTMLElement_get_onselectstart,
1375     HTMLElement_scrollIntoView,
1376     HTMLElement_contains,
1377     HTMLElement_get_sourceIndex,
1378     HTMLElement_get_recordNumber,
1379     HTMLElement_put_lang,
1380     HTMLElement_get_lang,
1381     HTMLElement_get_offsetLeft,
1382     HTMLElement_get_offsetTop,
1383     HTMLElement_get_offsetWidth,
1384     HTMLElement_get_offsetHeight,
1385     HTMLElement_get_offsetParent,
1386     HTMLElement_put_innerHTML,
1387     HTMLElement_get_innerHTML,
1388     HTMLElement_put_innerText,
1389     HTMLElement_get_innerText,
1390     HTMLElement_put_outerHTML,
1391     HTMLElement_get_outerHTML,
1392     HTMLElement_put_outerText,
1393     HTMLElement_get_outerText,
1394     HTMLElement_insertAdjacentHTML,
1395     HTMLElement_insertAdjacentText,
1396     HTMLElement_get_parentTextEdit,
1397     HTMLElement_get_isTextEdit,
1398     HTMLElement_click,
1399     HTMLElement_get_filters,
1400     HTMLElement_put_ondragstart,
1401     HTMLElement_get_ondragstart,
1402     HTMLElement_toString,
1403     HTMLElement_put_onbeforeupdate,
1404     HTMLElement_get_onbeforeupdate,
1405     HTMLElement_put_onafterupdate,
1406     HTMLElement_get_onafterupdate,
1407     HTMLElement_put_onerrorupdate,
1408     HTMLElement_get_onerrorupdate,
1409     HTMLElement_put_onrowexit,
1410     HTMLElement_get_onrowexit,
1411     HTMLElement_put_onrowenter,
1412     HTMLElement_get_onrowenter,
1413     HTMLElement_put_ondatasetchanged,
1414     HTMLElement_get_ondatasetchanged,
1415     HTMLElement_put_ondataavailable,
1416     HTMLElement_get_ondataavailable,
1417     HTMLElement_put_ondatasetcomplete,
1418     HTMLElement_get_ondatasetcomplete,
1419     HTMLElement_put_onfilterchange,
1420     HTMLElement_get_onfilterchange,
1421     HTMLElement_get_children,
1422     HTMLElement_get_all
1423 };
1424
1425 HRESULT HTMLElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
1426 {
1427     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
1428
1429     *ppv =  NULL;
1430
1431     if(IsEqualGUID(&IID_IUnknown, riid)) {
1432         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1433         *ppv = HTMLELEM(This);
1434     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1435         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
1436         *ppv = HTMLELEM(This);
1437     }else if(IsEqualGUID(&IID_IHTMLElement, riid)) {
1438         TRACE("(%p)->(IID_IHTMLElement %p)\n", This, ppv);
1439         *ppv = HTMLELEM(This);
1440     }else if(IsEqualGUID(&IID_IHTMLElement2, riid)) {
1441         TRACE("(%p)->(IID_IHTMLElement2 %p)\n", This, ppv);
1442         *ppv = HTMLELEM2(This);
1443     }else if(IsEqualGUID(&IID_IHTMLElement3, riid)) {
1444         TRACE("(%p)->(IID_IHTMLElement3 %p)\n", This, ppv);
1445         *ppv = HTMLELEM3(This);
1446     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
1447         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
1448         *ppv = CONPTCONT(&This->cp_container);
1449     }
1450
1451     if(*ppv) {
1452         IHTMLElement_AddRef(HTMLELEM(This));
1453         return S_OK;
1454     }
1455
1456     return HTMLDOMNode_QI(&This->node, riid, ppv);
1457 }
1458
1459 void HTMLElement_destructor(HTMLDOMNode *iface)
1460 {
1461     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
1462
1463     ConnectionPointContainer_Destroy(&This->cp_container);
1464
1465     if(This->nselem)
1466         nsIDOMHTMLElement_Release(This->nselem);
1467
1468     HTMLDOMNode_destructor(&This->node);
1469 }
1470
1471 static const NodeImplVtbl HTMLElementImplVtbl = {
1472     HTMLElement_QI,
1473     HTMLElement_destructor
1474 };
1475
1476 static const tid_t HTMLElement_iface_tids[] = {
1477     IHTMLDOMNode_tid,
1478     IHTMLDOMNode2_tid,
1479     IHTMLElement_tid,
1480     IHTMLElement2_tid,
1481     IHTMLElement3_tid,
1482     0
1483 };
1484
1485 static dispex_static_data_t HTMLElement_dispex = {
1486     NULL,
1487     DispHTMLUnknownElement_tid,
1488     NULL,
1489     HTMLElement_iface_tids
1490 };
1491
1492 void HTMLElement_Init(HTMLElement *This, dispex_static_data_t *dispex_data)
1493 {
1494     This->lpHTMLElementVtbl = &HTMLElementVtbl;
1495
1496     ConnectionPointContainer_Init(&This->cp_container, (IUnknown*)HTMLELEM(This));
1497
1498     HTMLElement2_Init(This);
1499     HTMLElement3_Init(This);
1500
1501     init_dispex(&This->node.dispex, (IUnknown*)HTMLELEM(This), dispex_data ? dispex_data : &HTMLElement_dispex);
1502 }
1503
1504 HTMLElement *HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL use_generic)
1505 {
1506     nsIDOMHTMLElement *nselem;
1507     HTMLElement *ret = NULL;
1508     nsAString class_name_str;
1509     const PRUnichar *class_name;
1510     nsresult nsres;
1511
1512     static const WCHAR wszA[]        = {'A',0};
1513     static const WCHAR wszBODY[]     = {'B','O','D','Y',0};
1514     static const WCHAR wszIFRAME[]   = {'I','F','R','A','M','E',0};
1515     static const WCHAR wszIMG[]      = {'I','M','G',0};
1516     static const WCHAR wszINPUT[]    = {'I','N','P','U','T',0};
1517     static const WCHAR wszOPTION[]   = {'O','P','T','I','O','N',0};
1518     static const WCHAR wszSCRIPT[]   = {'S','C','R','I','P','T',0};
1519     static const WCHAR wszSELECT[]   = {'S','E','L','E','C','T',0};
1520     static const WCHAR wszTABLE[]    = {'T','A','B','L','E',0};
1521     static const WCHAR wszTR[]       = {'T','R',0};
1522     static const WCHAR wszTEXTAREA[] = {'T','E','X','T','A','R','E','A',0};
1523
1524     nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMHTMLElement, (void**)&nselem);
1525     if(NS_FAILED(nsres))
1526         return NULL;
1527
1528     nsAString_Init(&class_name_str, NULL);
1529     nsIDOMHTMLElement_GetTagName(nselem, &class_name_str);
1530
1531     nsAString_GetData(&class_name_str, &class_name);
1532
1533     if(!strcmpW(class_name, wszA))
1534         ret = HTMLAnchorElement_Create(nselem);
1535     else if(!strcmpW(class_name, wszBODY))
1536         ret = HTMLBodyElement_Create(nselem);
1537     else if(!strcmpW(class_name, wszIFRAME))
1538         ret = HTMLIFrame_Create(nselem);
1539     else if(!strcmpW(class_name, wszIMG))
1540         ret = HTMLImgElement_Create(nselem);
1541     else if(!strcmpW(class_name, wszINPUT))
1542         ret = HTMLInputElement_Create(nselem);
1543     else if(!strcmpW(class_name, wszOPTION))
1544         ret = HTMLOptionElement_Create(nselem);
1545     else if(!strcmpW(class_name, wszSCRIPT))
1546         ret = HTMLScriptElement_Create(nselem);
1547     else if(!strcmpW(class_name, wszSELECT))
1548         ret = HTMLSelectElement_Create(nselem);
1549     else if(!strcmpW(class_name, wszTABLE))
1550         ret = HTMLTable_Create(nselem);
1551     else if(!strcmpW(class_name, wszTR))
1552         ret = HTMLTableRow_Create(nselem);
1553     else if(!strcmpW(class_name, wszTEXTAREA))
1554         ret = HTMLTextAreaElement_Create(nselem);
1555     else if(use_generic)
1556         ret = HTMLGenericElement_Create(nselem);
1557
1558     if(!ret) {
1559         ret = heap_alloc_zero(sizeof(HTMLElement));
1560         HTMLElement_Init(ret, NULL);
1561         ret->node.vtbl = &HTMLElementImplVtbl;
1562     }
1563
1564     TRACE("%s ret %p\n", debugstr_w(class_name), ret);
1565
1566     nsAString_Finish(&class_name_str);
1567
1568     ret->nselem = nselem;
1569     HTMLDOMNode_Init(doc, &ret->node, (nsIDOMNode*)nselem);
1570
1571     return ret;
1572 }