mshtml: Use stored nsdoc in IHTMLElement::insertAdjacentHTML.
[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     nsIDOMNSHTMLElement *nselem;
711     PRInt32 offset = 0;
712     nsresult nsres;
713
714     TRACE("(%p)->(%p)\n", This, p);
715
716     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
717     if(NS_FAILED(nsres)) {
718         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
719         return E_FAIL;
720     }
721
722     nsres = nsIDOMNSHTMLElement_GetOffsetWidth(nselem, &offset);
723     nsIDOMNSHTMLElement_Release(nselem);
724     if(NS_FAILED(nsres)) {
725         ERR("GetOffsetWidth failed: %08x\n", nsres);
726         return E_FAIL;
727     }
728
729     *p = offset;
730     return S_OK;
731 }
732
733 static HRESULT WINAPI HTMLElement_get_offsetHeight(IHTMLElement *iface, long *p)
734 {
735     HTMLElement *This = HTMLELEM_THIS(iface);
736     nsIDOMNSHTMLElement *nselem;
737     PRInt32 offset = 0;
738     nsresult nsres;
739
740     TRACE("(%p)->(%p)\n", This, p);
741
742     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
743     if(NS_FAILED(nsres)) {
744         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
745         return E_FAIL;
746     }
747
748     nsres = nsIDOMNSHTMLElement_GetOffsetHeight(nselem, &offset);
749     nsIDOMNSHTMLElement_Release(nselem);
750     if(NS_FAILED(nsres)) {
751         ERR("GetOffsetHeight failed: %08x\n", nsres);
752         return E_FAIL;
753     }
754
755     *p = offset;
756     return S_OK;
757 }
758
759 static HRESULT WINAPI HTMLElement_get_offsetParent(IHTMLElement *iface, IHTMLElement **p)
760 {
761     HTMLElement *This = HTMLELEM_THIS(iface);
762     FIXME("(%p)->(%p)\n", This, p);
763     return E_NOTIMPL;
764 }
765
766 static HRESULT WINAPI HTMLElement_put_innerHTML(IHTMLElement *iface, BSTR v)
767 {
768     HTMLElement *This = HTMLELEM_THIS(iface);
769     nsIDOMNSHTMLElement *nselem;
770     nsAString html_str;
771     nsresult nsres;
772
773     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
774
775     if(!This->nselem) {
776         FIXME("NULL nselem\n");
777         return E_NOTIMPL;
778     }
779
780     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
781     if(NS_FAILED(nsres)) {
782         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
783         return E_FAIL;
784     }
785
786     nsAString_Init(&html_str, v);
787     nsres = nsIDOMNSHTMLElement_SetInnerHTML(nselem, &html_str);
788     nsAString_Finish(&html_str);
789
790     if(NS_FAILED(nsres)) {
791         FIXME("SetInnerHtml failed %08x\n", nsres);
792         return E_FAIL;
793     }
794
795     return S_OK;
796 }
797
798 static HRESULT WINAPI HTMLElement_get_innerHTML(IHTMLElement *iface, BSTR *p)
799 {
800     HTMLElement *This = HTMLELEM_THIS(iface);
801     FIXME("(%p)->(%p)\n", This, p);
802     return E_NOTIMPL;
803 }
804
805 static HRESULT WINAPI HTMLElement_put_innerText(IHTMLElement *iface, BSTR v)
806 {
807     HTMLElement *This = HTMLELEM_THIS(iface);
808     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
809     return E_NOTIMPL;
810 }
811
812 static HRESULT WINAPI HTMLElement_get_innerText(IHTMLElement *iface, BSTR *p)
813 {
814     HTMLElement *This = HTMLELEM_THIS(iface);
815     FIXME("(%p)->(%p)\n", This, p);
816     return E_NOTIMPL;
817 }
818
819 static HRESULT WINAPI HTMLElement_put_outerHTML(IHTMLElement *iface, BSTR v)
820 {
821     HTMLElement *This = HTMLELEM_THIS(iface);
822     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
823     return E_NOTIMPL;
824 }
825
826 static HRESULT WINAPI HTMLElement_get_outerHTML(IHTMLElement *iface, BSTR *p)
827 {
828     HTMLElement *This = HTMLELEM_THIS(iface);
829     FIXME("(%p)->(%p)\n", This, p);
830     return E_NOTIMPL;
831 }
832
833 static HRESULT WINAPI HTMLElement_put_outerText(IHTMLElement *iface, BSTR v)
834 {
835     HTMLElement *This = HTMLELEM_THIS(iface);
836     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
837     return E_NOTIMPL;
838 }
839
840 static HRESULT WINAPI HTMLElement_get_outerText(IHTMLElement *iface, BSTR *p)
841 {
842     HTMLElement *This = HTMLELEM_THIS(iface);
843     FIXME("(%p)->(%p)\n", This, p);
844     return E_NOTIMPL;
845 }
846
847 static HRESULT HTMLElement_InsertAdjacentNode(HTMLElement *This, BSTR where, nsIDOMNode *nsnode)
848 {
849     static const WCHAR wszBeforeBegin[] = {'b','e','f','o','r','e','B','e','g','i','n',0};
850     static const WCHAR wszAfterBegin[] = {'a','f','t','e','r','B','e','g','i','n',0};
851     static const WCHAR wszBeforeEnd[] = {'b','e','f','o','r','e','E','n','d',0};
852     static const WCHAR wszAfterEnd[] = {'a','f','t','e','r','E','n','d',0};
853     nsresult nsres;
854
855     if(!This->nselem) {
856         FIXME("NULL nselem\n");
857         return E_NOTIMPL;
858     }
859
860     if (!strcmpiW(where, wszBeforeBegin))
861     {
862         nsIDOMNode *unused;
863         nsIDOMNode *parent;
864         nsres = nsIDOMNode_GetParentNode(This->nselem, &parent);
865         if (!parent) return E_INVALIDARG;
866         nsres = nsIDOMNode_InsertBefore(parent, nsnode,
867                                         (nsIDOMNode *)This->nselem, &unused);
868         if (unused) nsIDOMNode_Release(unused);
869         nsIDOMNode_Release(parent);
870     }
871     else if (!strcmpiW(where, wszAfterBegin))
872     {
873         nsIDOMNode *unused;
874         nsIDOMNode *first_child;
875         nsIDOMNode_GetFirstChild(This->nselem, &first_child);
876         nsres = nsIDOMNode_InsertBefore(This->nselem, nsnode, first_child, &unused);
877         if (unused) nsIDOMNode_Release(unused);
878         if (first_child) nsIDOMNode_Release(first_child);
879     }
880     else if (!strcmpiW(where, wszBeforeEnd))
881     {
882         nsIDOMNode *unused;
883         nsres = nsIDOMNode_AppendChild(This->nselem, nsnode, &unused);
884         if (unused) nsIDOMNode_Release(unused);
885     }
886     else if (!strcmpiW(where, wszAfterEnd))
887     {
888         nsIDOMNode *unused;
889         nsIDOMNode *next_sibling;
890         nsIDOMNode *parent;
891         nsIDOMNode_GetParentNode(This->nselem, &parent);
892         if (!parent) return E_INVALIDARG;
893
894         nsIDOMNode_GetNextSibling(This->nselem, &next_sibling);
895         if (next_sibling)
896         {
897             nsres = nsIDOMNode_InsertBefore(parent, nsnode, next_sibling, &unused);
898             nsIDOMNode_Release(next_sibling);
899         }
900         else
901             nsres = nsIDOMNode_AppendChild(parent, nsnode, &unused);
902         nsIDOMNode_Release(parent);
903         if (unused) nsIDOMNode_Release(unused);
904     }
905     else
906     {
907         ERR("invalid where: %s\n", debugstr_w(where));
908         return E_INVALIDARG;
909     }
910
911     if (NS_FAILED(nsres))
912         return E_FAIL;
913     else
914         return S_OK;
915 }
916
917 static HRESULT WINAPI HTMLElement_insertAdjacentHTML(IHTMLElement *iface, BSTR where,
918                                                      BSTR html)
919 {
920     HTMLElement *This = HTMLELEM_THIS(iface);
921     nsIDOMDocumentRange *nsdocrange;
922     nsIDOMRange *range;
923     nsIDOMNSRange *nsrange;
924     nsIDOMNode *nsnode;
925     nsAString ns_html;
926     nsresult nsres;
927     HRESULT hr;
928
929     TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(html));
930
931     if(!This->node.doc->nsdoc) {
932         WARN("NULL nsdoc\n");
933         return E_UNEXPECTED;
934     }
935
936     nsres = nsIDOMDocument_QueryInterface(This->node.doc->nsdoc, &IID_nsIDOMDocumentRange, (void **)&nsdocrange);
937     if(NS_FAILED(nsres))
938     {
939         ERR("getting nsIDOMDocumentRange failed: %08x\n", nsres);
940         return E_FAIL;
941     }
942     nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &range);
943     nsIDOMDocumentRange_Release(nsdocrange);
944     if(NS_FAILED(nsres))
945     {
946         ERR("CreateRange failed: %08x\n", nsres);
947         return E_FAIL;
948     }
949
950     nsIDOMRange_SetStartBefore(range, (nsIDOMNode *)This->nselem);
951
952     nsIDOMRange_QueryInterface(range, &IID_nsIDOMNSRange, (void **)&nsrange);
953     nsIDOMRange_Release(range);
954     if(NS_FAILED(nsres))
955     {
956         ERR("getting nsIDOMNSRange failed: %08x\n", nsres);
957         return E_FAIL;
958     }
959
960     nsAString_Init(&ns_html, html);
961
962     nsres = nsIDOMNSRange_CreateContextualFragment(nsrange, &ns_html, (nsIDOMDocumentFragment **)&nsnode);
963     nsIDOMNSRange_Release(nsrange);
964     nsAString_Finish(&ns_html);
965
966     if(NS_FAILED(nsres) || !nsnode)
967     {
968         ERR("CreateTextNode failed: %08x\n", nsres);
969         return E_FAIL;
970     }
971
972     hr = HTMLElement_InsertAdjacentNode(This, where, nsnode);
973     nsIDOMNode_Release(nsnode);
974
975     return hr;
976 }
977
978 static HRESULT WINAPI HTMLElement_insertAdjacentText(IHTMLElement *iface, BSTR where,
979                                                      BSTR text)
980 {
981     HTMLElement *This = HTMLELEM_THIS(iface);
982     nsresult nsres;
983     nsIDOMDocument *nsdoc;
984     nsIDOMNode *nsnode;
985     nsAString ns_text;
986     HRESULT hr;
987
988     TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(text));
989
990     nsres = nsIWebNavigation_GetDocument(This->node.doc->nscontainer->navigation, &nsdoc);
991     if(NS_FAILED(nsres) || !nsdoc)
992     {
993         ERR("GetDocument failed: %08x\n", nsres);
994         return E_FAIL;
995     }
996
997     nsAString_Init(&ns_text, text);
998
999     nsres = nsIDOMDocument_CreateTextNode(nsdoc, &ns_text, (nsIDOMText **)&nsnode);
1000     nsIDOMDocument_Release(nsdoc);
1001     nsAString_Finish(&ns_text);
1002
1003     if(NS_FAILED(nsres) || !nsnode)
1004     {
1005         ERR("CreateTextNode failed: %08x\n", nsres);
1006         return E_FAIL;
1007     }
1008
1009     hr = HTMLElement_InsertAdjacentNode(This, where, nsnode);
1010     nsIDOMNode_Release(nsnode);
1011
1012     return hr;
1013 }
1014
1015 static HRESULT WINAPI HTMLElement_get_parentTextEdit(IHTMLElement *iface, IHTMLElement **p)
1016 {
1017     HTMLElement *This = HTMLELEM_THIS(iface);
1018     FIXME("(%p)->(%p)\n", This, p);
1019     return E_NOTIMPL;
1020 }
1021
1022 static HRESULT WINAPI HTMLElement_get_isTextEdit(IHTMLElement *iface, VARIANT_BOOL *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_click(IHTMLElement *iface)
1030 {
1031     HTMLElement *This = HTMLELEM_THIS(iface);
1032     FIXME("(%p)\n", This);
1033     return E_NOTIMPL;
1034 }
1035
1036 static HRESULT WINAPI HTMLElement_get_filters(IHTMLElement *iface,
1037                                               IHTMLFiltersCollection **p)
1038 {
1039     HTMLElement *This = HTMLELEM_THIS(iface);
1040     FIXME("(%p)->(%p)\n", This, p);
1041     return E_NOTIMPL;
1042 }
1043
1044 static HRESULT WINAPI HTMLElement_put_ondragstart(IHTMLElement *iface, VARIANT v)
1045 {
1046     HTMLElement *This = HTMLELEM_THIS(iface);
1047     FIXME("(%p)->()\n", This);
1048     return E_NOTIMPL;
1049 }
1050
1051 static HRESULT WINAPI HTMLElement_get_ondragstart(IHTMLElement *iface, VARIANT *p)
1052 {
1053     HTMLElement *This = HTMLELEM_THIS(iface);
1054     FIXME("(%p)->(%p)\n", This, p);
1055     return E_NOTIMPL;
1056 }
1057
1058 static HRESULT WINAPI HTMLElement_toString(IHTMLElement *iface, BSTR *String)
1059 {
1060     HTMLElement *This = HTMLELEM_THIS(iface);
1061     FIXME("(%p)->(%p)\n", This, String);
1062     return E_NOTIMPL;
1063 }
1064
1065 static HRESULT WINAPI HTMLElement_put_onbeforeupdate(IHTMLElement *iface, VARIANT v)
1066 {
1067     HTMLElement *This = HTMLELEM_THIS(iface);
1068     FIXME("(%p)->()\n", This);
1069     return E_NOTIMPL;
1070 }
1071
1072 static HRESULT WINAPI HTMLElement_get_onbeforeupdate(IHTMLElement *iface, VARIANT *p)
1073 {
1074     HTMLElement *This = HTMLELEM_THIS(iface);
1075     FIXME("(%p)->(%p)\n", This, p);
1076     return E_NOTIMPL;
1077 }
1078
1079 static HRESULT WINAPI HTMLElement_put_onafterupdate(IHTMLElement *iface, VARIANT v)
1080 {
1081     HTMLElement *This = HTMLELEM_THIS(iface);
1082     FIXME("(%p)->()\n", This);
1083     return E_NOTIMPL;
1084 }
1085
1086 static HRESULT WINAPI HTMLElement_get_onafterupdate(IHTMLElement *iface, VARIANT *p)
1087 {
1088     HTMLElement *This = HTMLELEM_THIS(iface);
1089     FIXME("(%p)->(%p)\n", This, p);
1090     return E_NOTIMPL;
1091 }
1092
1093 static HRESULT WINAPI HTMLElement_put_onerrorupdate(IHTMLElement *iface, VARIANT v)
1094 {
1095     HTMLElement *This = HTMLELEM_THIS(iface);
1096     FIXME("(%p)->()\n", This);
1097     return E_NOTIMPL;
1098 }
1099
1100 static HRESULT WINAPI HTMLElement_get_onerrorupdate(IHTMLElement *iface, VARIANT *p)
1101 {
1102     HTMLElement *This = HTMLELEM_THIS(iface);
1103     FIXME("(%p)->(%p)\n", This, p);
1104     return E_NOTIMPL;
1105 }
1106
1107 static HRESULT WINAPI HTMLElement_put_onrowexit(IHTMLElement *iface, VARIANT v)
1108 {
1109     HTMLElement *This = HTMLELEM_THIS(iface);
1110     FIXME("(%p)->()\n", This);
1111     return E_NOTIMPL;
1112 }
1113
1114 static HRESULT WINAPI HTMLElement_get_onrowexit(IHTMLElement *iface, VARIANT *p)
1115 {
1116     HTMLElement *This = HTMLELEM_THIS(iface);
1117     FIXME("(%p)->(%p)\n", This, p);
1118     return E_NOTIMPL;
1119 }
1120
1121 static HRESULT WINAPI HTMLElement_put_onrowenter(IHTMLElement *iface, VARIANT v)
1122 {
1123     HTMLElement *This = HTMLELEM_THIS(iface);
1124     FIXME("(%p)->()\n", This);
1125     return E_NOTIMPL;
1126 }
1127
1128 static HRESULT WINAPI HTMLElement_get_onrowenter(IHTMLElement *iface, VARIANT *p)
1129 {
1130     HTMLElement *This = HTMLELEM_THIS(iface);
1131     FIXME("(%p)->(%p)\n", This, p);
1132     return E_NOTIMPL;
1133 }
1134
1135 static HRESULT WINAPI HTMLElement_put_ondatasetchanged(IHTMLElement *iface, VARIANT v)
1136 {
1137     HTMLElement *This = HTMLELEM_THIS(iface);
1138     FIXME("(%p)->()\n", This);
1139     return E_NOTIMPL;
1140 }
1141
1142 static HRESULT WINAPI HTMLElement_get_ondatasetchanged(IHTMLElement *iface, VARIANT *p)
1143 {
1144     HTMLElement *This = HTMLELEM_THIS(iface);
1145     FIXME("(%p)->(%p)\n", This, p);
1146     return E_NOTIMPL;
1147 }
1148
1149 static HRESULT WINAPI HTMLElement_put_ondataavailable(IHTMLElement *iface, VARIANT v)
1150 {
1151     HTMLElement *This = HTMLELEM_THIS(iface);
1152     FIXME("(%p)->()\n", This);
1153     return E_NOTIMPL;
1154 }
1155
1156 static HRESULT WINAPI HTMLElement_get_ondataavailable(IHTMLElement *iface, VARIANT *p)
1157 {
1158     HTMLElement *This = HTMLELEM_THIS(iface);
1159     FIXME("(%p)->(%p)\n", This, p);
1160     return E_NOTIMPL;
1161 }
1162
1163 static HRESULT WINAPI HTMLElement_put_ondatasetcomplete(IHTMLElement *iface, VARIANT v)
1164 {
1165     HTMLElement *This = HTMLELEM_THIS(iface);
1166     FIXME("(%p)->()\n", This);
1167     return E_NOTIMPL;
1168 }
1169
1170 static HRESULT WINAPI HTMLElement_get_ondatasetcomplete(IHTMLElement *iface, VARIANT *p)
1171 {
1172     HTMLElement *This = HTMLELEM_THIS(iface);
1173     FIXME("(%p)->(%p)\n", This, p);
1174     return E_NOTIMPL;
1175 }
1176
1177 static HRESULT WINAPI HTMLElement_put_onfilterchange(IHTMLElement *iface, VARIANT v)
1178 {
1179     HTMLElement *This = HTMLELEM_THIS(iface);
1180     FIXME("(%p)->()\n", This);
1181     return E_NOTIMPL;
1182 }
1183
1184 static HRESULT WINAPI HTMLElement_get_onfilterchange(IHTMLElement *iface, VARIANT *p)
1185 {
1186     HTMLElement *This = HTMLELEM_THIS(iface);
1187     FIXME("(%p)->(%p)\n", This, p);
1188     return E_NOTIMPL;
1189 }
1190
1191 static HRESULT WINAPI HTMLElement_get_children(IHTMLElement *iface, IDispatch **p)
1192 {
1193     HTMLElement *This = HTMLELEM_THIS(iface);
1194     nsIDOMNodeList *nsnode_list;
1195     nsresult nsres;
1196
1197     TRACE("(%p)->(%p)\n", This, p);
1198
1199     nsres = nsIDOMNode_GetChildNodes(This->node.nsnode, &nsnode_list);
1200     if(NS_FAILED(nsres)) {
1201         ERR("GetChildNodes failed: %08x\n", nsres);
1202         return E_FAIL;
1203     }
1204
1205     *p = (IDispatch*)create_collection_from_nodelist(This->node.doc, (IUnknown*)HTMLELEM(This), nsnode_list);
1206
1207     nsIDOMNodeList_Release(nsnode_list);
1208     return S_OK;
1209 }
1210
1211 static HRESULT WINAPI HTMLElement_get_all(IHTMLElement *iface, IDispatch **p)
1212 {
1213     HTMLElement *This = HTMLELEM_THIS(iface);
1214
1215     TRACE("(%p)->(%p)\n", This, p);
1216
1217     *p = (IDispatch*)create_all_collection(&This->node, FALSE);
1218     return S_OK;
1219 }
1220
1221 #undef HTMLELEM_THIS
1222
1223 static const IHTMLElementVtbl HTMLElementVtbl = {
1224     HTMLElement_QueryInterface,
1225     HTMLElement_AddRef,
1226     HTMLElement_Release,
1227     HTMLElement_GetTypeInfoCount,
1228     HTMLElement_GetTypeInfo,
1229     HTMLElement_GetIDsOfNames,
1230     HTMLElement_Invoke,
1231     HTMLElement_setAttribute,
1232     HTMLElement_getAttribute,
1233     HTMLElement_removeAttribute,
1234     HTMLElement_put_className,
1235     HTMLElement_get_className,
1236     HTMLElement_put_id,
1237     HTMLElement_get_id,
1238     HTMLElement_get_tagName,
1239     HTMLElement_get_parentElement,
1240     HTMLElement_get_style,
1241     HTMLElement_put_onhelp,
1242     HTMLElement_get_onhelp,
1243     HTMLElement_put_onclick,
1244     HTMLElement_get_onclick,
1245     HTMLElement_put_ondblclick,
1246     HTMLElement_get_ondblclick,
1247     HTMLElement_put_onkeydown,
1248     HTMLElement_get_onkeydown,
1249     HTMLElement_put_onkeyup,
1250     HTMLElement_get_onkeyup,
1251     HTMLElement_put_onkeypress,
1252     HTMLElement_get_onkeypress,
1253     HTMLElement_put_onmouseout,
1254     HTMLElement_get_onmouseout,
1255     HTMLElement_put_onmouseover,
1256     HTMLElement_get_onmouseover,
1257     HTMLElement_put_onmousemove,
1258     HTMLElement_get_onmousemove,
1259     HTMLElement_put_onmousedown,
1260     HTMLElement_get_onmousedown,
1261     HTMLElement_put_onmouseup,
1262     HTMLElement_get_onmouseup,
1263     HTMLElement_get_document,
1264     HTMLElement_put_title,
1265     HTMLElement_get_title,
1266     HTMLElement_put_language,
1267     HTMLElement_get_language,
1268     HTMLElement_put_onselectstart,
1269     HTMLElement_get_onselectstart,
1270     HTMLElement_scrollIntoView,
1271     HTMLElement_contains,
1272     HTMLElement_get_sourceIndex,
1273     HTMLElement_get_recordNumber,
1274     HTMLElement_put_lang,
1275     HTMLElement_get_lang,
1276     HTMLElement_get_offsetLeft,
1277     HTMLElement_get_offsetTop,
1278     HTMLElement_get_offsetWidth,
1279     HTMLElement_get_offsetHeight,
1280     HTMLElement_get_offsetParent,
1281     HTMLElement_put_innerHTML,
1282     HTMLElement_get_innerHTML,
1283     HTMLElement_put_innerText,
1284     HTMLElement_get_innerText,
1285     HTMLElement_put_outerHTML,
1286     HTMLElement_get_outerHTML,
1287     HTMLElement_put_outerText,
1288     HTMLElement_get_outerText,
1289     HTMLElement_insertAdjacentHTML,
1290     HTMLElement_insertAdjacentText,
1291     HTMLElement_get_parentTextEdit,
1292     HTMLElement_get_isTextEdit,
1293     HTMLElement_click,
1294     HTMLElement_get_filters,
1295     HTMLElement_put_ondragstart,
1296     HTMLElement_get_ondragstart,
1297     HTMLElement_toString,
1298     HTMLElement_put_onbeforeupdate,
1299     HTMLElement_get_onbeforeupdate,
1300     HTMLElement_put_onafterupdate,
1301     HTMLElement_get_onafterupdate,
1302     HTMLElement_put_onerrorupdate,
1303     HTMLElement_get_onerrorupdate,
1304     HTMLElement_put_onrowexit,
1305     HTMLElement_get_onrowexit,
1306     HTMLElement_put_onrowenter,
1307     HTMLElement_get_onrowenter,
1308     HTMLElement_put_ondatasetchanged,
1309     HTMLElement_get_ondatasetchanged,
1310     HTMLElement_put_ondataavailable,
1311     HTMLElement_get_ondataavailable,
1312     HTMLElement_put_ondatasetcomplete,
1313     HTMLElement_get_ondatasetcomplete,
1314     HTMLElement_put_onfilterchange,
1315     HTMLElement_get_onfilterchange,
1316     HTMLElement_get_children,
1317     HTMLElement_get_all
1318 };
1319
1320 HRESULT HTMLElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
1321 {
1322     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
1323
1324     *ppv =  NULL;
1325
1326     if(IsEqualGUID(&IID_IUnknown, riid)) {
1327         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1328         *ppv = HTMLELEM(This);
1329     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1330         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
1331         *ppv = HTMLELEM(This);
1332     }else if(IsEqualGUID(&IID_IHTMLElement, riid)) {
1333         TRACE("(%p)->(IID_IHTMLElement %p)\n", This, ppv);
1334         *ppv = HTMLELEM(This);
1335     }else if(IsEqualGUID(&IID_IHTMLElement2, riid)) {
1336         TRACE("(%p)->(IID_IHTMLElement2 %p)\n", This, ppv);
1337         *ppv = HTMLELEM2(This);
1338     }else if(IsEqualGUID(&IID_IHTMLElement3, riid)) {
1339         TRACE("(%p)->(IID_IHTMLElement3 %p)\n", This, ppv);
1340         *ppv = HTMLELEM3(This);
1341     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
1342         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
1343         *ppv = CONPTCONT(&This->cp_container);
1344     }
1345
1346     if(*ppv) {
1347         IHTMLElement_AddRef(HTMLELEM(This));
1348         return S_OK;
1349     }
1350
1351     return HTMLDOMNode_QI(&This->node, riid, ppv);
1352 }
1353
1354 void HTMLElement_destructor(HTMLDOMNode *iface)
1355 {
1356     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
1357
1358     ConnectionPointContainer_Destroy(&This->cp_container);
1359
1360     if(This->nselem)
1361         nsIDOMHTMLElement_Release(This->nselem);
1362
1363     HTMLDOMNode_destructor(&This->node);
1364 }
1365
1366 static const NodeImplVtbl HTMLElementImplVtbl = {
1367     HTMLElement_QI,
1368     HTMLElement_destructor
1369 };
1370
1371 static const tid_t HTMLElement_iface_tids[] = {
1372     IHTMLDOMNode_tid,
1373     IHTMLDOMNode2_tid,
1374     IHTMLElement_tid,
1375     IHTMLElement2_tid,
1376     0
1377 };
1378
1379 static dispex_static_data_t HTMLElement_dispex = {
1380     NULL,
1381     DispHTMLUnknownElement_tid,
1382     NULL,
1383     HTMLElement_iface_tids
1384 };
1385
1386 void HTMLElement_Init(HTMLElement *This)
1387 {
1388     This->lpHTMLElementVtbl = &HTMLElementVtbl;
1389
1390     ConnectionPointContainer_Init(&This->cp_container, (IUnknown*)HTMLELEM(This));
1391
1392     HTMLElement2_Init(This);
1393     HTMLElement3_Init(This);
1394
1395     if(!This->node.dispex.data)
1396         init_dispex(&This->node.dispex, (IUnknown*)HTMLELEM(This), &HTMLElement_dispex);
1397 }
1398
1399 HTMLElement *HTMLElement_Create(HTMLDocument *doc, nsIDOMNode *nsnode, BOOL use_generic)
1400 {
1401     nsIDOMHTMLElement *nselem;
1402     HTMLElement *ret = NULL;
1403     nsAString class_name_str;
1404     const PRUnichar *class_name;
1405     nsresult nsres;
1406
1407     static const WCHAR wszA[]        = {'A',0};
1408     static const WCHAR wszBODY[]     = {'B','O','D','Y',0};
1409     static const WCHAR wszIFRAME[]   = {'I','F','R','A','M','E',0};
1410     static const WCHAR wszIMG[]      = {'I','M','G',0};
1411     static const WCHAR wszINPUT[]    = {'I','N','P','U','T',0};
1412     static const WCHAR wszOPTION[]   = {'O','P','T','I','O','N',0};
1413     static const WCHAR wszSCRIPT[]   = {'S','C','R','I','P','T',0};
1414     static const WCHAR wszSELECT[]   = {'S','E','L','E','C','T',0};
1415     static const WCHAR wszTABLE[]    = {'T','A','B','L','E',0};
1416     static const WCHAR wszTR[]       = {'T','R',0};
1417     static const WCHAR wszTEXTAREA[] = {'T','E','X','T','A','R','E','A',0};
1418
1419     nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMHTMLElement, (void**)&nselem);
1420     if(NS_FAILED(nsres))
1421         return NULL;
1422
1423     nsAString_Init(&class_name_str, NULL);
1424     nsIDOMHTMLElement_GetTagName(nselem, &class_name_str);
1425
1426     nsAString_GetData(&class_name_str, &class_name);
1427
1428     if(!strcmpW(class_name, wszA))
1429         ret = HTMLAnchorElement_Create(nselem);
1430     else if(!strcmpW(class_name, wszBODY))
1431         ret = HTMLBodyElement_Create(nselem);
1432     else if(!strcmpW(class_name, wszIFRAME))
1433         ret = HTMLIFrame_Create(nselem);
1434     else if(!strcmpW(class_name, wszIMG))
1435         ret = HTMLImgElement_Create(nselem);
1436     else if(!strcmpW(class_name, wszINPUT))
1437         ret = HTMLInputElement_Create(nselem);
1438     else if(!strcmpW(class_name, wszOPTION))
1439         ret = HTMLOptionElement_Create(nselem);
1440     else if(!strcmpW(class_name, wszSCRIPT))
1441         ret = HTMLScriptElement_Create(nselem);
1442     else if(!strcmpW(class_name, wszSELECT))
1443         ret = HTMLSelectElement_Create(nselem);
1444     else if(!strcmpW(class_name, wszTABLE))
1445         ret = HTMLTable_Create(nselem);
1446     else if(!strcmpW(class_name, wszTR))
1447         ret = HTMLTableRow_Create(nselem);
1448     else if(!strcmpW(class_name, wszTEXTAREA))
1449         ret = HTMLTextAreaElement_Create(nselem);
1450     else if(use_generic)
1451         ret = HTMLGenericElement_Create(nselem);
1452
1453     if(!ret) {
1454         ret = heap_alloc_zero(sizeof(HTMLElement));
1455         HTMLElement_Init(ret);
1456         ret->node.vtbl = &HTMLElementImplVtbl;
1457     }
1458
1459     TRACE("%s ret %p\n", debugstr_w(class_name), ret);
1460
1461     nsAString_Finish(&class_name_str);
1462
1463     ret->nselem = nselem;
1464     HTMLDOMNode_Init(doc, &ret->node, (nsIDOMNode*)nselem);
1465
1466     return ret;
1467 }