mshtml: COM cleanup for the IHTMLElement3 iface.
[wine] / dlls / mshtml / htmldoc.c
1 /*
2  * Copyright 2005-2009 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 "wininet.h"
30 #include "ole2.h"
31 #include "perhist.h"
32 #include "mshtmdid.h"
33
34 #include "wine/debug.h"
35
36 #include "mshtml_private.h"
37 #include "htmlevent.h"
38 #include "pluginhost.h"
39
40 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
41
42 static inline HTMLDocument *impl_from_IHTMLDocument2(IHTMLDocument2 *iface)
43 {
44     return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument2_iface);
45 }
46
47 static HRESULT WINAPI HTMLDocument_QueryInterface(IHTMLDocument2 *iface, REFIID riid, void **ppv)
48 {
49     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
50
51     return htmldoc_query_interface(This, riid, ppv);
52 }
53
54 static ULONG WINAPI HTMLDocument_AddRef(IHTMLDocument2 *iface)
55 {
56     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
57
58     return htmldoc_addref(This);
59 }
60
61 static ULONG WINAPI HTMLDocument_Release(IHTMLDocument2 *iface)
62 {
63     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
64
65     return htmldoc_release(This);
66 }
67
68 static HRESULT WINAPI HTMLDocument_GetTypeInfoCount(IHTMLDocument2 *iface, UINT *pctinfo)
69 {
70     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
71
72     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
73 }
74
75 static HRESULT WINAPI HTMLDocument_GetTypeInfo(IHTMLDocument2 *iface, UINT iTInfo,
76                                                 LCID lcid, ITypeInfo **ppTInfo)
77 {
78     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
79
80     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
81 }
82
83 static HRESULT WINAPI HTMLDocument_GetIDsOfNames(IHTMLDocument2 *iface, REFIID riid,
84                                                 LPOLESTR *rgszNames, UINT cNames,
85                                                 LCID lcid, DISPID *rgDispId)
86 {
87     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
88
89     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
90 }
91
92 static HRESULT WINAPI HTMLDocument_Invoke(IHTMLDocument2 *iface, DISPID dispIdMember,
93                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
94                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
95 {
96     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
97
98     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
99             pVarResult, pExcepInfo, puArgErr);
100 }
101
102 static HRESULT WINAPI HTMLDocument_get_Script(IHTMLDocument2 *iface, IDispatch **p)
103 {
104     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
105
106     TRACE("(%p)->(%p)\n", This, p);
107
108     *p = (IDispatch*)&This->window->IHTMLWindow2_iface;
109     IDispatch_AddRef(*p);
110     return S_OK;
111 }
112
113 static HRESULT WINAPI HTMLDocument_get_all(IHTMLDocument2 *iface, IHTMLElementCollection **p)
114 {
115     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
116     nsIDOMElement *nselem = NULL;
117     HTMLDOMNode *node;
118     nsresult nsres;
119     HRESULT hres;
120
121     TRACE("(%p)->(%p)\n", This, p);
122
123     if(!This->doc_node->nsdoc) {
124         WARN("NULL nsdoc\n");
125         return E_UNEXPECTED;
126     }
127
128     nsres = nsIDOMHTMLDocument_GetDocumentElement(This->doc_node->nsdoc, &nselem);
129     if(NS_FAILED(nsres)) {
130         ERR("GetDocumentElement failed: %08x\n", nsres);
131         return E_FAIL;
132     }
133
134     if(!nselem) {
135         *p = NULL;
136         return S_OK;
137     }
138
139     hres = get_node(This->doc_node, (nsIDOMNode*)nselem, TRUE, &node);
140     if(SUCCEEDED(hres))
141         *p = create_all_collection(node, TRUE);
142     nsIDOMElement_Release(nselem);
143     return hres;
144 }
145
146 static HRESULT WINAPI HTMLDocument_get_body(IHTMLDocument2 *iface, IHTMLElement **p)
147 {
148     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
149     nsIDOMHTMLElement *nsbody = NULL;
150     HTMLDOMNode *node;
151     HRESULT hres;
152
153     TRACE("(%p)->(%p)\n", This, p);
154
155     if(This->doc_node->nsdoc) {
156         nsresult nsres;
157
158         nsres = nsIDOMHTMLDocument_GetBody(This->doc_node->nsdoc, &nsbody);
159         if(NS_FAILED(nsres)) {
160             TRACE("Could not get body: %08x\n", nsres);
161             return E_UNEXPECTED;
162         }
163     }
164
165     if(!nsbody) {
166         *p = NULL;
167         return S_OK;
168     }
169
170     hres = get_node(This->doc_node, (nsIDOMNode*)nsbody, TRUE, &node);
171     nsIDOMHTMLElement_Release(nsbody);
172     if(FAILED(hres))
173         return hres;
174
175     return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(node), &IID_IHTMLElement, (void**)p);
176 }
177
178 static HRESULT WINAPI HTMLDocument_get_activeElement(IHTMLDocument2 *iface, IHTMLElement **p)
179 {
180     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
181     FIXME("(%p)->(%p)\n", This, p);
182     return E_NOTIMPL;
183 }
184
185 static HRESULT WINAPI HTMLDocument_get_images(IHTMLDocument2 *iface, IHTMLElementCollection **p)
186 {
187     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
188     nsIDOMHTMLCollection *nscoll = NULL;
189     nsresult nsres;
190
191     TRACE("(%p)->(%p)\n", This, p);
192
193     if(!p)
194         return E_INVALIDARG;
195
196     *p = NULL;
197
198     if(!This->doc_node->nsdoc) {
199         WARN("NULL nsdoc\n");
200         return E_UNEXPECTED;
201     }
202
203     nsres = nsIDOMHTMLDocument_GetImages(This->doc_node->nsdoc, &nscoll);
204     if(NS_FAILED(nsres)) {
205         ERR("GetImages failed: %08x\n", nsres);
206         return E_FAIL;
207     }
208
209     if(nscoll) {
210         *p = create_collection_from_htmlcol(This->doc_node, (IUnknown*)&This->IHTMLDocument2_iface, nscoll);
211         nsIDOMElement_Release(nscoll);
212     }
213
214     return S_OK;
215 }
216
217 static HRESULT WINAPI HTMLDocument_get_applets(IHTMLDocument2 *iface, IHTMLElementCollection **p)
218 {
219     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
220     nsIDOMHTMLCollection *nscoll = NULL;
221     nsresult nsres;
222
223     TRACE("(%p)->(%p)\n", This, p);
224
225     if(!p)
226         return E_INVALIDARG;
227
228     *p = NULL;
229
230     if(!This->doc_node->nsdoc) {
231         WARN("NULL nsdoc\n");
232         return E_UNEXPECTED;
233     }
234
235     nsres = nsIDOMHTMLDocument_GetApplets(This->doc_node->nsdoc, &nscoll);
236     if(NS_FAILED(nsres)) {
237         ERR("GetApplets failed: %08x\n", nsres);
238         return E_FAIL;
239     }
240
241     if(nscoll) {
242         *p = create_collection_from_htmlcol(This->doc_node, (IUnknown*)&This->IHTMLDocument2_iface, nscoll);
243         nsIDOMElement_Release(nscoll);
244     }
245
246     return S_OK;
247 }
248
249 static HRESULT WINAPI HTMLDocument_get_links(IHTMLDocument2 *iface, IHTMLElementCollection **p)
250 {
251     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
252     nsIDOMHTMLCollection *nscoll = NULL;
253     nsresult nsres;
254
255     TRACE("(%p)->(%p)\n", This, p);
256
257     if(!p)
258         return E_INVALIDARG;
259
260     *p = NULL;
261
262     if(!This->doc_node->nsdoc) {
263         WARN("NULL nsdoc\n");
264         return E_UNEXPECTED;
265     }
266
267     nsres = nsIDOMHTMLDocument_GetLinks(This->doc_node->nsdoc, &nscoll);
268     if(NS_FAILED(nsres)) {
269         ERR("GetLinks failed: %08x\n", nsres);
270         return E_FAIL;
271     }
272
273     if(nscoll) {
274         *p = create_collection_from_htmlcol(This->doc_node, (IUnknown*)&This->IHTMLDocument2_iface, nscoll);
275         nsIDOMElement_Release(nscoll);
276     }
277
278     return S_OK;
279 }
280
281 static HRESULT WINAPI HTMLDocument_get_forms(IHTMLDocument2 *iface, IHTMLElementCollection **p)
282 {
283     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
284     nsIDOMHTMLCollection *nscoll = NULL;
285     nsresult nsres;
286
287     TRACE("(%p)->(%p)\n", This, p);
288
289     if(!p)
290         return E_INVALIDARG;
291
292     *p = NULL;
293
294     if(!This->doc_node->nsdoc) {
295         WARN("NULL nsdoc\n");
296         return E_UNEXPECTED;
297     }
298
299     nsres = nsIDOMHTMLDocument_GetForms(This->doc_node->nsdoc, &nscoll);
300     if(NS_FAILED(nsres)) {
301         ERR("GetForms failed: %08x\n", nsres);
302         return E_FAIL;
303     }
304
305     if(nscoll) {
306         *p = create_collection_from_htmlcol(This->doc_node, (IUnknown*)&This->IHTMLDocument2_iface, nscoll);
307         nsIDOMElement_Release(nscoll);
308     }
309
310     return S_OK;
311 }
312
313 static HRESULT WINAPI HTMLDocument_get_anchors(IHTMLDocument2 *iface, IHTMLElementCollection **p)
314 {
315     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
316     nsIDOMHTMLCollection *nscoll = NULL;
317     nsresult nsres;
318
319     TRACE("(%p)->(%p)\n", This, p);
320
321     if(!p)
322         return E_INVALIDARG;
323
324     *p = NULL;
325
326     if(!This->doc_node->nsdoc) {
327         WARN("NULL nsdoc\n");
328         return E_UNEXPECTED;
329     }
330
331     nsres = nsIDOMHTMLDocument_GetAnchors(This->doc_node->nsdoc, &nscoll);
332     if(NS_FAILED(nsres)) {
333         ERR("GetAnchors failed: %08x\n", nsres);
334         return E_FAIL;
335     }
336
337     if(nscoll) {
338         *p = create_collection_from_htmlcol(This->doc_node, (IUnknown*)&This->IHTMLDocument2_iface, nscoll);
339         nsIDOMElement_Release(nscoll);
340     }
341
342     return S_OK;
343 }
344
345 static HRESULT WINAPI HTMLDocument_put_title(IHTMLDocument2 *iface, BSTR v)
346 {
347     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
348     nsAString nsstr;
349     nsresult nsres;
350
351     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
352
353     if(!This->doc_node->nsdoc) {
354         WARN("NULL nsdoc\n");
355         return E_UNEXPECTED;
356     }
357
358     nsAString_InitDepend(&nsstr, v);
359     nsres = nsIDOMHTMLDocument_SetTitle(This->doc_node->nsdoc, &nsstr);
360     nsAString_Finish(&nsstr);
361     if(NS_FAILED(nsres))
362         ERR("SetTitle failed: %08x\n", nsres);
363
364     return S_OK;
365 }
366
367 static HRESULT WINAPI HTMLDocument_get_title(IHTMLDocument2 *iface, BSTR *p)
368 {
369     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
370     const PRUnichar *ret;
371     nsAString nsstr;
372     nsresult nsres;
373
374     TRACE("(%p)->(%p)\n", This, p);
375
376     if(!This->doc_node->nsdoc) {
377         WARN("NULL nsdoc\n");
378         return E_UNEXPECTED;
379     }
380
381
382     nsAString_Init(&nsstr, NULL);
383     nsres = nsIDOMHTMLDocument_GetTitle(This->doc_node->nsdoc, &nsstr);
384     if (NS_SUCCEEDED(nsres)) {
385         nsAString_GetData(&nsstr, &ret);
386         *p = SysAllocString(ret);
387     }
388     nsAString_Finish(&nsstr);
389
390     if(NS_FAILED(nsres)) {
391         ERR("GetTitle failed: %08x\n", nsres);
392         return E_FAIL;
393     }
394
395     return S_OK;
396 }
397
398 static HRESULT WINAPI HTMLDocument_get_scripts(IHTMLDocument2 *iface, IHTMLElementCollection **p)
399 {
400     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
401     FIXME("(%p)->(%p)\n", This, p);
402     return E_NOTIMPL;
403 }
404
405 static HRESULT WINAPI HTMLDocument_put_designMode(IHTMLDocument2 *iface, BSTR v)
406 {
407     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
408     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
409     return E_NOTIMPL;
410 }
411
412 static HRESULT WINAPI HTMLDocument_get_designMode(IHTMLDocument2 *iface, BSTR *p)
413 {
414     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
415     static WCHAR szOff[] = {'O','f','f',0};
416     FIXME("(%p)->(%p) always returning Off\n", This, p);
417
418     if(!p)
419         return E_INVALIDARG;
420
421     *p = SysAllocString(szOff);
422
423     return S_OK;
424 }
425
426 static HRESULT WINAPI HTMLDocument_get_selection(IHTMLDocument2 *iface, IHTMLSelectionObject **p)
427 {
428     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
429     nsISelection *nsselection;
430     nsresult nsres;
431
432     TRACE("(%p)->(%p)\n", This, p);
433
434     nsres = nsIDOMWindow_GetSelection(This->window->nswindow, &nsselection);
435     if(NS_FAILED(nsres)) {
436         ERR("GetSelection failed: %08x\n", nsres);
437         return E_FAIL;
438     }
439
440     return HTMLSelectionObject_Create(This->doc_node, nsselection, p);
441 }
442
443 static HRESULT WINAPI HTMLDocument_get_readyState(IHTMLDocument2 *iface, BSTR *p)
444 {
445     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
446
447     static const WCHAR wszUninitialized[] = {'u','n','i','n','i','t','i','a','l','i','z','e','d',0};
448     static const WCHAR wszLoading[] = {'l','o','a','d','i','n','g',0};
449     static const WCHAR wszLoaded[] = {'l','o','a','d','e','d',0};
450     static const WCHAR wszInteractive[] = {'i','n','t','e','r','a','c','t','i','v','e',0};
451     static const WCHAR wszComplete[] = {'c','o','m','p','l','e','t','e',0};
452
453     static const LPCWSTR readystate_str[] = {
454         wszUninitialized,
455         wszLoading,
456         wszLoaded,
457         wszInteractive,
458         wszComplete
459     };
460
461     TRACE("(%p)->(%p)\n", iface, p);
462
463     if(!p)
464         return E_POINTER;
465
466     *p = SysAllocString(readystate_str[This->window->readystate]);
467     return S_OK;
468 }
469
470 static HRESULT WINAPI HTMLDocument_get_frames(IHTMLDocument2 *iface, IHTMLFramesCollection2 **p)
471 {
472     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
473     FIXME("(%p)->(%p)\n", This, p);
474     return E_NOTIMPL;
475 }
476
477 static HRESULT WINAPI HTMLDocument_get_embeds(IHTMLDocument2 *iface, IHTMLElementCollection **p)
478 {
479     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
480     FIXME("(%p)->(%p)\n", This, p);
481     return E_NOTIMPL;
482 }
483
484 static HRESULT WINAPI HTMLDocument_get_plugins(IHTMLDocument2 *iface, IHTMLElementCollection **p)
485 {
486     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
487     FIXME("(%p)->(%p)\n", This, p);
488     return E_NOTIMPL;
489 }
490
491 static HRESULT WINAPI HTMLDocument_put_alinkColor(IHTMLDocument2 *iface, VARIANT v)
492 {
493     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
494     FIXME("(%p)\n", This);
495     return E_NOTIMPL;
496 }
497
498 static HRESULT WINAPI HTMLDocument_get_alinkColor(IHTMLDocument2 *iface, VARIANT *p)
499 {
500     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
501     FIXME("(%p)->(%p)\n", This, p);
502     return E_NOTIMPL;
503 }
504
505 static HRESULT WINAPI HTMLDocument_put_bgColor(IHTMLDocument2 *iface, VARIANT v)
506 {
507     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
508     FIXME("(%p)\n", This);
509     return E_NOTIMPL;
510 }
511
512 static HRESULT WINAPI HTMLDocument_get_bgColor(IHTMLDocument2 *iface, VARIANT *p)
513 {
514     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
515     FIXME("(%p)->(%p)\n", This, p);
516     return E_NOTIMPL;
517 }
518
519 static HRESULT WINAPI HTMLDocument_put_fgColor(IHTMLDocument2 *iface, VARIANT v)
520 {
521     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
522     FIXME("(%p)\n", This);
523     return E_NOTIMPL;
524 }
525
526 static HRESULT WINAPI HTMLDocument_get_fgColor(IHTMLDocument2 *iface, VARIANT *p)
527 {
528     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
529     FIXME("(%p)->(%p)\n", This, p);
530     return E_NOTIMPL;
531 }
532
533 static HRESULT WINAPI HTMLDocument_put_linkColor(IHTMLDocument2 *iface, VARIANT v)
534 {
535     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
536     FIXME("(%p)->()\n", This);
537     return E_NOTIMPL;
538 }
539
540 static HRESULT WINAPI HTMLDocument_get_linkColor(IHTMLDocument2 *iface, VARIANT *p)
541 {
542     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
543     FIXME("(%p)->(%p)\n", This, p);
544     return E_NOTIMPL;
545 }
546
547 static HRESULT WINAPI HTMLDocument_put_vlinkColor(IHTMLDocument2 *iface, VARIANT v)
548 {
549     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
550     FIXME("(%p)\n", This);
551     return E_NOTIMPL;
552 }
553
554 static HRESULT WINAPI HTMLDocument_get_vlinkColor(IHTMLDocument2 *iface, VARIANT *p)
555 {
556     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
557     FIXME("(%p)->(%p)\n", This, p);
558     return E_NOTIMPL;
559 }
560
561 static HRESULT WINAPI HTMLDocument_get_referrer(IHTMLDocument2 *iface, BSTR *p)
562 {
563     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
564
565     FIXME("(%p)->(%p)\n", This, p);
566
567     *p = NULL;
568     return S_OK;
569  }
570
571 static HRESULT WINAPI HTMLDocument_get_location(IHTMLDocument2 *iface, IHTMLLocation **p)
572 {
573     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
574
575     TRACE("(%p)->(%p)\n", This, p);
576
577     if(!This->doc_node->nsdoc) {
578         WARN("NULL nsdoc\n");
579         return E_UNEXPECTED;
580     }
581
582     return IHTMLWindow2_get_location(&This->window->IHTMLWindow2_iface, p);
583 }
584
585 static HRESULT WINAPI HTMLDocument_get_lastModified(IHTMLDocument2 *iface, BSTR *p)
586 {
587     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
588     FIXME("(%p)->(%p)\n", This, p);
589     return E_NOTIMPL;
590 }
591
592 static HRESULT WINAPI HTMLDocument_put_URL(IHTMLDocument2 *iface, BSTR v)
593 {
594     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
595     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
596     return E_NOTIMPL;
597 }
598
599 static HRESULT WINAPI HTMLDocument_get_URL(IHTMLDocument2 *iface, BSTR *p)
600 {
601     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
602
603     static const WCHAR about_blank_url[] =
604         {'a','b','o','u','t',':','b','l','a','n','k',0};
605
606     TRACE("(%p)->(%p)\n", iface, p);
607
608     *p = SysAllocString(This->window->url ? This->window->url : about_blank_url);
609     return *p ? S_OK : E_OUTOFMEMORY;
610 }
611
612 static HRESULT WINAPI HTMLDocument_put_domain(IHTMLDocument2 *iface, BSTR v)
613 {
614     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
615     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
616     return E_NOTIMPL;
617 }
618
619 static HRESULT WINAPI HTMLDocument_get_domain(IHTMLDocument2 *iface, BSTR *p)
620 {
621     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
622     FIXME("(%p)->(%p)\n", This, p);
623     return E_NOTIMPL;
624 }
625
626 static HRESULT WINAPI HTMLDocument_put_cookie(IHTMLDocument2 *iface, BSTR v)
627 {
628     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
629     BOOL bret;
630
631     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
632
633     bret = InternetSetCookieExW(This->window->url, NULL, v, 0, 0);
634     if(!bret) {
635         FIXME("InternetSetCookieExW failed: %u\n", GetLastError());
636         return HRESULT_FROM_WIN32(GetLastError());
637     }
638
639     return S_OK;
640 }
641
642 static HRESULT WINAPI HTMLDocument_get_cookie(IHTMLDocument2 *iface, BSTR *p)
643 {
644     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
645     DWORD size;
646     BOOL bret;
647
648     TRACE("(%p)->(%p)\n", This, p);
649
650     size = 0;
651     bret = InternetGetCookieExW(This->window->url, NULL, NULL, &size, 0, NULL);
652     if(!bret) {
653         switch(GetLastError()) {
654         case ERROR_INSUFFICIENT_BUFFER:
655             break;
656         case ERROR_NO_MORE_ITEMS:
657             *p = NULL;
658             return S_OK;
659         default:
660             FIXME("InternetGetCookieExW failed: %u\n", GetLastError());
661             return HRESULT_FROM_WIN32(GetLastError());
662         }
663     }
664
665     if(!size) {
666         *p = NULL;
667         return S_OK;
668     }
669
670     *p = SysAllocStringLen(NULL, size-1);
671     if(!*p)
672         return E_OUTOFMEMORY;
673
674     bret = InternetGetCookieExW(This->window->url, NULL, *p, &size, 0, NULL);
675     if(!bret) {
676         ERR("InternetGetCookieExW failed: %u\n", GetLastError());
677         return E_FAIL;
678     }
679
680     return S_OK;
681 }
682
683 static HRESULT WINAPI HTMLDocument_put_expando(IHTMLDocument2 *iface, VARIANT_BOOL v)
684 {
685     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
686     FIXME("(%p)->(%x)\n", This, v);
687     return E_NOTIMPL;
688 }
689
690 static HRESULT WINAPI HTMLDocument_get_expando(IHTMLDocument2 *iface, VARIANT_BOOL *p)
691 {
692     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
693     FIXME("(%p)->(%p)\n", This, p);
694     return E_NOTIMPL;
695 }
696
697 static HRESULT WINAPI HTMLDocument_put_charset(IHTMLDocument2 *iface, BSTR v)
698 {
699     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
700     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
701     return E_NOTIMPL;
702 }
703
704 static HRESULT WINAPI HTMLDocument_get_charset(IHTMLDocument2 *iface, BSTR *p)
705 {
706     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
707     FIXME("(%p)->(%p)\n", This, p);
708     return E_NOTIMPL;
709 }
710
711 static HRESULT WINAPI HTMLDocument_put_defaultCharset(IHTMLDocument2 *iface, BSTR v)
712 {
713     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
714     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
715     return E_NOTIMPL;
716 }
717
718 static HRESULT WINAPI HTMLDocument_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p)
719 {
720     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
721     FIXME("(%p)->(%p)\n", This, p);
722     return E_NOTIMPL;
723 }
724
725 static HRESULT WINAPI HTMLDocument_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
726 {
727     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
728     FIXME("(%p)->(%p)\n", This, p);
729     return E_NOTIMPL;
730 }
731
732 static HRESULT WINAPI HTMLDocument_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
733 {
734     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
735     FIXME("(%p)->(%p)\n", This, p);
736     return E_NOTIMPL;
737 }
738
739 static HRESULT WINAPI HTMLDocument_get_fileCreatedDate(IHTMLDocument2 *iface, BSTR *p)
740 {
741     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
742     FIXME("(%p)->(%p)\n", This, p);
743     return E_NOTIMPL;
744 }
745
746 static HRESULT WINAPI HTMLDocument_get_fileModifiedDate(IHTMLDocument2 *iface, BSTR *p)
747 {
748     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
749     FIXME("(%p)->(%p)\n", This, p);
750     return E_NOTIMPL;
751 }
752
753 static HRESULT WINAPI HTMLDocument_get_fileUpdatedDate(IHTMLDocument2 *iface, BSTR *p)
754 {
755     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
756     FIXME("(%p)->(%p)\n", This, p);
757     return E_NOTIMPL;
758 }
759
760 static HRESULT WINAPI HTMLDocument_get_security(IHTMLDocument2 *iface, BSTR *p)
761 {
762     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
763     FIXME("(%p)->(%p)\n", This, p);
764     return E_NOTIMPL;
765 }
766
767 static HRESULT WINAPI HTMLDocument_get_protocol(IHTMLDocument2 *iface, BSTR *p)
768 {
769     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
770     FIXME("(%p)->(%p)\n", This, p);
771     return E_NOTIMPL;
772 }
773
774 static HRESULT WINAPI HTMLDocument_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
775 {
776     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
777     FIXME("(%p)->(%p)\n", This, p);
778     return E_NOTIMPL;
779 }
780
781 static HRESULT document_write(HTMLDocument *This, SAFEARRAY *psarray, BOOL ln)
782 {
783     nsAString nsstr;
784     VARIANT *var;
785     ULONG i, argc;
786     nsresult nsres;
787     HRESULT hres;
788
789     if(!This->doc_node->nsdoc) {
790         WARN("NULL nsdoc\n");
791         return E_UNEXPECTED;
792     }
793
794     if (!psarray)
795         return S_OK;
796
797     if(psarray->cDims != 1) {
798         FIXME("cDims=%d\n", psarray->cDims);
799         return E_INVALIDARG;
800     }
801
802     hres = SafeArrayAccessData(psarray, (void**)&var);
803     if(FAILED(hres)) {
804         WARN("SafeArrayAccessData failed: %08x\n", hres);
805         return hres;
806     }
807
808     nsAString_Init(&nsstr, NULL);
809
810     argc = psarray->rgsabound[0].cElements;
811     for(i=0; i < argc; i++) {
812         if(V_VT(var+i) == VT_BSTR) {
813             nsAString_SetData(&nsstr, V_BSTR(var+i));
814             if(!ln || i != argc-1)
815                 nsres = nsIDOMHTMLDocument_Write(This->doc_node->nsdoc, &nsstr);
816             else
817                 nsres = nsIDOMHTMLDocument_Writeln(This->doc_node->nsdoc, &nsstr);
818             if(NS_FAILED(nsres))
819                 ERR("Write failed: %08x\n", nsres);
820         }else {
821             FIXME("vt=%d\n", V_VT(var+i));
822         }
823     }
824
825     nsAString_Finish(&nsstr);
826     SafeArrayUnaccessData(psarray);
827
828     return S_OK;
829 }
830
831 static HRESULT WINAPI HTMLDocument_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
832 {
833     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
834
835     TRACE("(%p)->(%p)\n", iface, psarray);
836
837     return document_write(This, psarray, FALSE);
838 }
839
840 static HRESULT WINAPI HTMLDocument_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
841 {
842     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
843
844     TRACE("(%p)->(%p)\n", This, psarray);
845
846     return document_write(This, psarray, TRUE);
847 }
848
849 static HRESULT WINAPI HTMLDocument_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
850                         VARIANT features, VARIANT replace, IDispatch **pomWindowResult)
851 {
852     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
853     nsresult nsres;
854
855     static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
856
857     TRACE("(%p)->(%s %s %s %s %p)\n", This, debugstr_w(url), debugstr_variant(&name),
858           debugstr_variant(&features), debugstr_variant(&replace), pomWindowResult);
859
860     if(!This->doc_node->nsdoc) {
861         ERR("!nsdoc\n");
862         return E_NOTIMPL;
863     }
864
865     if(!url || strcmpW(url, text_htmlW) || V_VT(&name) != VT_ERROR
866        || V_VT(&features) != VT_ERROR || V_VT(&replace) != VT_ERROR)
867         FIXME("unsupported args\n");
868
869     nsres = nsIDOMHTMLDocument_Open(This->doc_node->nsdoc);
870     if(NS_FAILED(nsres)) {
871         ERR("Open failed: %08x\n", nsres);
872         return E_FAIL;
873     }
874
875     *pomWindowResult = (IDispatch*)&This->window->IHTMLWindow2_iface;
876     IHTMLWindow2_AddRef(&This->window->IHTMLWindow2_iface);
877     return S_OK;
878 }
879
880 static HRESULT WINAPI HTMLDocument_close(IHTMLDocument2 *iface)
881 {
882     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
883     nsresult nsres;
884
885     TRACE("(%p)\n", This);
886
887     if(!This->doc_node->nsdoc) {
888         ERR("!nsdoc\n");
889         return E_NOTIMPL;
890     }
891
892     nsres = nsIDOMHTMLDocument_Close(This->doc_node->nsdoc);
893     if(NS_FAILED(nsres)) {
894         ERR("Close failed: %08x\n", nsres);
895         return E_FAIL;
896     }
897
898     return S_OK;
899 }
900
901 static HRESULT WINAPI HTMLDocument_clear(IHTMLDocument2 *iface)
902 {
903     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
904     nsIDOMNSHTMLDocument *nsdoc;
905     nsresult nsres;
906
907     TRACE("(%p)\n", This);
908
909     nsres = nsIDOMHTMLDocument_QueryInterface(This->doc_node->nsdoc, &IID_nsIDOMNSHTMLDocument, (void**)&nsdoc);
910     if(NS_FAILED(nsres)) {
911         ERR("Could not get nsIDOMNSHTMLDocument iface: %08x\n", nsres);
912         return E_FAIL;
913     }
914
915     nsres = nsIDOMNSHTMLDocument_Clear(nsdoc);
916     nsIDOMNSHTMLDocument_Release(nsdoc);
917     if(NS_FAILED(nsres)) {
918         ERR("Clear failed: %08x\n", nsres);
919         return E_FAIL;
920     }
921
922     return S_OK;
923 }
924
925 static HRESULT WINAPI HTMLDocument_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID,
926                                                         VARIANT_BOOL *pfRet)
927 {
928     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
929     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
930     return E_NOTIMPL;
931 }
932
933 static HRESULT WINAPI HTMLDocument_queryCommandEnabled(IHTMLDocument2 *iface, BSTR cmdID,
934                                                         VARIANT_BOOL *pfRet)
935 {
936     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
937     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
938     return E_NOTIMPL;
939 }
940
941 static HRESULT WINAPI HTMLDocument_queryCommandState(IHTMLDocument2 *iface, BSTR cmdID,
942                                                         VARIANT_BOOL *pfRet)
943 {
944     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
945     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
946     return E_NOTIMPL;
947 }
948
949 static HRESULT WINAPI HTMLDocument_queryCommandIndeterm(IHTMLDocument2 *iface, BSTR cmdID,
950                                                         VARIANT_BOOL *pfRet)
951 {
952     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
953     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
954     return E_NOTIMPL;
955 }
956
957 static HRESULT WINAPI HTMLDocument_queryCommandText(IHTMLDocument2 *iface, BSTR cmdID,
958                                                         BSTR *pfRet)
959 {
960     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
961     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
962     return E_NOTIMPL;
963 }
964
965 static HRESULT WINAPI HTMLDocument_queryCommandValue(IHTMLDocument2 *iface, BSTR cmdID,
966                                                         VARIANT *pfRet)
967 {
968     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
969     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
970     return E_NOTIMPL;
971 }
972
973 static HRESULT WINAPI HTMLDocument_execCommand(IHTMLDocument2 *iface, BSTR cmdID,
974                                 VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
975 {
976     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
977     FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(cmdID), showUI, pfRet);
978     return E_NOTIMPL;
979 }
980
981 static HRESULT WINAPI HTMLDocument_execCommandShowHelp(IHTMLDocument2 *iface, BSTR cmdID,
982                                                         VARIANT_BOOL *pfRet)
983 {
984     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
985     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
986     return E_NOTIMPL;
987 }
988
989 static HRESULT WINAPI HTMLDocument_createElement(IHTMLDocument2 *iface, BSTR eTag,
990                                                  IHTMLElement **newElem)
991 {
992     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
993     nsIDOMHTMLElement *nselem;
994     HTMLElement *elem;
995     HRESULT hres;
996
997     TRACE("(%p)->(%s %p)\n", This, debugstr_w(eTag), newElem);
998
999     hres = create_nselem(This->doc_node, eTag, &nselem);
1000     if(FAILED(hres))
1001         return hres;
1002
1003     hres = HTMLElement_Create(This->doc_node, (nsIDOMNode*)nselem, TRUE, &elem);
1004     nsIDOMHTMLElement_Release(nselem);
1005     if(FAILED(hres))
1006         return hres;
1007
1008     *newElem = &elem->IHTMLElement_iface;
1009     IHTMLElement_AddRef(&elem->IHTMLElement_iface);
1010     return S_OK;
1011 }
1012
1013 static HRESULT WINAPI HTMLDocument_put_onhelp(IHTMLDocument2 *iface, VARIANT v)
1014 {
1015     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1016     FIXME("(%p)\n", This);
1017     return E_NOTIMPL;
1018 }
1019
1020 static HRESULT WINAPI HTMLDocument_get_onhelp(IHTMLDocument2 *iface, VARIANT *p)
1021 {
1022     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1023     FIXME("(%p)->(%p)\n", This, p);
1024     return E_NOTIMPL;
1025 }
1026
1027 static HRESULT WINAPI HTMLDocument_put_onclick(IHTMLDocument2 *iface, VARIANT v)
1028 {
1029     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1030
1031     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1032
1033     return set_doc_event(This, EVENTID_CLICK, &v);
1034 }
1035
1036 static HRESULT WINAPI HTMLDocument_get_onclick(IHTMLDocument2 *iface, VARIANT *p)
1037 {
1038     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1039
1040     TRACE("(%p)->(%p)\n", This, p);
1041
1042     return get_doc_event(This, EVENTID_CLICK, p);
1043 }
1044
1045 static HRESULT WINAPI HTMLDocument_put_ondblclick(IHTMLDocument2 *iface, VARIANT v)
1046 {
1047     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1048     FIXME("(%p)\n", This);
1049     return E_NOTIMPL;
1050 }
1051
1052 static HRESULT WINAPI HTMLDocument_get_ondblclick(IHTMLDocument2 *iface, VARIANT *p)
1053 {
1054     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1055     FIXME("(%p)->(%p)\n", This, p);
1056     return E_NOTIMPL;
1057 }
1058
1059 static HRESULT WINAPI HTMLDocument_put_onkeyup(IHTMLDocument2 *iface, VARIANT v)
1060 {
1061     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1062
1063     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1064
1065     return set_doc_event(This, EVENTID_KEYUP, &v);
1066 }
1067
1068 static HRESULT WINAPI HTMLDocument_get_onkeyup(IHTMLDocument2 *iface, VARIANT *p)
1069 {
1070     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1071
1072     TRACE("(%p)->(%p)\n", This, p);
1073
1074     return get_doc_event(This, EVENTID_KEYUP, p);
1075 }
1076
1077 static HRESULT WINAPI HTMLDocument_put_onkeydown(IHTMLDocument2 *iface, VARIANT v)
1078 {
1079     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1080
1081     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1082
1083     return set_doc_event(This, EVENTID_KEYDOWN, &v);
1084 }
1085
1086 static HRESULT WINAPI HTMLDocument_get_onkeydown(IHTMLDocument2 *iface, VARIANT *p)
1087 {
1088     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1089
1090     TRACE("(%p)->(%p)\n", This, p);
1091
1092     return get_doc_event(This, EVENTID_KEYDOWN, p);
1093 }
1094
1095 static HRESULT WINAPI HTMLDocument_put_onkeypress(IHTMLDocument2 *iface, VARIANT v)
1096 {
1097     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1098     FIXME("(%p)\n", This);
1099     return E_NOTIMPL;
1100 }
1101
1102 static HRESULT WINAPI HTMLDocument_get_onkeypress(IHTMLDocument2 *iface, VARIANT *p)
1103 {
1104     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1105     FIXME("(%p)->(%p)\n", This, p);
1106     return E_NOTIMPL;
1107 }
1108
1109 static HRESULT WINAPI HTMLDocument_put_onmouseup(IHTMLDocument2 *iface, VARIANT v)
1110 {
1111     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1112
1113     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1114
1115     return set_doc_event(This, EVENTID_MOUSEUP, &v);
1116 }
1117
1118 static HRESULT WINAPI HTMLDocument_get_onmouseup(IHTMLDocument2 *iface, VARIANT *p)
1119 {
1120     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1121
1122     TRACE("(%p)->(%p)\n", This, p);
1123
1124     return get_doc_event(This, EVENTID_MOUSEUP, p);
1125 }
1126
1127 static HRESULT WINAPI HTMLDocument_put_onmousedown(IHTMLDocument2 *iface, VARIANT v)
1128 {
1129     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1130
1131     TRACE("(%p)->()\n", This);
1132
1133     return set_doc_event(This, EVENTID_MOUSEDOWN, &v);
1134 }
1135
1136 static HRESULT WINAPI HTMLDocument_get_onmousedown(IHTMLDocument2 *iface, VARIANT *p)
1137 {
1138     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1139
1140     TRACE("(%p)->(%p)\n", This, p);
1141
1142     return get_doc_event(This, EVENTID_MOUSEDOWN, p);
1143 }
1144
1145 static HRESULT WINAPI HTMLDocument_put_onmousemove(IHTMLDocument2 *iface, VARIANT v)
1146 {
1147     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1148     FIXME("(%p)\n", This);
1149     return E_NOTIMPL;
1150 }
1151
1152 static HRESULT WINAPI HTMLDocument_get_onmousemove(IHTMLDocument2 *iface, VARIANT *p)
1153 {
1154     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1155     FIXME("(%p)->(%p)\n", This, p);
1156     return E_NOTIMPL;
1157 }
1158
1159 static HRESULT WINAPI HTMLDocument_put_onmouseout(IHTMLDocument2 *iface, VARIANT v)
1160 {
1161     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1162
1163     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1164
1165     return set_doc_event(This, EVENTID_MOUSEOUT, &v);
1166 }
1167
1168 static HRESULT WINAPI HTMLDocument_get_onmouseout(IHTMLDocument2 *iface, VARIANT *p)
1169 {
1170     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1171
1172     TRACE("(%p)->(%p)\n", This, p);
1173
1174     return get_doc_event(This, EVENTID_MOUSEOUT, p);
1175 }
1176
1177 static HRESULT WINAPI HTMLDocument_put_onmouseover(IHTMLDocument2 *iface, VARIANT v)
1178 {
1179     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1180
1181     TRACE("(%p)\n", This);
1182
1183     return set_doc_event(This, EVENTID_MOUSEOVER, &v);
1184 }
1185
1186 static HRESULT WINAPI HTMLDocument_get_onmouseover(IHTMLDocument2 *iface, VARIANT *p)
1187 {
1188     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1189
1190     TRACE("(%p)->(%p)\n", This, p);
1191
1192     return get_doc_event(This, EVENTID_MOUSEOVER, p);
1193 }
1194
1195 static HRESULT WINAPI HTMLDocument_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v)
1196 {
1197     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1198
1199     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1200
1201     return set_doc_event(This, EVENTID_READYSTATECHANGE, &v);
1202 }
1203
1204 static HRESULT WINAPI HTMLDocument_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p)
1205 {
1206     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1207
1208     TRACE("(%p)->(%p)\n", This, p);
1209
1210     return get_doc_event(This, EVENTID_READYSTATECHANGE, p);
1211 }
1212
1213 static HRESULT WINAPI HTMLDocument_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v)
1214 {
1215     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1216     FIXME("(%p)\n", This);
1217     return E_NOTIMPL;
1218 }
1219
1220 static HRESULT WINAPI HTMLDocument_get_onafterupdate(IHTMLDocument2 *iface, VARIANT *p)
1221 {
1222     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1223     FIXME("(%p)->(%p)\n", This, p);
1224     return E_NOTIMPL;
1225 }
1226
1227 static HRESULT WINAPI HTMLDocument_put_onrowexit(IHTMLDocument2 *iface, VARIANT v)
1228 {
1229     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1230     FIXME("(%p)\n", This);
1231     return E_NOTIMPL;
1232 }
1233
1234 static HRESULT WINAPI HTMLDocument_get_onrowexit(IHTMLDocument2 *iface, VARIANT *p)
1235 {
1236     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1237     FIXME("(%p)->(%p)\n", This, p);
1238     return E_NOTIMPL;
1239 }
1240
1241 static HRESULT WINAPI HTMLDocument_put_onrowenter(IHTMLDocument2 *iface, VARIANT v)
1242 {
1243     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1244     FIXME("(%p)\n", This);
1245     return E_NOTIMPL;
1246 }
1247
1248 static HRESULT WINAPI HTMLDocument_get_onrowenter(IHTMLDocument2 *iface, VARIANT *p)
1249 {
1250     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1251     FIXME("(%p)->(%p)\n", This, p);
1252     return E_NOTIMPL;
1253 }
1254
1255 static HRESULT WINAPI HTMLDocument_put_ondragstart(IHTMLDocument2 *iface, VARIANT v)
1256 {
1257     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1258
1259     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1260
1261     return set_doc_event(This, EVENTID_DRAGSTART, &v);
1262 }
1263
1264 static HRESULT WINAPI HTMLDocument_get_ondragstart(IHTMLDocument2 *iface, VARIANT *p)
1265 {
1266     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1267
1268     TRACE("(%p)->(%p)\n", This, p);
1269
1270     return get_doc_event(This, EVENTID_DRAGSTART, p);
1271 }
1272
1273 static HRESULT WINAPI HTMLDocument_put_onselectstart(IHTMLDocument2 *iface, VARIANT v)
1274 {
1275     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1276
1277     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1278
1279     return set_doc_event(This, EVENTID_SELECTSTART, &v);
1280 }
1281
1282 static HRESULT WINAPI HTMLDocument_get_onselectstart(IHTMLDocument2 *iface, VARIANT *p)
1283 {
1284     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1285
1286     TRACE("(%p)->(%p)\n", This, p);
1287
1288     return get_doc_event(This, EVENTID_SELECTSTART, p);
1289 }
1290
1291 static HRESULT WINAPI HTMLDocument_elementFromPoint(IHTMLDocument2 *iface, LONG x, LONG y,
1292                                                         IHTMLElement **elementHit)
1293 {
1294     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1295     FIXME("(%p)->(%d %d %p)\n", This, x, y, elementHit);
1296     return E_NOTIMPL;
1297 }
1298
1299 static HRESULT WINAPI HTMLDocument_get_parentWindow(IHTMLDocument2 *iface, IHTMLWindow2 **p)
1300 {
1301     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1302
1303     TRACE("(%p)->(%p)\n", This, p);
1304
1305     *p = &This->window->IHTMLWindow2_iface;
1306     IHTMLWindow2_AddRef(*p);
1307     return S_OK;
1308 }
1309
1310 static HRESULT WINAPI HTMLDocument_get_styleSheets(IHTMLDocument2 *iface,
1311                                                    IHTMLStyleSheetsCollection **p)
1312 {
1313     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1314     nsIDOMStyleSheetList *nsstylelist;
1315     nsIDOMDocumentStyle *nsdocstyle;
1316     nsresult nsres;
1317
1318     TRACE("(%p)->(%p)\n", This, p);
1319
1320     *p = NULL;
1321
1322     if(!This->doc_node->nsdoc) {
1323         WARN("NULL nsdoc\n");
1324         return E_UNEXPECTED;
1325     }
1326
1327     nsIDOMHTMLDocument_QueryInterface(This->doc_node->nsdoc, &IID_nsIDOMDocumentStyle, (void**)&nsdocstyle);
1328     nsres = nsIDOMDocumentStyle_GetStyleSheets(nsdocstyle, &nsstylelist);
1329     nsIDOMDocumentStyle_Release(nsdocstyle);
1330     if(NS_FAILED(nsres)) {
1331         ERR("GetStyleSheets failed: %08x\n", nsres);
1332         return E_FAIL;
1333     }
1334
1335     *p = HTMLStyleSheetsCollection_Create(nsstylelist);
1336     nsIDOMDocumentStyle_Release(nsstylelist);
1337
1338     return S_OK;
1339 }
1340
1341 static HRESULT WINAPI HTMLDocument_put_onbeforeupdate(IHTMLDocument2 *iface, VARIANT v)
1342 {
1343     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1344     FIXME("(%p)\n", This);
1345     return E_NOTIMPL;
1346 }
1347
1348 static HRESULT WINAPI HTMLDocument_get_onbeforeupdate(IHTMLDocument2 *iface, VARIANT *p)
1349 {
1350     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1351     FIXME("(%p)->(%p)\n", This, p);
1352     return E_NOTIMPL;
1353 }
1354
1355 static HRESULT WINAPI HTMLDocument_put_onerrorupdate(IHTMLDocument2 *iface, VARIANT v)
1356 {
1357     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1358     FIXME("(%p)\n", This);
1359     return E_NOTIMPL;
1360 }
1361
1362 static HRESULT WINAPI HTMLDocument_get_onerrorupdate(IHTMLDocument2 *iface, VARIANT *p)
1363 {
1364     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1365     FIXME("(%p)->(%p)\n", This, p);
1366     return E_NOTIMPL;
1367 }
1368
1369 static HRESULT WINAPI HTMLDocument_toString(IHTMLDocument2 *iface, BSTR *String)
1370 {
1371     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1372     FIXME("(%p)->(%p)\n", This, String);
1373     return E_NOTIMPL;
1374 }
1375
1376 static HRESULT WINAPI HTMLDocument_createStyleSheet(IHTMLDocument2 *iface, BSTR bstrHref,
1377                                             LONG lIndex, IHTMLStyleSheet **ppnewStyleSheet)
1378 {
1379     HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1380
1381     FIXME("(%p)->(%s %d %p) semi-stub\n", This, debugstr_w(bstrHref), lIndex, ppnewStyleSheet);
1382
1383     *ppnewStyleSheet = HTMLStyleSheet_Create(NULL);
1384     return S_OK;
1385 }
1386
1387 static const IHTMLDocument2Vtbl HTMLDocumentVtbl = {
1388     HTMLDocument_QueryInterface,
1389     HTMLDocument_AddRef,
1390     HTMLDocument_Release,
1391     HTMLDocument_GetTypeInfoCount,
1392     HTMLDocument_GetTypeInfo,
1393     HTMLDocument_GetIDsOfNames,
1394     HTMLDocument_Invoke,
1395     HTMLDocument_get_Script,
1396     HTMLDocument_get_all,
1397     HTMLDocument_get_body,
1398     HTMLDocument_get_activeElement,
1399     HTMLDocument_get_images,
1400     HTMLDocument_get_applets,
1401     HTMLDocument_get_links,
1402     HTMLDocument_get_forms,
1403     HTMLDocument_get_anchors,
1404     HTMLDocument_put_title,
1405     HTMLDocument_get_title,
1406     HTMLDocument_get_scripts,
1407     HTMLDocument_put_designMode,
1408     HTMLDocument_get_designMode,
1409     HTMLDocument_get_selection,
1410     HTMLDocument_get_readyState,
1411     HTMLDocument_get_frames,
1412     HTMLDocument_get_embeds,
1413     HTMLDocument_get_plugins,
1414     HTMLDocument_put_alinkColor,
1415     HTMLDocument_get_alinkColor,
1416     HTMLDocument_put_bgColor,
1417     HTMLDocument_get_bgColor,
1418     HTMLDocument_put_fgColor,
1419     HTMLDocument_get_fgColor,
1420     HTMLDocument_put_linkColor,
1421     HTMLDocument_get_linkColor,
1422     HTMLDocument_put_vlinkColor,
1423     HTMLDocument_get_vlinkColor,
1424     HTMLDocument_get_referrer,
1425     HTMLDocument_get_location,
1426     HTMLDocument_get_lastModified,
1427     HTMLDocument_put_URL,
1428     HTMLDocument_get_URL,
1429     HTMLDocument_put_domain,
1430     HTMLDocument_get_domain,
1431     HTMLDocument_put_cookie,
1432     HTMLDocument_get_cookie,
1433     HTMLDocument_put_expando,
1434     HTMLDocument_get_expando,
1435     HTMLDocument_put_charset,
1436     HTMLDocument_get_charset,
1437     HTMLDocument_put_defaultCharset,
1438     HTMLDocument_get_defaultCharset,
1439     HTMLDocument_get_mimeType,
1440     HTMLDocument_get_fileSize,
1441     HTMLDocument_get_fileCreatedDate,
1442     HTMLDocument_get_fileModifiedDate,
1443     HTMLDocument_get_fileUpdatedDate,
1444     HTMLDocument_get_security,
1445     HTMLDocument_get_protocol,
1446     HTMLDocument_get_nameProp,
1447     HTMLDocument_write,
1448     HTMLDocument_writeln,
1449     HTMLDocument_open,
1450     HTMLDocument_close,
1451     HTMLDocument_clear,
1452     HTMLDocument_queryCommandSupported,
1453     HTMLDocument_queryCommandEnabled,
1454     HTMLDocument_queryCommandState,
1455     HTMLDocument_queryCommandIndeterm,
1456     HTMLDocument_queryCommandText,
1457     HTMLDocument_queryCommandValue,
1458     HTMLDocument_execCommand,
1459     HTMLDocument_execCommandShowHelp,
1460     HTMLDocument_createElement,
1461     HTMLDocument_put_onhelp,
1462     HTMLDocument_get_onhelp,
1463     HTMLDocument_put_onclick,
1464     HTMLDocument_get_onclick,
1465     HTMLDocument_put_ondblclick,
1466     HTMLDocument_get_ondblclick,
1467     HTMLDocument_put_onkeyup,
1468     HTMLDocument_get_onkeyup,
1469     HTMLDocument_put_onkeydown,
1470     HTMLDocument_get_onkeydown,
1471     HTMLDocument_put_onkeypress,
1472     HTMLDocument_get_onkeypress,
1473     HTMLDocument_put_onmouseup,
1474     HTMLDocument_get_onmouseup,
1475     HTMLDocument_put_onmousedown,
1476     HTMLDocument_get_onmousedown,
1477     HTMLDocument_put_onmousemove,
1478     HTMLDocument_get_onmousemove,
1479     HTMLDocument_put_onmouseout,
1480     HTMLDocument_get_onmouseout,
1481     HTMLDocument_put_onmouseover,
1482     HTMLDocument_get_onmouseover,
1483     HTMLDocument_put_onreadystatechange,
1484     HTMLDocument_get_onreadystatechange,
1485     HTMLDocument_put_onafterupdate,
1486     HTMLDocument_get_onafterupdate,
1487     HTMLDocument_put_onrowexit,
1488     HTMLDocument_get_onrowexit,
1489     HTMLDocument_put_onrowenter,
1490     HTMLDocument_get_onrowenter,
1491     HTMLDocument_put_ondragstart,
1492     HTMLDocument_get_ondragstart,
1493     HTMLDocument_put_onselectstart,
1494     HTMLDocument_get_onselectstart,
1495     HTMLDocument_elementFromPoint,
1496     HTMLDocument_get_parentWindow,
1497     HTMLDocument_get_styleSheets,
1498     HTMLDocument_put_onbeforeupdate,
1499     HTMLDocument_get_onbeforeupdate,
1500     HTMLDocument_put_onerrorupdate,
1501     HTMLDocument_get_onerrorupdate,
1502     HTMLDocument_toString,
1503     HTMLDocument_createStyleSheet
1504 };
1505
1506 static void HTMLDocument_on_advise(IUnknown *iface, cp_static_data_t *cp)
1507 {
1508     HTMLDocument *This = impl_from_IHTMLDocument2((IHTMLDocument2*)iface);
1509
1510     if(This->window)
1511         update_cp_events(This->window, &This->doc_node->node.event_target, cp, This->doc_node->node.nsnode);
1512 }
1513
1514 static inline HTMLDocument *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
1515 {
1516     return CONTAINING_RECORD(iface, HTMLDocument, ISupportErrorInfo_iface);
1517 }
1518
1519 static HRESULT WINAPI SupportErrorInfo_QueryInterface(ISupportErrorInfo *iface, REFIID riid, void **ppv)
1520 {
1521     HTMLDocument *This = impl_from_ISupportErrorInfo(iface);
1522     return htmldoc_query_interface(This, riid, ppv);
1523 }
1524
1525 static ULONG WINAPI SupportErrorInfo_AddRef(ISupportErrorInfo *iface)
1526 {
1527     HTMLDocument *This = impl_from_ISupportErrorInfo(iface);
1528     return htmldoc_addref(This);
1529 }
1530
1531 static ULONG WINAPI SupportErrorInfo_Release(ISupportErrorInfo *iface)
1532 {
1533     HTMLDocument *This = impl_from_ISupportErrorInfo(iface);
1534     return htmldoc_release(This);
1535 }
1536
1537 static HRESULT WINAPI SupportErrorInfo_InterfaceSupportsErrorInfo(ISupportErrorInfo *iface, REFIID riid)
1538 {
1539     FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
1540     return S_FALSE;
1541 }
1542
1543 static const ISupportErrorInfoVtbl SupportErrorInfoVtbl = {
1544     SupportErrorInfo_QueryInterface,
1545     SupportErrorInfo_AddRef,
1546     SupportErrorInfo_Release,
1547     SupportErrorInfo_InterfaceSupportsErrorInfo
1548 };
1549
1550 #define DISPEX_THIS(iface) DEFINE_THIS(HTMLDocument, IDispatchEx, iface)
1551
1552 static HRESULT WINAPI DocDispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
1553 {
1554     HTMLDocument *This = DISPEX_THIS(iface);
1555
1556     return htmldoc_query_interface(This, riid, ppv);
1557 }
1558
1559 static ULONG WINAPI DocDispatchEx_AddRef(IDispatchEx *iface)
1560 {
1561     HTMLDocument *This = DISPEX_THIS(iface);
1562
1563     return htmldoc_addref(This);
1564 }
1565
1566 static ULONG WINAPI DocDispatchEx_Release(IDispatchEx *iface)
1567 {
1568     HTMLDocument *This = DISPEX_THIS(iface);
1569
1570     return htmldoc_release(This);
1571 }
1572
1573 static HRESULT WINAPI DocDispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
1574 {
1575     HTMLDocument *This = DISPEX_THIS(iface);
1576
1577     return IDispatchEx_GetTypeInfoCount(This->dispex, pctinfo);
1578 }
1579
1580 static HRESULT WINAPI DocDispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
1581                                                LCID lcid, ITypeInfo **ppTInfo)
1582 {
1583     HTMLDocument *This = DISPEX_THIS(iface);
1584
1585     return IDispatchEx_GetTypeInfo(This->dispex, iTInfo, lcid, ppTInfo);
1586 }
1587
1588 static HRESULT WINAPI DocDispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
1589                                                  LPOLESTR *rgszNames, UINT cNames,
1590                                                  LCID lcid, DISPID *rgDispId)
1591 {
1592     HTMLDocument *This = DISPEX_THIS(iface);
1593
1594     return IDispatchEx_GetIDsOfNames(This->dispex, riid, rgszNames, cNames, lcid, rgDispId);
1595 }
1596
1597 static HRESULT WINAPI DocDispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
1598                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1599                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1600 {
1601     HTMLDocument *This = DISPEX_THIS(iface);
1602
1603     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1604           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1605
1606     switch(dispIdMember) {
1607     case DISPID_READYSTATE:
1608         TRACE("DISPID_READYSTATE\n");
1609
1610         if(!(wFlags & DISPATCH_PROPERTYGET))
1611             return E_INVALIDARG;
1612
1613         V_VT(pVarResult) = VT_I4;
1614         V_I4(pVarResult) = This->window->readystate;
1615         return S_OK;
1616     }
1617
1618     return IDispatchEx_Invoke(This->dispex, dispIdMember, riid, lcid, wFlags, pDispParams,
1619                               pVarResult, pExcepInfo, puArgErr);
1620 }
1621
1622 static HRESULT WINAPI DocDispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
1623 {
1624     HTMLDocument *This = DISPEX_THIS(iface);
1625
1626     return IDispatchEx_GetDispID(This->dispex, bstrName, grfdex, pid);
1627 }
1628
1629 static HRESULT WINAPI DocDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1630         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1631 {
1632     HTMLDocument *This = DISPEX_THIS(iface);
1633
1634     if(This->window && id == DISPID_IHTMLDOCUMENT2_LOCATION && (wFlags & DISPATCH_PROPERTYPUT))
1635         return IDispatchEx_InvokeEx(DISPATCHEX(This->window), DISPID_IHTMLWINDOW2_LOCATION, lcid, wFlags,
1636                 pdp, pvarRes, pei, pspCaller);
1637
1638
1639     return IDispatchEx_InvokeEx(This->dispex, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1640 }
1641
1642 static HRESULT WINAPI DocDispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
1643 {
1644     HTMLDocument *This = DISPEX_THIS(iface);
1645
1646     return IDispatchEx_DeleteMemberByName(This->dispex, bstrName, grfdex);
1647 }
1648
1649 static HRESULT WINAPI DocDispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
1650 {
1651     HTMLDocument *This = DISPEX_THIS(iface);
1652
1653     return IDispatchEx_DeleteMemberByDispID(This->dispex, id);
1654 }
1655
1656 static HRESULT WINAPI DocDispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
1657 {
1658     HTMLDocument *This = DISPEX_THIS(iface);
1659
1660     return IDispatchEx_GetMemberProperties(This->dispex, id, grfdexFetch, pgrfdex);
1661 }
1662
1663 static HRESULT WINAPI DocDispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
1664 {
1665     HTMLDocument *This = DISPEX_THIS(iface);
1666
1667     return IDispatchEx_GetMemberName(This->dispex, id, pbstrName);
1668 }
1669
1670 static HRESULT WINAPI DocDispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
1671 {
1672     HTMLDocument *This = DISPEX_THIS(iface);
1673
1674     return IDispatchEx_GetNextDispID(This->dispex, grfdex, id, pid);
1675 }
1676
1677 static HRESULT WINAPI DocDispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
1678 {
1679     HTMLDocument *This = DISPEX_THIS(iface);
1680
1681     return IDispatchEx_GetNameSpaceParent(This->dispex, ppunk);
1682 }
1683
1684 #undef DISPEX_THIS
1685
1686 static const IDispatchExVtbl DocDispatchExVtbl = {
1687     DocDispatchEx_QueryInterface,
1688     DocDispatchEx_AddRef,
1689     DocDispatchEx_Release,
1690     DocDispatchEx_GetTypeInfoCount,
1691     DocDispatchEx_GetTypeInfo,
1692     DocDispatchEx_GetIDsOfNames,
1693     DocDispatchEx_Invoke,
1694     DocDispatchEx_GetDispID,
1695     DocDispatchEx_InvokeEx,
1696     DocDispatchEx_DeleteMemberByName,
1697     DocDispatchEx_DeleteMemberByDispID,
1698     DocDispatchEx_GetMemberProperties,
1699     DocDispatchEx_GetMemberName,
1700     DocDispatchEx_GetNextDispID,
1701     DocDispatchEx_GetNameSpaceParent
1702 };
1703
1704 static BOOL htmldoc_qi(HTMLDocument *This, REFIID riid, void **ppv)
1705 {
1706     *ppv = NULL;
1707
1708     if(IsEqualGUID(&IID_IUnknown, riid)) {
1709         TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv);
1710         *ppv = &This->IHTMLDocument2_iface;
1711     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1712         TRACE("(%p)->(IID_IDispatch, %p)\n", This, ppv);
1713         *ppv = DISPATCHEX(This);
1714     }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
1715         TRACE("(%p)->(IID_IDispatchEx, %p)\n", This, ppv);
1716         *ppv = DISPATCHEX(This);
1717     }else if(IsEqualGUID(&IID_IHTMLDocument, riid)) {
1718         TRACE("(%p)->(IID_IHTMLDocument, %p)\n", This, ppv);
1719         *ppv = &This->IHTMLDocument2_iface;
1720     }else if(IsEqualGUID(&IID_IHTMLDocument2, riid)) {
1721         TRACE("(%p)->(IID_IHTMLDocument2, %p)\n", This, ppv);
1722         *ppv = &This->IHTMLDocument2_iface;
1723     }else if(IsEqualGUID(&IID_IHTMLDocument3, riid)) {
1724         TRACE("(%p)->(IID_IHTMLDocument3, %p)\n", This, ppv);
1725         *ppv = &This->IHTMLDocument3_iface;
1726     }else if(IsEqualGUID(&IID_IHTMLDocument4, riid)) {
1727         TRACE("(%p)->(IID_IHTMLDocument4, %p)\n", This, ppv);
1728         *ppv = &This->IHTMLDocument4_iface;
1729     }else if(IsEqualGUID(&IID_IHTMLDocument5, riid)) {
1730         TRACE("(%p)->(IID_IHTMLDocument5, %p)\n", This, ppv);
1731         *ppv = &This->IHTMLDocument5_iface;
1732     }else if(IsEqualGUID(&IID_IHTMLDocument6, riid)) {
1733         TRACE("(%p)->(IID_IHTMLDocument6, %p)\n", This, ppv);
1734         *ppv = &This->IHTMLDocument6_iface;
1735     }else if(IsEqualGUID(&IID_IPersist, riid)) {
1736         TRACE("(%p)->(IID_IPersist, %p)\n", This, ppv);
1737         *ppv = &This->IPersistFile_iface;
1738     }else if(IsEqualGUID(&IID_IPersistMoniker, riid)) {
1739         TRACE("(%p)->(IID_IPersistMoniker, %p)\n", This, ppv);
1740         *ppv = &This->IPersistMoniker_iface;
1741     }else if(IsEqualGUID(&IID_IPersistFile, riid)) {
1742         TRACE("(%p)->(IID_IPersistFile, %p)\n", This, ppv);
1743         *ppv = &This->IPersistFile_iface;
1744     }else if(IsEqualGUID(&IID_IMonikerProp, riid)) {
1745         TRACE("(%p)->(IID_IMonikerProp, %p)\n", This, ppv);
1746         *ppv = &This->IMonikerProp_iface;
1747     }else if(IsEqualGUID(&IID_IOleObject, riid)) {
1748         TRACE("(%p)->(IID_IOleObject, %p)\n", This, ppv);
1749         *ppv = &This->IOleObject_iface;
1750     }else if(IsEqualGUID(&IID_IOleDocument, riid)) {
1751         TRACE("(%p)->(IID_IOleDocument, %p)\n", This, ppv);
1752         *ppv = &This->IOleDocument_iface;
1753     }else if(IsEqualGUID(&IID_IOleDocumentView, riid)) {
1754         TRACE("(%p)->(IID_IOleDocumentView, %p)\n", This, ppv);
1755         *ppv = &This->IOleDocumentView_iface;
1756     }else if(IsEqualGUID(&IID_IOleInPlaceActiveObject, riid)) {
1757         TRACE("(%p)->(IID_IOleInPlaceActiveObject, %p)\n", This, ppv);
1758         *ppv = &This->IOleInPlaceActiveObject_iface;
1759     }else if(IsEqualGUID(&IID_IViewObject, riid)) {
1760         TRACE("(%p)->(IID_IViewObject, %p)\n", This, ppv);
1761         *ppv = &This->IViewObjectEx_iface;
1762     }else if(IsEqualGUID(&IID_IViewObject2, riid)) {
1763         TRACE("(%p)->(IID_IViewObject2, %p)\n", This, ppv);
1764         *ppv = &This->IViewObjectEx_iface;
1765     }else if(IsEqualGUID(&IID_IViewObjectEx, riid)) {
1766         TRACE("(%p)->(IID_IViewObjectEx, %p)\n", This, ppv);
1767         *ppv = &This->IViewObjectEx_iface;
1768     }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
1769         TRACE("(%p)->(IID_IOleWindow, %p)\n", This, ppv);
1770         *ppv = &This->IOleInPlaceActiveObject_iface;
1771     }else if(IsEqualGUID(&IID_IOleInPlaceObject, riid)) {
1772         TRACE("(%p)->(IID_IOleInPlaceObject, %p)\n", This, ppv);
1773         *ppv = &This->IOleInPlaceObjectWindowless_iface;
1774     }else if(IsEqualGUID(&IID_IOleInPlaceObjectWindowless, riid)) {
1775         TRACE("(%p)->(IID_IOleInPlaceObjectWindowless, %p)\n", This, ppv);
1776         *ppv = &This->IOleInPlaceObjectWindowless_iface;
1777     }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
1778         TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv);
1779         *ppv = &This->IServiceProvider_iface;
1780     }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
1781         TRACE("(%p)->(IID_IOleCommandTarget, %p)\n", This, ppv);
1782         *ppv = &This->IOleCommandTarget_iface;
1783     }else if(IsEqualGUID(&IID_IOleControl, riid)) {
1784         TRACE("(%p)->(IID_IOleControl, %p)\n", This, ppv);
1785         *ppv = &This->IOleControl_iface;
1786     }else if(IsEqualGUID(&IID_IHlinkTarget, riid)) {
1787         TRACE("(%p)->(IID_IHlinkTarget, %p)\n", This, ppv);
1788         *ppv = &This->IHlinkTarget_iface;
1789     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
1790         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
1791         *ppv = CONPTCONT(&This->cp_container);
1792     }else if(IsEqualGUID(&IID_IPersistStreamInit, riid)) {
1793         TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
1794         *ppv = &This->IPersistStreamInit_iface;
1795     }else if(IsEqualGUID(&DIID_DispHTMLDocument, riid)) {
1796         TRACE("(%p)->(DIID_DispHTMLDocument %p)\n", This, ppv);
1797         *ppv = &This->IHTMLDocument2_iface;
1798     }else if(IsEqualGUID(&IID_ISupportErrorInfo, riid)) {
1799         TRACE("(%p)->(IID_ISupportErrorInfo %p)\n", This, ppv);
1800         *ppv = &This->ISupportErrorInfo_iface;
1801     }else if(IsEqualGUID(&IID_IPersistHistory, riid)) {
1802         TRACE("(%p)->(IID_IPersistHistory %p)\n", This, ppv);
1803         *ppv = &This->IPersistHistory_iface;
1804     }else if(IsEqualGUID(&CLSID_CMarkup, riid)) {
1805         FIXME("(%p)->(CLSID_CMarkup %p)\n", This, ppv);
1806         *ppv = NULL;
1807     }else if(IsEqualGUID(&IID_IRunnableObject, riid)) {
1808         TRACE("(%p)->(IID_IRunnableObject %p) returning NULL\n", This, ppv);
1809         *ppv = NULL;
1810     }else if(IsEqualGUID(&IID_IPersistPropertyBag, riid)) {
1811         TRACE("(%p)->(IID_IPersistPropertyBag %p) returning NULL\n", This, ppv);
1812         *ppv = NULL;
1813     }else if(IsEqualGUID(&IID_IMarshal, riid)) {
1814         TRACE("(%p)->(IID_IMarshal %p) returning NULL\n", This, ppv);
1815         *ppv = NULL;
1816     }else if(IsEqualGUID(&IID_IExternalConnection, riid)) {
1817         TRACE("(%p)->(IID_IExternalConnection %p) returning NULL\n", This, ppv);
1818         *ppv = NULL;
1819     }else if(IsEqualGUID(&IID_IStdMarshalInfo, riid)) {
1820         TRACE("(%p)->(IID_IStdMarshalInfo %p) returning NULL\n", This, ppv);
1821         *ppv = NULL;
1822     }else if(IsEqualGUID(&IID_IObjectWithSite, riid)) {
1823         TRACE("(%p)->(IID_IObjectWithSite %p)\n", This, ppv);
1824         *ppv = &This->IObjectWithSite_iface;
1825     }else if(IsEqualGUID(&IID_IOleContainer, riid)) {
1826         TRACE("(%p)->(IID_IOleContainer %p)\n", This, ppv);
1827         *ppv = &This->IOleContainer_iface;
1828     }else {
1829         return FALSE;
1830     }
1831
1832     if(*ppv)
1833         IUnknown_AddRef((IUnknown*)*ppv);
1834     return TRUE;
1835 }
1836
1837 static cp_static_data_t HTMLDocumentEvents_data = { HTMLDocumentEvents_tid, HTMLDocument_on_advise };
1838
1839 static void init_doc(HTMLDocument *doc, IUnknown *unk_impl, IDispatchEx *dispex)
1840 {
1841     doc->IHTMLDocument2_iface.lpVtbl = &HTMLDocumentVtbl;
1842     doc->lpIDispatchExVtbl = &DocDispatchExVtbl;
1843     doc->ISupportErrorInfo_iface.lpVtbl = &SupportErrorInfoVtbl;
1844
1845     doc->unk_impl = unk_impl;
1846     doc->dispex = dispex;
1847     doc->task_magic = get_task_target_magic();
1848
1849     HTMLDocument_HTMLDocument3_Init(doc);
1850     HTMLDocument_HTMLDocument5_Init(doc);
1851     HTMLDocument_Persist_Init(doc);
1852     HTMLDocument_OleCmd_Init(doc);
1853     HTMLDocument_OleObj_Init(doc);
1854     HTMLDocument_View_Init(doc);
1855     HTMLDocument_Window_Init(doc);
1856     HTMLDocument_Service_Init(doc);
1857     HTMLDocument_Hlink_Init(doc);
1858
1859     ConnectionPointContainer_Init(&doc->cp_container, (IUnknown*)&doc->IHTMLDocument2_iface);
1860     ConnectionPoint_Init(&doc->cp_dispatch, &doc->cp_container, &IID_IDispatch, NULL);
1861     ConnectionPoint_Init(&doc->cp_propnotif, &doc->cp_container, &IID_IPropertyNotifySink, NULL);
1862     ConnectionPoint_Init(&doc->cp_htmldocevents, &doc->cp_container, &DIID_HTMLDocumentEvents, &HTMLDocumentEvents_data);
1863     ConnectionPoint_Init(&doc->cp_htmldocevents2, &doc->cp_container, &DIID_HTMLDocumentEvents2, NULL);
1864 }
1865
1866 static void destroy_htmldoc(HTMLDocument *This)
1867 {
1868     remove_target_tasks(This->task_magic);
1869
1870     ConnectionPointContainer_Destroy(&This->cp_container);
1871 }
1872
1873 static inline HTMLDocumentNode *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
1874 {
1875     return CONTAINING_RECORD(iface, HTMLDocumentNode, node);
1876 }
1877
1878 static HRESULT HTMLDocumentNode_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
1879 {
1880     HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface);
1881
1882     if(htmldoc_qi(&This->basedoc, riid, ppv))
1883         return *ppv ? S_OK : E_NOINTERFACE;
1884
1885     if(IsEqualGUID(&IID_IInternetHostSecurityManager, riid)) {
1886         TRACE("(%p)->(IID_IInternetHostSecurityManager %p)\n", This, ppv);
1887         *ppv = HOSTSECMGR(This);
1888     }else {
1889         return HTMLDOMNode_QI(&This->node, riid, ppv);
1890     }
1891
1892     IUnknown_AddRef((IUnknown*)*ppv);
1893     return S_OK;
1894 }
1895
1896 static void HTMLDocumentNode_destructor(HTMLDOMNode *iface)
1897 {
1898     HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface);
1899
1900     if(This->body_event_target)
1901         release_event_target(This->body_event_target);
1902     if(This->nsevent_listener)
1903         release_nsevents(This);
1904     if(This->catmgr)
1905         ICatInformation_Release(This->catmgr);
1906     if(This->secmgr)
1907         IInternetSecurityManager_Release(This->secmgr);
1908
1909     detach_selection(This);
1910     detach_ranges(This);
1911     release_nodes(This);
1912
1913     while(!list_empty(&This->plugin_hosts))
1914         detach_plugin_host(LIST_ENTRY(list_head(&This->plugin_hosts), PluginHost, entry));
1915
1916     if(This->nsdoc) {
1917         release_mutation(This);
1918         nsIDOMHTMLDocument_Release(This->nsdoc);
1919     }
1920
1921     heap_free(This->event_vector);
1922     destroy_htmldoc(&This->basedoc);
1923 }
1924
1925 static HRESULT HTMLDocumentNode_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode **ret)
1926 {
1927     HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface);
1928     FIXME("%p\n", This);
1929     return E_NOTIMPL;
1930 }
1931
1932 static const NodeImplVtbl HTMLDocumentNodeImplVtbl = {
1933     HTMLDocumentNode_QI,
1934     HTMLDocumentNode_destructor,
1935     HTMLDocumentNode_clone
1936 };
1937
1938 static HRESULT HTMLDocumentFragment_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode **ret)
1939 {
1940     HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface);
1941     HTMLDocumentNode *new_node;
1942     HRESULT hres;
1943
1944     hres = create_document_fragment(nsnode, This->node.doc, &new_node);
1945     if(FAILED(hres))
1946         return hres;
1947
1948     *ret = &new_node->node;
1949     return S_OK;
1950 }
1951
1952 static const NodeImplVtbl HTMLDocumentFragmentImplVtbl = {
1953     HTMLDocumentNode_QI,
1954     HTMLDocumentNode_destructor,
1955     HTMLDocumentFragment_clone
1956 };
1957
1958 static const tid_t HTMLDocumentNode_iface_tids[] = {
1959     IHTMLDOMNode_tid,
1960     IHTMLDOMNode2_tid,
1961     IHTMLDocument2_tid,
1962     IHTMLDocument3_tid,
1963     IHTMLDocument4_tid,
1964     IHTMLDocument5_tid,
1965     0
1966 };
1967
1968 static dispex_static_data_t HTMLDocumentNode_dispex = {
1969     NULL,
1970     DispHTMLDocument_tid,
1971     NULL,
1972     HTMLDocumentNode_iface_tids
1973 };
1974
1975 static HTMLDocumentNode *alloc_doc_node(HTMLDocumentObj *doc_obj, HTMLWindow *window)
1976 {
1977     HTMLDocumentNode *doc;
1978
1979     doc = heap_alloc_zero(sizeof(HTMLDocumentNode));
1980     if(!doc)
1981         return NULL;
1982
1983     doc->ref = 1;
1984     doc->basedoc.doc_node = doc;
1985     doc->basedoc.doc_obj = doc_obj;
1986     doc->basedoc.window = window;
1987
1988     init_dispex(&doc->node.dispex, (IUnknown*)HTMLDOMNODE(&doc->node), &HTMLDocumentNode_dispex);
1989     init_doc(&doc->basedoc, (IUnknown*)HTMLDOMNODE(&doc->node), DISPATCHEX(&doc->node.dispex));
1990     HTMLDocumentNode_SecMgr_Init(doc);
1991
1992     init_nsevents(doc);
1993
1994     list_init(&doc->bindings);
1995     list_init(&doc->selection_list);
1996     list_init(&doc->range_list);
1997     list_init(&doc->plugin_hosts);
1998
1999     return doc;
2000 }
2001
2002 HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocumentObj *doc_obj, HTMLWindow *window, HTMLDocumentNode **ret)
2003 {
2004     HTMLDocumentNode *doc;
2005     HRESULT hres;
2006
2007     doc = alloc_doc_node(doc_obj, window);
2008     if(!doc)
2009         return E_OUTOFMEMORY;
2010
2011     if(window == doc_obj->basedoc.window)
2012         doc->basedoc.cp_container.forward_container = &doc_obj->basedoc.cp_container;
2013
2014     nsIDOMHTMLDocument_AddRef(nsdoc);
2015     doc->nsdoc = nsdoc;
2016     init_mutation(doc);
2017
2018     HTMLDOMNode_Init(doc, &doc->node, (nsIDOMNode*)nsdoc);
2019     doc->node.vtbl = &HTMLDocumentNodeImplVtbl;
2020     doc->node.cp_container = &doc->basedoc.cp_container;
2021
2022     hres = CoInternetCreateSecurityManager(NULL, &doc->secmgr, 0);
2023     if(FAILED(hres)) {
2024         htmldoc_release(&doc->basedoc);
2025         return hres;
2026     }
2027
2028     *ret = doc;
2029     return S_OK;
2030 }
2031
2032 HRESULT create_document_fragment(nsIDOMNode *nsnode, HTMLDocumentNode *doc_node, HTMLDocumentNode **ret)
2033 {
2034     HTMLDocumentNode *doc_frag;
2035
2036     doc_frag = alloc_doc_node(doc_node->basedoc.doc_obj, doc_node->basedoc.window);
2037     if(!doc_frag)
2038         return E_OUTOFMEMORY;
2039
2040     HTMLDOMNode_Init(doc_node, &doc_frag->node, nsnode);
2041     doc_frag->node.vtbl = &HTMLDocumentFragmentImplVtbl;
2042     doc_frag->node.cp_container = &doc_frag->basedoc.cp_container;
2043
2044     htmldoc_addref(&doc_frag->basedoc);
2045     *ret = doc_frag;
2046     return S_OK;
2047 }
2048
2049 /**********************************************************
2050  * ICustomDoc implementation
2051  */
2052
2053 #define CUSTOMDOC_THIS(iface) DEFINE_THIS(HTMLDocumentObj, CustomDoc, iface)
2054
2055 static HRESULT WINAPI CustomDoc_QueryInterface(ICustomDoc *iface, REFIID riid, void **ppv)
2056 {
2057     HTMLDocumentObj *This = CUSTOMDOC_THIS(iface);
2058
2059     if(htmldoc_qi(&This->basedoc, riid, ppv))
2060         return *ppv ? S_OK : E_NOINTERFACE;
2061
2062     if(IsEqualGUID(&IID_ICustomDoc, riid)) {
2063         TRACE("(%p)->(IID_ICustomDoc %p)\n", This, ppv);
2064         *ppv = CUSTOMDOC(This);
2065     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
2066         return *ppv ? S_OK : E_NOINTERFACE;
2067     }else {
2068         FIXME("Unimplemented interface %s\n", debugstr_guid(riid));
2069         *ppv = NULL;
2070         return E_NOINTERFACE;
2071     }
2072
2073     IUnknown_AddRef((IUnknown*)*ppv);
2074     return S_OK;
2075 }
2076
2077 static ULONG WINAPI CustomDoc_AddRef(ICustomDoc *iface)
2078 {
2079     HTMLDocumentObj *This = CUSTOMDOC_THIS(iface);
2080     ULONG ref = InterlockedIncrement(&This->ref);
2081
2082     TRACE("(%p) ref = %u\n", This, ref);
2083
2084     return ref;
2085 }
2086
2087 static ULONG WINAPI CustomDoc_Release(ICustomDoc *iface)
2088 {
2089     HTMLDocumentObj *This = CUSTOMDOC_THIS(iface);
2090     ULONG ref = InterlockedDecrement(&This->ref);
2091
2092     TRACE("(%p) ref = %u\n", This, ref);
2093
2094     if(!ref) {
2095         if(This->basedoc.doc_node) {
2096             This->basedoc.doc_node->basedoc.doc_obj = NULL;
2097             htmldoc_release(&This->basedoc.doc_node->basedoc);
2098         }
2099         if(This->basedoc.window) {
2100             This->basedoc.window->doc_obj = NULL;
2101             IHTMLWindow2_Release(&This->basedoc.window->IHTMLWindow2_iface);
2102         }
2103         if(This->basedoc.advise_holder)
2104             IOleAdviseHolder_Release(This->basedoc.advise_holder);
2105
2106         if(This->view_sink)
2107             IAdviseSink_Release(This->view_sink);
2108         if(This->client)
2109             IOleObject_SetClientSite(&This->basedoc.IOleObject_iface, NULL);
2110         if(This->hostui)
2111             ICustomDoc_SetUIHandler(CUSTOMDOC(This), NULL);
2112         if(This->in_place_active)
2113             IOleInPlaceObjectWindowless_InPlaceDeactivate(&This->basedoc.IOleInPlaceObjectWindowless_iface);
2114         if(This->ipsite)
2115             IOleDocumentView_SetInPlaceSite(&This->basedoc.IOleDocumentView_iface, NULL);
2116         if(This->undomgr)
2117             IOleUndoManager_Release(This->undomgr);
2118         if(This->tooltips_hwnd)
2119             DestroyWindow(This->tooltips_hwnd);
2120
2121         if(This->hwnd)
2122             DestroyWindow(This->hwnd);
2123         heap_free(This->mime);
2124
2125         destroy_htmldoc(&This->basedoc);
2126         release_dispex(&This->dispex);
2127
2128         if(This->nscontainer)
2129             NSContainer_Release(This->nscontainer);
2130         heap_free(This);
2131     }
2132
2133     return ref;
2134 }
2135
2136 static HRESULT WINAPI CustomDoc_SetUIHandler(ICustomDoc *iface, IDocHostUIHandler *pUIHandler)
2137 {
2138     HTMLDocumentObj *This = CUSTOMDOC_THIS(iface);
2139     IOleCommandTarget *cmdtrg;
2140     HRESULT hres;
2141
2142     TRACE("(%p)->(%p)\n", This, pUIHandler);
2143
2144     if(This->custom_hostui && This->hostui == pUIHandler)
2145         return S_OK;
2146
2147     This->custom_hostui = TRUE;
2148
2149     if(This->hostui)
2150         IDocHostUIHandler_Release(This->hostui);
2151     if(pUIHandler)
2152         IDocHostUIHandler_AddRef(pUIHandler);
2153     This->hostui = pUIHandler;
2154     if(!pUIHandler)
2155         return S_OK;
2156
2157     hres = IDocHostUIHandler_QueryInterface(pUIHandler, &IID_IOleCommandTarget, (void**)&cmdtrg);
2158     if(SUCCEEDED(hres)) {
2159         FIXME("custom UI handler supports IOleCommandTarget\n");
2160         IOleCommandTarget_Release(cmdtrg);
2161     }
2162
2163     return S_OK;
2164 }
2165
2166 #undef CUSTOMDOC_THIS
2167
2168 static const ICustomDocVtbl CustomDocVtbl = {
2169     CustomDoc_QueryInterface,
2170     CustomDoc_AddRef,
2171     CustomDoc_Release,
2172     CustomDoc_SetUIHandler
2173 };
2174
2175 static const tid_t HTMLDocumentObj_iface_tids[] = {
2176     IHTMLDocument2_tid,
2177     IHTMLDocument3_tid,
2178     IHTMLDocument4_tid,
2179     IHTMLDocument5_tid,
2180     0
2181 };
2182 static dispex_static_data_t HTMLDocumentObj_dispex = {
2183     NULL,
2184     DispHTMLDocument_tid,
2185     NULL,
2186     HTMLDocumentObj_iface_tids
2187 };
2188
2189 HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
2190 {
2191     HTMLDocumentObj *doc;
2192     nsIDOMWindow *nswindow = NULL;
2193     nsresult nsres;
2194     HRESULT hres;
2195
2196     TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppvObject);
2197
2198     doc = heap_alloc_zero(sizeof(HTMLDocumentObj));
2199     if(!doc)
2200         return E_OUTOFMEMORY;
2201
2202     init_dispex(&doc->dispex, (IUnknown*)CUSTOMDOC(doc), &HTMLDocumentObj_dispex);
2203     init_doc(&doc->basedoc, (IUnknown*)CUSTOMDOC(doc), DISPATCHEX(&doc->dispex));
2204
2205     doc->lpCustomDocVtbl = &CustomDocVtbl;
2206     doc->ref = 1;
2207     doc->basedoc.doc_obj = doc;
2208
2209     doc->usermode = UNKNOWN_USERMODE;
2210
2211     doc->nscontainer = NSContainer_Create(doc, NULL);
2212     if(!doc->nscontainer) {
2213         ERR("Failed to init Gecko, returning CLASS_E_CLASSNOTAVAILABLE\n");
2214         htmldoc_release(&doc->basedoc);
2215         return CLASS_E_CLASSNOTAVAILABLE;
2216     }
2217
2218     hres = htmldoc_query_interface(&doc->basedoc, riid, ppvObject);
2219     htmldoc_release(&doc->basedoc);
2220     if(FAILED(hres))
2221         return hres;
2222
2223
2224     nsres = nsIWebBrowser_GetContentDOMWindow(doc->nscontainer->webbrowser, &nswindow);
2225     if(NS_FAILED(nsres))
2226         ERR("GetContentDOMWindow failed: %08x\n", nsres);
2227
2228     hres = HTMLWindow_Create(doc, nswindow, NULL /* FIXME */, &doc->basedoc.window);
2229     if(nswindow)
2230         nsIDOMWindow_Release(nswindow);
2231     if(FAILED(hres)) {
2232         htmldoc_release(&doc->basedoc);
2233         return hres;
2234     }
2235
2236     if(!doc->basedoc.doc_node && doc->basedoc.window->doc) {
2237         doc->basedoc.doc_node = doc->basedoc.window->doc;
2238         htmldoc_addref(&doc->basedoc.doc_node->basedoc);
2239     }
2240
2241     get_thread_hwnd();
2242
2243     return S_OK;
2244 }