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