winex11: add owned windows to taskbar if owner is not mapped
[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 void HTMLElement_Init(HTMLElement *This)
1286 {
1287     This->node.vtbl = &HTMLElementImplVtbl;
1288     This->lpHTMLElementVtbl = &HTMLElementVtbl;
1289
1290     ConnectionPointContainer_Init(&This->cp_container, (IUnknown*)HTMLELEM(This));
1291
1292     HTMLElement2_Init(This);
1293 }
1294
1295 HTMLElement *HTMLElement_Create(nsIDOMNode *nsnode)
1296 {
1297     nsIDOMHTMLElement *nselem;
1298     HTMLElement *ret = NULL;
1299     nsAString class_name_str;
1300     const PRUnichar *class_name;
1301     nsresult nsres;
1302
1303     static const WCHAR wszA[]        = {'A',0};
1304     static const WCHAR wszBODY[]     = {'B','O','D','Y',0};
1305     static const WCHAR wszINPUT[]    = {'I','N','P','U','T',0};
1306     static const WCHAR wszOPTION[]   = {'O','P','T','I','O','N',0};
1307     static const WCHAR wszSCRIPT[]   = {'S','C','R','I','P','T',0};
1308     static const WCHAR wszSELECT[]   = {'S','E','L','E','C','T',0};
1309     static const WCHAR wszTABLE[]    = {'T','A','B','L','E',0};
1310     static const WCHAR wszTEXTAREA[] = {'T','E','X','T','A','R','E','A',0};
1311
1312     nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMHTMLElement, (void**)&nselem);
1313     if(NS_FAILED(nsres))
1314         return NULL;
1315
1316     nsAString_Init(&class_name_str, NULL);
1317     nsIDOMHTMLElement_GetTagName(nselem, &class_name_str);
1318
1319     nsAString_GetData(&class_name_str, &class_name);
1320
1321     if(!strcmpW(class_name, wszA))
1322         ret = HTMLAnchorElement_Create(nselem);
1323     else if(!strcmpW(class_name, wszBODY))
1324         ret = HTMLBodyElement_Create(nselem);
1325     else if(!strcmpW(class_name, wszINPUT))
1326         ret = HTMLInputElement_Create(nselem);
1327     else if(!strcmpW(class_name, wszOPTION))
1328         ret = HTMLOptionElement_Create(nselem);
1329     else if(!strcmpW(class_name, wszSCRIPT))
1330         ret = HTMLScriptElement_Create(nselem);
1331     else if(!strcmpW(class_name, wszSELECT))
1332         ret = HTMLSelectElement_Create(nselem);
1333     else if(!strcmpW(class_name, wszTABLE))
1334         ret = HTMLTable_Create(nselem);
1335     else if(!strcmpW(class_name, wszTEXTAREA))
1336         ret = HTMLTextAreaElement_Create(nselem);
1337
1338     if(!ret) {
1339         ret = heap_alloc(sizeof(HTMLElement));
1340         HTMLElement_Init(ret);
1341     }
1342
1343     nsAString_Finish(&class_name_str);
1344
1345     ret->nselem = nselem;
1346
1347     return ret;
1348 }
1349
1350 typedef struct {
1351     const IHTMLElementCollectionVtbl *lpHTMLElementCollectionVtbl;
1352
1353     IUnknown *ref_unk;
1354     HTMLElement **elems;
1355     DWORD len;
1356
1357     LONG ref;
1358 } HTMLElementCollection;
1359
1360 #define HTMLELEMCOL(x)  ((IHTMLElementCollection*) &(x)->lpHTMLElementCollectionVtbl)
1361
1362 #define ELEMCOL_THIS(iface) DEFINE_THIS(HTMLElementCollection, HTMLElementCollection, iface)
1363
1364 static HRESULT WINAPI HTMLElementCollection_QueryInterface(IHTMLElementCollection *iface,
1365                                                            REFIID riid, void **ppv)
1366 {
1367     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1368
1369     *ppv = NULL;
1370
1371     if(IsEqualGUID(&IID_IUnknown, riid)) {
1372         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1373         *ppv = HTMLELEMCOL(This);
1374     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1375         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
1376         *ppv = HTMLELEMCOL(This);
1377     }else if(IsEqualGUID(&IID_IHTMLElementCollection, riid)) {
1378         TRACE("(%p)->(IID_IHTMLElementCollection %p)\n", This, ppv);
1379         *ppv = HTMLELEMCOL(This);
1380     }
1381
1382     if(*ppv) {
1383         IHTMLElementCollection_AddRef(HTMLELEMCOL(This));
1384         return S_OK;
1385     }
1386
1387     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1388     return E_NOINTERFACE;
1389 }
1390
1391 static ULONG WINAPI HTMLElementCollection_AddRef(IHTMLElementCollection *iface)
1392 {
1393     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1394     LONG ref = InterlockedIncrement(&This->ref);
1395
1396     TRACE("(%p) ref=%d\n", This, ref);
1397
1398     return ref;
1399 }
1400
1401 static ULONG WINAPI HTMLElementCollection_Release(IHTMLElementCollection *iface)
1402 {
1403     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1404     LONG ref = InterlockedDecrement(&This->ref);
1405
1406     TRACE("(%p) ref=%d\n", This, ref);
1407
1408     if(!ref) {
1409         IUnknown_Release(This->ref_unk);
1410         heap_free(This->elems);
1411         heap_free(This);
1412     }
1413
1414     return ref;
1415 }
1416
1417 static HRESULT WINAPI HTMLElementCollection_GetTypeInfoCount(IHTMLElementCollection *iface,
1418                                                              UINT *pctinfo)
1419 {
1420     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1421     FIXME("(%p)->(%p)\n", This, pctinfo);
1422     return E_NOTIMPL;
1423 }
1424
1425 static HRESULT WINAPI HTMLElementCollection_GetTypeInfo(IHTMLElementCollection *iface,
1426         UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1427 {
1428     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1429     FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
1430     return E_NOTIMPL;
1431 }
1432
1433 static HRESULT WINAPI HTMLElementCollection_GetIDsOfNames(IHTMLElementCollection *iface,
1434         REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1435 {
1436     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1437     FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1438                                         lcid, rgDispId);
1439     return E_NOTIMPL;
1440 }
1441
1442 static HRESULT WINAPI HTMLElementCollection_Invoke(IHTMLElementCollection *iface,
1443         DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1444         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1445 {
1446     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1447     FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1448             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1449     return E_NOTIMPL;
1450 }
1451
1452 static HRESULT WINAPI HTMLElementCollection_toString(IHTMLElementCollection *iface,
1453                                                      BSTR *String)
1454 {
1455     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1456     FIXME("(%p)->(%p)\n", This, String);
1457     return E_NOTIMPL;
1458 }
1459
1460 static HRESULT WINAPI HTMLElementCollection_put_length(IHTMLElementCollection *iface,
1461                                                        long v)
1462 {
1463     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1464     FIXME("(%p)->(%ld)\n", This, v);
1465     return E_NOTIMPL;
1466 }
1467
1468 static HRESULT WINAPI HTMLElementCollection_get_length(IHTMLElementCollection *iface,
1469                                                        long *p)
1470 {
1471     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1472
1473     TRACE("(%p)->(%p)\n", This, p);
1474
1475     *p = This->len;
1476     return S_OK;
1477 }
1478
1479 static HRESULT WINAPI HTMLElementCollection_get__newEnum(IHTMLElementCollection *iface,
1480                                                          IUnknown **p)
1481 {
1482     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1483     FIXME("(%p)->(%p)\n", This, p);
1484     return E_NOTIMPL;
1485 }
1486
1487 static BOOL is_elem_name(HTMLElement *elem, LPCWSTR name)
1488 {
1489     const PRUnichar *str;
1490     nsAString nsstr, nsname;
1491     BOOL ret = FALSE;
1492     nsresult nsres;
1493
1494     static const PRUnichar nameW[] = {'n','a','m','e',0};
1495
1496     nsAString_Init(&nsstr, NULL);
1497     nsIDOMHTMLElement_GetId(elem->nselem, &nsstr);
1498     nsAString_GetData(&nsstr, &str);
1499     if(!strcmpiW(str, name)) {
1500         nsAString_Finish(&nsstr);
1501         return TRUE;
1502     }
1503
1504     nsAString_Init(&nsname, nameW);
1505     nsres =  nsIDOMHTMLElement_GetAttribute(elem->nselem, &nsname, &nsstr);
1506     nsAString_Finish(&nsname);
1507     if(NS_SUCCEEDED(nsres)) {
1508         nsAString_GetData(&nsstr, &str);
1509         ret = !strcmpiW(str, name);
1510     }
1511
1512     nsAString_Finish(&nsstr);
1513     return ret;
1514 }
1515
1516 static HRESULT WINAPI HTMLElementCollection_item(IHTMLElementCollection *iface,
1517         VARIANT name, VARIANT index, IDispatch **pdisp)
1518 {
1519     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1520
1521     TRACE("(%p)->(v(%d) v(%d) %p)\n", This, V_VT(&name), V_VT(&index), pdisp);
1522
1523     *pdisp = NULL;
1524
1525     if(V_VT(&name) == VT_I4) {
1526         TRACE("name is VT_I4: %d\n", V_I4(&name));
1527
1528         if(V_I4(&name) < 0)
1529             return E_INVALIDARG;
1530         if(V_I4(&name) >= This->len)
1531             return S_OK;
1532
1533         *pdisp = (IDispatch*)This->elems[V_I4(&name)];
1534         IDispatch_AddRef(*pdisp);
1535         TRACE("Returning pdisp=%p\n", pdisp);
1536         return S_OK;
1537     }
1538
1539     if(V_VT(&name) == VT_BSTR) {
1540         DWORD i;
1541
1542         TRACE("name is VT_BSTR: %s\n", debugstr_w(V_BSTR(&name)));
1543
1544         if(V_VT(&index) == VT_I4) {
1545             LONG idx = V_I4(&index);
1546
1547             TRACE("index = %d\n", idx);
1548
1549             if(idx < 0)
1550                 return E_INVALIDARG;
1551
1552             for(i=0; i<This->len; i++) {
1553                 if(is_elem_name(This->elems[i], V_BSTR(&name)) && !idx--)
1554                     break;
1555             }
1556
1557             if(i != This->len) {
1558                 *pdisp = (IDispatch*)HTMLELEM(This->elems[i]);
1559                 IDispatch_AddRef(*pdisp);
1560             }
1561
1562             return S_OK;
1563         }else {
1564             elem_vector buf = {NULL, 0, 8};
1565
1566             buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*));
1567
1568             for(i=0; i<This->len; i++) {
1569                 if(is_elem_name(This->elems[i], V_BSTR(&name)))
1570                     elem_vector_add(&buf, This->elems[i]);
1571             }
1572
1573             if(buf.len > 1) {
1574                 elem_vector_normalize(&buf);
1575                 *pdisp = (IDispatch*)HTMLElementCollection_Create(This->ref_unk, buf.buf, buf.len);
1576             }else {
1577                 if(buf.len == 1) {
1578                     *pdisp = (IDispatch*)HTMLELEM(buf.buf[0]);
1579                     IDispatch_AddRef(*pdisp);
1580                 }
1581
1582                 heap_free(buf.buf);
1583             }
1584
1585             return S_OK;
1586         }
1587     }
1588
1589     FIXME("unsupported arguments\n");
1590     return E_INVALIDARG;
1591 }
1592
1593 static HRESULT WINAPI HTMLElementCollection_tags(IHTMLElementCollection *iface,
1594                                                  VARIANT tagName, IDispatch **pdisp)
1595 {
1596     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1597     DWORD i;
1598     nsAString tag_str;
1599     const PRUnichar *tag;
1600     elem_vector buf = {NULL, 0, 8};
1601
1602     if(V_VT(&tagName) != VT_BSTR) {
1603         WARN("Invalid arg\n");
1604         return DISP_E_MEMBERNOTFOUND;
1605     }
1606
1607     TRACE("(%p)->(%s %p)\n", This, debugstr_w(V_BSTR(&tagName)), pdisp);
1608
1609     buf.buf = heap_alloc(buf.size*sizeof(HTMLElement*));
1610
1611     nsAString_Init(&tag_str, NULL);
1612
1613     for(i=0; i<This->len; i++) {
1614         if(!This->elems[i]->nselem)
1615             continue;
1616
1617         nsIDOMElement_GetTagName(This->elems[i]->nselem, &tag_str);
1618         nsAString_GetData(&tag_str, &tag);
1619
1620         if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, tag, -1,
1621                           V_BSTR(&tagName), -1) == CSTR_EQUAL)
1622             elem_vector_add(&buf, This->elems[i]);
1623     }
1624
1625     nsAString_Finish(&tag_str);
1626     elem_vector_normalize(&buf);
1627
1628     TRACE("fount %d tags\n", buf.len);
1629
1630     *pdisp = (IDispatch*)HTMLElementCollection_Create(This->ref_unk, buf.buf, buf.len);
1631     return S_OK;
1632 }
1633
1634 #undef ELEMCOL_THIS
1635
1636 static const IHTMLElementCollectionVtbl HTMLElementCollectionVtbl = {
1637     HTMLElementCollection_QueryInterface,
1638     HTMLElementCollection_AddRef,
1639     HTMLElementCollection_Release,
1640     HTMLElementCollection_GetTypeInfoCount,
1641     HTMLElementCollection_GetTypeInfo,
1642     HTMLElementCollection_GetIDsOfNames,
1643     HTMLElementCollection_Invoke,
1644     HTMLElementCollection_toString,
1645     HTMLElementCollection_put_length,
1646     HTMLElementCollection_get_length,
1647     HTMLElementCollection_get__newEnum,
1648     HTMLElementCollection_item,
1649     HTMLElementCollection_tags
1650 };
1651
1652 IHTMLElementCollection *create_all_collection(HTMLDOMNode *node)
1653 {
1654     elem_vector buf = {NULL, 0, 8};
1655
1656     buf.buf = heap_alloc(buf.size*sizeof(HTMLElement**));
1657
1658     elem_vector_add(&buf, HTMLELEM_NODE_THIS(node));
1659     create_all_list(node->doc, node, &buf);
1660     elem_vector_normalize(&buf);
1661
1662     return HTMLElementCollection_Create((IUnknown*)HTMLDOMNODE(node), buf.buf, buf.len);
1663 }
1664
1665 static IHTMLElementCollection *HTMLElementCollection_Create(IUnknown *ref_unk,
1666             HTMLElement **elems, DWORD len)
1667 {
1668     HTMLElementCollection *ret = heap_alloc(sizeof(HTMLElementCollection));
1669
1670     ret->lpHTMLElementCollectionVtbl = &HTMLElementCollectionVtbl;
1671     ret->ref = 1;
1672     ret->elems = elems;
1673     ret->len = len;
1674
1675     IUnknown_AddRef(ref_unk);
1676     ret->ref_unk = ref_unk;
1677
1678     TRACE("ret=%p len=%d\n", ret, len);
1679
1680     return HTMLELEMCOL(ret);
1681 }