mshtml: Add stub implementation of IHTMLFormElement.
[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->nsdoc) {
48         WARN("NULL nsdoc\n");
49         return E_UNEXPECTED;
50     }
51
52     nsAString_Init(&tag_str, tag);
53     nsres = nsIDOMDocument_CreateElement(doc->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     if(This->node.vtbl->get_document)
573         return This->node.vtbl->get_document(&This->node, p);
574
575     *p = (IDispatch*)HTMLDOC(&This->node.doc->basedoc);
576     IDispatch_AddRef(*p);
577     return S_OK;
578 }
579
580 static HRESULT WINAPI HTMLElement_put_title(IHTMLElement *iface, BSTR v)
581 {
582     HTMLElement *This = HTMLELEM_THIS(iface);
583     nsAString title_str;
584     nsresult nsres;
585
586     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
587
588     nsAString_Init(&title_str, v);
589     nsres = nsIDOMHTMLElement_SetTitle(This->nselem, &title_str);
590     nsAString_Finish(&title_str);
591     if(NS_FAILED(nsres))
592         ERR("SetTitle failed: %08x\n", nsres);
593
594     return S_OK;
595 }
596
597 static HRESULT WINAPI HTMLElement_get_title(IHTMLElement *iface, BSTR *p)
598 {
599     HTMLElement *This = HTMLELEM_THIS(iface);
600     nsAString title_str;
601     nsresult nsres;
602
603     TRACE("(%p)->(%p)\n", This, p);
604
605     nsAString_Init(&title_str, NULL);
606     nsres = nsIDOMHTMLElement_GetTitle(This->nselem, &title_str);
607     if(NS_SUCCEEDED(nsres)) {
608         const PRUnichar *title;
609
610         nsAString_GetData(&title_str, &title);
611         *p = *title ? SysAllocString(title) : NULL;
612     }else {
613         ERR("GetTitle failed: %08x\n", nsres);
614         return E_FAIL;
615     }
616
617     return S_OK;
618 }
619
620 static HRESULT WINAPI HTMLElement_put_language(IHTMLElement *iface, BSTR v)
621 {
622     HTMLElement *This = HTMLELEM_THIS(iface);
623     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
624     return E_NOTIMPL;
625 }
626
627 static HRESULT WINAPI HTMLElement_get_language(IHTMLElement *iface, BSTR *p)
628 {
629     HTMLElement *This = HTMLELEM_THIS(iface);
630     FIXME("(%p)->(%p)\n", This, p);
631     return E_NOTIMPL;
632 }
633
634 static HRESULT WINAPI HTMLElement_put_onselectstart(IHTMLElement *iface, VARIANT v)
635 {
636     HTMLElement *This = HTMLELEM_THIS(iface);
637
638     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
639
640     return set_node_event(&This->node, EVENTID_SELECTSTART, &v);
641 }
642
643 static HRESULT WINAPI HTMLElement_get_onselectstart(IHTMLElement *iface, VARIANT *p)
644 {
645     HTMLElement *This = HTMLELEM_THIS(iface);
646
647     TRACE("(%p)->(%p)\n", This, p);
648
649     return get_node_event(&This->node, EVENTID_SELECTSTART, p);
650 }
651
652 static HRESULT WINAPI HTMLElement_scrollIntoView(IHTMLElement *iface, VARIANT varargStart)
653 {
654     HTMLElement *This = HTMLELEM_THIS(iface);
655     FIXME("(%p)->()\n", This);
656     return E_NOTIMPL;
657 }
658
659 static HRESULT WINAPI HTMLElement_contains(IHTMLElement *iface, IHTMLElement *pChild,
660                                            VARIANT_BOOL *pfResult)
661 {
662     HTMLElement *This = HTMLELEM_THIS(iface);
663     FIXME("(%p)->(%p %p)\n", This, pChild, pfResult);
664     return E_NOTIMPL;
665 }
666
667 static HRESULT WINAPI HTMLElement_get_sourceIndex(IHTMLElement *iface, LONG *p)
668 {
669     HTMLElement *This = HTMLELEM_THIS(iface);
670     FIXME("(%p)->(%p)\n", This, p);
671     return E_NOTIMPL;
672 }
673
674 static HRESULT WINAPI HTMLElement_get_recordNumber(IHTMLElement *iface, VARIANT *p)
675 {
676     HTMLElement *This = HTMLELEM_THIS(iface);
677     FIXME("(%p)->(%p)\n", This, p);
678     return E_NOTIMPL;
679 }
680
681 static HRESULT WINAPI HTMLElement_put_lang(IHTMLElement *iface, BSTR v)
682 {
683     HTMLElement *This = HTMLELEM_THIS(iface);
684     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
685     return E_NOTIMPL;
686 }
687
688 static HRESULT WINAPI HTMLElement_get_lang(IHTMLElement *iface, BSTR *p)
689 {
690     HTMLElement *This = HTMLELEM_THIS(iface);
691     FIXME("(%p)->(%p)\n", This, p);
692     return E_NOTIMPL;
693 }
694
695 static HRESULT WINAPI HTMLElement_get_offsetLeft(IHTMLElement *iface, LONG *p)
696 {
697     HTMLElement *This = HTMLELEM_THIS(iface);
698     FIXME("(%p)->(%p)\n", This, p);
699     return E_NOTIMPL;
700 }
701
702 static HRESULT WINAPI HTMLElement_get_offsetTop(IHTMLElement *iface, LONG *p)
703 {
704     HTMLElement *This = HTMLELEM_THIS(iface);
705     nsIDOMNSHTMLElement *nselem;
706     PRInt32 top = 0;
707     nsresult nsres;
708
709     TRACE("(%p)->(%p)\n", This, p);
710
711     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
712     if(NS_FAILED(nsres)) {
713         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
714         return E_FAIL;
715     }
716
717     nsres = nsIDOMNSHTMLElement_GetOffsetTop(nselem, &top);
718     nsIDOMNSHTMLElement_Release(nselem);
719     if(NS_FAILED(nsres)) {
720         ERR("GetOffsetTop failed: %08x\n", nsres);
721         return E_FAIL;
722     }
723
724     *p = top;
725     return S_OK;
726 }
727
728 static HRESULT WINAPI HTMLElement_get_offsetWidth(IHTMLElement *iface, LONG *p)
729 {
730     HTMLElement *This = HTMLELEM_THIS(iface);
731     nsIDOMNSHTMLElement *nselem;
732     PRInt32 offset = 0;
733     nsresult nsres;
734
735     TRACE("(%p)->(%p)\n", This, p);
736
737     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
738     if(NS_FAILED(nsres)) {
739         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
740         return E_FAIL;
741     }
742
743     nsres = nsIDOMNSHTMLElement_GetOffsetWidth(nselem, &offset);
744     nsIDOMNSHTMLElement_Release(nselem);
745     if(NS_FAILED(nsres)) {
746         ERR("GetOffsetWidth failed: %08x\n", nsres);
747         return E_FAIL;
748     }
749
750     *p = offset;
751     return S_OK;
752 }
753
754 static HRESULT WINAPI HTMLElement_get_offsetHeight(IHTMLElement *iface, LONG *p)
755 {
756     HTMLElement *This = HTMLELEM_THIS(iface);
757     nsIDOMNSHTMLElement *nselem;
758     PRInt32 offset = 0;
759     nsresult nsres;
760
761     TRACE("(%p)->(%p)\n", This, p);
762
763     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
764     if(NS_FAILED(nsres)) {
765         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
766         return E_FAIL;
767     }
768
769     nsres = nsIDOMNSHTMLElement_GetOffsetHeight(nselem, &offset);
770     nsIDOMNSHTMLElement_Release(nselem);
771     if(NS_FAILED(nsres)) {
772         ERR("GetOffsetHeight failed: %08x\n", nsres);
773         return E_FAIL;
774     }
775
776     *p = offset;
777     return S_OK;
778 }
779
780 static HRESULT WINAPI HTMLElement_get_offsetParent(IHTMLElement *iface, IHTMLElement **p)
781 {
782     HTMLElement *This = HTMLELEM_THIS(iface);
783     FIXME("(%p)->(%p)\n", This, p);
784     return E_NOTIMPL;
785 }
786
787 static HRESULT WINAPI HTMLElement_put_innerHTML(IHTMLElement *iface, BSTR v)
788 {
789     HTMLElement *This = HTMLELEM_THIS(iface);
790     nsIDOMNSHTMLElement *nselem;
791     nsAString html_str;
792     nsresult nsres;
793
794     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
795
796     if(!This->nselem) {
797         FIXME("NULL nselem\n");
798         return E_NOTIMPL;
799     }
800
801     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
802     if(NS_FAILED(nsres)) {
803         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
804         return E_FAIL;
805     }
806
807     nsAString_Init(&html_str, v);
808     nsres = nsIDOMNSHTMLElement_SetInnerHTML(nselem, &html_str);
809     nsAString_Finish(&html_str);
810
811     if(NS_FAILED(nsres)) {
812         FIXME("SetInnerHtml failed %08x\n", nsres);
813         return E_FAIL;
814     }
815
816     return S_OK;
817 }
818
819 static HRESULT WINAPI HTMLElement_get_innerHTML(IHTMLElement *iface, BSTR *p)
820 {
821     HTMLElement *This = HTMLELEM_THIS(iface);
822     nsIDOMNSHTMLElement *nselem;
823     nsAString html_str;
824     nsresult nsres;
825
826     TRACE("(%p)->(%p)\n", This, p);
827
828     if(!This->nselem) {
829         FIXME("NULL nselem\n");
830         return E_NOTIMPL;
831     }
832
833     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
834     if(NS_FAILED(nsres)) {
835         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
836         return E_FAIL;
837     }
838
839     nsAString_Init(&html_str, NULL);
840     nsres = nsIDOMNSHTMLElement_GetInnerHTML(nselem, &html_str);
841     if(NS_SUCCEEDED(nsres)) {
842         const PRUnichar *html;
843
844         nsAString_GetData(&html_str, &html);
845         *p = *html ? SysAllocString(html) : NULL;
846     }else {
847         FIXME("SetInnerHtml failed %08x\n", nsres);
848         *p = NULL;
849     }
850
851     nsAString_Finish(&html_str);
852     return S_OK;
853 }
854
855 static HRESULT WINAPI HTMLElement_put_innerText(IHTMLElement *iface, BSTR v)
856 {
857     HTMLElement *This = HTMLELEM_THIS(iface);
858     nsIDOMNode *nschild, *tmp;
859     nsIDOMText *text_node;
860     nsAString text_str;
861     nsresult nsres;
862
863     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
864
865     while(1) {
866         nsres = nsIDOMHTMLElement_GetLastChild(This->nselem, &nschild);
867         if(NS_FAILED(nsres)) {
868             ERR("GetLastChild failed: %08x\n", nsres);
869             return E_FAIL;
870         }
871         if(!nschild)
872             break;
873
874         nsres = nsIDOMHTMLElement_RemoveChild(This->nselem, nschild, &tmp);
875         nsIDOMNode_Release(nschild);
876         if(NS_FAILED(nsres)) {
877             ERR("RemoveChild failed: %08x\n", nsres);
878             return E_FAIL;
879         }
880         nsIDOMNode_Release(tmp);
881     }
882
883     nsAString_Init(&text_str, v);
884     nsres = nsIDOMHTMLDocument_CreateTextNode(This->node.doc->nsdoc, &text_str, &text_node);
885     nsAString_Finish(&text_str);
886     if(NS_FAILED(nsres)) {
887         ERR("CreateTextNode failed: %08x\n", nsres);
888         return E_FAIL;
889     }
890
891     nsres = nsIDOMHTMLElement_AppendChild(This->nselem, (nsIDOMNode*)text_node, &tmp);
892     if(NS_FAILED(nsres)) {
893         ERR("AppendChild failed: %08x\n", nsres);
894         return E_FAIL;
895     }
896
897     nsIDOMNode_Release(tmp);
898     return S_OK;
899 }
900
901 static HRESULT WINAPI HTMLElement_get_innerText(IHTMLElement *iface, BSTR *p)
902 {
903     HTMLElement *This = HTMLELEM_THIS(iface);
904
905     TRACE("(%p)->(%p)\n", This, p);
906
907     return get_node_text(&This->node, p);
908 }
909
910 static HRESULT WINAPI HTMLElement_put_outerHTML(IHTMLElement *iface, BSTR v)
911 {
912     HTMLElement *This = HTMLELEM_THIS(iface);
913     nsIDOMDocumentFragment *nsfragment;
914     nsIDOMDocumentRange *nsdocrange;
915     nsIDOMNSRange *nsrange;
916     nsIDOMNode *nsparent;
917     nsIDOMRange *range;
918     nsAString html_str;
919     nsresult nsres;
920     HRESULT hres = S_OK;
921
922     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
923
924     nsres = nsIDOMHTMLDocument_QueryInterface(This->node.doc->nsdoc, &IID_nsIDOMDocumentRange, (void**)&nsdocrange);
925     if(NS_FAILED(nsres))
926         return E_FAIL;
927
928     nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &range);
929     nsIDOMDocumentRange_Release(nsdocrange);
930     if(NS_FAILED(nsres)) {
931         ERR("CreateRange failed: %08x\n", nsres);
932         return E_FAIL;
933     }
934
935     nsres = nsIDOMRange_QueryInterface(range, &IID_nsIDOMNSRange, (void**)&nsrange);
936     nsIDOMRange_Release(range);
937     if(NS_FAILED(nsres)) {
938         ERR("Could not get nsIDOMNSRange: %08x\n", nsres);
939         return E_FAIL;
940     }
941
942     nsAString_Init(&html_str, v);
943     nsIDOMNSRange_CreateContextualFragment(nsrange, &html_str, &nsfragment);
944     nsIDOMNSRange_Release(nsrange);
945     nsAString_Finish(&html_str);
946     if(NS_FAILED(nsres)) {
947         ERR("CreateContextualFragment failed: %08x\n", nsres);
948         return E_FAIL;
949     }
950
951     nsres = nsIDOMNode_GetParentNode(This->node.nsnode, &nsparent);
952     if(NS_SUCCEEDED(nsres) && nsparent) {
953         nsIDOMNode *nstmp;
954
955         nsres = nsIDOMNode_ReplaceChild(nsparent, (nsIDOMNode*)nsfragment, This->node.nsnode, &nstmp);
956         nsIDOMNode_Release(nsparent);
957         if(NS_FAILED(nsres)) {
958             ERR("ReplaceChild failed: %08x\n", nsres);
959             hres = E_FAIL;
960         }else if(nstmp) {
961             nsIDOMNode_Release(nstmp);
962         }
963     }else {
964         ERR("GetParentNode failed: %08x\n", nsres);
965         hres = E_FAIL;
966     }
967
968     nsIDOMDocumentFragment_Release(nsfragment);
969     return hres;
970 }
971
972 static HRESULT WINAPI HTMLElement_get_outerHTML(IHTMLElement *iface, BSTR *p)
973 {
974     HTMLElement *This = HTMLELEM_THIS(iface);
975     nsAString html_str;
976     HRESULT hres;
977
978     WARN("(%p)->(%p) semi-stub\n", This, p);
979
980     nsAString_Init(&html_str, NULL);
981     hres = nsnode_to_nsstring(This->node.nsnode, &html_str);
982     if(SUCCEEDED(hres)) {
983         const PRUnichar *html;
984
985         nsAString_GetData(&html_str, &html);
986         *p = SysAllocString(html);
987         if(!*p)
988             hres = E_OUTOFMEMORY;
989     }
990
991     nsAString_Finish(&html_str);
992
993     TRACE("ret %s\n", debugstr_w(*p));
994     return S_OK;
995 }
996
997 static HRESULT WINAPI HTMLElement_put_outerText(IHTMLElement *iface, BSTR v)
998 {
999     HTMLElement *This = HTMLELEM_THIS(iface);
1000     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1001     return E_NOTIMPL;
1002 }
1003
1004 static HRESULT WINAPI HTMLElement_get_outerText(IHTMLElement *iface, BSTR *p)
1005 {
1006     HTMLElement *This = HTMLELEM_THIS(iface);
1007     FIXME("(%p)->(%p)\n", This, p);
1008     return E_NOTIMPL;
1009 }
1010
1011 static HRESULT HTMLElement_InsertAdjacentNode(HTMLElement *This, BSTR where, nsIDOMNode *nsnode)
1012 {
1013     static const WCHAR wszBeforeBegin[] = {'b','e','f','o','r','e','B','e','g','i','n',0};
1014     static const WCHAR wszAfterBegin[] = {'a','f','t','e','r','B','e','g','i','n',0};
1015     static const WCHAR wszBeforeEnd[] = {'b','e','f','o','r','e','E','n','d',0};
1016     static const WCHAR wszAfterEnd[] = {'a','f','t','e','r','E','n','d',0};
1017     nsresult nsres;
1018
1019     if (!strcmpiW(where, wszBeforeBegin))
1020     {
1021         nsIDOMNode *unused;
1022         nsIDOMNode *parent;
1023         nsres = nsIDOMNode_GetParentNode(This->node.nsnode, &parent);
1024         if (!parent) return E_INVALIDARG;
1025         nsres = nsIDOMNode_InsertBefore(parent, nsnode, This->node.nsnode, &unused);
1026         if (unused) nsIDOMNode_Release(unused);
1027         nsIDOMNode_Release(parent);
1028     }
1029     else if (!strcmpiW(where, wszAfterBegin))
1030     {
1031         nsIDOMNode *unused;
1032         nsIDOMNode *first_child;
1033         nsIDOMNode_GetFirstChild(This->node.nsnode, &first_child);
1034         nsres = nsIDOMNode_InsertBefore(This->node.nsnode, nsnode, first_child, &unused);
1035         if (unused) nsIDOMNode_Release(unused);
1036         if (first_child) nsIDOMNode_Release(first_child);
1037     }
1038     else if (!strcmpiW(where, wszBeforeEnd))
1039     {
1040         nsIDOMNode *unused;
1041         nsres = nsIDOMNode_AppendChild(This->node.nsnode, nsnode, &unused);
1042         if (unused) nsIDOMNode_Release(unused);
1043     }
1044     else if (!strcmpiW(where, wszAfterEnd))
1045     {
1046         nsIDOMNode *unused;
1047         nsIDOMNode *next_sibling;
1048         nsIDOMNode *parent;
1049         nsIDOMNode_GetParentNode(This->node.nsnode, &parent);
1050         if (!parent) return E_INVALIDARG;
1051
1052         nsIDOMNode_GetNextSibling(This->node.nsnode, &next_sibling);
1053         if (next_sibling)
1054         {
1055             nsres = nsIDOMNode_InsertBefore(parent, nsnode, next_sibling, &unused);
1056             nsIDOMNode_Release(next_sibling);
1057         }
1058         else
1059             nsres = nsIDOMNode_AppendChild(parent, nsnode, &unused);
1060         nsIDOMNode_Release(parent);
1061         if (unused) nsIDOMNode_Release(unused);
1062     }
1063     else
1064     {
1065         ERR("invalid where: %s\n", debugstr_w(where));
1066         return E_INVALIDARG;
1067     }
1068
1069     if (NS_FAILED(nsres))
1070         return E_FAIL;
1071     else
1072         return S_OK;
1073 }
1074
1075 static HRESULT WINAPI HTMLElement_insertAdjacentHTML(IHTMLElement *iface, BSTR where,
1076                                                      BSTR html)
1077 {
1078     HTMLElement *This = HTMLELEM_THIS(iface);
1079     nsIDOMDocumentRange *nsdocrange;
1080     nsIDOMRange *range;
1081     nsIDOMNSRange *nsrange;
1082     nsIDOMNode *nsnode;
1083     nsAString ns_html;
1084     nsresult nsres;
1085     HRESULT hr;
1086
1087     TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(html));
1088
1089     if(!This->node.doc->nsdoc) {
1090         WARN("NULL nsdoc\n");
1091         return E_UNEXPECTED;
1092     }
1093
1094     nsres = nsIDOMDocument_QueryInterface(This->node.doc->nsdoc, &IID_nsIDOMDocumentRange, (void **)&nsdocrange);
1095     if(NS_FAILED(nsres))
1096     {
1097         ERR("getting nsIDOMDocumentRange failed: %08x\n", nsres);
1098         return E_FAIL;
1099     }
1100     nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &range);
1101     nsIDOMDocumentRange_Release(nsdocrange);
1102     if(NS_FAILED(nsres))
1103     {
1104         ERR("CreateRange failed: %08x\n", nsres);
1105         return E_FAIL;
1106     }
1107
1108     nsIDOMRange_SetStartBefore(range, This->node.nsnode);
1109
1110     nsIDOMRange_QueryInterface(range, &IID_nsIDOMNSRange, (void **)&nsrange);
1111     nsIDOMRange_Release(range);
1112     if(NS_FAILED(nsres))
1113     {
1114         ERR("getting nsIDOMNSRange failed: %08x\n", nsres);
1115         return E_FAIL;
1116     }
1117
1118     nsAString_Init(&ns_html, html);
1119
1120     nsres = nsIDOMNSRange_CreateContextualFragment(nsrange, &ns_html, (nsIDOMDocumentFragment **)&nsnode);
1121     nsIDOMNSRange_Release(nsrange);
1122     nsAString_Finish(&ns_html);
1123
1124     if(NS_FAILED(nsres) || !nsnode)
1125     {
1126         ERR("CreateTextNode failed: %08x\n", nsres);
1127         return E_FAIL;
1128     }
1129
1130     hr = HTMLElement_InsertAdjacentNode(This, where, nsnode);
1131     nsIDOMNode_Release(nsnode);
1132
1133     return hr;
1134 }
1135
1136 static HRESULT WINAPI HTMLElement_insertAdjacentText(IHTMLElement *iface, BSTR where,
1137                                                      BSTR text)
1138 {
1139     HTMLElement *This = HTMLELEM_THIS(iface);
1140     nsIDOMNode *nsnode;
1141     nsAString ns_text;
1142     nsresult nsres;
1143     HRESULT hr;
1144
1145     TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(text));
1146
1147     if(!This->node.doc->nsdoc) {
1148         WARN("NULL nsdoc\n");
1149         return E_UNEXPECTED;
1150     }
1151
1152
1153     nsAString_Init(&ns_text, text);
1154     nsres = nsIDOMDocument_CreateTextNode(This->node.doc->nsdoc, &ns_text, (nsIDOMText **)&nsnode);
1155     nsAString_Finish(&ns_text);
1156
1157     if(NS_FAILED(nsres) || !nsnode)
1158     {
1159         ERR("CreateTextNode failed: %08x\n", nsres);
1160         return E_FAIL;
1161     }
1162
1163     hr = HTMLElement_InsertAdjacentNode(This, where, nsnode);
1164     nsIDOMNode_Release(nsnode);
1165
1166     return hr;
1167 }
1168
1169 static HRESULT WINAPI HTMLElement_get_parentTextEdit(IHTMLElement *iface, IHTMLElement **p)
1170 {
1171     HTMLElement *This = HTMLELEM_THIS(iface);
1172     FIXME("(%p)->(%p)\n", This, p);
1173     return E_NOTIMPL;
1174 }
1175
1176 static HRESULT WINAPI HTMLElement_get_isTextEdit(IHTMLElement *iface, VARIANT_BOOL *p)
1177 {
1178     HTMLElement *This = HTMLELEM_THIS(iface);
1179     FIXME("(%p)->(%p)\n", This, p);
1180     return E_NOTIMPL;
1181 }
1182
1183 static HRESULT WINAPI HTMLElement_click(IHTMLElement *iface)
1184 {
1185     HTMLElement *This = HTMLELEM_THIS(iface);
1186
1187     TRACE("(%p)\n", This);
1188
1189     return call_event(&This->node, EVENTID_CLICK);
1190 }
1191
1192 static HRESULT WINAPI HTMLElement_get_filters(IHTMLElement *iface,
1193                                               IHTMLFiltersCollection **p)
1194 {
1195     HTMLElement *This = HTMLELEM_THIS(iface);
1196     FIXME("(%p)->(%p)\n", This, p);
1197     return E_NOTIMPL;
1198 }
1199
1200 static HRESULT WINAPI HTMLElement_put_ondragstart(IHTMLElement *iface, VARIANT v)
1201 {
1202     HTMLElement *This = HTMLELEM_THIS(iface);
1203     FIXME("(%p)->()\n", This);
1204     return E_NOTIMPL;
1205 }
1206
1207 static HRESULT WINAPI HTMLElement_get_ondragstart(IHTMLElement *iface, VARIANT *p)
1208 {
1209     HTMLElement *This = HTMLELEM_THIS(iface);
1210     FIXME("(%p)->(%p)\n", This, p);
1211     return E_NOTIMPL;
1212 }
1213
1214 static HRESULT WINAPI HTMLElement_toString(IHTMLElement *iface, BSTR *String)
1215 {
1216     HTMLElement *This = HTMLELEM_THIS(iface);
1217     FIXME("(%p)->(%p)\n", This, String);
1218     return E_NOTIMPL;
1219 }
1220
1221 static HRESULT WINAPI HTMLElement_put_onbeforeupdate(IHTMLElement *iface, VARIANT v)
1222 {
1223     HTMLElement *This = HTMLELEM_THIS(iface);
1224     FIXME("(%p)->()\n", This);
1225     return E_NOTIMPL;
1226 }
1227
1228 static HRESULT WINAPI HTMLElement_get_onbeforeupdate(IHTMLElement *iface, VARIANT *p)
1229 {
1230     HTMLElement *This = HTMLELEM_THIS(iface);
1231     FIXME("(%p)->(%p)\n", This, p);
1232     return E_NOTIMPL;
1233 }
1234
1235 static HRESULT WINAPI HTMLElement_put_onafterupdate(IHTMLElement *iface, VARIANT v)
1236 {
1237     HTMLElement *This = HTMLELEM_THIS(iface);
1238     FIXME("(%p)->()\n", This);
1239     return E_NOTIMPL;
1240 }
1241
1242 static HRESULT WINAPI HTMLElement_get_onafterupdate(IHTMLElement *iface, VARIANT *p)
1243 {
1244     HTMLElement *This = HTMLELEM_THIS(iface);
1245     FIXME("(%p)->(%p)\n", This, p);
1246     return E_NOTIMPL;
1247 }
1248
1249 static HRESULT WINAPI HTMLElement_put_onerrorupdate(IHTMLElement *iface, VARIANT v)
1250 {
1251     HTMLElement *This = HTMLELEM_THIS(iface);
1252     FIXME("(%p)->()\n", This);
1253     return E_NOTIMPL;
1254 }
1255
1256 static HRESULT WINAPI HTMLElement_get_onerrorupdate(IHTMLElement *iface, VARIANT *p)
1257 {
1258     HTMLElement *This = HTMLELEM_THIS(iface);
1259     FIXME("(%p)->(%p)\n", This, p);
1260     return E_NOTIMPL;
1261 }
1262
1263 static HRESULT WINAPI HTMLElement_put_onrowexit(IHTMLElement *iface, VARIANT v)
1264 {
1265     HTMLElement *This = HTMLELEM_THIS(iface);
1266     FIXME("(%p)->()\n", This);
1267     return E_NOTIMPL;
1268 }
1269
1270 static HRESULT WINAPI HTMLElement_get_onrowexit(IHTMLElement *iface, VARIANT *p)
1271 {
1272     HTMLElement *This = HTMLELEM_THIS(iface);
1273     FIXME("(%p)->(%p)\n", This, p);
1274     return E_NOTIMPL;
1275 }
1276
1277 static HRESULT WINAPI HTMLElement_put_onrowenter(IHTMLElement *iface, VARIANT v)
1278 {
1279     HTMLElement *This = HTMLELEM_THIS(iface);
1280     FIXME("(%p)->()\n", This);
1281     return E_NOTIMPL;
1282 }
1283
1284 static HRESULT WINAPI HTMLElement_get_onrowenter(IHTMLElement *iface, VARIANT *p)
1285 {
1286     HTMLElement *This = HTMLELEM_THIS(iface);
1287     FIXME("(%p)->(%p)\n", This, p);
1288     return E_NOTIMPL;
1289 }
1290
1291 static HRESULT WINAPI HTMLElement_put_ondatasetchanged(IHTMLElement *iface, VARIANT v)
1292 {
1293     HTMLElement *This = HTMLELEM_THIS(iface);
1294     FIXME("(%p)->()\n", This);
1295     return E_NOTIMPL;
1296 }
1297
1298 static HRESULT WINAPI HTMLElement_get_ondatasetchanged(IHTMLElement *iface, VARIANT *p)
1299 {
1300     HTMLElement *This = HTMLELEM_THIS(iface);
1301     FIXME("(%p)->(%p)\n", This, p);
1302     return E_NOTIMPL;
1303 }
1304
1305 static HRESULT WINAPI HTMLElement_put_ondataavailable(IHTMLElement *iface, VARIANT v)
1306 {
1307     HTMLElement *This = HTMLELEM_THIS(iface);
1308     FIXME("(%p)->()\n", This);
1309     return E_NOTIMPL;
1310 }
1311
1312 static HRESULT WINAPI HTMLElement_get_ondataavailable(IHTMLElement *iface, VARIANT *p)
1313 {
1314     HTMLElement *This = HTMLELEM_THIS(iface);
1315     FIXME("(%p)->(%p)\n", This, p);
1316     return E_NOTIMPL;
1317 }
1318
1319 static HRESULT WINAPI HTMLElement_put_ondatasetcomplete(IHTMLElement *iface, VARIANT v)
1320 {
1321     HTMLElement *This = HTMLELEM_THIS(iface);
1322     FIXME("(%p)->()\n", This);
1323     return E_NOTIMPL;
1324 }
1325
1326 static HRESULT WINAPI HTMLElement_get_ondatasetcomplete(IHTMLElement *iface, VARIANT *p)
1327 {
1328     HTMLElement *This = HTMLELEM_THIS(iface);
1329     FIXME("(%p)->(%p)\n", This, p);
1330     return E_NOTIMPL;
1331 }
1332
1333 static HRESULT WINAPI HTMLElement_put_onfilterchange(IHTMLElement *iface, VARIANT v)
1334 {
1335     HTMLElement *This = HTMLELEM_THIS(iface);
1336     FIXME("(%p)->()\n", This);
1337     return E_NOTIMPL;
1338 }
1339
1340 static HRESULT WINAPI HTMLElement_get_onfilterchange(IHTMLElement *iface, VARIANT *p)
1341 {
1342     HTMLElement *This = HTMLELEM_THIS(iface);
1343     FIXME("(%p)->(%p)\n", This, p);
1344     return E_NOTIMPL;
1345 }
1346
1347 static HRESULT WINAPI HTMLElement_get_children(IHTMLElement *iface, IDispatch **p)
1348 {
1349     HTMLElement *This = HTMLELEM_THIS(iface);
1350     nsIDOMNodeList *nsnode_list;
1351     nsresult nsres;
1352
1353     TRACE("(%p)->(%p)\n", This, p);
1354
1355     nsres = nsIDOMNode_GetChildNodes(This->node.nsnode, &nsnode_list);
1356     if(NS_FAILED(nsres)) {
1357         ERR("GetChildNodes failed: %08x\n", nsres);
1358         return E_FAIL;
1359     }
1360
1361     *p = (IDispatch*)create_collection_from_nodelist(This->node.doc, (IUnknown*)HTMLELEM(This), nsnode_list);
1362
1363     nsIDOMNodeList_Release(nsnode_list);
1364     return S_OK;
1365 }
1366
1367 static HRESULT WINAPI HTMLElement_get_all(IHTMLElement *iface, IDispatch **p)
1368 {
1369     HTMLElement *This = HTMLELEM_THIS(iface);
1370
1371     TRACE("(%p)->(%p)\n", This, p);
1372
1373     *p = (IDispatch*)create_all_collection(&This->node, FALSE);
1374     return S_OK;
1375 }
1376
1377 #undef HTMLELEM_THIS
1378
1379 static const IHTMLElementVtbl HTMLElementVtbl = {
1380     HTMLElement_QueryInterface,
1381     HTMLElement_AddRef,
1382     HTMLElement_Release,
1383     HTMLElement_GetTypeInfoCount,
1384     HTMLElement_GetTypeInfo,
1385     HTMLElement_GetIDsOfNames,
1386     HTMLElement_Invoke,
1387     HTMLElement_setAttribute,
1388     HTMLElement_getAttribute,
1389     HTMLElement_removeAttribute,
1390     HTMLElement_put_className,
1391     HTMLElement_get_className,
1392     HTMLElement_put_id,
1393     HTMLElement_get_id,
1394     HTMLElement_get_tagName,
1395     HTMLElement_get_parentElement,
1396     HTMLElement_get_style,
1397     HTMLElement_put_onhelp,
1398     HTMLElement_get_onhelp,
1399     HTMLElement_put_onclick,
1400     HTMLElement_get_onclick,
1401     HTMLElement_put_ondblclick,
1402     HTMLElement_get_ondblclick,
1403     HTMLElement_put_onkeydown,
1404     HTMLElement_get_onkeydown,
1405     HTMLElement_put_onkeyup,
1406     HTMLElement_get_onkeyup,
1407     HTMLElement_put_onkeypress,
1408     HTMLElement_get_onkeypress,
1409     HTMLElement_put_onmouseout,
1410     HTMLElement_get_onmouseout,
1411     HTMLElement_put_onmouseover,
1412     HTMLElement_get_onmouseover,
1413     HTMLElement_put_onmousemove,
1414     HTMLElement_get_onmousemove,
1415     HTMLElement_put_onmousedown,
1416     HTMLElement_get_onmousedown,
1417     HTMLElement_put_onmouseup,
1418     HTMLElement_get_onmouseup,
1419     HTMLElement_get_document,
1420     HTMLElement_put_title,
1421     HTMLElement_get_title,
1422     HTMLElement_put_language,
1423     HTMLElement_get_language,
1424     HTMLElement_put_onselectstart,
1425     HTMLElement_get_onselectstart,
1426     HTMLElement_scrollIntoView,
1427     HTMLElement_contains,
1428     HTMLElement_get_sourceIndex,
1429     HTMLElement_get_recordNumber,
1430     HTMLElement_put_lang,
1431     HTMLElement_get_lang,
1432     HTMLElement_get_offsetLeft,
1433     HTMLElement_get_offsetTop,
1434     HTMLElement_get_offsetWidth,
1435     HTMLElement_get_offsetHeight,
1436     HTMLElement_get_offsetParent,
1437     HTMLElement_put_innerHTML,
1438     HTMLElement_get_innerHTML,
1439     HTMLElement_put_innerText,
1440     HTMLElement_get_innerText,
1441     HTMLElement_put_outerHTML,
1442     HTMLElement_get_outerHTML,
1443     HTMLElement_put_outerText,
1444     HTMLElement_get_outerText,
1445     HTMLElement_insertAdjacentHTML,
1446     HTMLElement_insertAdjacentText,
1447     HTMLElement_get_parentTextEdit,
1448     HTMLElement_get_isTextEdit,
1449     HTMLElement_click,
1450     HTMLElement_get_filters,
1451     HTMLElement_put_ondragstart,
1452     HTMLElement_get_ondragstart,
1453     HTMLElement_toString,
1454     HTMLElement_put_onbeforeupdate,
1455     HTMLElement_get_onbeforeupdate,
1456     HTMLElement_put_onafterupdate,
1457     HTMLElement_get_onafterupdate,
1458     HTMLElement_put_onerrorupdate,
1459     HTMLElement_get_onerrorupdate,
1460     HTMLElement_put_onrowexit,
1461     HTMLElement_get_onrowexit,
1462     HTMLElement_put_onrowenter,
1463     HTMLElement_get_onrowenter,
1464     HTMLElement_put_ondatasetchanged,
1465     HTMLElement_get_ondatasetchanged,
1466     HTMLElement_put_ondataavailable,
1467     HTMLElement_get_ondataavailable,
1468     HTMLElement_put_ondatasetcomplete,
1469     HTMLElement_get_ondatasetcomplete,
1470     HTMLElement_put_onfilterchange,
1471     HTMLElement_get_onfilterchange,
1472     HTMLElement_get_children,
1473     HTMLElement_get_all
1474 };
1475
1476 HRESULT HTMLElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
1477 {
1478     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
1479
1480     *ppv =  NULL;
1481
1482     if(IsEqualGUID(&IID_IUnknown, riid)) {
1483         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1484         *ppv = HTMLELEM(This);
1485     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1486         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
1487         *ppv = HTMLELEM(This);
1488     }else if(IsEqualGUID(&IID_IHTMLElement, riid)) {
1489         TRACE("(%p)->(IID_IHTMLElement %p)\n", This, ppv);
1490         *ppv = HTMLELEM(This);
1491     }else if(IsEqualGUID(&IID_IHTMLElement2, riid)) {
1492         TRACE("(%p)->(IID_IHTMLElement2 %p)\n", This, ppv);
1493         *ppv = HTMLELEM2(This);
1494     }else if(IsEqualGUID(&IID_IHTMLElement3, riid)) {
1495         TRACE("(%p)->(IID_IHTMLElement3 %p)\n", This, ppv);
1496         *ppv = HTMLELEM3(This);
1497     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
1498         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
1499         *ppv = CONPTCONT(&This->cp_container);
1500     }
1501
1502     if(*ppv) {
1503         IHTMLElement_AddRef(HTMLELEM(This));
1504         return S_OK;
1505     }
1506
1507     return HTMLDOMNode_QI(&This->node, riid, ppv);
1508 }
1509
1510 void HTMLElement_destructor(HTMLDOMNode *iface)
1511 {
1512     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
1513
1514     ConnectionPointContainer_Destroy(&This->cp_container);
1515
1516     if(This->nselem)
1517         nsIDOMHTMLElement_Release(This->nselem);
1518
1519     HTMLDOMNode_destructor(&This->node);
1520 }
1521
1522 static const NodeImplVtbl HTMLElementImplVtbl = {
1523     HTMLElement_QI,
1524     HTMLElement_destructor
1525 };
1526
1527 static const tid_t HTMLElement_iface_tids[] = {
1528     IHTMLDOMNode_tid,
1529     IHTMLDOMNode2_tid,
1530     IHTMLElement_tid,
1531     IHTMLElement2_tid,
1532     IHTMLElement3_tid,
1533     0
1534 };
1535
1536 static dispex_static_data_t HTMLElement_dispex = {
1537     NULL,
1538     DispHTMLUnknownElement_tid,
1539     NULL,
1540     HTMLElement_iface_tids
1541 };
1542
1543 void HTMLElement_Init(HTMLElement *This, HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, dispex_static_data_t *dispex_data)
1544 {
1545     This->lpHTMLElementVtbl = &HTMLElementVtbl;
1546
1547     HTMLElement2_Init(This);
1548     HTMLElement3_Init(This);
1549
1550     init_dispex(&This->node.dispex, (IUnknown*)HTMLELEM(This), dispex_data ? dispex_data : &HTMLElement_dispex);
1551
1552     if(nselem)
1553         nsIDOMHTMLElement_AddRef(nselem);
1554     This->nselem = nselem;
1555
1556     HTMLDOMNode_Init(doc, &This->node, (nsIDOMNode*)nselem);
1557
1558     ConnectionPointContainer_Init(&This->cp_container, (IUnknown*)HTMLELEM(This));
1559 }
1560
1561 HTMLElement *HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL use_generic)
1562 {
1563     nsIDOMHTMLElement *nselem;
1564     HTMLElement *ret = NULL;
1565     nsAString class_name_str;
1566     const PRUnichar *class_name;
1567     nsresult nsres;
1568
1569     static const WCHAR wszA[]        = {'A',0};
1570     static const WCHAR wszBODY[]     = {'B','O','D','Y',0};
1571     static const WCHAR wszFORM[]     = {'F','O','R','M',0};
1572     static const WCHAR wszIFRAME[]   = {'I','F','R','A','M','E',0};
1573     static const WCHAR wszIMG[]      = {'I','M','G',0};
1574     static const WCHAR wszINPUT[]    = {'I','N','P','U','T',0};
1575     static const WCHAR wszOPTION[]   = {'O','P','T','I','O','N',0};
1576     static const WCHAR wszSCRIPT[]   = {'S','C','R','I','P','T',0};
1577     static const WCHAR wszSELECT[]   = {'S','E','L','E','C','T',0};
1578     static const WCHAR wszTABLE[]    = {'T','A','B','L','E',0};
1579     static const WCHAR wszTR[]       = {'T','R',0};
1580     static const WCHAR wszTEXTAREA[] = {'T','E','X','T','A','R','E','A',0};
1581
1582     nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMHTMLElement, (void**)&nselem);
1583     if(NS_FAILED(nsres))
1584         return NULL;
1585
1586     nsAString_Init(&class_name_str, NULL);
1587     nsIDOMHTMLElement_GetTagName(nselem, &class_name_str);
1588
1589     nsAString_GetData(&class_name_str, &class_name);
1590
1591     if(!strcmpW(class_name, wszA))
1592         ret = HTMLAnchorElement_Create(doc, nselem);
1593     else if(!strcmpW(class_name, wszBODY))
1594         ret = HTMLBodyElement_Create(doc, nselem);
1595     else if(!strcmpW(class_name, wszFORM))
1596         ret = HTMLFormElement_Create(doc, nselem);
1597     else if(!strcmpW(class_name, wszIFRAME))
1598         ret = HTMLIFrame_Create(doc, nselem, NULL);
1599     else if(!strcmpW(class_name, wszIMG))
1600         ret = HTMLImgElement_Create(doc, nselem);
1601     else if(!strcmpW(class_name, wszINPUT))
1602         ret = HTMLInputElement_Create(doc, nselem);
1603     else if(!strcmpW(class_name, wszOPTION))
1604         ret = HTMLOptionElement_Create(doc, nselem);
1605     else if(!strcmpW(class_name, wszSCRIPT))
1606         ret = HTMLScriptElement_Create(doc, nselem);
1607     else if(!strcmpW(class_name, wszSELECT))
1608         ret = HTMLSelectElement_Create(doc, nselem);
1609     else if(!strcmpW(class_name, wszTABLE))
1610         ret = HTMLTable_Create(doc, nselem);
1611     else if(!strcmpW(class_name, wszTR))
1612         ret = HTMLTableRow_Create(doc, nselem);
1613     else if(!strcmpW(class_name, wszTEXTAREA))
1614         ret = HTMLTextAreaElement_Create(doc, nselem);
1615     else if(use_generic)
1616         ret = HTMLGenericElement_Create(doc, nselem);
1617
1618     if(!ret) {
1619         ret = heap_alloc_zero(sizeof(HTMLElement));
1620         HTMLElement_Init(ret, doc, nselem, NULL);
1621         ret->node.vtbl = &HTMLElementImplVtbl;
1622     }
1623
1624     TRACE("%s ret %p\n", debugstr_w(class_name), ret);
1625
1626     nsIDOMElement_Release(nselem);
1627     nsAString_Finish(&class_name_str);
1628
1629     return ret;
1630 }