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