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