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