avifil32: Use HeapAlloc instead of Local Alloc.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winnls.h"
30 #include "ole2.h"
31
32 #include "wine/debug.h"
33 #include "wine/unicode.h"
34
35 #include "mshtml_private.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38
39 static HRESULT HTMLElementCollection_Create(IUnknown*,HTMLElement**,DWORD,IDispatch**);
40
41 #define HTMLELEM_THIS(iface) DEFINE_THIS(HTMLElement, HTMLElement, iface)
42
43 static HRESULT WINAPI HTMLElement_QueryInterface(IHTMLElement *iface,
44                                                  REFIID riid, void **ppv)
45 {
46     HTMLElement *This = HTMLELEM_THIS(iface);
47
48     if(This->impl)
49         return IUnknown_QueryInterface(This->impl, riid, ppv);
50
51     *ppv =  NULL;
52
53     if(IsEqualGUID(&IID_IUnknown, riid)) {
54         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
55         *ppv = HTMLELEM(This);
56     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
57         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
58         *ppv = HTMLELEM(This);
59     }else if(IsEqualGUID(&IID_IHTMLDOMNode, riid)) {
60         TRACE("(%p)->(IID_IHTMLDOMNode %p)\n", This, ppv);
61         *ppv = HTMLDOMNODE(This->node);
62     }else if(IsEqualGUID(&IID_IHTMLElement, riid)) {
63         TRACE("(%p)->(IID_IHTMLElement %p)\n", This, ppv);
64         *ppv = HTMLELEM(This);
65     }
66
67     if(*ppv) {
68         IHTMLElement_AddRef(HTMLELEM(This));
69         return S_OK;
70     }
71
72     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
73     return E_NOINTERFACE;
74 }
75
76 static ULONG WINAPI HTMLElement_AddRef(IHTMLElement *iface)
77 {
78     HTMLElement *This = HTMLELEM_THIS(iface);
79
80     if(This->impl)
81         return IUnknown_AddRef(This->impl);
82
83     TRACE("(%p)\n", This);
84     return IHTMLDocument2_AddRef(HTMLDOC(This->node->doc));
85 }
86
87 static ULONG WINAPI HTMLElement_Release(IHTMLElement *iface)
88 {
89     HTMLElement *This = HTMLELEM_THIS(iface);
90
91     if(This->impl)
92         return IUnknown_Release(This->impl);
93
94     TRACE("(%p)\n", This);
95     return IHTMLDocument2_Release(HTMLDOC(This->node->doc));
96 }
97
98 static HRESULT WINAPI HTMLElement_GetTypeInfoCount(IHTMLElement *iface, UINT *pctinfo)
99 {
100     HTMLElement *This = HTMLELEM_THIS(iface);
101     FIXME("(%p)->(%p)\n", This, pctinfo);
102     return E_NOTIMPL;
103 }
104
105 static HRESULT WINAPI HTMLElement_GetTypeInfo(IHTMLElement *iface, UINT iTInfo,
106                                               LCID lcid, ITypeInfo **ppTInfo)
107 {
108     HTMLElement *This = HTMLELEM_THIS(iface);
109     FIXME("(%p)->(%u %lu %p)\n", This, iTInfo, lcid, ppTInfo);
110     return E_NOTIMPL;
111 }
112
113 static HRESULT WINAPI HTMLElement_GetIDsOfNames(IHTMLElement *iface, REFIID riid,
114                                                 LPOLESTR *rgszNames, UINT cNames,
115                                                 LCID lcid, DISPID *rgDispId)
116 {
117     HTMLElement *This = HTMLELEM_THIS(iface);
118     FIXME("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
119                                         lcid, rgDispId);
120     return E_NOTIMPL;
121 }
122
123 static HRESULT WINAPI HTMLElement_Invoke(IHTMLElement *iface, DISPID dispIdMember,
124                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
125                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
126 {
127     HTMLElement *This = HTMLELEM_THIS(iface);
128     FIXME("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
129             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
130     return E_NOTIMPL;
131 }
132
133 static HRESULT WINAPI HTMLElement_setAttribute(IHTMLElement *iface, BSTR strAttributeName,
134                                                VARIANT AttributeValue, LONG lFlags)
135 {
136     HTMLElement *This = HTMLELEM_THIS(iface);
137     FIXME("(%p)->(%s . %08lx)\n", This, debugstr_w(strAttributeName), lFlags);
138     return E_NOTIMPL;
139 }
140
141 static HRESULT WINAPI HTMLElement_getAttribute(IHTMLElement *iface, BSTR strAttributeName,
142                                                LONG lFlags, VARIANT *AttributeValue)
143 {
144     HTMLElement *This = HTMLELEM_THIS(iface);
145     nsAString attr_str;
146     nsAString value_str;
147     const PRUnichar *value;
148     nsresult nsres;
149     HRESULT hres = S_OK;
150
151     WARN("(%p)->(%s %08lx %p)\n", This, debugstr_w(strAttributeName), lFlags, AttributeValue);
152
153     nsAString_Init(&attr_str, strAttributeName);
154     nsAString_Init(&value_str, NULL);
155
156     nsres = nsIDOMHTMLElement_GetAttribute(This->nselem, &attr_str, &value_str);
157     nsAString_Finish(&attr_str);
158
159     if(NS_SUCCEEDED(nsres)) {
160         nsAString_GetData(&value_str, &value, NULL);
161         V_VT(AttributeValue) = VT_BSTR;
162         V_BSTR(AttributeValue) = SysAllocString(value);;
163         TRACE("attr_value=%s\n", debugstr_w(V_BSTR(AttributeValue)));
164     }else {
165         ERR("GetAttribute failed: %08lx\n", nsres);
166         hres = E_FAIL;
167     }
168
169     nsAString_Finish(&value_str);
170
171     return hres;
172 }
173
174 static HRESULT WINAPI HTMLElement_removeAttribute(IHTMLElement *iface, BSTR strAttributeName,
175                                                   LONG lFlags, VARIANT_BOOL *pfSuccess)
176 {
177     HTMLElement *This = HTMLELEM_THIS(iface);
178     FIXME("(%p)->()\n", This);
179     return E_NOTIMPL;
180 }
181
182 static HRESULT WINAPI HTMLElement_put_className(IHTMLElement *iface, BSTR v)
183 {
184     HTMLElement *This = HTMLELEM_THIS(iface);
185     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
186     return E_NOTIMPL;
187 }
188
189 static HRESULT WINAPI HTMLElement_get_className(IHTMLElement *iface, BSTR *p)
190 {
191     HTMLElement *This = HTMLELEM_THIS(iface);
192     FIXME("(%p)->(%p)\n", This, p);
193     return E_NOTIMPL;
194 }
195
196 static HRESULT WINAPI HTMLElement_put_id(IHTMLElement *iface, BSTR v)
197 {
198     HTMLElement *This = HTMLELEM_THIS(iface);
199     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
200     return E_NOTIMPL;
201 }
202
203 static HRESULT WINAPI HTMLElement_get_id(IHTMLElement *iface, BSTR *p)
204 {
205     HTMLElement *This = HTMLELEM_THIS(iface);
206     FIXME("(%p)->(%p)\n", This, p);
207     return E_NOTIMPL;
208 }
209
210 static HRESULT WINAPI HTMLElement_get_tagName(IHTMLElement *iface, BSTR *p)
211 {
212     HTMLElement *This = HTMLELEM_THIS(iface);
213     FIXME("(%p)->(%p)\n", This, p);
214     return E_NOTIMPL;
215 }
216
217 static HRESULT WINAPI HTMLElement_get_parentElement(IHTMLElement *iface, IHTMLElement **p)
218 {
219     HTMLElement *This = HTMLELEM_THIS(iface);
220     FIXME("(%p)->(%p)\n", This, p);
221     return E_NOTIMPL;
222 }
223
224 static HRESULT WINAPI HTMLElement_get_style(IHTMLElement *iface, IHTMLStyle **p)
225 {
226     HTMLElement *This = HTMLELEM_THIS(iface);
227     FIXME("(%p)->(%p)\n", This, p);
228     return E_NOTIMPL;
229 }
230
231 static HRESULT WINAPI HTMLElement_put_onhelp(IHTMLElement *iface, VARIANT v)
232 {
233     HTMLElement *This = HTMLELEM_THIS(iface);
234     FIXME("(%p)->()\n", This);
235     return E_NOTIMPL;
236 }
237
238 static HRESULT WINAPI HTMLElement_get_onhelp(IHTMLElement *iface, VARIANT *p)
239 {
240     HTMLElement *This = HTMLELEM_THIS(iface);
241     FIXME("(%p)->(%p)\n", This, p);
242     return E_NOTIMPL;
243 }
244
245 static HRESULT WINAPI HTMLElement_put_onclick(IHTMLElement *iface, VARIANT v)
246 {
247     HTMLElement *This = HTMLELEM_THIS(iface);
248     FIXME("(%p)->()\n", This);
249     return E_NOTIMPL;
250 }
251
252 static HRESULT WINAPI HTMLElement_get_onclick(IHTMLElement *iface, VARIANT *p)
253 {
254     HTMLElement *This = HTMLELEM_THIS(iface);
255     FIXME("(%p)->(%p)\n", This, p);
256     return E_NOTIMPL;
257 }
258
259 static HRESULT WINAPI HTMLElement_put_ondblclick(IHTMLElement *iface, VARIANT v)
260 {
261     HTMLElement *This = HTMLELEM_THIS(iface);
262     FIXME("(%p)->()\n", This);
263     return E_NOTIMPL;
264 }
265
266 static HRESULT WINAPI HTMLElement_get_ondblclick(IHTMLElement *iface, VARIANT *p)
267 {
268     HTMLElement *This = HTMLELEM_THIS(iface);
269     FIXME("(%p)->(%p)\n", This, p);
270     return E_NOTIMPL;
271 }
272
273 static HRESULT WINAPI HTMLElement_put_onkeydown(IHTMLElement *iface, VARIANT v)
274 {
275     HTMLElement *This = HTMLELEM_THIS(iface);
276     FIXME("(%p)->()\n", This);
277     return E_NOTIMPL;
278 }
279
280 static HRESULT WINAPI HTMLElement_get_onkeydown(IHTMLElement *iface, VARIANT *p)
281 {
282     HTMLElement *This = HTMLELEM_THIS(iface);
283     FIXME("(%p)->(%p)\n", This, p);
284     return E_NOTIMPL;
285 }
286
287 static HRESULT WINAPI HTMLElement_put_onkeyup(IHTMLElement *iface, VARIANT v)
288 {
289     HTMLElement *This = HTMLELEM_THIS(iface);
290     FIXME("(%p)->()\n", This);
291     return E_NOTIMPL;
292 }
293
294 static HRESULT WINAPI HTMLElement_get_onkeyup(IHTMLElement *iface, VARIANT *p)
295 {
296     HTMLElement *This = HTMLELEM_THIS(iface);
297     FIXME("(%p)->(%p)\n", This, p);
298     return E_NOTIMPL;
299 }
300
301 static HRESULT WINAPI HTMLElement_put_onkeypress(IHTMLElement *iface, VARIANT v)
302 {
303     HTMLElement *This = HTMLELEM_THIS(iface);
304     FIXME("(%p)->()\n", This);
305     return E_NOTIMPL;
306 }
307
308 static HRESULT WINAPI HTMLElement_get_onkeypress(IHTMLElement *iface, VARIANT *p)
309 {
310     HTMLElement *This = HTMLELEM_THIS(iface);
311     FIXME("(%p)->(%p)\n", This, p);
312     return E_NOTIMPL;
313 }
314
315 static HRESULT WINAPI HTMLElement_put_onmouseout(IHTMLElement *iface, VARIANT v)
316 {
317     HTMLElement *This = HTMLELEM_THIS(iface);
318     FIXME("(%p)->()\n", This);
319     return E_NOTIMPL;
320 }
321
322 static HRESULT WINAPI HTMLElement_get_onmouseout(IHTMLElement *iface, VARIANT *p)
323 {
324     HTMLElement *This = HTMLELEM_THIS(iface);
325     FIXME("(%p)->(%p)\n", This, p);
326     return E_NOTIMPL;
327 }
328
329 static HRESULT WINAPI HTMLElement_put_onmouseover(IHTMLElement *iface, VARIANT v)
330 {
331     HTMLElement *This = HTMLELEM_THIS(iface);
332     FIXME("(%p)->()\n", This);
333     return E_NOTIMPL;
334 }
335
336 static HRESULT WINAPI HTMLElement_get_onmouseover(IHTMLElement *iface, VARIANT *p)
337 {
338     HTMLElement *This = HTMLELEM_THIS(iface);
339     FIXME("(%p)->(%p)\n", This, p);
340     return E_NOTIMPL;
341 }
342
343 static HRESULT WINAPI HTMLElement_put_onmousemove(IHTMLElement *iface, VARIANT v)
344 {
345     HTMLElement *This = HTMLELEM_THIS(iface);
346     FIXME("(%p)->()\n", This);
347     return E_NOTIMPL;
348 }
349
350 static HRESULT WINAPI HTMLElement_get_onmousemove(IHTMLElement *iface, VARIANT *p)
351 {
352     HTMLElement *This = HTMLELEM_THIS(iface);
353     FIXME("(%p)->(%p)\n", This, p);
354     return E_NOTIMPL;
355 }
356
357 static HRESULT WINAPI HTMLElement_put_onmousedown(IHTMLElement *iface, VARIANT v)
358 {
359     HTMLElement *This = HTMLELEM_THIS(iface);
360     FIXME("(%p)->()\n", This);
361     return E_NOTIMPL;
362 }
363
364 static HRESULT WINAPI HTMLElement_get_onmousedown(IHTMLElement *iface, VARIANT *p)
365 {
366     HTMLElement *This = HTMLELEM_THIS(iface);
367     FIXME("(%p)->(%p)\n", This, p);
368     return E_NOTIMPL;
369 }
370
371 static HRESULT WINAPI HTMLElement_put_onmouseup(IHTMLElement *iface, VARIANT v)
372 {
373     HTMLElement *This = HTMLELEM_THIS(iface);
374     FIXME("(%p)->()\n", This);
375     return E_NOTIMPL;
376 }
377
378 static HRESULT WINAPI HTMLElement_get_onmouseup(IHTMLElement *iface, VARIANT *p)
379 {
380     HTMLElement *This = HTMLELEM_THIS(iface);
381     FIXME("(%p)->(%p)\n", This, p);
382     return E_NOTIMPL;
383 }
384
385 static HRESULT WINAPI HTMLElement_get_document(IHTMLElement *iface, IDispatch **p)
386 {
387     HTMLElement *This = HTMLELEM_THIS(iface);
388     FIXME("(%p)->(%p)\n", This, p);
389     return E_NOTIMPL;
390 }
391
392 static HRESULT WINAPI HTMLElement_put_title(IHTMLElement *iface, BSTR v)
393 {
394     HTMLElement *This = HTMLELEM_THIS(iface);
395     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
396     return E_NOTIMPL;
397 }
398
399 static HRESULT WINAPI HTMLElement_get_title(IHTMLElement *iface, BSTR *p)
400 {
401     HTMLElement *This = HTMLELEM_THIS(iface);
402     FIXME("(%p)->(%p)\n", This, p);
403     return E_NOTIMPL;
404 }
405
406 static HRESULT WINAPI HTMLElement_put_language(IHTMLElement *iface, BSTR v)
407 {
408     HTMLElement *This = HTMLELEM_THIS(iface);
409     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
410     return E_NOTIMPL;
411 }
412
413 static HRESULT WINAPI HTMLElement_get_language(IHTMLElement *iface, BSTR *p)
414 {
415     HTMLElement *This = HTMLELEM_THIS(iface);
416     FIXME("(%p)->(%p)\n", This, p);
417     return E_NOTIMPL;
418 }
419
420 static HRESULT WINAPI HTMLElement_put_onselectstart(IHTMLElement *iface, VARIANT v)
421 {
422     HTMLElement *This = HTMLELEM_THIS(iface);
423     FIXME("(%p)->()\n", This);
424     return E_NOTIMPL;
425 }
426
427 static HRESULT WINAPI HTMLElement_get_onselectstart(IHTMLElement *iface, VARIANT *p)
428 {
429     HTMLElement *This = HTMLELEM_THIS(iface);
430     FIXME("(%p)->(%p)\n", This, p);
431     return E_NOTIMPL;
432 }
433
434 static HRESULT WINAPI HTMLElement_scrollIntoView(IHTMLElement *iface, VARIANT varargStart)
435 {
436     HTMLElement *This = HTMLELEM_THIS(iface);
437     FIXME("(%p)->()\n", This);
438     return E_NOTIMPL;
439 }
440
441 static HRESULT WINAPI HTMLElement_contains(IHTMLElement *iface, IHTMLElement *pChild,
442                                            VARIANT_BOOL *pfResult)
443 {
444     HTMLElement *This = HTMLELEM_THIS(iface);
445     FIXME("(%p)->(%p %p)\n", This, pChild, pfResult);
446     return E_NOTIMPL;
447 }
448
449 static HRESULT WINAPI HTMLElement_get_sourceIndex(IHTMLElement *iface, long *p)
450 {
451     HTMLElement *This = HTMLELEM_THIS(iface);
452     FIXME("(%p)->(%p)\n", This, p);
453     return E_NOTIMPL;
454 }
455
456 static HRESULT WINAPI HTMLElement_get_recordNumber(IHTMLElement *iface, VARIANT *p)
457 {
458     HTMLElement *This = HTMLELEM_THIS(iface);
459     FIXME("(%p)->(%p)\n", This, p);
460     return E_NOTIMPL;
461 }
462
463 static HRESULT WINAPI HTMLElement_put_lang(IHTMLElement *iface, BSTR v)
464 {
465     HTMLElement *This = HTMLELEM_THIS(iface);
466     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
467     return E_NOTIMPL;
468 }
469
470 static HRESULT WINAPI HTMLElement_get_lang(IHTMLElement *iface, BSTR *p)
471 {
472     HTMLElement *This = HTMLELEM_THIS(iface);
473     FIXME("(%p)->(%p)\n", This, p);
474     return E_NOTIMPL;
475 }
476
477 static HRESULT WINAPI HTMLElement_get_offsetLeft(IHTMLElement *iface, long *p)
478 {
479     HTMLElement *This = HTMLELEM_THIS(iface);
480     FIXME("(%p)->(%p)\n", This, p);
481     return E_NOTIMPL;
482 }
483
484 static HRESULT WINAPI HTMLElement_get_offsetTop(IHTMLElement *iface, long *p)
485 {
486     HTMLElement *This = HTMLELEM_THIS(iface);
487     FIXME("(%p)->(%p)\n", This, p);
488     return E_NOTIMPL;
489 }
490
491 static HRESULT WINAPI HTMLElement_get_offsetWidth(IHTMLElement *iface, long *p)
492 {
493     HTMLElement *This = HTMLELEM_THIS(iface);
494     FIXME("(%p)->(%p)\n", This, p);
495     return E_NOTIMPL;
496 }
497
498 static HRESULT WINAPI HTMLElement_get_offsetHeight(IHTMLElement *iface, long *p)
499 {
500     HTMLElement *This = HTMLELEM_THIS(iface);
501     FIXME("(%p)->(%p)\n", This, p);
502     return E_NOTIMPL;
503 }
504
505 static HRESULT WINAPI HTMLElement_get_offsetParent(IHTMLElement *iface, IHTMLElement **p)
506 {
507     HTMLElement *This = HTMLELEM_THIS(iface);
508     FIXME("(%p)->(%p)\n", This, p);
509     return E_NOTIMPL;
510 }
511
512 static HRESULT WINAPI HTMLElement_put_innerHTML(IHTMLElement *iface, BSTR v)
513 {
514     HTMLElement *This = HTMLELEM_THIS(iface);
515     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
516     return E_NOTIMPL;
517 }
518
519 static HRESULT WINAPI HTMLElement_get_innerHTML(IHTMLElement *iface, BSTR *p)
520 {
521     HTMLElement *This = HTMLELEM_THIS(iface);
522     FIXME("(%p)->(%p)\n", This, p);
523     return E_NOTIMPL;
524 }
525
526 static HRESULT WINAPI HTMLElement_put_innerText(IHTMLElement *iface, BSTR v)
527 {
528     HTMLElement *This = HTMLELEM_THIS(iface);
529     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
530     return E_NOTIMPL;
531 }
532
533 static HRESULT WINAPI HTMLElement_get_innerText(IHTMLElement *iface, BSTR *p)
534 {
535     HTMLElement *This = HTMLELEM_THIS(iface);
536     FIXME("(%p)->(%p)\n", This, p);
537     return E_NOTIMPL;
538 }
539
540 static HRESULT WINAPI HTMLElement_put_outerHTML(IHTMLElement *iface, BSTR v)
541 {
542     HTMLElement *This = HTMLELEM_THIS(iface);
543     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
544     return E_NOTIMPL;
545 }
546
547 static HRESULT WINAPI HTMLElement_get_outerHTML(IHTMLElement *iface, BSTR *p)
548 {
549     HTMLElement *This = HTMLELEM_THIS(iface);
550     FIXME("(%p)->(%p)\n", This, p);
551     return E_NOTIMPL;
552 }
553
554 static HRESULT WINAPI HTMLElement_put_outerText(IHTMLElement *iface, BSTR v)
555 {
556     HTMLElement *This = HTMLELEM_THIS(iface);
557     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
558     return E_NOTIMPL;
559 }
560
561 static HRESULT WINAPI HTMLElement_get_outerText(IHTMLElement *iface, BSTR *p)
562 {
563     HTMLElement *This = HTMLELEM_THIS(iface);
564     FIXME("(%p)->(%p)\n", This, p);
565     return E_NOTIMPL;
566 }
567
568 static HRESULT WINAPI HTMLElement_insertAdjacentHTML(IHTMLElement *iface, BSTR where,
569                                                      BSTR html)
570 {
571     HTMLElement *This = HTMLELEM_THIS(iface);
572     FIXME("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(html));
573     return E_NOTIMPL;
574 }
575
576 static HRESULT WINAPI HTMLElement_insertAdjacentText(IHTMLElement *iface, BSTR where,
577                                                      BSTR text)
578 {
579     HTMLElement *This = HTMLELEM_THIS(iface);
580     FIXME("(%p)->(%s %s)\n", This, debugstr_w(where), debugstr_w(text));
581     return E_NOTIMPL;
582 }
583
584 static HRESULT WINAPI HTMLElement_get_parentTextEdit(IHTMLElement *iface, IHTMLElement **p)
585 {
586     HTMLElement *This = HTMLELEM_THIS(iface);
587     FIXME("(%p)->(%p)\n", This, p);
588     return E_NOTIMPL;
589 }
590
591 static HRESULT WINAPI HTMLElement_get_isTextEdit(IHTMLElement *iface, VARIANT_BOOL *p)
592 {
593     HTMLElement *This = HTMLELEM_THIS(iface);
594     FIXME("(%p)->(%p)\n", This, p);
595     return E_NOTIMPL;
596 }
597
598 static HRESULT WINAPI HTMLElement_click(IHTMLElement *iface)
599 {
600     HTMLElement *This = HTMLELEM_THIS(iface);
601     FIXME("(%p)\n", This);
602     return E_NOTIMPL;
603 }
604
605 static HRESULT WINAPI HTMLElement_get_filters(IHTMLElement *iface,
606                                               IHTMLFiltersCollection **p)
607 {
608     HTMLElement *This = HTMLELEM_THIS(iface);
609     FIXME("(%p)->(%p)\n", This, p);
610     return E_NOTIMPL;
611 }
612
613 static HRESULT WINAPI HTMLElement_put_ondragstart(IHTMLElement *iface, VARIANT v)
614 {
615     HTMLElement *This = HTMLELEM_THIS(iface);
616     FIXME("(%p)->()\n", This);
617     return E_NOTIMPL;
618 }
619
620 static HRESULT WINAPI HTMLElement_get_ondragstart(IHTMLElement *iface, VARIANT *p)
621 {
622     HTMLElement *This = HTMLELEM_THIS(iface);
623     FIXME("(%p)->(%p)\n", This, p);
624     return E_NOTIMPL;
625 }
626
627 static HRESULT WINAPI HTMLElement_toString(IHTMLElement *iface, BSTR *String)
628 {
629     HTMLElement *This = HTMLELEM_THIS(iface);
630     FIXME("(%p)->(%p)\n", This, String);
631     return E_NOTIMPL;
632 }
633
634 static HRESULT WINAPI HTMLElement_put_onbeforeupdate(IHTMLElement *iface, VARIANT v)
635 {
636     HTMLElement *This = HTMLELEM_THIS(iface);
637     FIXME("(%p)->()\n", This);
638     return E_NOTIMPL;
639 }
640
641 static HRESULT WINAPI HTMLElement_get_onbeforeupdate(IHTMLElement *iface, VARIANT *p)
642 {
643     HTMLElement *This = HTMLELEM_THIS(iface);
644     FIXME("(%p)->(%p)\n", This, p);
645     return E_NOTIMPL;
646 }
647
648 static HRESULT WINAPI HTMLElement_put_onafterupdate(IHTMLElement *iface, VARIANT v)
649 {
650     HTMLElement *This = HTMLELEM_THIS(iface);
651     FIXME("(%p)->()\n", This);
652     return E_NOTIMPL;
653 }
654
655 static HRESULT WINAPI HTMLElement_get_onafterupdate(IHTMLElement *iface, VARIANT *p)
656 {
657     HTMLElement *This = HTMLELEM_THIS(iface);
658     FIXME("(%p)->(%p)\n", This, p);
659     return E_NOTIMPL;
660 }
661
662 static HRESULT WINAPI HTMLElement_put_onerrorupdate(IHTMLElement *iface, VARIANT v)
663 {
664     HTMLElement *This = HTMLELEM_THIS(iface);
665     FIXME("(%p)->()\n", This);
666     return E_NOTIMPL;
667 }
668
669 static HRESULT WINAPI HTMLElement_get_onerrorupdate(IHTMLElement *iface, VARIANT *p)
670 {
671     HTMLElement *This = HTMLELEM_THIS(iface);
672     FIXME("(%p)->(%p)\n", This, p);
673     return E_NOTIMPL;
674 }
675
676 static HRESULT WINAPI HTMLElement_put_onrowexit(IHTMLElement *iface, VARIANT v)
677 {
678     HTMLElement *This = HTMLELEM_THIS(iface);
679     FIXME("(%p)->()\n", This);
680     return E_NOTIMPL;
681 }
682
683 static HRESULT WINAPI HTMLElement_get_onrowexit(IHTMLElement *iface, VARIANT *p)
684 {
685     HTMLElement *This = HTMLELEM_THIS(iface);
686     FIXME("(%p)->(%p)\n", This, p);
687     return E_NOTIMPL;
688 }
689
690 static HRESULT WINAPI HTMLElement_put_onrowenter(IHTMLElement *iface, VARIANT v)
691 {
692     HTMLElement *This = HTMLELEM_THIS(iface);
693     FIXME("(%p)->()\n", This);
694     return E_NOTIMPL;
695 }
696
697 static HRESULT WINAPI HTMLElement_get_onrowenter(IHTMLElement *iface, VARIANT *p)
698 {
699     HTMLElement *This = HTMLELEM_THIS(iface);
700     FIXME("(%p)->(%p)\n", This, p);
701     return E_NOTIMPL;
702 }
703
704 static HRESULT WINAPI HTMLElement_put_ondatasetchanged(IHTMLElement *iface, VARIANT v)
705 {
706     HTMLElement *This = HTMLELEM_THIS(iface);
707     FIXME("(%p)->()\n", This);
708     return E_NOTIMPL;
709 }
710
711 static HRESULT WINAPI HTMLElement_get_ondatasetchanged(IHTMLElement *iface, VARIANT *p)
712 {
713     HTMLElement *This = HTMLELEM_THIS(iface);
714     FIXME("(%p)->(%p)\n", This, p);
715     return E_NOTIMPL;
716 }
717
718 static HRESULT WINAPI HTMLElement_put_ondataavailable(IHTMLElement *iface, VARIANT v)
719 {
720     HTMLElement *This = HTMLELEM_THIS(iface);
721     FIXME("(%p)->()\n", This);
722     return E_NOTIMPL;
723 }
724
725 static HRESULT WINAPI HTMLElement_get_ondataavailable(IHTMLElement *iface, VARIANT *p)
726 {
727     HTMLElement *This = HTMLELEM_THIS(iface);
728     FIXME("(%p)->(%p)\n", This, p);
729     return E_NOTIMPL;
730 }
731
732 static HRESULT WINAPI HTMLElement_put_ondatasetcomplete(IHTMLElement *iface, VARIANT v)
733 {
734     HTMLElement *This = HTMLELEM_THIS(iface);
735     FIXME("(%p)->()\n", This);
736     return E_NOTIMPL;
737 }
738
739 static HRESULT WINAPI HTMLElement_get_ondatasetcomplete(IHTMLElement *iface, VARIANT *p)
740 {
741     HTMLElement *This = HTMLELEM_THIS(iface);
742     FIXME("(%p)->(%p)\n", This, p);
743     return E_NOTIMPL;
744 }
745
746 static HRESULT WINAPI HTMLElement_put_onfilterchange(IHTMLElement *iface, VARIANT v)
747 {
748     HTMLElement *This = HTMLELEM_THIS(iface);
749     FIXME("(%p)->()\n", This);
750     return E_NOTIMPL;
751 }
752
753 static HRESULT WINAPI HTMLElement_get_onfilterchange(IHTMLElement *iface, VARIANT *p)
754 {
755     HTMLElement *This = HTMLELEM_THIS(iface);
756     FIXME("(%p)->(%p)\n", This, p);
757     return E_NOTIMPL;
758 }
759
760 static HRESULT WINAPI HTMLElement_get_children(IHTMLElement *iface, IDispatch **p)
761 {
762     HTMLElement *This = HTMLELEM_THIS(iface);
763     FIXME("(%p)->(%p)\n", This, p);
764     return E_NOTIMPL;
765 }
766
767 static void create_all_list(HTMLDocument *doc, HTMLElement *elem, HTMLElement ***list, DWORD *size,
768                         DWORD *len)
769 {
770     nsIDOMNodeList *nsnode_list;
771     nsIDOMNode *iter;
772     PRUint32 list_len = 0, i;
773     HTMLDOMNode *node;
774     nsresult nsres;
775
776     nsres = nsIDOMNode_GetChildNodes(elem->node->nsnode, &nsnode_list);
777     if(NS_FAILED(nsres)) {
778         ERR("GetChildNodes failed: %08lx\n", nsres);
779         return;
780     }
781
782     nsIDOMNodeList_GetLength(nsnode_list, &list_len);
783     if(!list_len)
784         return;
785
786     for(i=0; i<list_len; i++) {
787         nsres = nsIDOMNodeList_Item(nsnode_list, i, &iter);
788         if(NS_FAILED(nsres)) {
789             ERR("Item failed: %08lx\n", nsres);
790             continue;
791         }
792
793         node = get_node(doc, iter);
794         if(node->node_type != NT_HTMLELEM)
795             continue;
796
797         if(*len == *size) {
798             *size <<= 1;
799             *list = HeapReAlloc(GetProcessHeap(), 0, *list, *size * sizeof(HTMLElement**));
800         }
801
802         (*list)[(*len)++] = (HTMLElement*)node->impl.elem;
803
804         create_all_list(doc, (HTMLElement*)node->impl.elem, list, size, len);
805     }
806 }
807
808 static HRESULT WINAPI HTMLElement_get_all(IHTMLElement *iface, IDispatch **p)
809 {
810     HTMLElement *This = HTMLELEM_THIS(iface);
811     HTMLElement **elem_list;
812     DWORD list_size = 8, len = 0;
813
814     TRACE("(%p)->(%p)\n", This, p);
815
816     elem_list = HeapAlloc(GetProcessHeap(), 0, list_size*sizeof(HTMLElement**));
817
818     create_all_list(This->node->doc, This, &elem_list, &list_size, &len);
819
820     if(!len) {
821         HeapFree(GetProcessHeap(), 0, elem_list);
822         elem_list = NULL;
823     }else if(list_size > len) {
824         elem_list = HeapReAlloc(GetProcessHeap(), 0, elem_list, len*sizeof(HTMLElement**));
825     }
826
827     return HTMLElementCollection_Create((IUnknown*)HTMLELEM(This), elem_list, len, p);
828 }
829
830 static void HTMLElement_destructor(IUnknown *iface)
831 {
832     HTMLElement *This = HTMLELEM_THIS(iface);
833
834     if(This->destructor)
835         This->destructor(This->impl);
836
837     if(This->nselem)
838         nsIDOMHTMLElement_Release(This->nselem);
839
840     HeapFree(GetProcessHeap(), 0, This);
841 }
842
843 #undef HTMLELEM_THIS
844
845 static const IHTMLElementVtbl HTMLElementVtbl = {
846     HTMLElement_QueryInterface,
847     HTMLElement_AddRef,
848     HTMLElement_Release,
849     HTMLElement_GetTypeInfoCount,
850     HTMLElement_GetTypeInfo,
851     HTMLElement_GetIDsOfNames,
852     HTMLElement_Invoke,
853     HTMLElement_setAttribute,
854     HTMLElement_getAttribute,
855     HTMLElement_removeAttribute,
856     HTMLElement_put_className,
857     HTMLElement_get_className,
858     HTMLElement_put_id,
859     HTMLElement_get_id,
860     HTMLElement_get_tagName,
861     HTMLElement_get_parentElement,
862     HTMLElement_get_style,
863     HTMLElement_put_onhelp,
864     HTMLElement_get_onhelp,
865     HTMLElement_put_onclick,
866     HTMLElement_get_onclick,
867     HTMLElement_put_ondblclick,
868     HTMLElement_get_ondblclick,
869     HTMLElement_put_onkeydown,
870     HTMLElement_get_onkeydown,
871     HTMLElement_put_onkeyup,
872     HTMLElement_get_onkeyup,
873     HTMLElement_put_onkeypress,
874     HTMLElement_get_onkeypress,
875     HTMLElement_put_onmouseout,
876     HTMLElement_get_onmouseout,
877     HTMLElement_put_onmouseover,
878     HTMLElement_get_onmouseover,
879     HTMLElement_put_onmousemove,
880     HTMLElement_get_onmousemove,
881     HTMLElement_put_onmousedown,
882     HTMLElement_get_onmousedown,
883     HTMLElement_put_onmouseup,
884     HTMLElement_get_onmouseup,
885     HTMLElement_get_document,
886     HTMLElement_put_title,
887     HTMLElement_get_title,
888     HTMLElement_put_language,
889     HTMLElement_get_language,
890     HTMLElement_put_onselectstart,
891     HTMLElement_get_onselectstart,
892     HTMLElement_scrollIntoView,
893     HTMLElement_contains,
894     HTMLElement_get_sourceIndex,
895     HTMLElement_get_recordNumber,
896     HTMLElement_put_lang,
897     HTMLElement_get_lang,
898     HTMLElement_get_offsetLeft,
899     HTMLElement_get_offsetTop,
900     HTMLElement_get_offsetWidth,
901     HTMLElement_get_offsetHeight,
902     HTMLElement_get_offsetParent,
903     HTMLElement_put_innerHTML,
904     HTMLElement_get_innerHTML,
905     HTMLElement_put_innerText,
906     HTMLElement_get_innerText,
907     HTMLElement_put_outerHTML,
908     HTMLElement_get_outerHTML,
909     HTMLElement_put_outerText,
910     HTMLElement_get_outerText,
911     HTMLElement_insertAdjacentHTML,
912     HTMLElement_insertAdjacentText,
913     HTMLElement_get_parentTextEdit,
914     HTMLElement_get_isTextEdit,
915     HTMLElement_click,
916     HTMLElement_get_filters,
917     HTMLElement_put_ondragstart,
918     HTMLElement_get_ondragstart,
919     HTMLElement_toString,
920     HTMLElement_put_onbeforeupdate,
921     HTMLElement_get_onbeforeupdate,
922     HTMLElement_put_onafterupdate,
923     HTMLElement_get_onafterupdate,
924     HTMLElement_put_onerrorupdate,
925     HTMLElement_get_onerrorupdate,
926     HTMLElement_put_onrowexit,
927     HTMLElement_get_onrowexit,
928     HTMLElement_put_onrowenter,
929     HTMLElement_get_onrowenter,
930     HTMLElement_put_ondatasetchanged,
931     HTMLElement_get_ondatasetchanged,
932     HTMLElement_put_ondataavailable,
933     HTMLElement_get_ondataavailable,
934     HTMLElement_put_ondatasetcomplete,
935     HTMLElement_get_ondatasetcomplete,
936     HTMLElement_put_onfilterchange,
937     HTMLElement_get_onfilterchange,
938     HTMLElement_get_children,
939     HTMLElement_get_all
940 };
941
942 void HTMLElement_Create(HTMLDOMNode *node)
943 {
944     HTMLElement *ret;
945     nsAString class_name_str;
946     const PRUnichar *class_name;
947     nsresult nsres;
948
949     static const WCHAR wszBODY[]     = {'B','O','D','Y',0};
950     static const WCHAR wszINPUT[]    = {'I','N','P','U','T',0};
951     static const WCHAR wszSELECT[]   = {'S','E','L','E','C','T',0};
952     static const WCHAR wszTEXTAREA[] = {'T','E','X','T','A','R','E','A',0};
953
954     ret = HeapAlloc(GetProcessHeap(), 0, sizeof(HTMLElement));
955     ret->lpHTMLElementVtbl = &HTMLElementVtbl;
956     ret->node = node;
957     ret->impl = NULL;
958     ret->destructor = NULL;
959
960     node->node_type = NT_HTMLELEM;
961     node->impl.elem = HTMLELEM(ret);
962     node->destructor = HTMLElement_destructor;
963
964     nsres = nsIDOMNode_QueryInterface(node->nsnode, &IID_nsIDOMHTMLElement, (void**)&ret->nselem);
965     if(NS_FAILED(nsres))
966         return;
967
968     nsAString_Init(&class_name_str, NULL);
969     nsIDOMHTMLElement_GetTagName(ret->nselem, &class_name_str);
970
971     nsAString_GetData(&class_name_str, &class_name, NULL);
972
973     if(!strcmpW(class_name, wszBODY))
974         HTMLBodyElement_Create(ret);
975     else if(!strcmpW(class_name, wszINPUT))
976         HTMLInputElement_Create(ret);
977     else if(!strcmpW(class_name, wszSELECT))
978         HTMLSelectElement_Create(ret);
979     else if(!strcmpW(class_name, wszTEXTAREA))
980         HTMLTextAreaElement_Create(ret);
981
982     nsAString_Finish(&class_name_str);
983 }
984
985 typedef struct {
986     const IHTMLElementCollectionVtbl *lpHTMLElementCollectionVtbl;
987
988     IUnknown *ref_unk;
989     HTMLElement **elems;
990     DWORD len;
991
992     LONG ref;
993 } HTMLElementCollection;
994
995 #define HTMLELEMCOL(x)  ((IHTMLElementCollection*) &(x)->lpHTMLElementCollectionVtbl)
996
997 #define ELEMCOL_THIS(iface) DEFINE_THIS(HTMLElementCollection, HTMLElementCollection, iface)
998
999 static HRESULT WINAPI HTMLElementCollection_QueryInterface(IHTMLElementCollection *iface,
1000                                                            REFIID riid, void **ppv)
1001 {
1002     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1003
1004     *ppv = NULL;
1005
1006     if(IsEqualGUID(&IID_IUnknown, riid)) {
1007         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
1008         *ppv = HTMLELEMCOL(This);
1009     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1010         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
1011         *ppv = HTMLELEMCOL(This);
1012     }else if(IsEqualGUID(&IID_IHTMLElementCollection, riid)) {
1013         TRACE("(%p)->(IID_IHTMLElementCollection %p)\n", This, ppv);
1014         *ppv = HTMLELEMCOL(This);
1015     }
1016
1017     if(*ppv) {
1018         IHTMLElementCollection_AddRef(HTMLELEMCOL(This));
1019         return S_OK;
1020     }
1021
1022     FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
1023     return E_NOINTERFACE;
1024 }
1025
1026 static ULONG WINAPI HTMLElementCollection_AddRef(IHTMLElementCollection *iface)
1027 {
1028     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1029     LONG ref = InterlockedIncrement(&This->ref);
1030
1031     TRACE("(%p) ref=%ld\n", This, ref);
1032
1033     return ref;
1034 }
1035
1036 static ULONG WINAPI HTMLElementCollection_Release(IHTMLElementCollection *iface)
1037 {
1038     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1039     LONG ref = InterlockedDecrement(&This->ref);
1040
1041     TRACE("(%p) ref=%ld\n", This, ref);
1042
1043     if(!ref) {
1044         IUnknown_Release(This->ref_unk);
1045         HeapFree(GetProcessHeap(), 0, This->elems);
1046         HeapFree(GetProcessHeap(), 0, This);
1047     }
1048
1049     return ref;
1050 }
1051
1052 static HRESULT WINAPI HTMLElementCollection_GetTypeInfoCount(IHTMLElementCollection *iface,
1053                                                              UINT *pctinfo)
1054 {
1055     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1056     FIXME("(%p)->(%p)\n", This, pctinfo);
1057     return E_NOTIMPL;
1058 }
1059
1060 static HRESULT WINAPI HTMLElementCollection_GetTypeInfo(IHTMLElementCollection *iface,
1061         UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
1062 {
1063     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1064     FIXME("(%p)->(%u %lu %p)\n", This, iTInfo, lcid, ppTInfo);
1065     return E_NOTIMPL;
1066 }
1067
1068 static HRESULT WINAPI HTMLElementCollection_GetIDsOfNames(IHTMLElementCollection *iface,
1069         REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1070 {
1071     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1072     FIXME("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
1073                                         lcid, rgDispId);
1074     return E_NOTIMPL;
1075 }
1076
1077 static HRESULT WINAPI HTMLElementCollection_Invoke(IHTMLElementCollection *iface,
1078         DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1079         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1080 {
1081     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1082     FIXME("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1083             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1084     return E_NOTIMPL;
1085 }
1086
1087 static HRESULT WINAPI HTMLElementCollection_toString(IHTMLElementCollection *iface,
1088                                                      BSTR *String)
1089 {
1090     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1091     FIXME("(%p)->(%p)\n", This, String);
1092     return E_NOTIMPL;
1093 }
1094
1095 static HRESULT WINAPI HTMLElementCollection_put_length(IHTMLElementCollection *iface,
1096                                                        long v)
1097 {
1098     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1099     FIXME("(%p)->(%ld)\n", This, v);
1100     return E_NOTIMPL;
1101 }
1102
1103 static HRESULT WINAPI HTMLElementCollection_get_length(IHTMLElementCollection *iface,
1104                                                        long *p)
1105 {
1106     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1107
1108     TRACE("(%p)->(%p)\n", This, p);
1109
1110     *p = This->len;
1111     return S_OK;
1112 }
1113
1114 static HRESULT WINAPI HTMLElementCollection_get__newEnum(IHTMLElementCollection *iface,
1115                                                          IUnknown **p)
1116 {
1117     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1118     FIXME("(%p)->(%p)\n", This, p);
1119     return E_NOTIMPL;
1120 }
1121
1122 static HRESULT WINAPI HTMLElementCollection_item(IHTMLElementCollection *iface,
1123         VARIANT name, VARIANT index, IDispatch **pdisp)
1124 {
1125     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1126
1127     if(V_VT(&index) != VT_I4) {
1128         WARN("Invalid index vt=%d\n", V_VT(&index));
1129         return E_INVALIDARG;
1130     }
1131
1132     if(V_VT(&name) != VT_I4 || V_I4(&name) != V_I4(&index))
1133         FIXME("Unsupproted name vt=%d\n", V_VT(&name));
1134
1135     TRACE("(%p)->(%ld %ld %p)\n", This, V_I4(&name), V_I4(&index), pdisp);
1136
1137     if(V_I4(&index) < 0 || V_I4(&index) >= This->len)
1138         return E_INVALIDARG;
1139
1140     *pdisp = (IDispatch*)This->elems[V_I4(&index)];
1141     IDispatch_AddRef(*pdisp);
1142     return S_OK;
1143 }
1144
1145 static HRESULT WINAPI HTMLElementCollection_tags(IHTMLElementCollection *iface,
1146                                                  VARIANT tagName, IDispatch **pdisp)
1147 {
1148     HTMLElementCollection *This = ELEMCOL_THIS(iface);
1149     DWORD size = 8, len = 0, i;
1150     HTMLElement **elem_list;
1151     nsAString tag_str;
1152     const PRUnichar *tag;
1153
1154     if(V_VT(&tagName) != VT_BSTR) {
1155         WARN("Invalid arg\n");
1156         return E_INVALIDARG;
1157     }
1158
1159     TRACE("(%p)->(%s %p)\n", This, debugstr_w(V_BSTR(&tagName)), pdisp);
1160
1161     elem_list = HeapAlloc(GetProcessHeap(), 0, size*sizeof(HTMLElement*));
1162
1163     nsAString_Init(&tag_str, NULL);
1164
1165     for(i=0; i<This->len; i++) {
1166         if(!This->elems[i]->nselem)
1167             continue;
1168
1169         nsIDOMElement_GetTagName(This->elems[i]->nselem, &tag_str);
1170         nsAString_GetData(&tag_str, &tag, NULL);
1171
1172         if(CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, tag, -1,
1173                           V_BSTR(&tagName), -1) == CSTR_EQUAL) {
1174             if(len == size) {
1175                 size <<= 2;
1176                 elem_list = HeapReAlloc(GetProcessHeap(), 0, elem_list, size);
1177             }
1178
1179             elem_list[len++] = This->elems[i];
1180         }
1181     }
1182
1183     nsAString_Finish(&tag_str);
1184
1185     TRACE("fount %ld tags\n", len);
1186
1187     if(!len) {
1188         HeapFree(GetProcessHeap(), 0, elem_list);
1189         elem_list = NULL;
1190     }else if(size > len) {
1191         HeapReAlloc(GetProcessHeap(), 0, elem_list, len);
1192     }
1193
1194     return HTMLElementCollection_Create(This->ref_unk, elem_list, len, pdisp);
1195 }
1196
1197 #undef ELEMCOL_THIS
1198
1199 static const IHTMLElementCollectionVtbl HTMLElementCollectionVtbl = {
1200     HTMLElementCollection_QueryInterface,
1201     HTMLElementCollection_AddRef,
1202     HTMLElementCollection_Release,
1203     HTMLElementCollection_GetTypeInfoCount,
1204     HTMLElementCollection_GetTypeInfo,
1205     HTMLElementCollection_GetIDsOfNames,
1206     HTMLElementCollection_Invoke,
1207     HTMLElementCollection_toString,
1208     HTMLElementCollection_put_length,
1209     HTMLElementCollection_get_length,
1210     HTMLElementCollection_get__newEnum,
1211     HTMLElementCollection_item,
1212     HTMLElementCollection_tags
1213 };
1214
1215 static HRESULT HTMLElementCollection_Create(IUnknown *ref_unk, HTMLElement **elems, DWORD len,
1216                                             IDispatch **p)
1217 {
1218     HTMLElementCollection *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(HTMLElementCollection));
1219
1220     ret->lpHTMLElementCollectionVtbl = &HTMLElementCollectionVtbl;
1221     ret->ref = 1;
1222     ret->elems = elems;
1223     ret->len = len;
1224
1225     IUnknown_AddRef(ref_unk);
1226     ret->ref_unk = ref_unk;
1227
1228     TRACE("ret=%p len=%ld\n", ret, len);
1229
1230     *p = (IDispatch*)ret;
1231     return S_OK;
1232 }