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