Release 1.5.29.
[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;
570     nsresult nsres;
571
572     TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pelColl);
573
574     if(!This->doc_node->nsdoc) {
575         WARN("NULL nsdoc\n");
576         return E_UNEXPECTED;
577     }
578
579     nsAString_InitDepend(&id_str, v);
580     nsres = nsIDOMHTMLDocument_GetElementsByTagName(This->doc_node->nsdoc, &id_str, &nslist);
581     nsAString_Finish(&id_str);
582     if(FAILED(nsres)) {
583         ERR("GetElementByName failed: %08x\n", nsres);
584         return E_FAIL;
585     }
586
587     *pelColl = create_collection_from_nodelist(This->doc_node, nslist);
588     nsIDOMNodeList_Release(nslist);
589
590     return S_OK;
591 }
592
593 static const IHTMLDocument3Vtbl HTMLDocument3Vtbl = {
594     HTMLDocument3_QueryInterface,
595     HTMLDocument3_AddRef,
596     HTMLDocument3_Release,
597     HTMLDocument3_GetTypeInfoCount,
598     HTMLDocument3_GetTypeInfo,
599     HTMLDocument3_GetIDsOfNames,
600     HTMLDocument3_Invoke,
601     HTMLDocument3_releaseCapture,
602     HTMLDocument3_recalc,
603     HTMLDocument3_createTextNode,
604     HTMLDocument3_get_documentElement,
605     HTMLDocument3_uniqueID,
606     HTMLDocument3_attachEvent,
607     HTMLDocument3_detachEvent,
608     HTMLDocument3_put_onrowsdelete,
609     HTMLDocument3_get_onrowsdelete,
610     HTMLDocument3_put_onrowsinserted,
611     HTMLDocument3_get_onrowsinserted,
612     HTMLDocument3_put_oncellchange,
613     HTMLDocument3_get_oncellchange,
614     HTMLDocument3_put_ondatasetchanged,
615     HTMLDocument3_get_ondatasetchanged,
616     HTMLDocument3_put_ondataavailable,
617     HTMLDocument3_get_ondataavailable,
618     HTMLDocument3_put_ondatasetcomplete,
619     HTMLDocument3_get_ondatasetcomplete,
620     HTMLDocument3_put_onpropertychange,
621     HTMLDocument3_get_onpropertychange,
622     HTMLDocument3_put_dir,
623     HTMLDocument3_get_dir,
624     HTMLDocument3_put_oncontextmenu,
625     HTMLDocument3_get_oncontextmenu,
626     HTMLDocument3_put_onstop,
627     HTMLDocument3_get_onstop,
628     HTMLDocument3_createDocumentFragment,
629     HTMLDocument3_get_parentDocument,
630     HTMLDocument3_put_enableDownload,
631     HTMLDocument3_get_enableDownload,
632     HTMLDocument3_put_baseUrl,
633     HTMLDocument3_get_baseUrl,
634     HTMLDocument3_get_childNodes,
635     HTMLDocument3_put_inheritStyleSheets,
636     HTMLDocument3_get_inheritStyleSheets,
637     HTMLDocument3_put_onbeforeeditfocus,
638     HTMLDocument3_get_onbeforeeditfocus,
639     HTMLDocument3_getElementsByName,
640     HTMLDocument3_getElementById,
641     HTMLDocument3_getElementsByTagName
642 };
643
644 static inline HTMLDocument *impl_from_IHTMLDocument4(IHTMLDocument4 *iface)
645 {
646     return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument4_iface);
647 }
648
649 static HRESULT WINAPI HTMLDocument4_QueryInterface(IHTMLDocument4 *iface,
650                                                    REFIID riid, void **ppv)
651 {
652     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
653     return htmldoc_query_interface(This, riid, ppv);
654 }
655
656 static ULONG WINAPI HTMLDocument4_AddRef(IHTMLDocument4 *iface)
657 {
658     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
659     return htmldoc_addref(This);
660 }
661
662 static ULONG WINAPI HTMLDocument4_Release(IHTMLDocument4 *iface)
663 {
664     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
665     return htmldoc_release(This);
666 }
667
668 static HRESULT WINAPI HTMLDocument4_GetTypeInfoCount(IHTMLDocument4 *iface, UINT *pctinfo)
669 {
670     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
671     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
672 }
673
674 static HRESULT WINAPI HTMLDocument4_GetTypeInfo(IHTMLDocument4 *iface, UINT iTInfo,
675                                                 LCID lcid, ITypeInfo **ppTInfo)
676 {
677     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
678     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
679 }
680
681 static HRESULT WINAPI HTMLDocument4_GetIDsOfNames(IHTMLDocument4 *iface, REFIID riid,
682                                                 LPOLESTR *rgszNames, UINT cNames,
683                                                 LCID lcid, DISPID *rgDispId)
684 {
685     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
686     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
687             rgDispId);
688 }
689
690 static HRESULT WINAPI HTMLDocument4_Invoke(IHTMLDocument4 *iface, DISPID dispIdMember,
691                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
692                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
693 {
694     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
695     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
696             pDispParams, pVarResult, pExcepInfo, puArgErr);
697 }
698
699 static HRESULT WINAPI HTMLDocument4_focus(IHTMLDocument4 *iface)
700 {
701     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
702     nsIDOMHTMLElement *nsbody;
703     nsresult nsres;
704
705     TRACE("(%p)->()\n", This);
706
707     nsres = nsIDOMHTMLDocument_GetBody(This->doc_node->nsdoc, &nsbody);
708     if(NS_FAILED(nsres) || !nsbody) {
709         ERR("GetBody failed: %08x\n", nsres);
710         return E_FAIL;
711     }
712
713     nsres = nsIDOMHTMLElement_Focus(nsbody);
714     nsIDOMHTMLElement_Release(nsbody);
715     if(NS_FAILED(nsres)) {
716         ERR("Focus failed: %08x\n", nsres);
717         return E_FAIL;
718     }
719
720     return S_OK;
721 }
722
723 static HRESULT WINAPI HTMLDocument4_hasFocus(IHTMLDocument4 *iface, VARIANT_BOOL *pfFocus)
724 {
725     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
726     FIXME("(%p)->(%p)\n", This, pfFocus);
727     return E_NOTIMPL;
728 }
729
730 static HRESULT WINAPI HTMLDocument4_put_onselectionchange(IHTMLDocument4 *iface, VARIANT v)
731 {
732     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
733     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
734     return E_NOTIMPL;
735 }
736
737 static HRESULT WINAPI HTMLDocument4_get_onselectionchange(IHTMLDocument4 *iface, VARIANT *p)
738 {
739     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
740     FIXME("(%p)->(%p)\n", This, p);
741     return E_NOTIMPL;
742 }
743
744 static HRESULT WINAPI HTMLDocument4_get_namespace(IHTMLDocument4 *iface, IDispatch **p)
745 {
746     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
747     FIXME("(%p)->(%p)\n", This, p);
748     return E_NOTIMPL;
749 }
750
751 static HRESULT WINAPI HTMLDocument4_createDocumentFromUrl(IHTMLDocument4 *iface, BSTR bstrUrl,
752         BSTR bstrOptions, IHTMLDocument2 **newDoc)
753 {
754     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
755     FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(bstrUrl), debugstr_w(bstrOptions), newDoc);
756     return E_NOTIMPL;
757 }
758
759 static HRESULT WINAPI HTMLDocument4_put_media(IHTMLDocument4 *iface, BSTR v)
760 {
761     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
762     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
763     return E_NOTIMPL;
764 }
765
766 static HRESULT WINAPI HTMLDocument4_get_media(IHTMLDocument4 *iface, BSTR *p)
767 {
768     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
769     FIXME("(%p)->(%p)\n", This, p);
770     return E_NOTIMPL;
771 }
772
773 static HRESULT WINAPI HTMLDocument4_createEventObject(IHTMLDocument4 *iface,
774         VARIANT *pvarEventObject, IHTMLEventObj **ppEventObj)
775 {
776     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
777
778     TRACE("(%p)->(%s %p)\n", This, debugstr_variant(pvarEventObject), ppEventObj);
779
780     if(pvarEventObject && V_VT(pvarEventObject) != VT_ERROR && V_VT(pvarEventObject) != VT_EMPTY) {
781         FIXME("unsupported pvarEventObject %s\n", debugstr_variant(pvarEventObject));
782         return E_NOTIMPL;
783     }
784
785     return create_event_obj(ppEventObj);
786 }
787
788 static HRESULT WINAPI HTMLDocument4_fireEvent(IHTMLDocument4 *iface, BSTR bstrEventName,
789         VARIANT *pvarEventObject, VARIANT_BOOL *pfCanceled)
790 {
791     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
792
793     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(bstrEventName), pvarEventObject, pfCanceled);
794
795     return dispatch_event(&This->doc_node->node, bstrEventName, pvarEventObject, pfCanceled);
796 }
797
798 static HRESULT WINAPI HTMLDocument4_createRenderStyle(IHTMLDocument4 *iface, BSTR v,
799         IHTMLRenderStyle **ppIHTMLRenderStyle)
800 {
801     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
802     FIXME("(%p)->(%s %p)\n", This, debugstr_w(v), ppIHTMLRenderStyle);
803     return E_NOTIMPL;
804 }
805
806 static HRESULT WINAPI HTMLDocument4_put_oncontrolselect(IHTMLDocument4 *iface, VARIANT v)
807 {
808     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
809     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
810     return E_NOTIMPL;
811 }
812
813 static HRESULT WINAPI HTMLDocument4_get_oncontrolselect(IHTMLDocument4 *iface, VARIANT *p)
814 {
815     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
816     FIXME("(%p)->(%p)\n", This, p);
817     return E_NOTIMPL;
818 }
819
820 static HRESULT WINAPI HTMLDocument4_get_URLEncoded(IHTMLDocument4 *iface, BSTR *p)
821 {
822     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
823     FIXME("(%p)->(%p)\n", This, p);
824     return E_NOTIMPL;
825 }
826
827 static const IHTMLDocument4Vtbl HTMLDocument4Vtbl = {
828     HTMLDocument4_QueryInterface,
829     HTMLDocument4_AddRef,
830     HTMLDocument4_Release,
831     HTMLDocument4_GetTypeInfoCount,
832     HTMLDocument4_GetTypeInfo,
833     HTMLDocument4_GetIDsOfNames,
834     HTMLDocument4_Invoke,
835     HTMLDocument4_focus,
836     HTMLDocument4_hasFocus,
837     HTMLDocument4_put_onselectionchange,
838     HTMLDocument4_get_onselectionchange,
839     HTMLDocument4_get_namespace,
840     HTMLDocument4_createDocumentFromUrl,
841     HTMLDocument4_put_media,
842     HTMLDocument4_get_media,
843     HTMLDocument4_createEventObject,
844     HTMLDocument4_fireEvent,
845     HTMLDocument4_createRenderStyle,
846     HTMLDocument4_put_oncontrolselect,
847     HTMLDocument4_get_oncontrolselect,
848     HTMLDocument4_get_URLEncoded
849 };
850
851 void HTMLDocument_HTMLDocument3_Init(HTMLDocument *This)
852 {
853     This->IHTMLDocument3_iface.lpVtbl = &HTMLDocument3Vtbl;
854     This->IHTMLDocument4_iface.lpVtbl = &HTMLDocument4Vtbl;
855 }