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