comctl32/imagelist: Use proper color format for merged image lists.
[wine] / dlls / mshtml / htmldoc3.c
1 /*
2  * Copyright 2005 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 #include <assert.h>
24
25 #define COBJMACROS
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "ole2.h"
31
32 #include "wine/debug.h"
33
34 #include "mshtml_private.h"
35 #include "htmlevent.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38
39 HRESULT get_doc_elem_by_id(HTMLDocumentNode *doc, const WCHAR *id, HTMLElement **ret)
40 {
41     nsIDOMNodeList *nsnode_list;
42     nsIDOMElement *nselem;
43     nsIDOMNode *nsnode;
44     nsAString id_str;
45     nsresult nsres;
46     HRESULT hres;
47
48     if(!doc->nsdoc) {
49         WARN("NULL nsdoc\n");
50         return E_UNEXPECTED;
51     }
52
53     nsAString_InitDepend(&id_str, id);
54     /* get element by id attribute */
55     nsres = nsIDOMHTMLDocument_GetElementById(doc->nsdoc, &id_str, &nselem);
56     if(FAILED(nsres)) {
57         ERR("GetElementById failed: %08x\n", nsres);
58         nsAString_Finish(&id_str);
59         return E_FAIL;
60     }
61
62     /* get first element by name attribute */
63     nsres = nsIDOMHTMLDocument_GetElementsByName(doc->nsdoc, &id_str, &nsnode_list);
64     nsAString_Finish(&id_str);
65     if(FAILED(nsres)) {
66         ERR("getElementsByName failed: %08x\n", nsres);
67         if(nselem)
68             nsIDOMElement_Release(nselem);
69         return E_FAIL;
70     }
71
72     nsres = nsIDOMNodeList_Item(nsnode_list, 0, &nsnode);
73     nsIDOMNodeList_Release(nsnode_list);
74     assert(nsres == NS_OK);
75
76     if(nsnode && nselem) {
77         UINT16 pos;
78
79         nsres = nsIDOMNode_CompareDocumentPosition(nsnode, (nsIDOMNode*)nselem, &pos);
80         if(NS_FAILED(nsres)) {
81             FIXME("CompareDocumentPosition failed: 0x%08x\n", nsres);
82             nsIDOMNode_Release(nsnode);
83             nsIDOMElement_Release(nselem);
84             return E_FAIL;
85         }
86
87         TRACE("CompareDocumentPosition gave: 0x%x\n", pos);
88         if(!(pos & (DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS))) {
89             nsIDOMElement_Release(nselem);
90             nselem = NULL;
91         }
92     }
93
94     if(nsnode) {
95         if(!nselem) {
96             nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMElement, (void**)&nselem);
97             assert(nsres == NS_OK);
98         }
99         nsIDOMNode_Release(nsnode);
100     }
101
102     if(!nselem) {
103         *ret = NULL;
104         return S_OK;
105     }
106
107     hres = get_elem(doc, nselem, ret);
108     nsIDOMElement_Release(nselem);
109     return hres;
110 }
111
112 static inline HTMLDocument *impl_from_IHTMLDocument3(IHTMLDocument3 *iface)
113 {
114     return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument3_iface);
115 }
116
117 static HRESULT WINAPI HTMLDocument3_QueryInterface(IHTMLDocument3 *iface,
118                                                   REFIID riid, void **ppv)
119 {
120     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
121     return htmldoc_query_interface(This, riid, ppv);
122 }
123
124 static ULONG WINAPI HTMLDocument3_AddRef(IHTMLDocument3 *iface)
125 {
126     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
127     return htmldoc_addref(This);
128 }
129
130 static ULONG WINAPI HTMLDocument3_Release(IHTMLDocument3 *iface)
131 {
132     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
133     return htmldoc_release(This);
134 }
135
136 static HRESULT WINAPI HTMLDocument3_GetTypeInfoCount(IHTMLDocument3 *iface, UINT *pctinfo)
137 {
138     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
139     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
140 }
141
142 static HRESULT WINAPI HTMLDocument3_GetTypeInfo(IHTMLDocument3 *iface, UINT iTInfo,
143                                                 LCID lcid, ITypeInfo **ppTInfo)
144 {
145     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
146     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
147 }
148
149 static HRESULT WINAPI HTMLDocument3_GetIDsOfNames(IHTMLDocument3 *iface, REFIID riid,
150                                                 LPOLESTR *rgszNames, UINT cNames,
151                                                 LCID lcid, DISPID *rgDispId)
152 {
153     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
154     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
155             rgDispId);
156 }
157
158 static HRESULT WINAPI HTMLDocument3_Invoke(IHTMLDocument3 *iface, DISPID dispIdMember,
159                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
160                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
161 {
162     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
163     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
164             pDispParams, pVarResult, pExcepInfo, puArgErr);
165 }
166
167 static HRESULT WINAPI HTMLDocument3_releaseCapture(IHTMLDocument3 *iface)
168 {
169     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
170     FIXME("(%p)\n", This);
171     return E_NOTIMPL;
172 }
173
174 static HRESULT WINAPI HTMLDocument3_recalc(IHTMLDocument3 *iface, VARIANT_BOOL fForce)
175 {
176     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
177     FIXME("(%p)->(%x)\n", This, fForce);
178     return E_NOTIMPL;
179 }
180
181 static HRESULT WINAPI HTMLDocument3_createTextNode(IHTMLDocument3 *iface, BSTR text,
182                                                    IHTMLDOMNode **newTextNode)
183 {
184     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
185     nsIDOMText *nstext;
186     HTMLDOMNode *node;
187     nsAString text_str;
188     nsresult nsres;
189     HRESULT hres;
190
191     TRACE("(%p)->(%s %p)\n", This, debugstr_w(text), newTextNode);
192
193     if(!This->doc_node->nsdoc) {
194         WARN("NULL nsdoc\n");
195         return E_UNEXPECTED;
196     }
197
198     nsAString_InitDepend(&text_str, text);
199     nsres = nsIDOMHTMLDocument_CreateTextNode(This->doc_node->nsdoc, &text_str, &nstext);
200     nsAString_Finish(&text_str);
201     if(NS_FAILED(nsres)) {
202         ERR("CreateTextNode failed: %08x\n", nsres);
203         return E_FAIL;
204     }
205
206     hres = HTMLDOMTextNode_Create(This->doc_node, (nsIDOMNode*)nstext, &node);
207     nsIDOMText_Release(nstext);
208     if(FAILED(hres))
209         return hres;
210
211     *newTextNode = &node->IHTMLDOMNode_iface;
212     return S_OK;
213 }
214
215 static HRESULT WINAPI HTMLDocument3_get_documentElement(IHTMLDocument3 *iface, IHTMLElement **p)
216 {
217     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
218     nsIDOMElement *nselem = NULL;
219     HTMLDOMNode *node;
220     nsresult nsres;
221     HRESULT hres;
222
223     TRACE("(%p)->(%p)\n", This, p);
224
225     if(This->window->readystate == READYSTATE_UNINITIALIZED) {
226         *p = NULL;
227         return S_OK;
228     }
229
230     if(!This->doc_node->nsdoc) {
231         WARN("NULL nsdoc\n");
232         return E_UNEXPECTED;
233     }
234
235     nsres = nsIDOMHTMLDocument_GetDocumentElement(This->doc_node->nsdoc, &nselem);
236     if(NS_FAILED(nsres)) {
237         ERR("GetDocumentElement failed: %08x\n", nsres);
238         return E_FAIL;
239     }
240
241     if(!nselem) {
242         *p = NULL;
243         return S_OK;
244     }
245
246     hres = get_node(This->doc_node, (nsIDOMNode *)nselem, TRUE, &node);
247     nsIDOMElement_Release(nselem);
248     if(FAILED(hres))
249         return hres;
250
251     hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)p);
252     node_release(node);
253     return hres;
254 }
255
256 static HRESULT WINAPI HTMLDocument3_uniqueID(IHTMLDocument3 *iface, BSTR *p)
257 {
258     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
259     FIXME("(%p)->(%p)\n", This, p);
260     return E_NOTIMPL;
261 }
262
263 static HRESULT WINAPI HTMLDocument3_attachEvent(IHTMLDocument3 *iface, BSTR event,
264                                                 IDispatch* pDisp, VARIANT_BOOL *pfResult)
265 {
266     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
267
268     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
269
270     return attach_event(&This->doc_node->node.event_target, This->doc_node->node.nsnode, This, event, pDisp, pfResult);
271 }
272
273 static HRESULT WINAPI HTMLDocument3_detachEvent(IHTMLDocument3 *iface, BSTR event,
274                                                 IDispatch *pDisp)
275 {
276     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
277
278     TRACE("(%p)->(%s %p)\n", This, debugstr_w(event), pDisp);
279
280     return detach_event(This->doc_node->node.event_target, This, event, pDisp);
281 }
282
283 static HRESULT WINAPI HTMLDocument3_put_onrowsdelete(IHTMLDocument3 *iface, VARIANT v)
284 {
285     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
286     FIXME("(%p)->()\n", This);
287     return E_NOTIMPL;
288 }
289
290 static HRESULT WINAPI HTMLDocument3_get_onrowsdelete(IHTMLDocument3 *iface, VARIANT *p)
291 {
292     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
293     FIXME("(%p)->(%p)\n", This, p);
294     return E_NOTIMPL;
295 }
296
297 static HRESULT WINAPI HTMLDocument3_put_onrowsinserted(IHTMLDocument3 *iface, VARIANT v)
298 {
299     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
300     FIXME("(%p)->()\n", This);
301     return E_NOTIMPL;
302 }
303
304 static HRESULT WINAPI HTMLDocument3_get_onrowsinserted(IHTMLDocument3 *iface, VARIANT *p)
305 {
306     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
307     FIXME("(%p)->(%p)\n", This, p);
308     return E_NOTIMPL;
309 }
310
311 static HRESULT WINAPI HTMLDocument3_put_oncellchange(IHTMLDocument3 *iface, VARIANT v)
312 {
313     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
314     FIXME("(%p)->()\n", This);
315     return E_NOTIMPL;
316 }
317
318 static HRESULT WINAPI HTMLDocument3_get_oncellchange(IHTMLDocument3 *iface, VARIANT *p)
319 {
320     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
321     FIXME("(%p)->(%p)\n", This, p);
322     return E_NOTIMPL;
323 }
324
325 static HRESULT WINAPI HTMLDocument3_put_ondatasetchanged(IHTMLDocument3 *iface, VARIANT v)
326 {
327     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
328     FIXME("(%p)->()\n", This);
329     return E_NOTIMPL;
330 }
331
332 static HRESULT WINAPI HTMLDocument3_get_ondatasetchanged(IHTMLDocument3 *iface, VARIANT *p)
333 {
334     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
335     FIXME("(%p)->(%p)\n", This, p);
336     return E_NOTIMPL;
337 }
338
339 static HRESULT WINAPI HTMLDocument3_put_ondataavailable(IHTMLDocument3 *iface, VARIANT v)
340 {
341     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
342     FIXME("(%p)->()\n", This);
343     return E_NOTIMPL;
344 }
345
346 static HRESULT WINAPI HTMLDocument3_get_ondataavailable(IHTMLDocument3 *iface, VARIANT *p)
347 {
348     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
349     FIXME("(%p)->(%p)\n", This, p);
350     return E_NOTIMPL;
351 }
352
353 static HRESULT WINAPI HTMLDocument3_put_ondatasetcomplete(IHTMLDocument3 *iface, VARIANT v)
354 {
355     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
356     FIXME("(%p)->()\n", This);
357     return E_NOTIMPL;
358 }
359
360 static HRESULT WINAPI HTMLDocument3_get_ondatasetcomplete(IHTMLDocument3 *iface, VARIANT *p)
361 {
362     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
363     FIXME("(%p)->(%p)\n", This, p);
364     return E_NOTIMPL;
365 }
366
367 static HRESULT WINAPI HTMLDocument3_put_onpropertychange(IHTMLDocument3 *iface, VARIANT v)
368 {
369     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
370     FIXME("(%p)->()\n", This);
371     return E_NOTIMPL;
372 }
373
374 static HRESULT WINAPI HTMLDocument3_get_onpropertychange(IHTMLDocument3 *iface, VARIANT *p)
375 {
376     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
377     FIXME("(%p)->(%p)\n", This, p);
378     return E_NOTIMPL;
379 }
380
381 static HRESULT WINAPI HTMLDocument3_put_dir(IHTMLDocument3 *iface, BSTR v)
382 {
383     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
384     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
385     return E_NOTIMPL;
386 }
387
388 static HRESULT WINAPI HTMLDocument3_get_dir(IHTMLDocument3 *iface, BSTR *p)
389 {
390     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
391     FIXME("(%p)->(%p)\n", This, p);
392     return E_NOTIMPL;
393 }
394
395 static HRESULT WINAPI HTMLDocument3_put_oncontextmenu(IHTMLDocument3 *iface, VARIANT v)
396 {
397     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
398
399     TRACE("(%p)->()\n", This);
400
401     return set_doc_event(This, EVENTID_CONTEXTMENU, &v);
402 }
403
404 static HRESULT WINAPI HTMLDocument3_get_oncontextmenu(IHTMLDocument3 *iface, VARIANT *p)
405 {
406     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
407
408     TRACE("(%p)->(%p)\n", This, p);
409
410     return get_doc_event(This, EVENTID_CONTEXTMENU, p);
411 }
412
413 static HRESULT WINAPI HTMLDocument3_put_onstop(IHTMLDocument3 *iface, VARIANT v)
414 {
415     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
416     FIXME("(%p)->()\n", This);
417     return E_NOTIMPL;
418 }
419
420 static HRESULT WINAPI HTMLDocument3_get_onstop(IHTMLDocument3 *iface, VARIANT *p)
421 {
422     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
423     FIXME("(%p)->(%p)\n", This, p);
424     return E_NOTIMPL;
425 }
426
427 static HRESULT WINAPI HTMLDocument3_createDocumentFragment(IHTMLDocument3 *iface,
428                                                            IHTMLDocument2 **ppNewDoc)
429 {
430     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
431     nsIDOMDocumentFragment *doc_frag;
432     HTMLDocumentNode *docnode;
433     nsresult nsres;
434     HRESULT hres;
435
436     TRACE("(%p)->(%p)\n", This, ppNewDoc);
437
438     if(!This->doc_node->nsdoc) {
439         FIXME("NULL nsdoc\n");
440         return E_NOTIMPL;
441     }
442
443     nsres = nsIDOMHTMLDocument_CreateDocumentFragment(This->doc_node->nsdoc, &doc_frag);
444     if(NS_FAILED(nsres)) {
445         ERR("CreateDocumentFragment failed: %08x\n", nsres);
446         return E_FAIL;
447     }
448
449     hres = create_document_fragment((nsIDOMNode*)doc_frag, This->doc_node, &docnode);
450     nsIDOMDocumentFragment_Release(doc_frag);
451     if(FAILED(hres))
452         return hres;
453
454     *ppNewDoc = &docnode->basedoc.IHTMLDocument2_iface;
455     return S_OK;
456 }
457
458 static HRESULT WINAPI HTMLDocument3_get_parentDocument(IHTMLDocument3 *iface,
459                                                        IHTMLDocument2 **p)
460 {
461     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
462     FIXME("(%p)->(%p)\n", This, p);
463     return E_NOTIMPL;
464 }
465
466 static HRESULT WINAPI HTMLDocument3_put_enableDownload(IHTMLDocument3 *iface,
467                                                        VARIANT_BOOL v)
468 {
469     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
470     FIXME("(%p)->(%x)\n", This, v);
471     return E_NOTIMPL;
472 }
473
474 static HRESULT WINAPI HTMLDocument3_get_enableDownload(IHTMLDocument3 *iface,
475                                                        VARIANT_BOOL *p)
476 {
477     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
478     FIXME("(%p)->(%p)\n", This, p);
479     return E_NOTIMPL;
480 }
481
482 static HRESULT WINAPI HTMLDocument3_put_baseUrl(IHTMLDocument3 *iface, BSTR v)
483 {
484     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
485     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
486     return E_NOTIMPL;
487 }
488
489 static HRESULT WINAPI HTMLDocument3_get_baseUrl(IHTMLDocument3 *iface, BSTR *p)
490 {
491     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
492     FIXME("(%p)->(%p)\n", This, p);
493     return E_NOTIMPL;
494 }
495
496 static HRESULT WINAPI HTMLDocument3_get_childNodes(IHTMLDocument3 *iface, IDispatch **p)
497 {
498     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
499
500     TRACE("(%p)->(%p)\n", This, p);
501
502     return IHTMLDOMNode_get_childNodes(&This->doc_node->node.IHTMLDOMNode_iface, p);
503 }
504
505 static HRESULT WINAPI HTMLDocument3_put_inheritStyleSheets(IHTMLDocument3 *iface,
506                                                            VARIANT_BOOL v)
507 {
508     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
509     FIXME("(%p)->()\n", This);
510     return E_NOTIMPL;
511 }
512
513 static HRESULT WINAPI HTMLDocument3_get_inheritStyleSheets(IHTMLDocument3 *iface,
514                                                            VARIANT_BOOL *p)
515 {
516     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
517     FIXME("(%p)->(%p)\n", This, p);
518     return E_NOTIMPL;
519 }
520
521 static HRESULT WINAPI HTMLDocument3_put_onbeforeeditfocus(IHTMLDocument3 *iface, VARIANT v)
522 {
523     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
524     FIXME("(%p)->()\n", This);
525     return E_NOTIMPL;
526 }
527
528 static HRESULT WINAPI HTMLDocument3_get_onbeforeeditfocus(IHTMLDocument3 *iface, VARIANT *p)
529 {
530     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
531     FIXME("(%p)->(%p)\n", This, p);
532     return E_NOTIMPL;
533 }
534
535 static HRESULT WINAPI HTMLDocument3_getElementsByName(IHTMLDocument3 *iface, BSTR v,
536                                                       IHTMLElementCollection **ppelColl)
537 {
538     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
539     FIXME("(%p)->(%s %p)\n", This, debugstr_w(v), ppelColl);
540     return E_NOTIMPL;
541 }
542
543
544 static HRESULT WINAPI HTMLDocument3_getElementById(IHTMLDocument3 *iface, BSTR v,
545                                                    IHTMLElement **pel)
546 {
547     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
548     HTMLElement *elem;
549     HRESULT hres;
550
551     TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pel);
552
553     hres = get_doc_elem_by_id(This->doc_node, v, &elem);
554     if(FAILED(hres) || !elem) {
555         *pel = NULL;
556         return hres;
557     }
558
559     *pel = &elem->IHTMLElement_iface;
560     return S_OK;
561 }
562
563
564 static HRESULT WINAPI HTMLDocument3_getElementsByTagName(IHTMLDocument3 *iface, BSTR v,
565                                                          IHTMLElementCollection **pelColl)
566 {
567     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
568     nsIDOMNodeList *nslist;
569     nsAString id_str, ns_str;
570     nsresult nsres;
571     static const WCHAR str[] = {'*',0};
572
573     TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pelColl);
574
575     if(!This->doc_node->nsdoc) {
576         WARN("NULL nsdoc\n");
577         return E_UNEXPECTED;
578     }
579
580     nsAString_InitDepend(&id_str, v);
581     nsAString_InitDepend(&ns_str, str);
582     nsres = nsIDOMHTMLDocument_GetElementsByTagNameNS(This->doc_node->nsdoc, &ns_str, &id_str, &nslist);
583     nsAString_Finish(&id_str);
584     nsAString_Finish(&ns_str);
585     if(FAILED(nsres)) {
586         ERR("GetElementByName failed: %08x\n", nsres);
587         return E_FAIL;
588     }
589
590     *pelColl = create_collection_from_nodelist(This->doc_node, nslist);
591     nsIDOMNodeList_Release(nslist);
592
593     return S_OK;
594 }
595
596 static const IHTMLDocument3Vtbl HTMLDocument3Vtbl = {
597     HTMLDocument3_QueryInterface,
598     HTMLDocument3_AddRef,
599     HTMLDocument3_Release,
600     HTMLDocument3_GetTypeInfoCount,
601     HTMLDocument3_GetTypeInfo,
602     HTMLDocument3_GetIDsOfNames,
603     HTMLDocument3_Invoke,
604     HTMLDocument3_releaseCapture,
605     HTMLDocument3_recalc,
606     HTMLDocument3_createTextNode,
607     HTMLDocument3_get_documentElement,
608     HTMLDocument3_uniqueID,
609     HTMLDocument3_attachEvent,
610     HTMLDocument3_detachEvent,
611     HTMLDocument3_put_onrowsdelete,
612     HTMLDocument3_get_onrowsdelete,
613     HTMLDocument3_put_onrowsinserted,
614     HTMLDocument3_get_onrowsinserted,
615     HTMLDocument3_put_oncellchange,
616     HTMLDocument3_get_oncellchange,
617     HTMLDocument3_put_ondatasetchanged,
618     HTMLDocument3_get_ondatasetchanged,
619     HTMLDocument3_put_ondataavailable,
620     HTMLDocument3_get_ondataavailable,
621     HTMLDocument3_put_ondatasetcomplete,
622     HTMLDocument3_get_ondatasetcomplete,
623     HTMLDocument3_put_onpropertychange,
624     HTMLDocument3_get_onpropertychange,
625     HTMLDocument3_put_dir,
626     HTMLDocument3_get_dir,
627     HTMLDocument3_put_oncontextmenu,
628     HTMLDocument3_get_oncontextmenu,
629     HTMLDocument3_put_onstop,
630     HTMLDocument3_get_onstop,
631     HTMLDocument3_createDocumentFragment,
632     HTMLDocument3_get_parentDocument,
633     HTMLDocument3_put_enableDownload,
634     HTMLDocument3_get_enableDownload,
635     HTMLDocument3_put_baseUrl,
636     HTMLDocument3_get_baseUrl,
637     HTMLDocument3_get_childNodes,
638     HTMLDocument3_put_inheritStyleSheets,
639     HTMLDocument3_get_inheritStyleSheets,
640     HTMLDocument3_put_onbeforeeditfocus,
641     HTMLDocument3_get_onbeforeeditfocus,
642     HTMLDocument3_getElementsByName,
643     HTMLDocument3_getElementById,
644     HTMLDocument3_getElementsByTagName
645 };
646
647 static inline HTMLDocument *impl_from_IHTMLDocument4(IHTMLDocument4 *iface)
648 {
649     return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument4_iface);
650 }
651
652 static HRESULT WINAPI HTMLDocument4_QueryInterface(IHTMLDocument4 *iface,
653                                                    REFIID riid, void **ppv)
654 {
655     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
656     return htmldoc_query_interface(This, riid, ppv);
657 }
658
659 static ULONG WINAPI HTMLDocument4_AddRef(IHTMLDocument4 *iface)
660 {
661     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
662     return htmldoc_addref(This);
663 }
664
665 static ULONG WINAPI HTMLDocument4_Release(IHTMLDocument4 *iface)
666 {
667     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
668     return htmldoc_release(This);
669 }
670
671 static HRESULT WINAPI HTMLDocument4_GetTypeInfoCount(IHTMLDocument4 *iface, UINT *pctinfo)
672 {
673     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
674     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
675 }
676
677 static HRESULT WINAPI HTMLDocument4_GetTypeInfo(IHTMLDocument4 *iface, UINT iTInfo,
678                                                 LCID lcid, ITypeInfo **ppTInfo)
679 {
680     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
681     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
682 }
683
684 static HRESULT WINAPI HTMLDocument4_GetIDsOfNames(IHTMLDocument4 *iface, REFIID riid,
685                                                 LPOLESTR *rgszNames, UINT cNames,
686                                                 LCID lcid, DISPID *rgDispId)
687 {
688     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
689     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
690             rgDispId);
691 }
692
693 static HRESULT WINAPI HTMLDocument4_Invoke(IHTMLDocument4 *iface, DISPID dispIdMember,
694                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
695                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
696 {
697     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
698     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
699             pDispParams, pVarResult, pExcepInfo, puArgErr);
700 }
701
702 static HRESULT WINAPI HTMLDocument4_focus(IHTMLDocument4 *iface)
703 {
704     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
705     nsIDOMHTMLElement *nsbody;
706     nsresult nsres;
707
708     TRACE("(%p)->()\n", This);
709
710     nsres = nsIDOMHTMLDocument_GetBody(This->doc_node->nsdoc, &nsbody);
711     if(NS_FAILED(nsres) || !nsbody) {
712         ERR("GetBody failed: %08x\n", nsres);
713         return E_FAIL;
714     }
715
716     nsres = nsIDOMHTMLElement_Focus(nsbody);
717     nsIDOMHTMLElement_Release(nsbody);
718     if(NS_FAILED(nsres)) {
719         ERR("Focus failed: %08x\n", nsres);
720         return E_FAIL;
721     }
722
723     return S_OK;
724 }
725
726 static HRESULT WINAPI HTMLDocument4_hasFocus(IHTMLDocument4 *iface, VARIANT_BOOL *pfFocus)
727 {
728     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
729     FIXME("(%p)->(%p)\n", This, pfFocus);
730     return E_NOTIMPL;
731 }
732
733 static HRESULT WINAPI HTMLDocument4_put_onselectionchange(IHTMLDocument4 *iface, VARIANT v)
734 {
735     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
736     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
737     return E_NOTIMPL;
738 }
739
740 static HRESULT WINAPI HTMLDocument4_get_onselectionchange(IHTMLDocument4 *iface, VARIANT *p)
741 {
742     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
743     FIXME("(%p)->(%p)\n", This, p);
744     return E_NOTIMPL;
745 }
746
747 static HRESULT WINAPI HTMLDocument4_get_namespace(IHTMLDocument4 *iface, IDispatch **p)
748 {
749     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
750     FIXME("(%p)->(%p)\n", This, p);
751     return E_NOTIMPL;
752 }
753
754 static HRESULT WINAPI HTMLDocument4_createDocumentFromUrl(IHTMLDocument4 *iface, BSTR bstrUrl,
755         BSTR bstrOptions, IHTMLDocument2 **newDoc)
756 {
757     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
758     FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(bstrUrl), debugstr_w(bstrOptions), newDoc);
759     return E_NOTIMPL;
760 }
761
762 static HRESULT WINAPI HTMLDocument4_put_media(IHTMLDocument4 *iface, BSTR v)
763 {
764     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
765     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
766     return E_NOTIMPL;
767 }
768
769 static HRESULT WINAPI HTMLDocument4_get_media(IHTMLDocument4 *iface, BSTR *p)
770 {
771     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
772     FIXME("(%p)->(%p)\n", This, p);
773     return E_NOTIMPL;
774 }
775
776 static HRESULT WINAPI HTMLDocument4_createEventObject(IHTMLDocument4 *iface,
777         VARIANT *pvarEventObject, IHTMLEventObj **ppEventObj)
778 {
779     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
780
781     TRACE("(%p)->(%s %p)\n", This, debugstr_variant(pvarEventObject), ppEventObj);
782
783     if(pvarEventObject && V_VT(pvarEventObject) != VT_ERROR && V_VT(pvarEventObject) != VT_EMPTY) {
784         FIXME("unsupported pvarEventObject %s\n", debugstr_variant(pvarEventObject));
785         return E_NOTIMPL;
786     }
787
788     return create_event_obj(ppEventObj);
789 }
790
791 static HRESULT WINAPI HTMLDocument4_fireEvent(IHTMLDocument4 *iface, BSTR bstrEventName,
792         VARIANT *pvarEventObject, VARIANT_BOOL *pfCanceled)
793 {
794     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
795
796     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(bstrEventName), pvarEventObject, pfCanceled);
797
798     return dispatch_event(&This->doc_node->node, bstrEventName, pvarEventObject, pfCanceled);
799 }
800
801 static HRESULT WINAPI HTMLDocument4_createRenderStyle(IHTMLDocument4 *iface, BSTR v,
802         IHTMLRenderStyle **ppIHTMLRenderStyle)
803 {
804     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
805     FIXME("(%p)->(%s %p)\n", This, debugstr_w(v), ppIHTMLRenderStyle);
806     return E_NOTIMPL;
807 }
808
809 static HRESULT WINAPI HTMLDocument4_put_oncontrolselect(IHTMLDocument4 *iface, VARIANT v)
810 {
811     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
812     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
813     return E_NOTIMPL;
814 }
815
816 static HRESULT WINAPI HTMLDocument4_get_oncontrolselect(IHTMLDocument4 *iface, VARIANT *p)
817 {
818     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
819     FIXME("(%p)->(%p)\n", This, p);
820     return E_NOTIMPL;
821 }
822
823 static HRESULT WINAPI HTMLDocument4_get_URLEncoded(IHTMLDocument4 *iface, BSTR *p)
824 {
825     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
826     FIXME("(%p)->(%p)\n", This, p);
827     return E_NOTIMPL;
828 }
829
830 static const IHTMLDocument4Vtbl HTMLDocument4Vtbl = {
831     HTMLDocument4_QueryInterface,
832     HTMLDocument4_AddRef,
833     HTMLDocument4_Release,
834     HTMLDocument4_GetTypeInfoCount,
835     HTMLDocument4_GetTypeInfo,
836     HTMLDocument4_GetIDsOfNames,
837     HTMLDocument4_Invoke,
838     HTMLDocument4_focus,
839     HTMLDocument4_hasFocus,
840     HTMLDocument4_put_onselectionchange,
841     HTMLDocument4_get_onselectionchange,
842     HTMLDocument4_get_namespace,
843     HTMLDocument4_createDocumentFromUrl,
844     HTMLDocument4_put_media,
845     HTMLDocument4_get_media,
846     HTMLDocument4_createEventObject,
847     HTMLDocument4_fireEvent,
848     HTMLDocument4_createRenderStyle,
849     HTMLDocument4_put_oncontrolselect,
850     HTMLDocument4_get_oncontrolselect,
851     HTMLDocument4_get_URLEncoded
852 };
853
854 void HTMLDocument_HTMLDocument3_Init(HTMLDocument *This)
855 {
856     This->IHTMLDocument3_iface.lpVtbl = &HTMLDocument3Vtbl;
857     This->IHTMLDocument4_iface.lpVtbl = &HTMLDocument4Vtbl;
858 }