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