mshtml: Pass dispex info to HTMLElement_Init in HTMLElement_Create.
[wine] / dlls / mshtml / htmlelem.c
1 /*
2  * Copyright 2006 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19
20 #include <stdarg.h>
21
22 #define COBJMACROS
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "winreg.h"
28 #include "ole2.h"
29 #include "shlwapi.h"
30
31 #include "wine/debug.h"
32 #include "wine/unicode.h"
33
34 #include "mshtml_private.h"
35 #include "htmlevent.h"
36
37 typedef struct
38 {
39     DispatchEx dispex;
40     const IHTMLFiltersCollectionVtbl *lpHTMLFiltersCollectionVtbl;
41
42     LONG ref;
43 } HTMLFiltersCollection;
44
45 #define HTMLFILTERSCOLLECTION(x)     ((IHTMLFiltersCollection*)  &(x)->lpHTMLFiltersCollectionVtbl)
46
47 #define HTMLFILTERSCOLLECTION_THIS(iface) \
48     DEFINE_THIS(HTMLFiltersCollection, HTMLFiltersCollection, iface)
49
50 IHTMLFiltersCollection *HTMLFiltersCollection_Create(void);
51
52
53 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
54
55 #define HTMLELEM_THIS(iface) DEFINE_THIS(HTMLElement, HTMLElement, iface)
56
57 HRESULT create_nselem(HTMLDocumentNode *doc, const WCHAR *tag, nsIDOMHTMLElement **ret)
58 {
59     nsIDOMElement *nselem;
60     nsAString tag_str;
61     nsresult nsres;
62
63     if(!doc->nsdoc) {
64         WARN("NULL nsdoc\n");
65         return E_UNEXPECTED;
66     }
67
68     nsAString_Init(&tag_str, tag);
69     nsres = nsIDOMDocument_CreateElement(doc->nsdoc, &tag_str, &nselem);
70     nsAString_Finish(&tag_str);
71     if(NS_FAILED(nsres)) {
72         ERR("CreateElement failed: %08x\n", nsres);
73         return E_FAIL;
74     }
75
76     nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLElement, (void**)ret);
77     nsIDOMElement_Release(nselem);
78     if(NS_FAILED(nsres)) {
79         ERR("Could not get nsIDOMHTMLElement iface: %08x\n", nsres);
80         return E_FAIL;
81     }
82
83     return S_OK;
84 }
85
86 #define HTMLELEM_NODE_THIS(iface) DEFINE_THIS2(HTMLElement, node, iface)
87
88 static HRESULT WINAPI HTMLElement_QueryInterface(IHTMLElement *iface,
89                                                  REFIID riid, void **ppv)
90 {
91     HTMLElement *This = HTMLELEM_THIS(iface);
92
93     return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->node), riid, ppv);
94 }
95
96 static ULONG WINAPI HTMLElement_AddRef(IHTMLElement *iface)
97 {
98     HTMLElement *This = HTMLELEM_THIS(iface);
99
100     return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->node));
101 }
102
103 static ULONG WINAPI HTMLElement_Release(IHTMLElement *iface)
104 {
105     HTMLElement *This = HTMLELEM_THIS(iface);
106
107     return IHTMLDOMNode_Release(HTMLDOMNODE(&This->node));
108 }
109
110 static HRESULT WINAPI HTMLElement_GetTypeInfoCount(IHTMLElement *iface, UINT *pctinfo)
111 {
112     HTMLElement *This = HTMLELEM_THIS(iface);
113     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->node.dispex), pctinfo);
114 }
115
116 static HRESULT WINAPI HTMLElement_GetTypeInfo(IHTMLElement *iface, UINT iTInfo,
117                                               LCID lcid, ITypeInfo **ppTInfo)
118 {
119     HTMLElement *This = HTMLELEM_THIS(iface);
120     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->node.dispex), iTInfo, lcid, ppTInfo);
121 }
122
123 static HRESULT WINAPI HTMLElement_GetIDsOfNames(IHTMLElement *iface, REFIID riid,
124                                                 LPOLESTR *rgszNames, UINT cNames,
125                                                 LCID lcid, DISPID *rgDispId)
126 {
127     HTMLElement *This = HTMLELEM_THIS(iface);
128     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->node.dispex), riid, rgszNames, cNames, lcid, rgDispId);
129 }
130
131 static HRESULT WINAPI HTMLElement_Invoke(IHTMLElement *iface, DISPID dispIdMember,
132                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
133                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
134 {
135     HTMLElement *This = HTMLELEM_THIS(iface);
136     return IDispatchEx_Invoke(DISPATCHEX(&This->node.dispex), dispIdMember, riid, lcid,
137             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
138 }
139
140 static HRESULT WINAPI HTMLElement_setAttribute(IHTMLElement *iface, BSTR strAttributeName,
141                                                VARIANT AttributeValue, LONG lFlags)
142 {
143     HTMLElement *This = HTMLELEM_THIS(iface);
144     HRESULT hres;
145     DISPID dispid, dispidNamed = DISPID_PROPERTYPUT;
146     DISPPARAMS dispParams;
147     EXCEPINFO excep;
148
149     TRACE("(%p)->(%s . %08x)\n", This, debugstr_w(strAttributeName), lFlags);
150
151     hres = IDispatchEx_GetDispID(DISPATCHEX(&This->node.dispex), strAttributeName,
152             fdexNameCaseInsensitive | fdexNameEnsure, &dispid);
153     if(FAILED(hres))
154         return hres;
155
156     dispParams.cArgs = 1;
157     dispParams.cNamedArgs = 1;
158     dispParams.rgdispidNamedArgs = &dispidNamed;
159     dispParams.rgvarg = &AttributeValue;
160
161     hres = IDispatchEx_InvokeEx(DISPATCHEX(&This->node.dispex), dispid,
162             LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dispParams,
163             NULL, &excep, NULL);
164     return hres;
165 }
166
167 static HRESULT WINAPI HTMLElement_getAttribute(IHTMLElement *iface, BSTR strAttributeName,
168                                                LONG lFlags, VARIANT *AttributeValue)
169 {
170     HTMLElement *This = HTMLELEM_THIS(iface);
171     DISPID dispid;
172     HRESULT hres;
173     DISPPARAMS dispParams = {NULL, NULL, 0, 0};
174     EXCEPINFO excep;
175
176     TRACE("(%p)->(%s %08x %p)\n", This, debugstr_w(strAttributeName), lFlags, AttributeValue);
177
178     hres = IDispatchEx_GetDispID(DISPATCHEX(&This->node.dispex), strAttributeName,
179             fdexNameCaseInsensitive, &dispid);
180     if(hres == DISP_E_UNKNOWNNAME) {
181         V_VT(AttributeValue) = VT_NULL;
182         return S_OK;
183     }
184
185     if(FAILED(hres)) {
186         V_VT(AttributeValue) = VT_NULL;
187         return hres;
188     }
189
190     hres = IDispatchEx_InvokeEx(DISPATCHEX(&This->node.dispex), dispid,
191             LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dispParams,
192             AttributeValue, &excep, NULL);
193
194     return hres;
195 }
196
197 static HRESULT WINAPI HTMLElement_removeAttribute(IHTMLElement *iface, BSTR strAttributeName,
198                                                   LONG lFlags, VARIANT_BOOL *pfSuccess)
199 {
200     HTMLElement *This = HTMLELEM_THIS(iface);
201     FIXME("(%p)->()\n", This);
202     return E_NOTIMPL;
203 }
204
205 static HRESULT WINAPI HTMLElement_put_className(IHTMLElement *iface, BSTR v)
206 {
207     HTMLElement *This = HTMLELEM_THIS(iface);
208     nsAString classname_str;
209     nsresult nsres;
210
211     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
212
213     if(!This->nselem) {
214         FIXME("NULL nselem\n");
215         return E_NOTIMPL;
216     }
217
218     nsAString_Init(&classname_str, v);
219     nsres = nsIDOMHTMLElement_SetClassName(This->nselem, &classname_str);
220     nsAString_Finish(&classname_str);
221     if(NS_FAILED(nsres))
222         ERR("SetClassName failed: %08x\n", nsres);
223
224     return S_OK;
225 }
226
227 static HRESULT WINAPI HTMLElement_get_className(IHTMLElement *iface, BSTR *p)
228 {
229     HTMLElement *This = HTMLELEM_THIS(iface);
230     nsAString class_str;
231     nsresult nsres;
232     HRESULT hres = S_OK;
233
234     TRACE("(%p)->(%p)\n", This, p);
235
236     if(!This->nselem) {
237         FIXME("NULL nselem\n");
238         return E_NOTIMPL;
239     }
240
241     nsAString_Init(&class_str, NULL);
242     nsres = nsIDOMHTMLElement_GetClassName(This->nselem, &class_str);
243
244     if(NS_SUCCEEDED(nsres)) {
245         const PRUnichar *class;
246         nsAString_GetData(&class_str, &class);
247         *p = *class ? SysAllocString(class) : NULL;
248     }else {
249         ERR("GetClassName failed: %08x\n", nsres);
250         hres = E_FAIL;
251     }
252
253     nsAString_Finish(&class_str);
254
255     TRACE("className=%s\n", debugstr_w(*p));
256     return hres;
257 }
258
259 static HRESULT WINAPI HTMLElement_put_id(IHTMLElement *iface, BSTR v)
260 {
261     HTMLElement *This = HTMLELEM_THIS(iface);
262     nsAString id_str;
263     nsresult nsres;
264
265     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
266
267     if(!This->nselem) {
268         FIXME("nselem == NULL\n");
269         return S_OK;
270     }
271
272     nsAString_Init(&id_str, v);
273     nsres = nsIDOMHTMLElement_SetId(This->nselem, &id_str);
274     nsAString_Finish(&id_str);
275     if(NS_FAILED(nsres))
276         ERR("SetId failed: %08x\n", nsres);
277
278     return S_OK;
279 }
280
281 static HRESULT WINAPI HTMLElement_get_id(IHTMLElement *iface, BSTR *p)
282 {
283     HTMLElement *This = HTMLELEM_THIS(iface);
284     const PRUnichar *id;
285     nsAString id_str;
286     nsresult nsres;
287
288     TRACE("(%p)->(%p)\n", This, p);
289
290     *p = NULL;
291
292     if(!This->nselem)
293         return S_OK;
294
295     nsAString_Init(&id_str, NULL);
296     nsres = nsIDOMHTMLElement_GetId(This->nselem, &id_str);
297     nsAString_GetData(&id_str, &id);
298
299     if(NS_FAILED(nsres))
300         ERR("GetId failed: %08x\n", nsres);
301     else if(*id)
302         *p = SysAllocString(id);
303
304     nsAString_Finish(&id_str);
305     return S_OK;
306 }
307
308 static HRESULT WINAPI HTMLElement_get_tagName(IHTMLElement *iface, BSTR *p)
309 {
310     HTMLElement *This = HTMLELEM_THIS(iface);
311     const PRUnichar *tag;
312     nsAString tag_str;
313     nsresult nsres;
314
315     TRACE("(%p)->(%p)\n", This, p);
316
317     if(!This->nselem) {
318         static const WCHAR comment_tagW[] = {'!',0};
319
320         WARN("NULL nselem, assuming comment\n");
321
322         *p = SysAllocString(comment_tagW);
323         return S_OK;
324     }
325
326     nsAString_Init(&tag_str, NULL);
327     nsres = nsIDOMHTMLElement_GetTagName(This->nselem, &tag_str);
328     if(NS_SUCCEEDED(nsres)) {
329         nsAString_GetData(&tag_str, &tag);
330         *p = SysAllocString(tag);
331     }else {
332         ERR("GetTagName failed: %08x\n", nsres);
333         *p = NULL;
334     }
335     nsAString_Finish(&tag_str);
336
337     return S_OK;
338 }
339
340 static HRESULT WINAPI HTMLElement_get_parentElement(IHTMLElement *iface, IHTMLElement **p)
341 {
342     HTMLElement *This = HTMLELEM_THIS(iface);
343     IHTMLDOMNode *node;
344     HRESULT hres;
345
346     TRACE("(%p)->(%p)\n", This, p);
347
348     hres = IHTMLDOMNode_get_parentNode(HTMLDOMNODE(&This->node), &node);
349     if(FAILED(hres))
350         return hres;
351
352     hres = IHTMLDOMNode_QueryInterface(node, &IID_IHTMLElement, (void**)p);
353     IHTMLDOMNode_Release(node);
354     if(FAILED(hres))
355         *p = NULL;
356
357     return S_OK;
358 }
359
360 static HRESULT WINAPI HTMLElement_get_style(IHTMLElement *iface, IHTMLStyle **p)
361 {
362     HTMLElement *This = HTMLELEM_THIS(iface);
363     nsIDOMElementCSSInlineStyle *nselemstyle;
364     nsIDOMCSSStyleDeclaration *nsstyle;
365     nsresult nsres;
366
367     TRACE("(%p)->(%p)\n", This, p);
368
369     if(!This->nselem) {
370         FIXME("NULL nselem\n");
371         return E_NOTIMPL;
372     }
373
374     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMElementCSSInlineStyle,
375                                              (void**)&nselemstyle);
376     if(NS_FAILED(nsres)) {
377         ERR("Coud not get nsIDOMCSSStyleDeclaration interface: %08x\n", nsres);
378         return E_FAIL;
379     }
380
381     nsres = nsIDOMElementCSSInlineStyle_GetStyle(nselemstyle, &nsstyle);
382     nsIDOMElementCSSInlineStyle_Release(nselemstyle);
383     if(NS_FAILED(nsres)) {
384         ERR("GetStyle failed: %08x\n", nsres);
385         return E_FAIL;
386     }
387
388     /* FIXME: Store style instead of creating a new instance in each call */
389     *p = HTMLStyle_Create(nsstyle);
390
391     nsIDOMCSSStyleDeclaration_Release(nsstyle);
392     return S_OK;
393 }
394
395 static HRESULT WINAPI HTMLElement_put_onhelp(IHTMLElement *iface, VARIANT v)
396 {
397     HTMLElement *This = HTMLELEM_THIS(iface);
398     FIXME("(%p)->()\n", This);
399     return E_NOTIMPL;
400 }
401
402 static HRESULT WINAPI HTMLElement_get_onhelp(IHTMLElement *iface, VARIANT *p)
403 {
404     HTMLElement *This = HTMLELEM_THIS(iface);
405     FIXME("(%p)->(%p)\n", This, p);
406     return E_NOTIMPL;
407 }
408
409 static HRESULT WINAPI HTMLElement_put_onclick(IHTMLElement *iface, VARIANT v)
410 {
411     HTMLElement *This = HTMLELEM_THIS(iface);
412
413     TRACE("(%p)->()\n", This);
414
415     return set_node_event(&This->node, EVENTID_CLICK, &v);
416 }
417
418 static HRESULT WINAPI HTMLElement_get_onclick(IHTMLElement *iface, VARIANT *p)
419 {
420     HTMLElement *This = HTMLELEM_THIS(iface);
421
422     TRACE("(%p)->(%p)\n", This, p);
423
424     return get_node_event(&This->node, EVENTID_CLICK, p);
425 }
426
427 static HRESULT WINAPI HTMLElement_put_ondblclick(IHTMLElement *iface, VARIANT v)
428 {
429     HTMLElement *This = HTMLELEM_THIS(iface);
430
431     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
432
433     return set_node_event(&This->node, EVENTID_DBLCLICK, &v);
434 }
435
436 static HRESULT WINAPI HTMLElement_get_ondblclick(IHTMLElement *iface, VARIANT *p)
437 {
438     HTMLElement *This = HTMLELEM_THIS(iface);
439
440     TRACE("(%p)->(%p)\n", This, p);
441
442     return get_node_event(&This->node, EVENTID_DBLCLICK, p);
443 }
444
445 static HRESULT WINAPI HTMLElement_put_onkeydown(IHTMLElement *iface, VARIANT v)
446 {
447     HTMLElement *This = HTMLELEM_THIS(iface);
448
449     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
450
451     return set_node_event(&This->node, EVENTID_KEYDOWN, &v);
452 }
453
454 static HRESULT WINAPI HTMLElement_get_onkeydown(IHTMLElement *iface, VARIANT *p)
455 {
456     HTMLElement *This = HTMLELEM_THIS(iface);
457
458     TRACE("(%p)->(%p)\n", This, p);
459
460     return get_node_event(&This->node, EVENTID_KEYDOWN, p);
461 }
462
463 static HRESULT WINAPI HTMLElement_put_onkeyup(IHTMLElement *iface, VARIANT v)
464 {
465     HTMLElement *This = HTMLELEM_THIS(iface);
466
467     TRACE("(%p)->()\n", This);
468
469     return set_node_event(&This->node, EVENTID_KEYUP, &v);
470 }
471
472 static HRESULT WINAPI HTMLElement_get_onkeyup(IHTMLElement *iface, VARIANT *p)
473 {
474     HTMLElement *This = HTMLELEM_THIS(iface);
475     FIXME("(%p)->(%p)\n", This, p);
476     return E_NOTIMPL;
477 }
478
479 static HRESULT WINAPI HTMLElement_put_onkeypress(IHTMLElement *iface, VARIANT v)
480 {
481     HTMLElement *This = HTMLELEM_THIS(iface);
482     FIXME("(%p)->()\n", This);
483     return E_NOTIMPL;
484 }
485
486 static HRESULT WINAPI HTMLElement_get_onkeypress(IHTMLElement *iface, VARIANT *p)
487 {
488     HTMLElement *This = HTMLELEM_THIS(iface);
489     FIXME("(%p)->(%p)\n", This, p);
490     return E_NOTIMPL;
491 }
492
493 static HRESULT WINAPI HTMLElement_put_onmouseout(IHTMLElement *iface, VARIANT v)
494 {
495     HTMLElement *This = HTMLELEM_THIS(iface);
496
497     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
498
499     return set_node_event(&This->node, EVENTID_MOUSEOUT, &v);
500 }
501
502 static HRESULT WINAPI HTMLElement_get_onmouseout(IHTMLElement *iface, VARIANT *p)
503 {
504     HTMLElement *This = HTMLELEM_THIS(iface);
505
506     TRACE("(%p)->(%p)\n", This, p);
507
508     return get_node_event(&This->node, EVENTID_MOUSEOUT, p);
509 }
510
511 static HRESULT WINAPI HTMLElement_put_onmouseover(IHTMLElement *iface, VARIANT v)
512 {
513     HTMLElement *This = HTMLELEM_THIS(iface);
514
515     TRACE("(%p)->()\n", This);
516
517     return set_node_event(&This->node, EVENTID_MOUSEOVER, &v);
518 }
519
520 static HRESULT WINAPI HTMLElement_get_onmouseover(IHTMLElement *iface, VARIANT *p)
521 {
522     HTMLElement *This = HTMLELEM_THIS(iface);
523
524     TRACE("(%p)->(%p)\n", This, p);
525
526     return get_node_event(&This->node, EVENTID_MOUSEOVER, p);
527 }
528
529 static HRESULT WINAPI HTMLElement_put_onmousemove(IHTMLElement *iface, VARIANT v)
530 {
531     HTMLElement *This = HTMLELEM_THIS(iface);
532     FIXME("(%p)->()\n", This);
533     return E_NOTIMPL;
534 }
535
536 static HRESULT WINAPI HTMLElement_get_onmousemove(IHTMLElement *iface, VARIANT *p)
537 {
538     HTMLElement *This = HTMLELEM_THIS(iface);
539     FIXME("(%p)->(%p)\n", This, p);
540     return E_NOTIMPL;
541 }
542
543 static HRESULT WINAPI HTMLElement_put_onmousedown(IHTMLElement *iface, VARIANT v)
544 {
545     HTMLElement *This = HTMLELEM_THIS(iface);
546
547     TRACE("(%p)->()\n", This);
548
549     return set_node_event(&This->node, EVENTID_MOUSEDOWN, &v);
550 }
551
552 static HRESULT WINAPI HTMLElement_get_onmousedown(IHTMLElement *iface, VARIANT *p)
553 {
554     HTMLElement *This = HTMLELEM_THIS(iface);
555
556     TRACE("(%p)->(%p)\n", This, p);
557
558     return get_node_event(&This->node, EVENTID_MOUSEDOWN, p);
559 }
560
561 static HRESULT WINAPI HTMLElement_put_onmouseup(IHTMLElement *iface, VARIANT v)
562 {
563     HTMLElement *This = HTMLELEM_THIS(iface);
564
565     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
566
567     return set_node_event(&This->node, EVENTID_MOUSEUP, &v);
568 }
569
570 static HRESULT WINAPI HTMLElement_get_onmouseup(IHTMLElement *iface, VARIANT *p)
571 {
572     HTMLElement *This = HTMLELEM_THIS(iface);
573
574     TRACE("(%p)->(%p)\n", This, p);
575
576     return get_node_event(&This->node, EVENTID_MOUSEUP, p);
577 }
578
579 static HRESULT WINAPI HTMLElement_get_document(IHTMLElement *iface, IDispatch **p)
580 {
581     HTMLElement *This = HTMLELEM_THIS(iface);
582
583     TRACE("(%p)->(%p)\n", This, p);
584
585     if(!p)
586         return E_POINTER;
587
588     if(This->node.vtbl->get_document)
589         return This->node.vtbl->get_document(&This->node, p);
590
591     *p = (IDispatch*)HTMLDOC(&This->node.doc->basedoc);
592     IDispatch_AddRef(*p);
593     return S_OK;
594 }
595
596 static HRESULT WINAPI HTMLElement_put_title(IHTMLElement *iface, BSTR v)
597 {
598     HTMLElement *This = HTMLELEM_THIS(iface);
599     nsAString title_str;
600     nsresult nsres;
601
602     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
603
604     nsAString_Init(&title_str, v);
605     nsres = nsIDOMHTMLElement_SetTitle(This->nselem, &title_str);
606     nsAString_Finish(&title_str);
607     if(NS_FAILED(nsres))
608         ERR("SetTitle failed: %08x\n", nsres);
609
610     return S_OK;
611 }
612
613 static HRESULT WINAPI HTMLElement_get_title(IHTMLElement *iface, BSTR *p)
614 {
615     HTMLElement *This = HTMLELEM_THIS(iface);
616     nsAString title_str;
617     nsresult nsres;
618
619     TRACE("(%p)->(%p)\n", This, p);
620
621     nsAString_Init(&title_str, NULL);
622     nsres = nsIDOMHTMLElement_GetTitle(This->nselem, &title_str);
623     if(NS_SUCCEEDED(nsres)) {
624         const PRUnichar *title;
625
626         nsAString_GetData(&title_str, &title);
627         *p = *title ? SysAllocString(title) : NULL;
628     }else {
629         ERR("GetTitle failed: %08x\n", nsres);
630         return E_FAIL;
631     }
632
633     return S_OK;
634 }
635
636 static HRESULT WINAPI HTMLElement_put_language(IHTMLElement *iface, BSTR v)
637 {
638     HTMLElement *This = HTMLELEM_THIS(iface);
639     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
640     return E_NOTIMPL;
641 }
642
643 static HRESULT WINAPI HTMLElement_get_language(IHTMLElement *iface, BSTR *p)
644 {
645     HTMLElement *This = HTMLELEM_THIS(iface);
646     FIXME("(%p)->(%p)\n", This, p);
647     return E_NOTIMPL;
648 }
649
650 static HRESULT WINAPI HTMLElement_put_onselectstart(IHTMLElement *iface, VARIANT v)
651 {
652     HTMLElement *This = HTMLELEM_THIS(iface);
653
654     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
655
656     return set_node_event(&This->node, EVENTID_SELECTSTART, &v);
657 }
658
659 static HRESULT WINAPI HTMLElement_get_onselectstart(IHTMLElement *iface, VARIANT *p)
660 {
661     HTMLElement *This = HTMLELEM_THIS(iface);
662
663     TRACE("(%p)->(%p)\n", This, p);
664
665     return get_node_event(&This->node, EVENTID_SELECTSTART, p);
666 }
667
668 static HRESULT WINAPI HTMLElement_scrollIntoView(IHTMLElement *iface, VARIANT varargStart)
669 {
670     HTMLElement *This = HTMLELEM_THIS(iface);
671     FIXME("(%p)->()\n", This);
672     return E_NOTIMPL;
673 }
674
675 static HRESULT WINAPI HTMLElement_contains(IHTMLElement *iface, IHTMLElement *pChild,
676                                            VARIANT_BOOL *pfResult)
677 {
678     HTMLElement *This = HTMLELEM_THIS(iface);
679     FIXME("(%p)->(%p %p)\n", This, pChild, pfResult);
680     return E_NOTIMPL;
681 }
682
683 static HRESULT WINAPI HTMLElement_get_sourceIndex(IHTMLElement *iface, LONG *p)
684 {
685     HTMLElement *This = HTMLELEM_THIS(iface);
686     FIXME("(%p)->(%p)\n", This, p);
687     return E_NOTIMPL;
688 }
689
690 static HRESULT WINAPI HTMLElement_get_recordNumber(IHTMLElement *iface, VARIANT *p)
691 {
692     HTMLElement *This = HTMLELEM_THIS(iface);
693     FIXME("(%p)->(%p)\n", This, p);
694     return E_NOTIMPL;
695 }
696
697 static HRESULT WINAPI HTMLElement_put_lang(IHTMLElement *iface, BSTR v)
698 {
699     HTMLElement *This = HTMLELEM_THIS(iface);
700     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
701     return E_NOTIMPL;
702 }
703
704 static HRESULT WINAPI HTMLElement_get_lang(IHTMLElement *iface, BSTR *p)
705 {
706     HTMLElement *This = HTMLELEM_THIS(iface);
707     FIXME("(%p)->(%p)\n", This, p);
708     return E_NOTIMPL;
709 }
710
711 static HRESULT WINAPI HTMLElement_get_offsetLeft(IHTMLElement *iface, LONG *p)
712 {
713     HTMLElement *This = HTMLELEM_THIS(iface);
714     FIXME("(%p)->(%p)\n", This, p);
715     return E_NOTIMPL;
716 }
717
718 static HRESULT WINAPI HTMLElement_get_offsetTop(IHTMLElement *iface, LONG *p)
719 {
720     HTMLElement *This = HTMLELEM_THIS(iface);
721     nsIDOMNSHTMLElement *nselem;
722     PRInt32 top = 0;
723     nsresult nsres;
724
725     TRACE("(%p)->(%p)\n", This, p);
726
727     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
728     if(NS_FAILED(nsres)) {
729         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
730         return E_FAIL;
731     }
732
733     nsres = nsIDOMNSHTMLElement_GetOffsetTop(nselem, &top);
734     nsIDOMNSHTMLElement_Release(nselem);
735     if(NS_FAILED(nsres)) {
736         ERR("GetOffsetTop failed: %08x\n", nsres);
737         return E_FAIL;
738     }
739
740     *p = top;
741     return S_OK;
742 }
743
744 static HRESULT WINAPI HTMLElement_get_offsetWidth(IHTMLElement *iface, LONG *p)
745 {
746     HTMLElement *This = HTMLELEM_THIS(iface);
747     nsIDOMNSHTMLElement *nselem;
748     PRInt32 offset = 0;
749     nsresult nsres;
750
751     TRACE("(%p)->(%p)\n", This, p);
752
753     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
754     if(NS_FAILED(nsres)) {
755         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
756         return E_FAIL;
757     }
758
759     nsres = nsIDOMNSHTMLElement_GetOffsetWidth(nselem, &offset);
760     nsIDOMNSHTMLElement_Release(nselem);
761     if(NS_FAILED(nsres)) {
762         ERR("GetOffsetWidth failed: %08x\n", nsres);
763         return E_FAIL;
764     }
765
766     *p = offset;
767     return S_OK;
768 }
769
770 static HRESULT WINAPI HTMLElement_get_offsetHeight(IHTMLElement *iface, LONG *p)
771 {
772     HTMLElement *This = HTMLELEM_THIS(iface);
773     nsIDOMNSHTMLElement *nselem;
774     PRInt32 offset = 0;
775     nsresult nsres;
776
777     TRACE("(%p)->(%p)\n", This, p);
778
779     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
780     if(NS_FAILED(nsres)) {
781         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
782         return E_FAIL;
783     }
784
785     nsres = nsIDOMNSHTMLElement_GetOffsetHeight(nselem, &offset);
786     nsIDOMNSHTMLElement_Release(nselem);
787     if(NS_FAILED(nsres)) {
788         ERR("GetOffsetHeight failed: %08x\n", nsres);
789         return E_FAIL;
790     }
791
792     *p = offset;
793     return S_OK;
794 }
795
796 static HRESULT WINAPI HTMLElement_get_offsetParent(IHTMLElement *iface, IHTMLElement **p)
797 {
798     HTMLElement *This = HTMLELEM_THIS(iface);
799     FIXME("(%p)->(%p)\n", This, p);
800     return E_NOTIMPL;
801 }
802
803 static HRESULT WINAPI HTMLElement_put_innerHTML(IHTMLElement *iface, BSTR v)
804 {
805     HTMLElement *This = HTMLELEM_THIS(iface);
806     nsIDOMNSHTMLElement *nselem;
807     nsAString html_str;
808     nsresult nsres;
809
810     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
811
812     if(!This->nselem) {
813         FIXME("NULL nselem\n");
814         return E_NOTIMPL;
815     }
816
817     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
818     if(NS_FAILED(nsres)) {
819         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
820         return E_FAIL;
821     }
822
823     nsAString_Init(&html_str, v);
824     nsres = nsIDOMNSHTMLElement_SetInnerHTML(nselem, &html_str);
825     nsAString_Finish(&html_str);
826
827     if(NS_FAILED(nsres)) {
828         FIXME("SetInnerHtml failed %08x\n", nsres);
829         return E_FAIL;
830     }
831
832     return S_OK;
833 }
834
835 static HRESULT WINAPI HTMLElement_get_innerHTML(IHTMLElement *iface, BSTR *p)
836 {
837     HTMLElement *This = HTMLELEM_THIS(iface);
838     nsIDOMNSHTMLElement *nselem;
839     nsAString html_str;
840     nsresult nsres;
841
842     TRACE("(%p)->(%p)\n", This, p);
843
844     if(!This->nselem) {
845         FIXME("NULL nselem\n");
846         return E_NOTIMPL;
847     }
848
849     nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
850     if(NS_FAILED(nsres)) {
851         ERR("Could not get nsIDOMNSHTMLElement: %08x\n", nsres);
852         return E_FAIL;
853     }
854
855     nsAString_Init(&html_str, NULL);
856     nsres = nsIDOMNSHTMLElement_GetInnerHTML(nselem, &html_str);
857     if(NS_SUCCEEDED(nsres)) {
858         const PRUnichar *html;
859
860         nsAString_GetData(&html_str, &html);
861         *p = *html ? SysAllocString(html) : NULL;
862     }else {
863         FIXME("SetInnerHtml failed %08x\n", nsres);
864         *p = NULL;
865     }
866
867     nsAString_Finish(&html_str);
868     return S_OK;
869 }
870
871 static HRESULT WINAPI HTMLElement_put_innerText(IHTMLElement *iface, BSTR v)
872 {
873     HTMLElement *This = HTMLELEM_THIS(iface);
874     nsIDOMNode *nschild, *tmp;
875     nsIDOMText *text_node;
876     nsAString text_str;
877     nsresult nsres;
878
879     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
880
881     while(1) {
882         nsres = nsIDOMHTMLElement_GetLastChild(This->nselem, &nschild);
883         if(NS_FAILED(nsres)) {
884             ERR("GetLastChild failed: %08x\n", nsres);
885             return E_FAIL;
886         }
887         if(!nschild)
888             break;
889
890         nsres = nsIDOMHTMLElement_RemoveChild(This->nselem, nschild, &tmp);
891         nsIDOMNode_Release(nschild);
892         if(NS_FAILED(nsres)) {
893             ERR("RemoveChild failed: %08x\n", nsres);
894             return E_FAIL;
895         }
896         nsIDOMNode_Release(tmp);
897     }
898
899     nsAString_Init(&text_str, v);
900     nsres = nsIDOMHTMLDocument_CreateTextNode(This->node.doc->nsdoc, &text_str, &text_node);
901     nsAString_Finish(&text_str);
902     if(NS_FAILED(nsres)) {
903         ERR("CreateTextNode failed: %08x\n", nsres);
904         return E_FAIL;
905     }
906
907     nsres = nsIDOMHTMLElement_AppendChild(This->nselem, (nsIDOMNode*)text_node, &tmp);
908     if(NS_FAILED(nsres)) {
909         ERR("AppendChild failed: %08x\n", nsres);
910         return E_FAIL;
911     }
912
913     nsIDOMNode_Release(tmp);
914     return S_OK;
915 }
916
917 static HRESULT WINAPI HTMLElement_get_innerText(IHTMLElement *iface, BSTR *p)
918 {
919     HTMLElement *This = HTMLELEM_THIS(iface);
920
921     TRACE("(%p)->(%p)\n", This, p);
922
923     return get_node_text(&This->node, p);
924 }
925
926 static HRESULT WINAPI HTMLElement_put_outerHTML(IHTMLElement *iface, BSTR v)
927 {
928     HTMLElement *This = HTMLELEM_THIS(iface);
929     nsIDOMDocumentFragment *nsfragment;
930     nsIDOMDocumentRange *nsdocrange;
931     nsIDOMNSRange *nsrange;
932     nsIDOMNode *nsparent;
933     nsIDOMRange *range;
934     nsAString html_str;
935     nsresult nsres;
936     HRESULT hres = S_OK;
937
938     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
939
940     nsres = nsIDOMHTMLDocument_QueryInterface(This->node.doc->nsdoc, &IID_nsIDOMDocumentRange, (void**)&nsdocrange);
941     if(NS_FAILED(nsres))
942         return E_FAIL;
943
944     nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &range);
945     nsIDOMDocumentRange_Release(nsdocrange);
946     if(NS_FAILED(nsres)) {
947         ERR("CreateRange failed: %08x\n", nsres);
948         return E_FAIL;
949     }
950
951     nsres = nsIDOMRange_QueryInterface(range, &IID_nsIDOMNSRange, (void**)&nsrange);
952     nsIDOMRange_Release(range);
953     if(NS_FAILED(nsres)) {
954         ERR("Could not get nsIDOMNSRange: %08x\n", nsres);
955         return E_FAIL;
956     }
957
958     nsAString_Init(&html_str, v);
959     nsIDOMNSRange_CreateContextualFragment(nsrange, &html_str, &nsfragment);
960     nsIDOMNSRange_Release(nsrange);
961     nsAString_Finish(&html_str);
962     if(NS_FAILED(nsres)) {
963         ERR("CreateContextualFragment failed: %08x\n", nsres);
964         return E_FAIL;
965     }
966
967     nsres = nsIDOMNode_GetParentNode(This->node.nsnode, &nsparent);
968     if(NS_SUCCEEDED(nsres) && nsparent) {
969         nsIDOMNode *nstmp;
970
971         nsres = nsIDOMNode_ReplaceChild(nsparent, (nsIDOMNode*)nsfragment, This->node.nsnode, &nstmp);
972         nsIDOMNode_Release(nsparent);
973         if(NS_FAILED(nsres)) {
974             ERR("ReplaceChild failed: %08x\n", nsres);
975             hres = E_FAIL;
976         }else if(nstmp) {
977             nsIDOMNode_Release(nstmp);
978         }
979     }else {
980         ERR("GetParentNode failed: %08x\n", nsres);
981         hres = E_FAIL;
982     }
983
984     nsIDOMDocumentFragment_Release(nsfragment);
985     return hres;
986 }
987
988 static HRESULT WINAPI HTMLElement_get_outerHTML(IHTMLElement *iface, BSTR *p)
989 {
990     HTMLElement *This = HTMLELEM_THIS(iface);
991     nsAString html_str;
992     HRESULT hres;
993
994     WARN("(%p)->(%p) semi-stub\n", This, p);
995
996     nsAString_Init(&html_str, NULL);
997     hres = nsnode_to_nsstring(This->node.nsnode, &html_str);
998     if(SUCCEEDED(hres)) {
999         const PRUnichar *html;
1000
1001         nsAString_GetData(&html_str, &html);
1002         *p = SysAllocString(html);
1003         if(!*p)
1004             hres = E_OUTOFMEMORY;
1005     }
1006
1007     nsAString_Finish(&html_str);
1008
1009     TRACE("ret %s\n", debugstr_w(*p));
1010     return S_OK;
1011 }
1012
1013 static HRESULT WINAPI HTMLElement_put_outerText(IHTMLElement *iface, BSTR v)
1014 {
1015     HTMLElement *This = HTMLELEM_THIS(iface);
1016     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
1017     return E_NOTIMPL;
1018 }
1019
1020 static HRESULT WINAPI HTMLElement_get_outerText(IHTMLElement *iface, BSTR *p)
1021 {
1022     HTMLElement *This = HTMLELEM_THIS(iface);
1023     FIXME("(%p)->(%p)\n", This, p);
1024     return E_NOTIMPL;
1025 }
1026
1027 static HRESULT HTMLElement_InsertAdjacentNode(HTMLElement *This, BSTR where, nsIDOMNode *nsnode)
1028 {
1029     static const WCHAR wszBeforeBegin[] = {'b','e','f','o','r','e','B','e','g','i','n',0};
1030     static const WCHAR wszAfterBegin[] = {'a','f','t','e','r','B','e','g','i','n',0};
1031     static const WCHAR wszBeforeEnd[] = {'b','e','f','o','r','e','E','n','d',0};
1032     static const WCHAR wszAfterEnd[] = {'a','f','t','e','r','E','n','d',0};
1033     nsresult nsres;
1034
1035     if (!strcmpiW(where, wszBeforeBegin))
1036     {
1037         nsIDOMNode *unused;
1038         nsIDOMNode *parent;
1039         nsres = nsIDOMNode_GetParentNode(This->node.nsnode, &parent);
1040         if (!parent) return E_INVALIDARG;
1041         nsres = nsIDOMNode_InsertBefore(parent, nsnode, This->node.nsnode, &unused);
1042         if (unused) nsIDOMNode_Release(unused);
1043         nsIDOMNode_Release(parent);
1044     }
1045     else if (!strcmpiW(where, wszAfterBegin))
1046     {
1047         nsIDOMNode *unused;
1048         nsIDOMNode *first_child;
1049         nsIDOMNode_GetFirstChild(This->node.nsnode, &first_child);
1050         nsres = nsIDOMNode_InsertBefore(This->node.nsnode, nsnode, first_child, &unused);
1051         if (unused) nsIDOMNode_Release(unused);
1052         if (first_child) nsIDOMNode_Release(first_child);
1053     }
1054     else if (!strcmpiW(where, wszBeforeEnd))
1055     {
1056         nsIDOMNode *unused;
1057         nsres = nsIDOMNode_AppendChild(This->node.nsnode, nsnode, &unused);
1058         if (unused) nsIDOMNode_Release(unused);
1059     }
1060     else if (!strcmpiW(where, wszAfterEnd))
1061     {
1062         nsIDOMNode *unused;
1063         nsIDOMNode *next_sibling;
1064         nsIDOMNode *parent;
1065         nsIDOMNode_GetParentNode(This->node.nsnode, &parent);
1066         if (!parent) return E_INVALIDARG;
1067
1068         nsIDOMNode_GetNextSibling(This->node.nsnode, &next_sibling);
1069         if (next_sibling)
1070         {
1071             nsres = nsIDOMNode_InsertBefore(parent, nsnode, next_sibling, &unused);
1072             nsIDOMNode_Release(next_sibling);
1073         }
1074         else
1075             nsres = nsIDOMNode_AppendChild(parent, nsnode, &unused);
1076         nsIDOMNode_Release(parent);
1077         if (unused) nsIDOMNode_Release(unused);
1078     }
1079     else
1080     {
1081         ERR("invalid where: %s\n", debugstr_w(where));
1082         return E_INVALIDARG;
1083     }
1084
1085     if (NS_FAILED(nsres))
1086         return E_FAIL;
1087     else
1088         return S_OK;
1089 }
1090
1091 static HRESULT WINAPI HTMLElement_insertAdjacentHTML(IHTMLElement *iface, BSTR where,
1092                                                      BSTR html)
1093 {
1094     HTMLElement *This = HTMLELEM_THIS(iface);
1095     nsIDOMDocumentRange *nsdocrange;
1096     nsIDOMRange *range;
1097     nsIDOMNSRange *nsrange;
1098     nsIDOMNode *nsnode;
1099     nsAString ns_html;
1100     nsresult nsres;
1101     HRESULT hr;
1102
1103     TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(html));
1104
1105     if(!This->node.doc->nsdoc) {
1106         WARN("NULL nsdoc\n");
1107         return E_UNEXPECTED;
1108     }
1109
1110     nsres = nsIDOMDocument_QueryInterface(This->node.doc->nsdoc, &IID_nsIDOMDocumentRange, (void **)&nsdocrange);
1111     if(NS_FAILED(nsres))
1112     {
1113         ERR("getting nsIDOMDocumentRange failed: %08x\n", nsres);
1114         return E_FAIL;
1115     }
1116     nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &range);
1117     nsIDOMDocumentRange_Release(nsdocrange);
1118     if(NS_FAILED(nsres))
1119     {
1120         ERR("CreateRange failed: %08x\n", nsres);
1121         return E_FAIL;
1122     }
1123
1124     nsIDOMRange_SetStartBefore(range, This->node.nsnode);
1125
1126     nsIDOMRange_QueryInterface(range, &IID_nsIDOMNSRange, (void **)&nsrange);
1127     nsIDOMRange_Release(range);
1128     if(NS_FAILED(nsres))
1129     {
1130         ERR("getting nsIDOMNSRange failed: %08x\n", nsres);
1131         return E_FAIL;
1132     }
1133
1134     nsAString_Init(&ns_html, html);
1135
1136     nsres = nsIDOMNSRange_CreateContextualFragment(nsrange, &ns_html, (nsIDOMDocumentFragment **)&nsnode);
1137     nsIDOMNSRange_Release(nsrange);
1138     nsAString_Finish(&ns_html);
1139
1140     if(NS_FAILED(nsres) || !nsnode)
1141     {
1142         ERR("CreateTextNode failed: %08x\n", nsres);
1143         return E_FAIL;
1144     }
1145
1146     hr = HTMLElement_InsertAdjacentNode(This, where, nsnode);
1147     nsIDOMNode_Release(nsnode);
1148
1149     return hr;
1150 }
1151
1152 static HRESULT WINAPI HTMLElement_insertAdjacentText(IHTMLElement *iface, BSTR where,
1153                                                      BSTR text)
1154 {
1155     HTMLElement *This = HTMLELEM_THIS(iface);
1156     nsIDOMNode *nsnode;
1157     nsAString ns_text;
1158     nsresult nsres;
1159     HRESULT hr;
1160
1161     TRACE("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(text));
1162
1163     if(!This->node.doc->nsdoc) {
1164         WARN("NULL nsdoc\n");
1165         return E_UNEXPECTED;
1166     }
1167
1168
1169     nsAString_Init(&ns_text, text);
1170     nsres = nsIDOMDocument_CreateTextNode(This->node.doc->nsdoc, &ns_text, (nsIDOMText **)&nsnode);
1171     nsAString_Finish(&ns_text);
1172
1173     if(NS_FAILED(nsres) || !nsnode)
1174     {
1175         ERR("CreateTextNode failed: %08x\n", nsres);
1176         return E_FAIL;
1177     }
1178
1179     hr = HTMLElement_InsertAdjacentNode(This, where, nsnode);
1180     nsIDOMNode_Release(nsnode);
1181
1182     return hr;
1183 }
1184
1185 static HRESULT WINAPI HTMLElement_get_parentTextEdit(IHTMLElement *iface, IHTMLElement **p)
1186 {
1187     HTMLElement *This = HTMLELEM_THIS(iface);
1188     FIXME("(%p)->(%p)\n", This, p);
1189     return E_NOTIMPL;
1190 }
1191
1192 static HRESULT WINAPI HTMLElement_get_isTextEdit(IHTMLElement *iface, VARIANT_BOOL *p)
1193 {
1194     HTMLElement *This = HTMLELEM_THIS(iface);
1195     FIXME("(%p)->(%p)\n", This, p);
1196     return E_NOTIMPL;
1197 }
1198
1199 static HRESULT WINAPI HTMLElement_click(IHTMLElement *iface)
1200 {
1201     HTMLElement *This = HTMLELEM_THIS(iface);
1202
1203     TRACE("(%p)\n", This);
1204
1205     return call_event(&This->node, EVENTID_CLICK);
1206 }
1207
1208 static HRESULT WINAPI HTMLElement_get_filters(IHTMLElement *iface,
1209                                               IHTMLFiltersCollection **p)
1210 {
1211     HTMLElement *This = HTMLELEM_THIS(iface);
1212     TRACE("(%p)->(%p)\n", This, p);
1213
1214     if(!p)
1215         return E_POINTER;
1216
1217     *p = HTMLFiltersCollection_Create();
1218
1219     return S_OK;
1220 }
1221
1222 static HRESULT WINAPI HTMLElement_put_ondragstart(IHTMLElement *iface, VARIANT v)
1223 {
1224     HTMLElement *This = HTMLELEM_THIS(iface);
1225     FIXME("(%p)->()\n", This);
1226     return E_NOTIMPL;
1227 }
1228
1229 static HRESULT WINAPI HTMLElement_get_ondragstart(IHTMLElement *iface, VARIANT *p)
1230 {
1231     HTMLElement *This = HTMLELEM_THIS(iface);
1232     FIXME("(%p)->(%p)\n", This, p);
1233     return E_NOTIMPL;
1234 }
1235
1236 static HRESULT WINAPI HTMLElement_toString(IHTMLElement *iface, BSTR *String)
1237 {
1238     HTMLElement *This = HTMLELEM_THIS(iface);
1239     FIXME("(%p)->(%p)\n", This, String);
1240     return E_NOTIMPL;
1241 }
1242
1243 static HRESULT WINAPI HTMLElement_put_onbeforeupdate(IHTMLElement *iface, VARIANT v)
1244 {
1245     HTMLElement *This = HTMLELEM_THIS(iface);
1246     FIXME("(%p)->()\n", This);
1247     return E_NOTIMPL;
1248 }
1249
1250 static HRESULT WINAPI HTMLElement_get_onbeforeupdate(IHTMLElement *iface, VARIANT *p)
1251 {
1252     HTMLElement *This = HTMLELEM_THIS(iface);
1253     FIXME("(%p)->(%p)\n", This, p);
1254     return E_NOTIMPL;
1255 }
1256
1257 static HRESULT WINAPI HTMLElement_put_onafterupdate(IHTMLElement *iface, VARIANT v)
1258 {
1259     HTMLElement *This = HTMLELEM_THIS(iface);
1260     FIXME("(%p)->()\n", This);
1261     return E_NOTIMPL;
1262 }
1263
1264 static HRESULT WINAPI HTMLElement_get_onafterupdate(IHTMLElement *iface, VARIANT *p)
1265 {
1266     HTMLElement *This = HTMLELEM_THIS(iface);
1267     FIXME("(%p)->(%p)\n", This, p);
1268     return E_NOTIMPL;
1269 }
1270
1271 static HRESULT WINAPI HTMLElement_put_onerrorupdate(IHTMLElement *iface, VARIANT v)
1272 {
1273     HTMLElement *This = HTMLELEM_THIS(iface);
1274     FIXME("(%p)->()\n", This);
1275     return E_NOTIMPL;
1276 }
1277
1278 static HRESULT WINAPI HTMLElement_get_onerrorupdate(IHTMLElement *iface, VARIANT *p)
1279 {
1280     HTMLElement *This = HTMLELEM_THIS(iface);
1281     FIXME("(%p)->(%p)\n", This, p);
1282     return E_NOTIMPL;
1283 }
1284
1285 static HRESULT WINAPI HTMLElement_put_onrowexit(IHTMLElement *iface, VARIANT v)
1286 {
1287     HTMLElement *This = HTMLELEM_THIS(iface);
1288     FIXME("(%p)->()\n", This);
1289     return E_NOTIMPL;
1290 }
1291
1292 static HRESULT WINAPI HTMLElement_get_onrowexit(IHTMLElement *iface, VARIANT *p)
1293 {
1294     HTMLElement *This = HTMLELEM_THIS(iface);
1295     FIXME("(%p)->(%p)\n", This, p);
1296     return E_NOTIMPL;
1297 }
1298
1299 static HRESULT WINAPI HTMLElement_put_onrowenter(IHTMLElement *iface, VARIANT v)
1300 {
1301     HTMLElement *This = HTMLELEM_THIS(iface);
1302     FIXME("(%p)->()\n", This);
1303     return E_NOTIMPL;
1304 }
1305
1306 static HRESULT WINAPI HTMLElement_get_onrowenter(IHTMLElement *iface, VARIANT *p)
1307 {
1308     HTMLElement *This = HTMLELEM_THIS(iface);
1309     FIXME("(%p)->(%p)\n", This, p);
1310     return E_NOTIMPL;
1311 }
1312
1313 static HRESULT WINAPI HTMLElement_put_ondatasetchanged(IHTMLElement *iface, VARIANT v)
1314 {
1315     HTMLElement *This = HTMLELEM_THIS(iface);
1316     FIXME("(%p)->()\n", This);
1317     return E_NOTIMPL;
1318 }
1319
1320 static HRESULT WINAPI HTMLElement_get_ondatasetchanged(IHTMLElement *iface, VARIANT *p)
1321 {
1322     HTMLElement *This = HTMLELEM_THIS(iface);
1323     FIXME("(%p)->(%p)\n", This, p);
1324     return E_NOTIMPL;
1325 }
1326
1327 static HRESULT WINAPI HTMLElement_put_ondataavailable(IHTMLElement *iface, VARIANT v)
1328 {
1329     HTMLElement *This = HTMLELEM_THIS(iface);
1330     FIXME("(%p)->()\n", This);
1331     return E_NOTIMPL;
1332 }
1333
1334 static HRESULT WINAPI HTMLElement_get_ondataavailable(IHTMLElement *iface, VARIANT *p)
1335 {
1336     HTMLElement *This = HTMLELEM_THIS(iface);
1337     FIXME("(%p)->(%p)\n", This, p);
1338     return E_NOTIMPL;
1339 }
1340
1341 static HRESULT WINAPI HTMLElement_put_ondatasetcomplete(IHTMLElement *iface, VARIANT v)
1342 {
1343     HTMLElement *This = HTMLELEM_THIS(iface);
1344     FIXME("(%p)->()\n", This);
1345     return E_NOTIMPL;
1346 }
1347
1348 static HRESULT WINAPI HTMLElement_get_ondatasetcomplete(IHTMLElement *iface, VARIANT *p)
1349 {
1350     HTMLElement *This = HTMLELEM_THIS(iface);
1351     FIXME("(%p)->(%p)\n", This, p);
1352     return E_NOTIMPL;
1353 }
1354
1355 static HRESULT WINAPI HTMLElement_put_onfilterchange(IHTMLElement *iface, VARIANT v)
1356 {
1357     HTMLElement *This = HTMLELEM_THIS(iface);
1358     FIXME("(%p)->()\n", This);
1359     return E_NOTIMPL;
1360 }
1361
1362 static HRESULT WINAPI HTMLElement_get_onfilterchange(IHTMLElement *iface, VARIANT *p)
1363 {
1364     HTMLElement *This = HTMLELEM_THIS(iface);
1365     FIXME("(%p)->(%p)\n", This, p);
1366     return E_NOTIMPL;
1367 }
1368
1369 static HRESULT WINAPI HTMLElement_get_children(IHTMLElement *iface, IDispatch **p)
1370 {
1371     HTMLElement *This = HTMLELEM_THIS(iface);
1372     nsIDOMNodeList *nsnode_list;
1373     nsresult nsres;
1374
1375     TRACE("(%p)->(%p)\n", This, p);
1376
1377     nsres = nsIDOMNode_GetChildNodes(This->node.nsnode, &nsnode_list);
1378     if(NS_FAILED(nsres)) {
1379         ERR("GetChildNodes failed: %08x\n", nsres);
1380         return E_FAIL;
1381     }
1382
1383     *p = (IDispatch*)create_collection_from_nodelist(This->node.doc, (IUnknown*)HTMLELEM(This), nsnode_list);
1384
1385     nsIDOMNodeList_Release(nsnode_list);
1386     return S_OK;
1387 }
1388
1389 static HRESULT WINAPI HTMLElement_get_all(IHTMLElement *iface, IDispatch **p)
1390 {
1391     HTMLElement *This = HTMLELEM_THIS(iface);
1392
1393     TRACE("(%p)->(%p)\n", This, p);
1394
1395     *p = (IDispatch*)create_all_collection(&This->node, FALSE);
1396     return S_OK;
1397 }
1398
1399 static HRESULT HTMLElement_get_dispid(IUnknown *iface, BSTR name,
1400         DWORD grfdex, DISPID *pid)
1401 {
1402     HTMLElement *This = HTMLELEM_THIS(iface);
1403
1404     if(This->node.vtbl->get_dispid)
1405         return This->node.vtbl->get_dispid(&This->node, name, grfdex, pid);
1406
1407     return DISP_E_UNKNOWNNAME;
1408 }
1409
1410 static HRESULT HTMLElement_invoke(IUnknown *iface, DISPID id, LCID lcid,
1411         WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei,
1412         IServiceProvider *caller)
1413 {
1414     HTMLElement *This = HTMLELEM_THIS(iface);
1415
1416     if(This->node.vtbl->invoke)
1417         return This->node.vtbl->invoke(&This->node, id, lcid, flags,
1418                 params, res, ei, caller);
1419
1420     ERR("(%p): element has no invoke method\n", This);
1421     return E_NOTIMPL;
1422 }
1423
1424 #undef HTMLELEM_THIS
1425
1426 static const IHTMLElementVtbl HTMLElementVtbl = {
1427     HTMLElement_QueryInterface,
1428     HTMLElement_AddRef,
1429     HTMLElement_Release,
1430     HTMLElement_GetTypeInfoCount,
1431     HTMLElement_GetTypeInfo,
1432     HTMLElement_GetIDsOfNames,
1433     HTMLElement_Invoke,
1434     HTMLElement_setAttribute,
1435     HTMLElement_getAttribute,
1436     HTMLElement_removeAttribute,
1437     HTMLElement_put_className,
1438     HTMLElement_get_className,
1439     HTMLElement_put_id,
1440     HTMLElement_get_id,
1441     HTMLElement_get_tagName,
1442     HTMLElement_get_parentElement,
1443     HTMLElement_get_style,
1444     HTMLElement_put_onhelp,
1445     HTMLElement_get_onhelp,
1446     HTMLElement_put_onclick,
1447     HTMLElement_get_onclick,
1448     HTMLElement_put_ondblclick,
1449     HTMLElement_get_ondblclick,
1450     HTMLElement_put_onkeydown,
1451     HTMLElement_get_onkeydown,
1452     HTMLElement_put_onkeyup,
1453     HTMLElement_get_onkeyup,
1454     HTMLElement_put_onkeypress,
1455     HTMLElement_get_onkeypress,
1456     HTMLElement_put_onmouseout,
1457     HTMLElement_get_onmouseout,
1458     HTMLElement_put_onmouseover,
1459     HTMLElement_get_onmouseover,
1460     HTMLElement_put_onmousemove,
1461     HTMLElement_get_onmousemove,
1462     HTMLElement_put_onmousedown,
1463     HTMLElement_get_onmousedown,
1464     HTMLElement_put_onmouseup,
1465     HTMLElement_get_onmouseup,
1466     HTMLElement_get_document,
1467     HTMLElement_put_title,
1468     HTMLElement_get_title,
1469     HTMLElement_put_language,
1470     HTMLElement_get_language,
1471     HTMLElement_put_onselectstart,
1472     HTMLElement_get_onselectstart,
1473     HTMLElement_scrollIntoView,
1474     HTMLElement_contains,
1475     HTMLElement_get_sourceIndex,
1476     HTMLElement_get_recordNumber,
1477     HTMLElement_put_lang,
1478     HTMLElement_get_lang,
1479     HTMLElement_get_offsetLeft,
1480     HTMLElement_get_offsetTop,
1481     HTMLElement_get_offsetWidth,
1482     HTMLElement_get_offsetHeight,
1483     HTMLElement_get_offsetParent,
1484     HTMLElement_put_innerHTML,
1485     HTMLElement_get_innerHTML,
1486     HTMLElement_put_innerText,
1487     HTMLElement_get_innerText,
1488     HTMLElement_put_outerHTML,
1489     HTMLElement_get_outerHTML,
1490     HTMLElement_put_outerText,
1491     HTMLElement_get_outerText,
1492     HTMLElement_insertAdjacentHTML,
1493     HTMLElement_insertAdjacentText,
1494     HTMLElement_get_parentTextEdit,
1495     HTMLElement_get_isTextEdit,
1496     HTMLElement_click,
1497     HTMLElement_get_filters,
1498     HTMLElement_put_ondragstart,
1499     HTMLElement_get_ondragstart,
1500     HTMLElement_toString,
1501     HTMLElement_put_onbeforeupdate,
1502     HTMLElement_get_onbeforeupdate,
1503     HTMLElement_put_onafterupdate,
1504     HTMLElement_get_onafterupdate,
1505     HTMLElement_put_onerrorupdate,
1506     HTMLElement_get_onerrorupdate,
1507     HTMLElement_put_onrowexit,
1508     HTMLElement_get_onrowexit,
1509     HTMLElement_put_onrowenter,
1510     HTMLElement_get_onrowenter,
1511     HTMLElement_put_ondatasetchanged,
1512     HTMLElement_get_ondatasetchanged,
1513     HTMLElement_put_ondataavailable,
1514     HTMLElement_get_ondataavailable,
1515     HTMLElement_put_ondatasetcomplete,
1516     HTMLElement_get_ondatasetcomplete,
1517     HTMLElement_put_onfilterchange,
1518     HTMLElement_get_onfilterchange,
1519     HTMLElement_get_children,
1520     HTMLElement_get_all
1521 };
1522
1523 HRESULT HTMLElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
1524 {
1525     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
1526
1527     *ppv =  NULL;
1528
1529     if(IsEqualGUID(&IID_IUnknown, riid)) {
1530         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1531         *ppv = HTMLELEM(This);
1532     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1533         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
1534         *ppv = HTMLELEM(This);
1535     }else if(IsEqualGUID(&IID_IHTMLElement, riid)) {
1536         TRACE("(%p)->(IID_IHTMLElement %p)\n", This, ppv);
1537         *ppv = HTMLELEM(This);
1538     }else if(IsEqualGUID(&IID_IHTMLElement2, riid)) {
1539         TRACE("(%p)->(IID_IHTMLElement2 %p)\n", This, ppv);
1540         *ppv = HTMLELEM2(This);
1541     }else if(IsEqualGUID(&IID_IHTMLElement3, riid)) {
1542         TRACE("(%p)->(IID_IHTMLElement3 %p)\n", This, ppv);
1543         *ppv = HTMLELEM3(This);
1544     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
1545         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
1546         *ppv = CONPTCONT(&This->cp_container);
1547     }
1548
1549     if(*ppv) {
1550         IHTMLElement_AddRef(HTMLELEM(This));
1551         return S_OK;
1552     }
1553
1554     return HTMLDOMNode_QI(&This->node, riid, ppv);
1555 }
1556
1557 void HTMLElement_destructor(HTMLDOMNode *iface)
1558 {
1559     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
1560
1561     ConnectionPointContainer_Destroy(&This->cp_container);
1562
1563     if(This->nselem)
1564         nsIDOMHTMLElement_Release(This->nselem);
1565
1566     HTMLDOMNode_destructor(&This->node);
1567 }
1568
1569 static const NodeImplVtbl HTMLElementImplVtbl = {
1570     HTMLElement_QI,
1571     HTMLElement_destructor
1572 };
1573
1574 static const tid_t HTMLElement_iface_tids[] = {
1575     HTMLELEMENT_TIDS,
1576     0
1577 };
1578
1579 static dispex_static_data_vtbl_t HTMLElement_dispex_vtbl = {
1580     NULL,
1581     HTMLElement_get_dispid,
1582     HTMLElement_invoke
1583 };
1584
1585 static dispex_static_data_t HTMLElement_dispex = {
1586     &HTMLElement_dispex_vtbl,
1587     DispHTMLUnknownElement_tid,
1588     NULL,
1589     HTMLElement_iface_tids
1590 };
1591
1592 void HTMLElement_Init(HTMLElement *This, HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, dispex_static_data_t *dispex_data)
1593 {
1594     This->lpHTMLElementVtbl = &HTMLElementVtbl;
1595
1596     HTMLElement2_Init(This);
1597     HTMLElement3_Init(This);
1598
1599     if(dispex_data && !dispex_data->vtbl)
1600         dispex_data->vtbl = &HTMLElement_dispex_vtbl;
1601     init_dispex(&This->node.dispex, (IUnknown*)HTMLELEM(This), dispex_data ? dispex_data : &HTMLElement_dispex);
1602
1603     if(nselem)
1604         nsIDOMHTMLElement_AddRef(nselem);
1605     This->nselem = nselem;
1606
1607     HTMLDOMNode_Init(doc, &This->node, (nsIDOMNode*)nselem);
1608
1609     ConnectionPointContainer_Init(&This->cp_container, (IUnknown*)HTMLELEM(This));
1610 }
1611
1612 HTMLElement *HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL use_generic)
1613 {
1614     nsIDOMHTMLElement *nselem;
1615     HTMLElement *ret = NULL;
1616     nsAString class_name_str;
1617     const PRUnichar *class_name;
1618     nsresult nsres;
1619
1620     static const WCHAR wszA[]        = {'A',0};
1621     static const WCHAR wszBODY[]     = {'B','O','D','Y',0};
1622     static const WCHAR wszFORM[]     = {'F','O','R','M',0};
1623     static const WCHAR wszFRAME[]    = {'F','R','A','M','E',0};
1624     static const WCHAR wszIFRAME[]   = {'I','F','R','A','M','E',0};
1625     static const WCHAR wszIMG[]      = {'I','M','G',0};
1626     static const WCHAR wszINPUT[]    = {'I','N','P','U','T',0};
1627     static const WCHAR wszOPTION[]   = {'O','P','T','I','O','N',0};
1628     static const WCHAR wszSCRIPT[]   = {'S','C','R','I','P','T',0};
1629     static const WCHAR wszSELECT[]   = {'S','E','L','E','C','T',0};
1630     static const WCHAR wszTABLE[]    = {'T','A','B','L','E',0};
1631     static const WCHAR wszTR[]       = {'T','R',0};
1632     static const WCHAR wszTEXTAREA[] = {'T','E','X','T','A','R','E','A',0};
1633
1634     nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMHTMLElement, (void**)&nselem);
1635     if(NS_FAILED(nsres))
1636         return NULL;
1637
1638     nsAString_Init(&class_name_str, NULL);
1639     nsIDOMHTMLElement_GetTagName(nselem, &class_name_str);
1640
1641     nsAString_GetData(&class_name_str, &class_name);
1642
1643     if(!strcmpW(class_name, wszA))
1644         ret = HTMLAnchorElement_Create(doc, nselem);
1645     else if(!strcmpW(class_name, wszBODY))
1646         ret = HTMLBodyElement_Create(doc, nselem);
1647     else if(!strcmpW(class_name, wszFORM))
1648         ret = HTMLFormElement_Create(doc, nselem);
1649     else if(!strcmpW(class_name, wszFRAME))
1650         ret = HTMLFrameElement_Create(doc, nselem);
1651     else if(!strcmpW(class_name, wszIFRAME))
1652         ret = HTMLIFrame_Create(doc, nselem);
1653     else if(!strcmpW(class_name, wszIMG))
1654         ret = HTMLImgElement_Create(doc, nselem);
1655     else if(!strcmpW(class_name, wszINPUT))
1656         ret = HTMLInputElement_Create(doc, nselem);
1657     else if(!strcmpW(class_name, wszOPTION))
1658         ret = HTMLOptionElement_Create(doc, nselem);
1659     else if(!strcmpW(class_name, wszSCRIPT))
1660         ret = HTMLScriptElement_Create(doc, nselem);
1661     else if(!strcmpW(class_name, wszSELECT))
1662         ret = HTMLSelectElement_Create(doc, nselem);
1663     else if(!strcmpW(class_name, wszTABLE))
1664         ret = HTMLTable_Create(doc, nselem);
1665     else if(!strcmpW(class_name, wszTR))
1666         ret = HTMLTableRow_Create(doc, nselem);
1667     else if(!strcmpW(class_name, wszTEXTAREA))
1668         ret = HTMLTextAreaElement_Create(doc, nselem);
1669     else if(use_generic)
1670         ret = HTMLGenericElement_Create(doc, nselem);
1671
1672     if(!ret) {
1673         ret = heap_alloc_zero(sizeof(HTMLElement));
1674         HTMLElement_Init(ret, doc, nselem, &HTMLElement_dispex);
1675         ret->node.vtbl = &HTMLElementImplVtbl;
1676     }
1677
1678     TRACE("%s ret %p\n", debugstr_w(class_name), ret);
1679
1680     nsIDOMElement_Release(nselem);
1681     nsAString_Finish(&class_name_str);
1682
1683     return ret;
1684 }
1685
1686 /* interaface IHTMLFiltersCollection */
1687 static HRESULT WINAPI HTMLFiltersCollection_QueryInterface(IHTMLFiltersCollection *iface, REFIID riid, void **ppv)
1688 {
1689     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1690
1691     TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppv );
1692
1693     if(IsEqualGUID(&IID_IUnknown, riid)) {
1694         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1695         *ppv = HTMLFILTERSCOLLECTION(This);
1696     }else if(IsEqualGUID(&IID_IHTMLFiltersCollection, riid)) {
1697         TRACE("(%p)->(IID_IHTMLFiltersCollection %p)\n", This, ppv);
1698         *ppv = HTMLFILTERSCOLLECTION(This);
1699     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
1700         return *ppv ? S_OK : E_NOINTERFACE;
1701     }
1702
1703     if(*ppv) {
1704         IUnknown_AddRef((IUnknown*)*ppv);
1705         return S_OK;
1706     }
1707
1708     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1709     return E_NOINTERFACE;
1710 }
1711
1712 static ULONG WINAPI HTMLFiltersCollection_AddRef(IHTMLFiltersCollection *iface)
1713 {
1714     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1715     LONG ref = InterlockedIncrement(&This->ref);
1716
1717     TRACE("(%p) ref=%d\n", This, ref);
1718
1719     return ref;
1720 }
1721
1722 static ULONG WINAPI HTMLFiltersCollection_Release(IHTMLFiltersCollection *iface)
1723 {
1724     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1725     LONG ref = InterlockedDecrement(&This->ref);
1726
1727     TRACE("(%p) ref=%d\n", This, ref);
1728
1729     if(!ref)
1730     {
1731         heap_free(This);
1732     }
1733
1734     return ref;
1735 }
1736
1737 static HRESULT WINAPI HTMLFiltersCollection_GetTypeInfoCount(IHTMLFiltersCollection *iface, UINT *pctinfo)
1738 {
1739     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1740     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo);
1741 }
1742
1743 static HRESULT WINAPI HTMLFiltersCollection_GetTypeInfo(IHTMLFiltersCollection *iface,
1744                                     UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1745 {
1746     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1747     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo);
1748 }
1749
1750 static HRESULT WINAPI HTMLFiltersCollection_GetIDsOfNames(IHTMLFiltersCollection *iface,
1751                                     REFIID riid, LPOLESTR *rgszNames, UINT cNames,
1752                                     LCID lcid, DISPID *rgDispId)
1753 {
1754     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1755     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId);
1756 }
1757
1758 static HRESULT WINAPI HTMLFiltersCollection_Invoke(IHTMLFiltersCollection *iface, DISPID dispIdMember, REFIID riid,
1759                                     LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
1760                                     EXCEPINFO *pExcepInfo, UINT *puArgErr)
1761 {
1762     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1763     return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid,
1764             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1765 }
1766
1767 static HRESULT WINAPI HTMLFiltersCollection_get_length(IHTMLFiltersCollection *iface, LONG *p)
1768 {
1769     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1770
1771     FIXME("(%p)->(%p) Always returning 0\n", This, p);
1772
1773         if(!p)
1774                 return E_POINTER;
1775
1776     if(p)
1777         *p = 0;
1778
1779     return S_OK;
1780 }
1781
1782 static HRESULT WINAPI HTMLFiltersCollection_get__newEnum(IHTMLFiltersCollection *iface, IUnknown **p)
1783 {
1784     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1785     FIXME("(%p)->(%p)\n", This, p);
1786     return E_NOTIMPL;
1787 }
1788
1789 static HRESULT WINAPI HTMLFiltersCollection_item(IHTMLFiltersCollection *iface, VARIANT *pvarIndex, VARIANT *pvarResult)
1790 {
1791     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1792     FIXME("(%p)->(%p, %p)\n", This, pvarIndex, pvarResult);
1793     return E_NOTIMPL;
1794 }
1795
1796 static const IHTMLFiltersCollectionVtbl HTMLFiltersCollectionVtbl = {
1797     HTMLFiltersCollection_QueryInterface,
1798     HTMLFiltersCollection_AddRef,
1799     HTMLFiltersCollection_Release,
1800     HTMLFiltersCollection_GetTypeInfoCount,
1801     HTMLFiltersCollection_GetTypeInfo,
1802     HTMLFiltersCollection_GetIDsOfNames,
1803     HTMLFiltersCollection_Invoke,
1804     HTMLFiltersCollection_get_length,
1805     HTMLFiltersCollection_get__newEnum,
1806     HTMLFiltersCollection_item
1807 };
1808
1809 static HRESULT HTMLFiltersCollection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
1810 {
1811     WCHAR *ptr;
1812     int idx = 0;
1813
1814     for(ptr = name; *ptr && isdigitW(*ptr); ptr++)
1815         idx = idx*10 + (*ptr-'0');
1816     if(*ptr)
1817         return DISP_E_UNKNOWNNAME;
1818
1819     *dispid = MSHTML_DISPID_CUSTOM_MIN + idx;
1820     TRACE("ret %x\n", *dispid);
1821     return S_OK;
1822 }
1823
1824 static HRESULT HTMLFiltersCollection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
1825         VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
1826 {
1827     HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface);
1828
1829     TRACE("(%p)->(%x %x %x %p %p %p)\n", This, id, lcid, flags, params, res, ei);
1830
1831     V_VT(res) = VT_DISPATCH;
1832     V_DISPATCH(res) = NULL;
1833
1834     FIXME("always returning NULL\n");
1835
1836     return S_OK;
1837 }
1838
1839 static const dispex_static_data_vtbl_t HTMLFiltersCollection_dispex_vtbl = {
1840     NULL,
1841     HTMLFiltersCollection_get_dispid,
1842     HTMLFiltersCollection_invoke
1843 };
1844
1845 static const tid_t HTMLFiltersCollection_iface_tids[] = {
1846     IHTMLFiltersCollection_tid,
1847     0
1848 };
1849 static dispex_static_data_t HTMLFiltersCollection_dispex = {
1850     &HTMLFiltersCollection_dispex_vtbl,
1851     IHTMLFiltersCollection_tid,
1852     NULL,
1853     HTMLFiltersCollection_iface_tids
1854 };
1855
1856 IHTMLFiltersCollection *HTMLFiltersCollection_Create()
1857 {
1858     HTMLFiltersCollection *ret = heap_alloc(sizeof(HTMLFiltersCollection));
1859
1860     ret->lpHTMLFiltersCollectionVtbl = &HTMLFiltersCollectionVtbl;
1861     ret->ref = 1;
1862
1863     init_dispex(&ret->dispex, (IUnknown*)HTMLFILTERSCOLLECTION(ret),  &HTMLFiltersCollection_dispex);
1864
1865     return HTMLFILTERSCOLLECTION(ret);
1866 }