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