mshtml: Added IHTMLElement::put_outerHTML implementation.
[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     *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->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     nsIDOMDocumentFragment *nsfragment;
912     nsIDOMDocumentRange *nsdocrange;
913     nsIDOMNSRange *nsrange;
914     nsIDOMNode *nsparent;
915     nsIDOMRange *range;
916     nsAString html_str;
917     nsresult nsres;
918     HRESULT hres = S_OK;
919
920     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
921
922     nsres = nsIDOMHTMLDocument_QueryInterface(This->node.doc->nsdoc, &IID_nsIDOMDocumentRange, (void**)&nsdocrange);
923     if(NS_FAILED(nsres))
924         return E_FAIL;
925
926     nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &range);
927     nsIDOMDocumentRange_Release(nsdocrange);
928     if(NS_FAILED(nsres)) {
929         ERR("CreateRange failed: %08x\n", nsres);
930         return E_FAIL;
931     }
932
933     nsres = nsIDOMRange_QueryInterface(range, &IID_nsIDOMNSRange, (void**)&nsrange);
934     nsIDOMRange_Release(range);
935     if(NS_FAILED(nsres)) {
936         ERR("Could not get nsIDOMNSRange: %08x\n", nsres);
937         return E_FAIL;
938     }
939
940     nsAString_Init(&html_str, v);
941     nsIDOMNSRange_CreateContextualFragment(nsrange, &html_str, &nsfragment);
942     nsIDOMNSRange_Release(nsrange);
943     nsAString_Finish(&html_str);
944     if(NS_FAILED(nsres)) {
945         ERR("CreateContextualFragment failed: %08x\n", nsres);
946         return E_FAIL;
947     }
948
949     nsres = nsIDOMNode_GetParentNode(This->node.nsnode, &nsparent);
950     if(NS_SUCCEEDED(nsres) && nsparent) {
951         nsIDOMNode *nstmp;
952
953         nsres = nsIDOMNode_ReplaceChild(nsparent, (nsIDOMNode*)nsfragment, This->node.nsnode, &nstmp);
954         nsIDOMNode_Release(nsparent);
955         if(NS_FAILED(nsres)) {
956             ERR("ReplaceChild failed: %08x\n", nsres);
957             hres = E_FAIL;
958         }else if(nstmp) {
959             nsIDOMNode_Release(nstmp);
960         }
961     }else {
962         ERR("GetParentNode failed: %08x\n", nsres);
963         hres = E_FAIL;
964     }
965
966     nsIDOMDocumentFragment_Release(nsfragment);
967     return hres;
968 }
969
970 static HRESULT WINAPI HTMLElement_get_outerHTML(IHTMLElement *iface, BSTR *p)
971 {
972     HTMLElement *This = HTMLELEM_THIS(iface);
973     nsAString html_str;
974     HRESULT hres;
975
976     WARN("(%p)->(%p) semi-stub\n", This, p);
977
978     nsAString_Init(&html_str, NULL);
979     hres = nsnode_to_nsstring(This->node.nsnode, &html_str);
980     if(SUCCEEDED(hres)) {
981         const PRUnichar *html;
982
983         nsAString_GetData(&html_str, &html);
984         *p = SysAllocString(html);
985         if(!*p)
986             hres = E_OUTOFMEMORY;
987     }
988
989     nsAString_Finish(&html_str);
990
991     TRACE("ret %s\n", debugstr_w(*p));
992     return S_OK;
993 }
994
995 static HRESULT WINAPI HTMLElement_put_outerText(IHTMLElement *iface, BSTR v)
996 {
997     HTMLElement *This = HTMLELEM_THIS(iface);
998     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
999     return E_NOTIMPL;
1000 }
1001
1002 static HRESULT WINAPI HTMLElement_get_outerText(IHTMLElement *iface, BSTR *p)
1003 {
1004     HTMLElement *This = HTMLELEM_THIS(iface);
1005     FIXME("(%p)->(%p)\n", This, p);
1006     return E_NOTIMPL;
1007 }
1008
1009 static HRESULT HTMLElement_InsertAdjacentNode(HTMLElement *This, BSTR where, nsIDOMNode *nsnode)
1010 {
1011     static const WCHAR wszBeforeBegin[] = {'b','e','f','o','r','e','B','e','g','i','n',0};
1012     static const WCHAR wszAfterBegin[] = {'a','f','t','e','r','B','e','g','i','n',0};
1013     static const WCHAR wszBeforeEnd[] = {'b','e','f','o','r','e','E','n','d',0};
1014     static const WCHAR wszAfterEnd[] = {'a','f','t','e','r','E','n','d',0};
1015     nsresult nsres;
1016
1017     if(!This->nselem) {
1018         FIXME("NULL nselem\n");
1019         return E_NOTIMPL;
1020     }
1021
1022     if (!strcmpiW(where, wszBeforeBegin))
1023     {
1024         nsIDOMNode *unused;
1025         nsIDOMNode *parent;
1026         nsres = nsIDOMNode_GetParentNode(This->nselem, &parent);
1027         if (!parent) return E_INVALIDARG;
1028         nsres = nsIDOMNode_InsertBefore(parent, nsnode,
1029                                         (nsIDOMNode *)This->nselem, &unused);
1030         if (unused) nsIDOMNode_Release(unused);
1031         nsIDOMNode_Release(parent);
1032     }
1033     else if (!strcmpiW(where, wszAfterBegin))
1034     {
1035         nsIDOMNode *unused;
1036         nsIDOMNode *first_child;
1037         nsIDOMNode_GetFirstChild(This->nselem, &first_child);
1038         nsres = nsIDOMNode_InsertBefore(This->nselem, nsnode, first_child, &unused);
1039         if (unused) nsIDOMNode_Release(unused);
1040         if (first_child) nsIDOMNode_Release(first_child);
1041     }
1042     else if (!strcmpiW(where, wszBeforeEnd))
1043     {
1044         nsIDOMNode *unused;
1045         nsres = nsIDOMNode_AppendChild(This->nselem, nsnode, &unused);
1046         if (unused) nsIDOMNode_Release(unused);
1047     }
1048     else if (!strcmpiW(where, wszAfterEnd))
1049     {
1050         nsIDOMNode *unused;
1051         nsIDOMNode *next_sibling;
1052         nsIDOMNode *parent;
1053         nsIDOMNode_GetParentNode(This->nselem, &parent);
1054         if (!parent) return E_INVALIDARG;
1055
1056         nsIDOMNode_GetNextSibling(This->nselem, &next_sibling);
1057         if (next_sibling)
1058         {
1059             nsres = nsIDOMNode_InsertBefore(parent, nsnode, next_sibling, &unused);
1060             nsIDOMNode_Release(next_sibling);
1061         }
1062         else
1063             nsres = nsIDOMNode_AppendChild(parent, nsnode, &unused);
1064         nsIDOMNode_Release(parent);
1065         if (unused) nsIDOMNode_Release(unused);
1066     }
1067     else
1068     {
1069         ERR("invalid where: %s\n", debugstr_w(where));
1070         return E_INVALIDARG;
1071     }
1072
1073     if (NS_FAILED(nsres))
1074         return E_FAIL;
1075     else
1076         return S_OK;
1077 }
1078
1079 static HRESULT WINAPI HTMLElement_insertAdjacentHTML(IHTMLElement *iface, BSTR where,
1080                                                      BSTR html)
1081 {
1082     HTMLElement *This = HTMLELEM_THIS(iface);
1083     nsIDOMDocumentRange *nsdocrange;
1084     nsIDOMRange *range;
1085     nsIDOMNSRange *nsrange;
1086     nsIDOMNode *nsnode;
1087     nsAString ns_html;
1088     nsresult nsres;
1089     HRESULT hr;
1090
1091     TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(html));
1092
1093     if(!This->node.doc->nsdoc) {
1094         WARN("NULL nsdoc\n");
1095         return E_UNEXPECTED;
1096     }
1097
1098     nsres = nsIDOMDocument_QueryInterface(This->node.doc->nsdoc, &IID_nsIDOMDocumentRange, (void **)&nsdocrange);
1099     if(NS_FAILED(nsres))
1100     {
1101         ERR("getting nsIDOMDocumentRange failed: %08x\n", nsres);
1102         return E_FAIL;
1103     }
1104     nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &range);
1105     nsIDOMDocumentRange_Release(nsdocrange);
1106     if(NS_FAILED(nsres))
1107     {
1108         ERR("CreateRange failed: %08x\n", nsres);
1109         return E_FAIL;
1110     }
1111
1112     nsIDOMRange_SetStartBefore(range, (nsIDOMNode *)This->nselem);
1113
1114     nsIDOMRange_QueryInterface(range, &IID_nsIDOMNSRange, (void **)&nsrange);
1115     nsIDOMRange_Release(range);
1116     if(NS_FAILED(nsres))
1117     {
1118         ERR("getting nsIDOMNSRange failed: %08x\n", nsres);
1119         return E_FAIL;
1120     }
1121
1122     nsAString_Init(&ns_html, html);
1123
1124     nsres = nsIDOMNSRange_CreateContextualFragment(nsrange, &ns_html, (nsIDOMDocumentFragment **)&nsnode);
1125     nsIDOMNSRange_Release(nsrange);
1126     nsAString_Finish(&ns_html);
1127
1128     if(NS_FAILED(nsres) || !nsnode)
1129     {
1130         ERR("CreateTextNode failed: %08x\n", nsres);
1131         return E_FAIL;
1132     }
1133
1134     hr = HTMLElement_InsertAdjacentNode(This, where, nsnode);
1135     nsIDOMNode_Release(nsnode);
1136
1137     return hr;
1138 }
1139
1140 static HRESULT WINAPI HTMLElement_insertAdjacentText(IHTMLElement *iface, BSTR where,
1141                                                      BSTR text)
1142 {
1143     HTMLElement *This = HTMLELEM_THIS(iface);
1144     nsIDOMNode *nsnode;
1145     nsAString ns_text;
1146     nsresult nsres;
1147     HRESULT hr;
1148
1149     TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(text));
1150
1151     if(!This->node.doc->nsdoc) {
1152         WARN("NULL nsdoc\n");
1153         return E_UNEXPECTED;
1154     }
1155
1156
1157     nsAString_Init(&ns_text, text);
1158     nsres = nsIDOMDocument_CreateTextNode(This->node.doc->nsdoc, &ns_text, (nsIDOMText **)&nsnode);
1159     nsAString_Finish(&ns_text);
1160
1161     if(NS_FAILED(nsres) || !nsnode)
1162     {
1163         ERR("CreateTextNode failed: %08x\n", nsres);
1164         return E_FAIL;
1165     }
1166
1167     hr = HTMLElement_InsertAdjacentNode(This, where, nsnode);
1168     nsIDOMNode_Release(nsnode);
1169
1170     return hr;
1171 }
1172
1173 static HRESULT WINAPI HTMLElement_get_parentTextEdit(IHTMLElement *iface, IHTMLElement **p)
1174 {
1175     HTMLElement *This = HTMLELEM_THIS(iface);
1176     FIXME("(%p)->(%p)\n", This, p);
1177     return E_NOTIMPL;
1178 }
1179
1180 static HRESULT WINAPI HTMLElement_get_isTextEdit(IHTMLElement *iface, VARIANT_BOOL *p)
1181 {
1182     HTMLElement *This = HTMLELEM_THIS(iface);
1183     FIXME("(%p)->(%p)\n", This, p);
1184     return E_NOTIMPL;
1185 }
1186
1187 static HRESULT WINAPI HTMLElement_click(IHTMLElement *iface)
1188 {
1189     HTMLElement *This = HTMLELEM_THIS(iface);
1190
1191     TRACE("(%p)\n", This);
1192
1193     return call_event(&This->node, EVENTID_CLICK);
1194 }
1195
1196 static HRESULT WINAPI HTMLElement_get_filters(IHTMLElement *iface,
1197                                               IHTMLFiltersCollection **p)
1198 {
1199     HTMLElement *This = HTMLELEM_THIS(iface);
1200     FIXME("(%p)->(%p)\n", This, p);
1201     return E_NOTIMPL;
1202 }
1203
1204 static HRESULT WINAPI HTMLElement_put_ondragstart(IHTMLElement *iface, VARIANT v)
1205 {
1206     HTMLElement *This = HTMLELEM_THIS(iface);
1207     FIXME("(%p)->()\n", This);
1208     return E_NOTIMPL;
1209 }
1210
1211 static HRESULT WINAPI HTMLElement_get_ondragstart(IHTMLElement *iface, VARIANT *p)
1212 {
1213     HTMLElement *This = HTMLELEM_THIS(iface);
1214     FIXME("(%p)->(%p)\n", This, p);
1215     return E_NOTIMPL;
1216 }
1217
1218 static HRESULT WINAPI HTMLElement_toString(IHTMLElement *iface, BSTR *String)
1219 {
1220     HTMLElement *This = HTMLELEM_THIS(iface);
1221     FIXME("(%p)->(%p)\n", This, String);
1222     return E_NOTIMPL;
1223 }
1224
1225 static HRESULT WINAPI HTMLElement_put_onbeforeupdate(IHTMLElement *iface, VARIANT v)
1226 {
1227     HTMLElement *This = HTMLELEM_THIS(iface);
1228     FIXME("(%p)->()\n", This);
1229     return E_NOTIMPL;
1230 }
1231
1232 static HRESULT WINAPI HTMLElement_get_onbeforeupdate(IHTMLElement *iface, VARIANT *p)
1233 {
1234     HTMLElement *This = HTMLELEM_THIS(iface);
1235     FIXME("(%p)->(%p)\n", This, p);
1236     return E_NOTIMPL;
1237 }
1238
1239 static HRESULT WINAPI HTMLElement_put_onafterupdate(IHTMLElement *iface, VARIANT v)
1240 {
1241     HTMLElement *This = HTMLELEM_THIS(iface);
1242     FIXME("(%p)->()\n", This);
1243     return E_NOTIMPL;
1244 }
1245
1246 static HRESULT WINAPI HTMLElement_get_onafterupdate(IHTMLElement *iface, VARIANT *p)
1247 {
1248     HTMLElement *This = HTMLELEM_THIS(iface);
1249     FIXME("(%p)->(%p)\n", This, p);
1250     return E_NOTIMPL;
1251 }
1252
1253 static HRESULT WINAPI HTMLElement_put_onerrorupdate(IHTMLElement *iface, VARIANT v)
1254 {
1255     HTMLElement *This = HTMLELEM_THIS(iface);
1256     FIXME("(%p)->()\n", This);
1257     return E_NOTIMPL;
1258 }
1259
1260 static HRESULT WINAPI HTMLElement_get_onerrorupdate(IHTMLElement *iface, VARIANT *p)
1261 {
1262     HTMLElement *This = HTMLELEM_THIS(iface);
1263     FIXME("(%p)->(%p)\n", This, p);
1264     return E_NOTIMPL;
1265 }
1266
1267 static HRESULT WINAPI HTMLElement_put_onrowexit(IHTMLElement *iface, VARIANT v)
1268 {
1269     HTMLElement *This = HTMLELEM_THIS(iface);
1270     FIXME("(%p)->()\n", This);
1271     return E_NOTIMPL;
1272 }
1273
1274 static HRESULT WINAPI HTMLElement_get_onrowexit(IHTMLElement *iface, VARIANT *p)
1275 {
1276     HTMLElement *This = HTMLELEM_THIS(iface);
1277     FIXME("(%p)->(%p)\n", This, p);
1278     return E_NOTIMPL;
1279 }
1280
1281 static HRESULT WINAPI HTMLElement_put_onrowenter(IHTMLElement *iface, VARIANT v)
1282 {
1283     HTMLElement *This = HTMLELEM_THIS(iface);
1284     FIXME("(%p)->()\n", This);
1285     return E_NOTIMPL;
1286 }
1287
1288 static HRESULT WINAPI HTMLElement_get_onrowenter(IHTMLElement *iface, VARIANT *p)
1289 {
1290     HTMLElement *This = HTMLELEM_THIS(iface);
1291     FIXME("(%p)->(%p)\n", This, p);
1292     return E_NOTIMPL;
1293 }
1294
1295 static HRESULT WINAPI HTMLElement_put_ondatasetchanged(IHTMLElement *iface, VARIANT v)
1296 {
1297     HTMLElement *This = HTMLELEM_THIS(iface);
1298     FIXME("(%p)->()\n", This);
1299     return E_NOTIMPL;
1300 }
1301
1302 static HRESULT WINAPI HTMLElement_get_ondatasetchanged(IHTMLElement *iface, VARIANT *p)
1303 {
1304     HTMLElement *This = HTMLELEM_THIS(iface);
1305     FIXME("(%p)->(%p)\n", This, p);
1306     return E_NOTIMPL;
1307 }
1308
1309 static HRESULT WINAPI HTMLElement_put_ondataavailable(IHTMLElement *iface, VARIANT v)
1310 {
1311     HTMLElement *This = HTMLELEM_THIS(iface);
1312     FIXME("(%p)->()\n", This);
1313     return E_NOTIMPL;
1314 }
1315
1316 static HRESULT WINAPI HTMLElement_get_ondataavailable(IHTMLElement *iface, VARIANT *p)
1317 {
1318     HTMLElement *This = HTMLELEM_THIS(iface);
1319     FIXME("(%p)->(%p)\n", This, p);
1320     return E_NOTIMPL;
1321 }
1322
1323 static HRESULT WINAPI HTMLElement_put_ondatasetcomplete(IHTMLElement *iface, VARIANT v)
1324 {
1325     HTMLElement *This = HTMLELEM_THIS(iface);
1326     FIXME("(%p)->()\n", This);
1327     return E_NOTIMPL;
1328 }
1329
1330 static HRESULT WINAPI HTMLElement_get_ondatasetcomplete(IHTMLElement *iface, VARIANT *p)
1331 {
1332     HTMLElement *This = HTMLELEM_THIS(iface);
1333     FIXME("(%p)->(%p)\n", This, p);
1334     return E_NOTIMPL;
1335 }
1336
1337 static HRESULT WINAPI HTMLElement_put_onfilterchange(IHTMLElement *iface, VARIANT v)
1338 {
1339     HTMLElement *This = HTMLELEM_THIS(iface);
1340     FIXME("(%p)->()\n", This);
1341     return E_NOTIMPL;
1342 }
1343
1344 static HRESULT WINAPI HTMLElement_get_onfilterchange(IHTMLElement *iface, VARIANT *p)
1345 {
1346     HTMLElement *This = HTMLELEM_THIS(iface);
1347     FIXME("(%p)->(%p)\n", This, p);
1348     return E_NOTIMPL;
1349 }
1350
1351 static HRESULT WINAPI HTMLElement_get_children(IHTMLElement *iface, IDispatch **p)
1352 {
1353     HTMLElement *This = HTMLELEM_THIS(iface);
1354     nsIDOMNodeList *nsnode_list;
1355     nsresult nsres;
1356
1357     TRACE("(%p)->(%p)\n", This, p);
1358
1359     nsres = nsIDOMNode_GetChildNodes(This->node.nsnode, &nsnode_list);
1360     if(NS_FAILED(nsres)) {
1361         ERR("GetChildNodes failed: %08x\n", nsres);
1362         return E_FAIL;
1363     }
1364
1365     *p = (IDispatch*)create_collection_from_nodelist(This->node.doc, (IUnknown*)HTMLELEM(This), nsnode_list);
1366
1367     nsIDOMNodeList_Release(nsnode_list);
1368     return S_OK;
1369 }
1370
1371 static HRESULT WINAPI HTMLElement_get_all(IHTMLElement *iface, IDispatch **p)
1372 {
1373     HTMLElement *This = HTMLELEM_THIS(iface);
1374
1375     TRACE("(%p)->(%p)\n", This, p);
1376
1377     *p = (IDispatch*)create_all_collection(&This->node, FALSE);
1378     return S_OK;
1379 }
1380
1381 #undef HTMLELEM_THIS
1382
1383 static const IHTMLElementVtbl HTMLElementVtbl = {
1384     HTMLElement_QueryInterface,
1385     HTMLElement_AddRef,
1386     HTMLElement_Release,
1387     HTMLElement_GetTypeInfoCount,
1388     HTMLElement_GetTypeInfo,
1389     HTMLElement_GetIDsOfNames,
1390     HTMLElement_Invoke,
1391     HTMLElement_setAttribute,
1392     HTMLElement_getAttribute,
1393     HTMLElement_removeAttribute,
1394     HTMLElement_put_className,
1395     HTMLElement_get_className,
1396     HTMLElement_put_id,
1397     HTMLElement_get_id,
1398     HTMLElement_get_tagName,
1399     HTMLElement_get_parentElement,
1400     HTMLElement_get_style,
1401     HTMLElement_put_onhelp,
1402     HTMLElement_get_onhelp,
1403     HTMLElement_put_onclick,
1404     HTMLElement_get_onclick,
1405     HTMLElement_put_ondblclick,
1406     HTMLElement_get_ondblclick,
1407     HTMLElement_put_onkeydown,
1408     HTMLElement_get_onkeydown,
1409     HTMLElement_put_onkeyup,
1410     HTMLElement_get_onkeyup,
1411     HTMLElement_put_onkeypress,
1412     HTMLElement_get_onkeypress,
1413     HTMLElement_put_onmouseout,
1414     HTMLElement_get_onmouseout,
1415     HTMLElement_put_onmouseover,
1416     HTMLElement_get_onmouseover,
1417     HTMLElement_put_onmousemove,
1418     HTMLElement_get_onmousemove,
1419     HTMLElement_put_onmousedown,
1420     HTMLElement_get_onmousedown,
1421     HTMLElement_put_onmouseup,
1422     HTMLElement_get_onmouseup,
1423     HTMLElement_get_document,
1424     HTMLElement_put_title,
1425     HTMLElement_get_title,
1426     HTMLElement_put_language,
1427     HTMLElement_get_language,
1428     HTMLElement_put_onselectstart,
1429     HTMLElement_get_onselectstart,
1430     HTMLElement_scrollIntoView,
1431     HTMLElement_contains,
1432     HTMLElement_get_sourceIndex,
1433     HTMLElement_get_recordNumber,
1434     HTMLElement_put_lang,
1435     HTMLElement_get_lang,
1436     HTMLElement_get_offsetLeft,
1437     HTMLElement_get_offsetTop,
1438     HTMLElement_get_offsetWidth,
1439     HTMLElement_get_offsetHeight,
1440     HTMLElement_get_offsetParent,
1441     HTMLElement_put_innerHTML,
1442     HTMLElement_get_innerHTML,
1443     HTMLElement_put_innerText,
1444     HTMLElement_get_innerText,
1445     HTMLElement_put_outerHTML,
1446     HTMLElement_get_outerHTML,
1447     HTMLElement_put_outerText,
1448     HTMLElement_get_outerText,
1449     HTMLElement_insertAdjacentHTML,
1450     HTMLElement_insertAdjacentText,
1451     HTMLElement_get_parentTextEdit,
1452     HTMLElement_get_isTextEdit,
1453     HTMLElement_click,
1454     HTMLElement_get_filters,
1455     HTMLElement_put_ondragstart,
1456     HTMLElement_get_ondragstart,
1457     HTMLElement_toString,
1458     HTMLElement_put_onbeforeupdate,
1459     HTMLElement_get_onbeforeupdate,
1460     HTMLElement_put_onafterupdate,
1461     HTMLElement_get_onafterupdate,
1462     HTMLElement_put_onerrorupdate,
1463     HTMLElement_get_onerrorupdate,
1464     HTMLElement_put_onrowexit,
1465     HTMLElement_get_onrowexit,
1466     HTMLElement_put_onrowenter,
1467     HTMLElement_get_onrowenter,
1468     HTMLElement_put_ondatasetchanged,
1469     HTMLElement_get_ondatasetchanged,
1470     HTMLElement_put_ondataavailable,
1471     HTMLElement_get_ondataavailable,
1472     HTMLElement_put_ondatasetcomplete,
1473     HTMLElement_get_ondatasetcomplete,
1474     HTMLElement_put_onfilterchange,
1475     HTMLElement_get_onfilterchange,
1476     HTMLElement_get_children,
1477     HTMLElement_get_all
1478 };
1479
1480 HRESULT HTMLElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
1481 {
1482     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
1483
1484     *ppv =  NULL;
1485
1486     if(IsEqualGUID(&IID_IUnknown, riid)) {
1487         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1488         *ppv = HTMLELEM(This);
1489     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1490         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
1491         *ppv = HTMLELEM(This);
1492     }else if(IsEqualGUID(&IID_IHTMLElement, riid)) {
1493         TRACE("(%p)->(IID_IHTMLElement %p)\n", This, ppv);
1494         *ppv = HTMLELEM(This);
1495     }else if(IsEqualGUID(&IID_IHTMLElement2, riid)) {
1496         TRACE("(%p)->(IID_IHTMLElement2 %p)\n", This, ppv);
1497         *ppv = HTMLELEM2(This);
1498     }else if(IsEqualGUID(&IID_IHTMLElement3, riid)) {
1499         TRACE("(%p)->(IID_IHTMLElement3 %p)\n", This, ppv);
1500         *ppv = HTMLELEM3(This);
1501     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
1502         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
1503         *ppv = CONPTCONT(&This->cp_container);
1504     }
1505
1506     if(*ppv) {
1507         IHTMLElement_AddRef(HTMLELEM(This));
1508         return S_OK;
1509     }
1510
1511     return HTMLDOMNode_QI(&This->node, riid, ppv);
1512 }
1513
1514 void HTMLElement_destructor(HTMLDOMNode *iface)
1515 {
1516     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
1517
1518     ConnectionPointContainer_Destroy(&This->cp_container);
1519
1520     if(This->nselem)
1521         nsIDOMHTMLElement_Release(This->nselem);
1522
1523     HTMLDOMNode_destructor(&This->node);
1524 }
1525
1526 static const NodeImplVtbl HTMLElementImplVtbl = {
1527     HTMLElement_QI,
1528     HTMLElement_destructor
1529 };
1530
1531 static const tid_t HTMLElement_iface_tids[] = {
1532     IHTMLDOMNode_tid,
1533     IHTMLDOMNode2_tid,
1534     IHTMLElement_tid,
1535     IHTMLElement2_tid,
1536     IHTMLElement3_tid,
1537     0
1538 };
1539
1540 static dispex_static_data_t HTMLElement_dispex = {
1541     NULL,
1542     DispHTMLUnknownElement_tid,
1543     NULL,
1544     HTMLElement_iface_tids
1545 };
1546
1547 void HTMLElement_Init(HTMLElement *This, HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, dispex_static_data_t *dispex_data)
1548 {
1549     This->lpHTMLElementVtbl = &HTMLElementVtbl;
1550
1551     HTMLElement2_Init(This);
1552     HTMLElement3_Init(This);
1553
1554     init_dispex(&This->node.dispex, (IUnknown*)HTMLELEM(This), dispex_data ? dispex_data : &HTMLElement_dispex);
1555
1556     if(nselem)
1557         nsIDOMHTMLElement_AddRef(nselem);
1558     This->nselem = nselem;
1559
1560     HTMLDOMNode_Init(doc, &This->node, (nsIDOMNode*)nselem);
1561
1562     ConnectionPointContainer_Init(&This->cp_container, (IUnknown*)HTMLELEM(This));
1563 }
1564
1565 HTMLElement *HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL use_generic)
1566 {
1567     nsIDOMHTMLElement *nselem;
1568     HTMLElement *ret = NULL;
1569     nsAString class_name_str;
1570     const PRUnichar *class_name;
1571     nsresult nsres;
1572
1573     static const WCHAR wszA[]        = {'A',0};
1574     static const WCHAR wszBODY[]     = {'B','O','D','Y',0};
1575     static const WCHAR wszIFRAME[]   = {'I','F','R','A','M','E',0};
1576     static const WCHAR wszIMG[]      = {'I','M','G',0};
1577     static const WCHAR wszINPUT[]    = {'I','N','P','U','T',0};
1578     static const WCHAR wszOPTION[]   = {'O','P','T','I','O','N',0};
1579     static const WCHAR wszSCRIPT[]   = {'S','C','R','I','P','T',0};
1580     static const WCHAR wszSELECT[]   = {'S','E','L','E','C','T',0};
1581     static const WCHAR wszTABLE[]    = {'T','A','B','L','E',0};
1582     static const WCHAR wszTR[]       = {'T','R',0};
1583     static const WCHAR wszTEXTAREA[] = {'T','E','X','T','A','R','E','A',0};
1584
1585     nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMHTMLElement, (void**)&nselem);
1586     if(NS_FAILED(nsres))
1587         return NULL;
1588
1589     nsAString_Init(&class_name_str, NULL);
1590     nsIDOMHTMLElement_GetTagName(nselem, &class_name_str);
1591
1592     nsAString_GetData(&class_name_str, &class_name);
1593
1594     if(!strcmpW(class_name, wszA))
1595         ret = HTMLAnchorElement_Create(doc, nselem);
1596     else if(!strcmpW(class_name, wszBODY))
1597         ret = HTMLBodyElement_Create(doc, nselem);
1598     else if(!strcmpW(class_name, wszIFRAME))
1599         ret = HTMLIFrame_Create(doc, nselem, NULL);
1600     else if(!strcmpW(class_name, wszIMG))
1601         ret = HTMLImgElement_Create(doc, nselem);
1602     else if(!strcmpW(class_name, wszINPUT))
1603         ret = HTMLInputElement_Create(doc, nselem);
1604     else if(!strcmpW(class_name, wszOPTION))
1605         ret = HTMLOptionElement_Create(doc, nselem);
1606     else if(!strcmpW(class_name, wszSCRIPT))
1607         ret = HTMLScriptElement_Create(doc, nselem);
1608     else if(!strcmpW(class_name, wszSELECT))
1609         ret = HTMLSelectElement_Create(doc, nselem);
1610     else if(!strcmpW(class_name, wszTABLE))
1611         ret = HTMLTable_Create(doc, nselem);
1612     else if(!strcmpW(class_name, wszTR))
1613         ret = HTMLTableRow_Create(doc, nselem);
1614     else if(!strcmpW(class_name, wszTEXTAREA))
1615         ret = HTMLTextAreaElement_Create(doc, nselem);
1616     else if(use_generic)
1617         ret = HTMLGenericElement_Create(doc, nselem);
1618
1619     if(!ret) {
1620         ret = heap_alloc_zero(sizeof(HTMLElement));
1621         HTMLElement_Init(ret, doc, nselem, NULL);
1622         ret->node.vtbl = &HTMLElementImplVtbl;
1623     }
1624
1625     TRACE("%s ret %p\n", debugstr_w(class_name), ret);
1626
1627     nsIDOMElement_Release(nselem);
1628     nsAString_Finish(&class_name_str);
1629
1630     return ret;
1631 }