mshtml: Added HTMLAttributeCollection_get_length implementation.
[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         nsIDOM3Node *node3;
511         PRUint16 pos;
512
513         nsres = nsIDOMNode_QueryInterface(nsnode_by_name, &IID_nsIDOM3Node, (void**)&node3);
514         if(NS_FAILED(nsres)) {
515             FIXME("failed to get nsIDOM3Node interface: 0x%08x\n", nsres);
516             nsIDOMNode_Release(nsnode_by_name);
517             nsIDOMNode_Release(nsnode_by_id);
518             return E_FAIL;
519         }
520
521         nsres = nsIDOM3Node_CompareDocumentPosition(node3, nsnode_by_id, &pos);
522         nsIDOM3Node_Release(node3);
523         if(NS_FAILED(nsres)) {
524             FIXME("nsIDOM3Node_CompareDocumentPosition failed: 0x%08x\n", nsres);
525             nsIDOMNode_Release(nsnode_by_name);
526             nsIDOMNode_Release(nsnode_by_id);
527             return E_FAIL;
528         }
529
530         TRACE("CompareDocumentPosition gave: 0x%x\n", pos);
531         if(pos & PRECEDING || pos & CONTAINS) {
532             nsnode = nsnode_by_id;
533             nsIDOMNode_Release(nsnode_by_name);
534         }else {
535             nsnode = nsnode_by_name;
536             nsIDOMNode_Release(nsnode_by_id);
537         }
538     }else
539         nsnode = nsnode_by_name ? nsnode_by_name : nsnode_by_id;
540
541     if(nsnode) {
542         hres = get_node(This->doc_node, nsnode, TRUE, &node);
543         nsIDOMNode_Release(nsnode);
544
545         if(SUCCEEDED(hres))
546             hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement,
547                     (void**)pel);
548     }else {
549         *pel = NULL;
550         hres = S_OK;
551     }
552
553     return hres;
554 }
555
556
557 static HRESULT WINAPI HTMLDocument3_getElementsByTagName(IHTMLDocument3 *iface, BSTR v,
558                                                          IHTMLElementCollection **pelColl)
559 {
560     HTMLDocument *This = impl_from_IHTMLDocument3(iface);
561     nsIDOMNodeList *nslist;
562     nsAString id_str, ns_str;
563     nsresult nsres;
564     static const WCHAR str[] = {'*',0};
565
566     TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pelColl);
567
568     if(!This->doc_node->nsdoc) {
569         WARN("NULL nsdoc\n");
570         return E_UNEXPECTED;
571     }
572
573     nsAString_InitDepend(&id_str, v);
574     nsAString_InitDepend(&ns_str, str);
575     nsres = nsIDOMHTMLDocument_GetElementsByTagNameNS(This->doc_node->nsdoc, &ns_str, &id_str, &nslist);
576     nsAString_Finish(&id_str);
577     nsAString_Finish(&ns_str);
578     if(FAILED(nsres)) {
579         ERR("GetElementByName failed: %08x\n", nsres);
580         return E_FAIL;
581     }
582
583     *pelColl = create_collection_from_nodelist(This->doc_node,
584                                                (IUnknown*)&This->IHTMLDocument3_iface, nslist);
585     nsIDOMNodeList_Release(nslist);
586
587     return S_OK;
588 }
589
590 static const IHTMLDocument3Vtbl HTMLDocument3Vtbl = {
591     HTMLDocument3_QueryInterface,
592     HTMLDocument3_AddRef,
593     HTMLDocument3_Release,
594     HTMLDocument3_GetTypeInfoCount,
595     HTMLDocument3_GetTypeInfo,
596     HTMLDocument3_GetIDsOfNames,
597     HTMLDocument3_Invoke,
598     HTMLDocument3_releaseCapture,
599     HTMLDocument3_recalc,
600     HTMLDocument3_createTextNode,
601     HTMLDocument3_get_documentElement,
602     HTMLDocument3_uniqueID,
603     HTMLDocument3_attachEvent,
604     HTMLDocument3_detachEvent,
605     HTMLDocument3_put_onrowsdelete,
606     HTMLDocument3_get_onrowsdelete,
607     HTMLDocument3_put_onrowsinserted,
608     HTMLDocument3_get_onrowsinserted,
609     HTMLDocument3_put_oncellchange,
610     HTMLDocument3_get_oncellchange,
611     HTMLDocument3_put_ondatasetchanged,
612     HTMLDocument3_get_ondatasetchanged,
613     HTMLDocument3_put_ondataavailable,
614     HTMLDocument3_get_ondataavailable,
615     HTMLDocument3_put_ondatasetcomplete,
616     HTMLDocument3_get_ondatasetcomplete,
617     HTMLDocument3_put_onpropertychange,
618     HTMLDocument3_get_onpropertychange,
619     HTMLDocument3_put_dir,
620     HTMLDocument3_get_dir,
621     HTMLDocument3_put_oncontextmenu,
622     HTMLDocument3_get_oncontextmenu,
623     HTMLDocument3_put_onstop,
624     HTMLDocument3_get_onstop,
625     HTMLDocument3_createDocumentFragment,
626     HTMLDocument3_get_parentDocument,
627     HTMLDocument3_put_enableDownload,
628     HTMLDocument3_get_enableDownload,
629     HTMLDocument3_put_baseUrl,
630     HTMLDocument3_get_baseUrl,
631     HTMLDocument3_get_childNodes,
632     HTMLDocument3_put_inheritStyleSheets,
633     HTMLDocument3_get_inheritStyleSheets,
634     HTMLDocument3_put_onbeforeeditfocus,
635     HTMLDocument3_get_onbeforeeditfocus,
636     HTMLDocument3_getElementsByName,
637     HTMLDocument3_getElementById,
638     HTMLDocument3_getElementsByTagName
639 };
640
641 static inline HTMLDocument *impl_from_IHTMLDocument4(IHTMLDocument4 *iface)
642 {
643     return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument4_iface);
644 }
645
646 static HRESULT WINAPI HTMLDocument4_QueryInterface(IHTMLDocument4 *iface,
647                                                    REFIID riid, void **ppv)
648 {
649     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
650     return htmldoc_query_interface(This, riid, ppv);
651 }
652
653 static ULONG WINAPI HTMLDocument4_AddRef(IHTMLDocument4 *iface)
654 {
655     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
656     return htmldoc_addref(This);
657 }
658
659 static ULONG WINAPI HTMLDocument4_Release(IHTMLDocument4 *iface)
660 {
661     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
662     return htmldoc_release(This);
663 }
664
665 static HRESULT WINAPI HTMLDocument4_GetTypeInfoCount(IHTMLDocument4 *iface, UINT *pctinfo)
666 {
667     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
668     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
669 }
670
671 static HRESULT WINAPI HTMLDocument4_GetTypeInfo(IHTMLDocument4 *iface, UINT iTInfo,
672                                                 LCID lcid, ITypeInfo **ppTInfo)
673 {
674     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
675     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
676 }
677
678 static HRESULT WINAPI HTMLDocument4_GetIDsOfNames(IHTMLDocument4 *iface, REFIID riid,
679                                                 LPOLESTR *rgszNames, UINT cNames,
680                                                 LCID lcid, DISPID *rgDispId)
681 {
682     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
683     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
684             rgDispId);
685 }
686
687 static HRESULT WINAPI HTMLDocument4_Invoke(IHTMLDocument4 *iface, DISPID dispIdMember,
688                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
689                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
690 {
691     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
692     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
693             pDispParams, pVarResult, pExcepInfo, puArgErr);
694 }
695
696 static HRESULT WINAPI HTMLDocument4_focus(IHTMLDocument4 *iface)
697 {
698     HTMLDocument *This = impl_from_IHTMLDocument4(iface);
699     nsIDOMHTMLElement *nsbody;
700     nsresult nsres;
701
702     TRACE("(%p)->()\n", This);
703
704     nsres = nsIDOMHTMLDocument_GetBody(This->doc_node->nsdoc, &nsbody);
705     if(NS_FAILED(nsres) || !nsbody) {
706         ERR("GetBody failed: %08x\n", nsres);
707         return E_FAIL;
708     }
709
710     nsres = nsIDOMHTMLElement_Focus(nsbody);
711     nsIDOMHTMLElement_Release(nsbody);
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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(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 = impl_from_IHTMLDocument4(iface);
811     FIXME("(%p)->(%p)\n", This, p);
812     return E_NOTIMPL;
813 }
814
815 static const IHTMLDocument4Vtbl HTMLDocument4Vtbl = {
816     HTMLDocument4_QueryInterface,
817     HTMLDocument4_AddRef,
818     HTMLDocument4_Release,
819     HTMLDocument4_GetTypeInfoCount,
820     HTMLDocument4_GetTypeInfo,
821     HTMLDocument4_GetIDsOfNames,
822     HTMLDocument4_Invoke,
823     HTMLDocument4_focus,
824     HTMLDocument4_hasFocus,
825     HTMLDocument4_put_onselectionchange,
826     HTMLDocument4_get_onselectionchange,
827     HTMLDocument4_get_namespace,
828     HTMLDocument4_createDocumentFromUrl,
829     HTMLDocument4_put_media,
830     HTMLDocument4_get_media,
831     HTMLDocument4_createEventObject,
832     HTMLDocument4_fireEvent,
833     HTMLDocument4_createRenderStyle,
834     HTMLDocument4_put_oncontrolselect,
835     HTMLDocument4_get_oncontrolselect,
836     HTMLDocument4_get_URLEncoded
837 };
838
839 void HTMLDocument_HTMLDocument3_Init(HTMLDocument *This)
840 {
841     This->IHTMLDocument3_iface.lpVtbl = &HTMLDocument3Vtbl;
842     This->IHTMLDocument4_iface.lpVtbl = &HTMLDocument4Vtbl;
843 }