mshtml: Moved usermode to HTMLDocumentObj.
[wine] / dlls / mshtml / htmldoc.c
1 /*
2  * Copyright 2005 Jacek Caban
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "config.h"
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "ole2.h"
30 #include "perhist.h"
31
32 #include "wine/debug.h"
33
34 #include "mshtml_private.h"
35 #include "htmlevent.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38
39 #define HTMLDOC_THIS(iface) DEFINE_THIS(HTMLDocument, HTMLDocument2, iface)
40
41 static HRESULT WINAPI HTMLDocument_QueryInterface(IHTMLDocument2 *iface, REFIID riid, void **ppv)
42 {
43     HTMLDocument *This = HTMLDOC_THIS(iface);
44
45     return htmldoc_query_interface(This, riid, ppv);
46 }
47
48 static ULONG WINAPI HTMLDocument_AddRef(IHTMLDocument2 *iface)
49 {
50     HTMLDocument *This = HTMLDOC_THIS(iface);
51
52     return htmldoc_addref(This);
53 }
54
55 static ULONG WINAPI HTMLDocument_Release(IHTMLDocument2 *iface)
56 {
57     HTMLDocument *This = HTMLDOC_THIS(iface);
58
59     return htmldoc_release(This);
60 }
61
62 static HRESULT WINAPI HTMLDocument_GetTypeInfoCount(IHTMLDocument2 *iface, UINT *pctinfo)
63 {
64     HTMLDocument *This = HTMLDOC_THIS(iface);
65
66     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(This), pctinfo);
67 }
68
69 static HRESULT WINAPI HTMLDocument_GetTypeInfo(IHTMLDocument2 *iface, UINT iTInfo,
70                                                 LCID lcid, ITypeInfo **ppTInfo)
71 {
72     HTMLDocument *This = HTMLDOC_THIS(iface);
73
74     return IDispatchEx_GetTypeInfo(DISPATCHEX(This), iTInfo, lcid, ppTInfo);
75 }
76
77 static HRESULT WINAPI HTMLDocument_GetIDsOfNames(IHTMLDocument2 *iface, REFIID riid,
78                                                 LPOLESTR *rgszNames, UINT cNames,
79                                                 LCID lcid, DISPID *rgDispId)
80 {
81     HTMLDocument *This = HTMLDOC_THIS(iface);
82
83     return IDispatchEx_GetIDsOfNames(DISPATCHEX(This), riid, rgszNames, cNames, lcid, rgDispId);
84 }
85
86 static HRESULT WINAPI HTMLDocument_Invoke(IHTMLDocument2 *iface, DISPID dispIdMember,
87                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
88                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
89 {
90     HTMLDocument *This = HTMLDOC_THIS(iface);
91
92     return IDispatchEx_Invoke(DISPATCHEX(This), dispIdMember, riid, lcid, wFlags, pDispParams,
93             pVarResult, pExcepInfo, puArgErr);
94 }
95
96 static HRESULT WINAPI HTMLDocument_get_Script(IHTMLDocument2 *iface, IDispatch **p)
97 {
98     HTMLDocument *This = HTMLDOC_THIS(iface);
99
100     TRACE("(%p)->(%p)\n", This, p);
101
102     *p = (IDispatch*)HTMLWINDOW2(This->window);
103     IDispatch_AddRef(*p);
104     return S_OK;
105 }
106
107 static HRESULT WINAPI HTMLDocument_get_all(IHTMLDocument2 *iface, IHTMLElementCollection **p)
108 {
109     HTMLDocument *This = HTMLDOC_THIS(iface);
110     nsIDOMElement *nselem = NULL;
111     nsresult nsres;
112
113     TRACE("(%p)->(%p)\n", This, p);
114
115     if(!This->nsdoc) {
116         WARN("NULL nsdoc\n");
117         return E_UNEXPECTED;
118     }
119
120     nsres = nsIDOMHTMLDocument_GetDocumentElement(This->nsdoc, &nselem);
121     if(NS_FAILED(nsres)) {
122         ERR("GetDocumentElement failed: %08x\n", nsres);
123         return E_FAIL;
124     }
125
126     if(nselem) {
127         *p = create_all_collection(get_node(This, (nsIDOMNode*)nselem, TRUE), TRUE);
128         nsIDOMElement_Release(nselem);
129     }else {
130         *p = NULL;
131     }
132
133     return S_OK;
134 }
135
136 static HRESULT WINAPI HTMLDocument_get_body(IHTMLDocument2 *iface, IHTMLElement **p)
137 {
138     HTMLDocument *This = HTMLDOC_THIS(iface);
139     nsIDOMHTMLElement *nsbody = NULL;
140     HTMLDOMNode *node;
141     nsresult nsres;
142
143     TRACE("(%p)->(%p)\n", This, p);
144
145     if(!This->nsdoc) {
146         WARN("NULL nsdoc\n");
147         return E_UNEXPECTED;
148     }
149
150     nsres = nsIDOMHTMLDocument_GetBody(This->nsdoc, &nsbody);
151     if(NS_FAILED(nsres)) {
152         TRACE("Could not get body: %08x\n", nsres);
153         return E_UNEXPECTED;
154     }
155
156     if(nsbody) {
157         node = get_node(This, (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->nsdoc) {
190         WARN("NULL nsdoc\n");
191         return E_UNEXPECTED;
192     }
193
194     nsres = nsIDOMHTMLDocument_GetImages(This->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, (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->nsdoc) {
222         WARN("NULL nsdoc\n");
223         return E_UNEXPECTED;
224     }
225
226     nsres = nsIDOMHTMLDocument_GetApplets(This->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, (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->nsdoc) {
254         WARN("NULL nsdoc\n");
255         return E_UNEXPECTED;
256     }
257
258     nsres = nsIDOMHTMLDocument_GetLinks(This->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, (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->nsdoc) {
286         WARN("NULL nsdoc\n");
287         return E_UNEXPECTED;
288     }
289
290     nsres = nsIDOMHTMLDocument_GetForms(This->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, (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->nsdoc) {
318         WARN("NULL nsdoc\n");
319         return E_UNEXPECTED;
320     }
321
322     nsres = nsIDOMHTMLDocument_GetAnchors(This->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, (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->nsdoc) {
345         WARN("NULL nsdoc\n");
346         return E_UNEXPECTED;
347     }
348
349     nsAString_Init(&nsstr, v);
350     nsres = nsIDOMHTMLDocument_SetTitle(This->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->nsdoc) {
368         WARN("NULL nsdoc\n");
369         return E_UNEXPECTED;
370     }
371
372
373     nsAString_Init(&nsstr, NULL);
374     nsres = nsIDOMHTMLDocument_GetTitle(This->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->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     FIXME("(%p)->(%p)\n", This, p);
556     return E_NOTIMPL;
557 }
558
559 static HRESULT WINAPI HTMLDocument_get_location(IHTMLDocument2 *iface, IHTMLLocation **p)
560 {
561     HTMLDocument *This = HTMLDOC_THIS(iface);
562
563     TRACE("(%p)->(%p)\n", This, p);
564
565     return IHTMLWindow2_get_location(HTMLWINDOW2(This->window), p);
566 }
567
568 static HRESULT WINAPI HTMLDocument_get_lastModified(IHTMLDocument2 *iface, BSTR *p)
569 {
570     HTMLDocument *This = HTMLDOC_THIS(iface);
571     FIXME("(%p)->(%p)\n", This, p);
572     return E_NOTIMPL;
573 }
574
575 static HRESULT WINAPI HTMLDocument_put_URL(IHTMLDocument2 *iface, BSTR v)
576 {
577     HTMLDocument *This = HTMLDOC_THIS(iface);
578     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
579     return E_NOTIMPL;
580 }
581
582 static HRESULT WINAPI HTMLDocument_get_URL(IHTMLDocument2 *iface, BSTR *p)
583 {
584     HTMLDocument *This = HTMLDOC_THIS(iface);
585
586     static const WCHAR about_blank_url[] =
587         {'a','b','o','u','t',':','b','l','a','n','k',0};
588
589     TRACE("(%p)->(%p)\n", iface, p);
590
591     *p = SysAllocString(This->doc_obj->url ? This->doc_obj->url : about_blank_url);
592     return *p ? S_OK : E_OUTOFMEMORY;
593 }
594
595 static HRESULT WINAPI HTMLDocument_put_domain(IHTMLDocument2 *iface, BSTR v)
596 {
597     HTMLDocument *This = HTMLDOC_THIS(iface);
598     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
599     return E_NOTIMPL;
600 }
601
602 static HRESULT WINAPI HTMLDocument_get_domain(IHTMLDocument2 *iface, BSTR *p)
603 {
604     HTMLDocument *This = HTMLDOC_THIS(iface);
605     FIXME("(%p)->(%p)\n", This, p);
606     return E_NOTIMPL;
607 }
608
609 static HRESULT WINAPI HTMLDocument_put_cookie(IHTMLDocument2 *iface, BSTR v)
610 {
611     HTMLDocument *This = HTMLDOC_THIS(iface);
612     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
613     return E_NOTIMPL;
614 }
615
616 static HRESULT WINAPI HTMLDocument_get_cookie(IHTMLDocument2 *iface, BSTR *p)
617 {
618     HTMLDocument *This = HTMLDOC_THIS(iface);
619     FIXME("(%p)->(%p)\n", This, p);
620     return E_NOTIMPL;
621 }
622
623 static HRESULT WINAPI HTMLDocument_put_expando(IHTMLDocument2 *iface, VARIANT_BOOL v)
624 {
625     HTMLDocument *This = HTMLDOC_THIS(iface);
626     FIXME("(%p)->(%x)\n", This, v);
627     return E_NOTIMPL;
628 }
629
630 static HRESULT WINAPI HTMLDocument_get_expando(IHTMLDocument2 *iface, VARIANT_BOOL *p)
631 {
632     HTMLDocument *This = HTMLDOC_THIS(iface);
633     FIXME("(%p)->(%p)\n", This, p);
634     return E_NOTIMPL;
635 }
636
637 static HRESULT WINAPI HTMLDocument_put_charset(IHTMLDocument2 *iface, BSTR v)
638 {
639     HTMLDocument *This = HTMLDOC_THIS(iface);
640     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
641     return E_NOTIMPL;
642 }
643
644 static HRESULT WINAPI HTMLDocument_get_charset(IHTMLDocument2 *iface, BSTR *p)
645 {
646     HTMLDocument *This = HTMLDOC_THIS(iface);
647     FIXME("(%p)->(%p)\n", This, p);
648     return E_NOTIMPL;
649 }
650
651 static HRESULT WINAPI HTMLDocument_put_defaultCharset(IHTMLDocument2 *iface, BSTR v)
652 {
653     HTMLDocument *This = HTMLDOC_THIS(iface);
654     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
655     return E_NOTIMPL;
656 }
657
658 static HRESULT WINAPI HTMLDocument_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p)
659 {
660     HTMLDocument *This = HTMLDOC_THIS(iface);
661     FIXME("(%p)->(%p)\n", This, p);
662     return E_NOTIMPL;
663 }
664
665 static HRESULT WINAPI HTMLDocument_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
666 {
667     HTMLDocument *This = HTMLDOC_THIS(iface);
668     FIXME("(%p)->(%p)\n", This, p);
669     return E_NOTIMPL;
670 }
671
672 static HRESULT WINAPI HTMLDocument_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
673 {
674     HTMLDocument *This = HTMLDOC_THIS(iface);
675     FIXME("(%p)->(%p)\n", This, p);
676     return E_NOTIMPL;
677 }
678
679 static HRESULT WINAPI HTMLDocument_get_fileCreatedDate(IHTMLDocument2 *iface, BSTR *p)
680 {
681     HTMLDocument *This = HTMLDOC_THIS(iface);
682     FIXME("(%p)->(%p)\n", This, p);
683     return E_NOTIMPL;
684 }
685
686 static HRESULT WINAPI HTMLDocument_get_fileModifiedDate(IHTMLDocument2 *iface, BSTR *p)
687 {
688     HTMLDocument *This = HTMLDOC_THIS(iface);
689     FIXME("(%p)->(%p)\n", This, p);
690     return E_NOTIMPL;
691 }
692
693 static HRESULT WINAPI HTMLDocument_get_fileUpdatedDate(IHTMLDocument2 *iface, BSTR *p)
694 {
695     HTMLDocument *This = HTMLDOC_THIS(iface);
696     FIXME("(%p)->(%p)\n", This, p);
697     return E_NOTIMPL;
698 }
699
700 static HRESULT WINAPI HTMLDocument_get_security(IHTMLDocument2 *iface, BSTR *p)
701 {
702     HTMLDocument *This = HTMLDOC_THIS(iface);
703     FIXME("(%p)->(%p)\n", This, p);
704     return E_NOTIMPL;
705 }
706
707 static HRESULT WINAPI HTMLDocument_get_protocol(IHTMLDocument2 *iface, BSTR *p)
708 {
709     HTMLDocument *This = HTMLDOC_THIS(iface);
710     FIXME("(%p)->(%p)\n", This, p);
711     return E_NOTIMPL;
712 }
713
714 static HRESULT WINAPI HTMLDocument_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
715 {
716     HTMLDocument *This = HTMLDOC_THIS(iface);
717     FIXME("(%p)->(%p)\n", This, p);
718     return E_NOTIMPL;
719 }
720
721 static HRESULT document_write(HTMLDocument *This, SAFEARRAY *psarray, BOOL ln)
722 {
723     nsAString nsstr;
724     VARIANT *var;
725     ULONG i, argc;
726     nsresult nsres;
727     HRESULT hres;
728
729     if(!This->nsdoc) {
730         WARN("NULL nsdoc\n");
731         return E_UNEXPECTED;
732     }
733
734     if(psarray->cDims != 1) {
735         FIXME("cDims=%d\n", psarray->cDims);
736         return E_INVALIDARG;
737     }
738
739     hres = SafeArrayAccessData(psarray, (void**)&var);
740     if(FAILED(hres)) {
741         WARN("SafeArrayAccessData failed: %08x\n", hres);
742         return hres;
743     }
744
745     nsAString_Init(&nsstr, NULL);
746
747     argc = psarray->rgsabound[0].cElements;
748     for(i=0; i < argc; i++) {
749         if(V_VT(var+i) == VT_BSTR) {
750             nsAString_SetData(&nsstr, V_BSTR(var+i));
751             if(!ln || i != argc-1)
752                 nsres = nsIDOMHTMLDocument_Write(This->nsdoc, &nsstr);
753             else
754                 nsres = nsIDOMHTMLDocument_Writeln(This->nsdoc, &nsstr);
755             if(NS_FAILED(nsres))
756                 ERR("Write failed: %08x\n", nsres);
757         }else {
758             FIXME("vt=%d\n", V_VT(var+i));
759         }
760     }
761
762     nsAString_Finish(&nsstr);
763     SafeArrayUnaccessData(psarray);
764
765     return S_OK;
766 }
767
768 static HRESULT WINAPI HTMLDocument_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
769 {
770     HTMLDocument *This = HTMLDOC_THIS(iface);
771
772     TRACE("(%p)->(%p)\n", iface, psarray);
773
774     return document_write(This, psarray, FALSE);
775 }
776
777 static HRESULT WINAPI HTMLDocument_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
778 {
779     HTMLDocument *This = HTMLDOC_THIS(iface);
780
781     TRACE("(%p)->(%p)\n", This, psarray);
782
783     return document_write(This, psarray, TRUE);
784 }
785
786 static HRESULT WINAPI HTMLDocument_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
787                         VARIANT features, VARIANT replace, IDispatch **pomWindowResult)
788 {
789     HTMLDocument *This = HTMLDOC_THIS(iface);
790     nsresult nsres;
791
792     static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};
793
794     TRACE("(%p)->(%s %s %s %s %p)\n", This, debugstr_w(url), debugstr_variant(&name),
795           debugstr_variant(&features), debugstr_variant(&replace), pomWindowResult);
796
797     if(!This->nsdoc) {
798         ERR("!nsdoc\n");
799         return E_NOTIMPL;
800     }
801
802     if(!url || strcmpW(url, text_htmlW) || V_VT(&name) != VT_ERROR
803        || V_VT(&features) != VT_ERROR || V_VT(&replace) != VT_ERROR)
804         FIXME("unsupported args\n");
805
806     nsres = nsIDOMHTMLDocument_Open(This->nsdoc);
807     if(NS_FAILED(nsres)) {
808         ERR("Open failed: %08x\n", nsres);
809         return E_FAIL;
810     }
811
812     *pomWindowResult = (IDispatch*)HTMLWINDOW2(This->window);
813     IHTMLWindow2_AddRef(HTMLWINDOW2(This->window));
814     return S_OK;
815 }
816
817 static HRESULT WINAPI HTMLDocument_close(IHTMLDocument2 *iface)
818 {
819     HTMLDocument *This = HTMLDOC_THIS(iface);
820     nsresult nsres;
821
822     TRACE("(%p)\n", This);
823
824     if(!This->nsdoc) {
825         ERR("!nsdoc\n");
826         return E_NOTIMPL;
827     }
828
829     nsres = nsIDOMHTMLDocument_Close(This->nsdoc);
830     if(NS_FAILED(nsres)) {
831         ERR("Close failed: %08x\n", nsres);
832         return E_FAIL;
833     }
834
835     return S_OK;
836 }
837
838 static HRESULT WINAPI HTMLDocument_clear(IHTMLDocument2 *iface)
839 {
840     HTMLDocument *This = HTMLDOC_THIS(iface);
841     FIXME("(%p)\n", This);
842     return E_NOTIMPL;
843 }
844
845 static HRESULT WINAPI HTMLDocument_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID,
846                                                         VARIANT_BOOL *pfRet)
847 {
848     HTMLDocument *This = HTMLDOC_THIS(iface);
849     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
850     return E_NOTIMPL;
851 }
852
853 static HRESULT WINAPI HTMLDocument_queryCommandEnabled(IHTMLDocument2 *iface, BSTR cmdID,
854                                                         VARIANT_BOOL *pfRet)
855 {
856     HTMLDocument *This = HTMLDOC_THIS(iface);
857     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
858     return E_NOTIMPL;
859 }
860
861 static HRESULT WINAPI HTMLDocument_queryCommandState(IHTMLDocument2 *iface, BSTR cmdID,
862                                                         VARIANT_BOOL *pfRet)
863 {
864     HTMLDocument *This = HTMLDOC_THIS(iface);
865     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
866     return E_NOTIMPL;
867 }
868
869 static HRESULT WINAPI HTMLDocument_queryCommandIndeterm(IHTMLDocument2 *iface, BSTR cmdID,
870                                                         VARIANT_BOOL *pfRet)
871 {
872     HTMLDocument *This = HTMLDOC_THIS(iface);
873     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
874     return E_NOTIMPL;
875 }
876
877 static HRESULT WINAPI HTMLDocument_queryCommandText(IHTMLDocument2 *iface, BSTR cmdID,
878                                                         BSTR *pfRet)
879 {
880     HTMLDocument *This = HTMLDOC_THIS(iface);
881     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
882     return E_NOTIMPL;
883 }
884
885 static HRESULT WINAPI HTMLDocument_queryCommandValue(IHTMLDocument2 *iface, BSTR cmdID,
886                                                         VARIANT *pfRet)
887 {
888     HTMLDocument *This = HTMLDOC_THIS(iface);
889     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
890     return E_NOTIMPL;
891 }
892
893 static HRESULT WINAPI HTMLDocument_execCommand(IHTMLDocument2 *iface, BSTR cmdID,
894                                 VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
895 {
896     HTMLDocument *This = HTMLDOC_THIS(iface);
897     FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(cmdID), showUI, pfRet);
898     return E_NOTIMPL;
899 }
900
901 static HRESULT WINAPI HTMLDocument_execCommandShowHelp(IHTMLDocument2 *iface, BSTR cmdID,
902                                                         VARIANT_BOOL *pfRet)
903 {
904     HTMLDocument *This = HTMLDOC_THIS(iface);
905     FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
906     return E_NOTIMPL;
907 }
908
909 static HRESULT WINAPI HTMLDocument_createElement(IHTMLDocument2 *iface, BSTR eTag,
910                                                  IHTMLElement **newElem)
911 {
912     HTMLDocument *This = HTMLDOC_THIS(iface);
913     nsIDOMElement *nselem;
914     HTMLElement *elem;
915     nsAString tag_str;
916     nsresult nsres;
917
918     TRACE("(%p)->(%s %p)\n", This, debugstr_w(eTag), newElem);
919
920     if(!This->nsdoc) {
921         WARN("NULL nsdoc\n");
922         return E_UNEXPECTED;
923     }
924
925     nsAString_Init(&tag_str, eTag);
926     nsres = nsIDOMDocument_CreateElement(This->nsdoc, &tag_str, &nselem);
927     nsAString_Finish(&tag_str);
928     if(NS_FAILED(nsres)) {
929         ERR("CreateElement failed: %08x\n", nsres);
930         return E_FAIL;
931     }
932
933     elem = HTMLElement_Create(This, (nsIDOMNode*)nselem, TRUE);
934     nsIDOMElement_Release(nselem);
935
936     *newElem = HTMLELEM(elem);
937     IHTMLElement_AddRef(HTMLELEM(elem));
938     return S_OK;
939 }
940
941 static HRESULT WINAPI HTMLDocument_put_onhelp(IHTMLDocument2 *iface, VARIANT v)
942 {
943     HTMLDocument *This = HTMLDOC_THIS(iface);
944     FIXME("(%p)\n", This);
945     return E_NOTIMPL;
946 }
947
948 static HRESULT WINAPI HTMLDocument_get_onhelp(IHTMLDocument2 *iface, VARIANT *p)
949 {
950     HTMLDocument *This = HTMLDOC_THIS(iface);
951     FIXME("(%p)->(%p)\n", This, p);
952     return E_NOTIMPL;
953 }
954
955 static HRESULT WINAPI HTMLDocument_put_onclick(IHTMLDocument2 *iface, VARIANT v)
956 {
957     HTMLDocument *This = HTMLDOC_THIS(iface);
958
959     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
960
961     return set_doc_event(This, EVENTID_CLICK, &v);
962 }
963
964 static HRESULT WINAPI HTMLDocument_get_onclick(IHTMLDocument2 *iface, VARIANT *p)
965 {
966     HTMLDocument *This = HTMLDOC_THIS(iface);
967
968     TRACE("(%p)->(%p)\n", This, p);
969
970     return get_doc_event(This, EVENTID_CLICK, p);
971 }
972
973 static HRESULT WINAPI HTMLDocument_put_ondblclick(IHTMLDocument2 *iface, VARIANT v)
974 {
975     HTMLDocument *This = HTMLDOC_THIS(iface);
976     FIXME("(%p)\n", This);
977     return E_NOTIMPL;
978 }
979
980 static HRESULT WINAPI HTMLDocument_get_ondblclick(IHTMLDocument2 *iface, VARIANT *p)
981 {
982     HTMLDocument *This = HTMLDOC_THIS(iface);
983     FIXME("(%p)->(%p)\n", This, p);
984     return E_NOTIMPL;
985 }
986
987 static HRESULT WINAPI HTMLDocument_put_onkeyup(IHTMLDocument2 *iface, VARIANT v)
988 {
989     HTMLDocument *This = HTMLDOC_THIS(iface);
990
991     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
992
993     return set_doc_event(This, EVENTID_KEYUP, &v);
994 }
995
996 static HRESULT WINAPI HTMLDocument_get_onkeyup(IHTMLDocument2 *iface, VARIANT *p)
997 {
998     HTMLDocument *This = HTMLDOC_THIS(iface);
999
1000     TRACE("(%p)->(%p)\n", This, p);
1001
1002     return get_doc_event(This, EVENTID_KEYUP, p);
1003 }
1004
1005 static HRESULT WINAPI HTMLDocument_put_onkeydown(IHTMLDocument2 *iface, VARIANT v)
1006 {
1007     HTMLDocument *This = HTMLDOC_THIS(iface);
1008
1009     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1010
1011     return set_doc_event(This, EVENTID_KEYDOWN, &v);
1012 }
1013
1014 static HRESULT WINAPI HTMLDocument_get_onkeydown(IHTMLDocument2 *iface, VARIANT *p)
1015 {
1016     HTMLDocument *This = HTMLDOC_THIS(iface);
1017
1018     TRACE("(%p)->(%p)\n", This, p);
1019
1020     return get_doc_event(This, EVENTID_KEYDOWN, p);
1021 }
1022
1023 static HRESULT WINAPI HTMLDocument_put_onkeypress(IHTMLDocument2 *iface, VARIANT v)
1024 {
1025     HTMLDocument *This = HTMLDOC_THIS(iface);
1026     FIXME("(%p)\n", This);
1027     return E_NOTIMPL;
1028 }
1029
1030 static HRESULT WINAPI HTMLDocument_get_onkeypress(IHTMLDocument2 *iface, VARIANT *p)
1031 {
1032     HTMLDocument *This = HTMLDOC_THIS(iface);
1033     FIXME("(%p)->(%p)\n", This, p);
1034     return E_NOTIMPL;
1035 }
1036
1037 static HRESULT WINAPI HTMLDocument_put_onmouseup(IHTMLDocument2 *iface, VARIANT v)
1038 {
1039     HTMLDocument *This = HTMLDOC_THIS(iface);
1040     FIXME("(%p)\n", This);
1041     return E_NOTIMPL;
1042 }
1043
1044 static HRESULT WINAPI HTMLDocument_get_onmouseup(IHTMLDocument2 *iface, VARIANT *p)
1045 {
1046     HTMLDocument *This = HTMLDOC_THIS(iface);
1047     FIXME("(%p)->(%p)\n", This, p);
1048     return E_NOTIMPL;
1049 }
1050
1051 static HRESULT WINAPI HTMLDocument_put_onmousedown(IHTMLDocument2 *iface, VARIANT v)
1052 {
1053     HTMLDocument *This = HTMLDOC_THIS(iface);
1054     FIXME("(%p)\n", This);
1055     return E_NOTIMPL;
1056 }
1057
1058 static HRESULT WINAPI HTMLDocument_get_onmousedown(IHTMLDocument2 *iface, VARIANT *p)
1059 {
1060     HTMLDocument *This = HTMLDOC_THIS(iface);
1061     FIXME("(%p)->(%p)\n", This, p);
1062     return E_NOTIMPL;
1063 }
1064
1065 static HRESULT WINAPI HTMLDocument_put_onmousemove(IHTMLDocument2 *iface, VARIANT v)
1066 {
1067     HTMLDocument *This = HTMLDOC_THIS(iface);
1068     FIXME("(%p)\n", This);
1069     return E_NOTIMPL;
1070 }
1071
1072 static HRESULT WINAPI HTMLDocument_get_onmousemove(IHTMLDocument2 *iface, VARIANT *p)
1073 {
1074     HTMLDocument *This = HTMLDOC_THIS(iface);
1075     FIXME("(%p)->(%p)\n", This, p);
1076     return E_NOTIMPL;
1077 }
1078
1079 static HRESULT WINAPI HTMLDocument_put_onmouseout(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_onmouseout(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_onmouseover(IHTMLDocument2 *iface, VARIANT v)
1094 {
1095     HTMLDocument *This = HTMLDOC_THIS(iface);
1096
1097     TRACE("(%p)\n", This);
1098
1099     return set_doc_event(This, EVENTID_MOUSEOVER, &v);
1100 }
1101
1102 static HRESULT WINAPI HTMLDocument_get_onmouseover(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_MOUSEOVER, p);
1109 }
1110
1111 static HRESULT WINAPI HTMLDocument_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v)
1112 {
1113     HTMLDocument *This = HTMLDOC_THIS(iface);
1114     FIXME("(%p)\n", This);
1115     return E_NOTIMPL;
1116 }
1117
1118 static HRESULT WINAPI HTMLDocument_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p)
1119 {
1120     HTMLDocument *This = HTMLDOC_THIS(iface);
1121     FIXME("(%p)->(%p)\n", This, p);
1122     return E_NOTIMPL;
1123 }
1124
1125 static HRESULT WINAPI HTMLDocument_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v)
1126 {
1127     HTMLDocument *This = HTMLDOC_THIS(iface);
1128     FIXME("(%p)\n", This);
1129     return E_NOTIMPL;
1130 }
1131
1132 static HRESULT WINAPI HTMLDocument_get_onafterupdate(IHTMLDocument2 *iface, VARIANT *p)
1133 {
1134     HTMLDocument *This = HTMLDOC_THIS(iface);
1135     FIXME("(%p)->(%p)\n", This, p);
1136     return E_NOTIMPL;
1137 }
1138
1139 static HRESULT WINAPI HTMLDocument_put_onrowexit(IHTMLDocument2 *iface, VARIANT v)
1140 {
1141     HTMLDocument *This = HTMLDOC_THIS(iface);
1142     FIXME("(%p)\n", This);
1143     return E_NOTIMPL;
1144 }
1145
1146 static HRESULT WINAPI HTMLDocument_get_onrowexit(IHTMLDocument2 *iface, VARIANT *p)
1147 {
1148     HTMLDocument *This = HTMLDOC_THIS(iface);
1149     FIXME("(%p)->(%p)\n", This, p);
1150     return E_NOTIMPL;
1151 }
1152
1153 static HRESULT WINAPI HTMLDocument_put_onrowenter(IHTMLDocument2 *iface, VARIANT v)
1154 {
1155     HTMLDocument *This = HTMLDOC_THIS(iface);
1156     FIXME("(%p)\n", This);
1157     return E_NOTIMPL;
1158 }
1159
1160 static HRESULT WINAPI HTMLDocument_get_onrowenter(IHTMLDocument2 *iface, VARIANT *p)
1161 {
1162     HTMLDocument *This = HTMLDOC_THIS(iface);
1163     FIXME("(%p)->(%p)\n", This, p);
1164     return E_NOTIMPL;
1165 }
1166
1167 static HRESULT WINAPI HTMLDocument_put_ondragstart(IHTMLDocument2 *iface, VARIANT v)
1168 {
1169     HTMLDocument *This = HTMLDOC_THIS(iface);
1170
1171     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1172
1173     return set_doc_event(This, EVENTID_DRAGSTART, &v);
1174 }
1175
1176 static HRESULT WINAPI HTMLDocument_get_ondragstart(IHTMLDocument2 *iface, VARIANT *p)
1177 {
1178     HTMLDocument *This = HTMLDOC_THIS(iface);
1179
1180     TRACE("(%p)->(%p)\n", This, p);
1181
1182     return get_doc_event(This, EVENTID_DRAGSTART, p);
1183 }
1184
1185 static HRESULT WINAPI HTMLDocument_put_onselectstart(IHTMLDocument2 *iface, VARIANT v)
1186 {
1187     HTMLDocument *This = HTMLDOC_THIS(iface);
1188
1189     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1190
1191     return set_doc_event(This, EVENTID_SELECTSTART, &v);
1192 }
1193
1194 static HRESULT WINAPI HTMLDocument_get_onselectstart(IHTMLDocument2 *iface, VARIANT *p)
1195 {
1196     HTMLDocument *This = HTMLDOC_THIS(iface);
1197
1198     TRACE("(%p)->(%p)\n", This, p);
1199
1200     return get_doc_event(This, EVENTID_SELECTSTART, p);
1201 }
1202
1203 static HRESULT WINAPI HTMLDocument_elementFromPoint(IHTMLDocument2 *iface, LONG x, LONG y,
1204                                                         IHTMLElement **elementHit)
1205 {
1206     HTMLDocument *This = HTMLDOC_THIS(iface);
1207     FIXME("(%p)->(%d %d %p)\n", This, x, y, elementHit);
1208     return E_NOTIMPL;
1209 }
1210
1211 static HRESULT WINAPI HTMLDocument_get_parentWindow(IHTMLDocument2 *iface, IHTMLWindow2 **p)
1212 {
1213     HTMLDocument *This = HTMLDOC_THIS(iface);
1214
1215     TRACE("(%p)->(%p)\n", This, p);
1216
1217     *p = HTMLWINDOW2(This->window);
1218     IHTMLWindow2_AddRef(*p);
1219     return S_OK;
1220 }
1221
1222 static HRESULT WINAPI HTMLDocument_get_styleSheets(IHTMLDocument2 *iface,
1223                                                    IHTMLStyleSheetsCollection **p)
1224 {
1225     HTMLDocument *This = HTMLDOC_THIS(iface);
1226     nsIDOMStyleSheetList *nsstylelist;
1227     nsIDOMDocumentStyle *nsdocstyle;
1228     nsresult nsres;
1229
1230     TRACE("(%p)->(%p)\n", This, p);
1231
1232     *p = NULL;
1233
1234     if(!This->nsdoc) {
1235         WARN("NULL nsdoc\n");
1236         return E_UNEXPECTED;
1237     }
1238
1239     nsIDOMHTMLDocument_QueryInterface(This->nsdoc, &IID_nsIDOMDocumentStyle, (void**)&nsdocstyle);
1240     nsres = nsIDOMDocumentStyle_GetStyleSheets(nsdocstyle, &nsstylelist);
1241     nsIDOMDocumentStyle_Release(nsdocstyle);
1242     if(NS_FAILED(nsres)) {
1243         ERR("GetStyleSheets failed: %08x\n", nsres);
1244         return E_FAIL;
1245     }
1246
1247     *p = HTMLStyleSheetsCollection_Create(nsstylelist);
1248     nsIDOMDocumentStyle_Release(nsstylelist);
1249
1250     return S_OK;
1251 }
1252
1253 static HRESULT WINAPI HTMLDocument_put_onbeforeupdate(IHTMLDocument2 *iface, VARIANT v)
1254 {
1255     HTMLDocument *This = HTMLDOC_THIS(iface);
1256     FIXME("(%p)\n", This);
1257     return E_NOTIMPL;
1258 }
1259
1260 static HRESULT WINAPI HTMLDocument_get_onbeforeupdate(IHTMLDocument2 *iface, VARIANT *p)
1261 {
1262     HTMLDocument *This = HTMLDOC_THIS(iface);
1263     FIXME("(%p)->(%p)\n", This, p);
1264     return E_NOTIMPL;
1265 }
1266
1267 static HRESULT WINAPI HTMLDocument_put_onerrorupdate(IHTMLDocument2 *iface, VARIANT v)
1268 {
1269     HTMLDocument *This = HTMLDOC_THIS(iface);
1270     FIXME("(%p)\n", This);
1271     return E_NOTIMPL;
1272 }
1273
1274 static HRESULT WINAPI HTMLDocument_get_onerrorupdate(IHTMLDocument2 *iface, VARIANT *p)
1275 {
1276     HTMLDocument *This = HTMLDOC_THIS(iface);
1277     FIXME("(%p)->(%p)\n", This, p);
1278     return E_NOTIMPL;
1279 }
1280
1281 static HRESULT WINAPI HTMLDocument_toString(IHTMLDocument2 *iface, BSTR *String)
1282 {
1283     HTMLDocument *This = HTMLDOC_THIS(iface);
1284     FIXME("(%p)->(%p)\n", This, String);
1285     return E_NOTIMPL;
1286 }
1287
1288 static HRESULT WINAPI HTMLDocument_createStyleSheet(IHTMLDocument2 *iface, BSTR bstrHref,
1289                                             LONG lIndex, IHTMLStyleSheet **ppnewStyleSheet)
1290 {
1291     HTMLDocument *This = HTMLDOC_THIS(iface);
1292
1293     FIXME("(%p)->(%s %d %p) semi-stub\n", This, debugstr_w(bstrHref), lIndex, ppnewStyleSheet);
1294
1295     *ppnewStyleSheet = HTMLStyleSheet_Create(NULL);
1296     return S_OK;
1297 }
1298
1299 static const IHTMLDocument2Vtbl HTMLDocumentVtbl = {
1300     HTMLDocument_QueryInterface,
1301     HTMLDocument_AddRef,
1302     HTMLDocument_Release,
1303     HTMLDocument_GetTypeInfoCount,
1304     HTMLDocument_GetTypeInfo,
1305     HTMLDocument_GetIDsOfNames,
1306     HTMLDocument_Invoke,
1307     HTMLDocument_get_Script,
1308     HTMLDocument_get_all,
1309     HTMLDocument_get_body,
1310     HTMLDocument_get_activeElement,
1311     HTMLDocument_get_images,
1312     HTMLDocument_get_applets,
1313     HTMLDocument_get_links,
1314     HTMLDocument_get_forms,
1315     HTMLDocument_get_anchors,
1316     HTMLDocument_put_title,
1317     HTMLDocument_get_title,
1318     HTMLDocument_get_scripts,
1319     HTMLDocument_put_designMode,
1320     HTMLDocument_get_designMode,
1321     HTMLDocument_get_selection,
1322     HTMLDocument_get_readyState,
1323     HTMLDocument_get_frames,
1324     HTMLDocument_get_embeds,
1325     HTMLDocument_get_plugins,
1326     HTMLDocument_put_alinkColor,
1327     HTMLDocument_get_alinkColor,
1328     HTMLDocument_put_bgColor,
1329     HTMLDocument_get_bgColor,
1330     HTMLDocument_put_fgColor,
1331     HTMLDocument_get_fgColor,
1332     HTMLDocument_put_linkColor,
1333     HTMLDocument_get_linkColor,
1334     HTMLDocument_put_vlinkColor,
1335     HTMLDocument_get_vlinkColor,
1336     HTMLDocument_get_referrer,
1337     HTMLDocument_get_location,
1338     HTMLDocument_get_lastModified,
1339     HTMLDocument_put_URL,
1340     HTMLDocument_get_URL,
1341     HTMLDocument_put_domain,
1342     HTMLDocument_get_domain,
1343     HTMLDocument_put_cookie,
1344     HTMLDocument_get_cookie,
1345     HTMLDocument_put_expando,
1346     HTMLDocument_get_expando,
1347     HTMLDocument_put_charset,
1348     HTMLDocument_get_charset,
1349     HTMLDocument_put_defaultCharset,
1350     HTMLDocument_get_defaultCharset,
1351     HTMLDocument_get_mimeType,
1352     HTMLDocument_get_fileSize,
1353     HTMLDocument_get_fileCreatedDate,
1354     HTMLDocument_get_fileModifiedDate,
1355     HTMLDocument_get_fileUpdatedDate,
1356     HTMLDocument_get_security,
1357     HTMLDocument_get_protocol,
1358     HTMLDocument_get_nameProp,
1359     HTMLDocument_write,
1360     HTMLDocument_writeln,
1361     HTMLDocument_open,
1362     HTMLDocument_close,
1363     HTMLDocument_clear,
1364     HTMLDocument_queryCommandSupported,
1365     HTMLDocument_queryCommandEnabled,
1366     HTMLDocument_queryCommandState,
1367     HTMLDocument_queryCommandIndeterm,
1368     HTMLDocument_queryCommandText,
1369     HTMLDocument_queryCommandValue,
1370     HTMLDocument_execCommand,
1371     HTMLDocument_execCommandShowHelp,
1372     HTMLDocument_createElement,
1373     HTMLDocument_put_onhelp,
1374     HTMLDocument_get_onhelp,
1375     HTMLDocument_put_onclick,
1376     HTMLDocument_get_onclick,
1377     HTMLDocument_put_ondblclick,
1378     HTMLDocument_get_ondblclick,
1379     HTMLDocument_put_onkeyup,
1380     HTMLDocument_get_onkeyup,
1381     HTMLDocument_put_onkeydown,
1382     HTMLDocument_get_onkeydown,
1383     HTMLDocument_put_onkeypress,
1384     HTMLDocument_get_onkeypress,
1385     HTMLDocument_put_onmouseup,
1386     HTMLDocument_get_onmouseup,
1387     HTMLDocument_put_onmousedown,
1388     HTMLDocument_get_onmousedown,
1389     HTMLDocument_put_onmousemove,
1390     HTMLDocument_get_onmousemove,
1391     HTMLDocument_put_onmouseout,
1392     HTMLDocument_get_onmouseout,
1393     HTMLDocument_put_onmouseover,
1394     HTMLDocument_get_onmouseover,
1395     HTMLDocument_put_onreadystatechange,
1396     HTMLDocument_get_onreadystatechange,
1397     HTMLDocument_put_onafterupdate,
1398     HTMLDocument_get_onafterupdate,
1399     HTMLDocument_put_onrowexit,
1400     HTMLDocument_get_onrowexit,
1401     HTMLDocument_put_onrowenter,
1402     HTMLDocument_get_onrowenter,
1403     HTMLDocument_put_ondragstart,
1404     HTMLDocument_get_ondragstart,
1405     HTMLDocument_put_onselectstart,
1406     HTMLDocument_get_onselectstart,
1407     HTMLDocument_elementFromPoint,
1408     HTMLDocument_get_parentWindow,
1409     HTMLDocument_get_styleSheets,
1410     HTMLDocument_put_onbeforeupdate,
1411     HTMLDocument_get_onbeforeupdate,
1412     HTMLDocument_put_onerrorupdate,
1413     HTMLDocument_get_onerrorupdate,
1414     HTMLDocument_toString,
1415     HTMLDocument_createStyleSheet
1416 };
1417
1418 #define SUPPINFO_THIS(iface) DEFINE_THIS(HTMLDocument, SupportErrorInfo, iface)
1419
1420 static HRESULT WINAPI SupportErrorInfo_QueryInterface(ISupportErrorInfo *iface, REFIID riid, void **ppv)
1421 {
1422     HTMLDocument *This = SUPPINFO_THIS(iface);
1423     return IHTMLDocument_QueryInterface(HTMLDOC(This), riid, ppv);
1424 }
1425
1426 static ULONG WINAPI SupportErrorInfo_AddRef(ISupportErrorInfo *iface)
1427 {
1428     HTMLDocument *This = SUPPINFO_THIS(iface);
1429     return IHTMLDocument_AddRef(HTMLDOC(This));
1430 }
1431
1432 static ULONG WINAPI SupportErrorInfo_Release(ISupportErrorInfo *iface)
1433 {
1434     HTMLDocument *This = SUPPINFO_THIS(iface);
1435     return IHTMLDocument_Release(HTMLDOC(This));
1436 }
1437
1438 static HRESULT WINAPI SupportErrorInfo_InterfaceSupportsErrorInfo(ISupportErrorInfo *iface, REFIID riid)
1439 {
1440     FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
1441     return S_FALSE;
1442 }
1443
1444 static const ISupportErrorInfoVtbl SupportErrorInfoVtbl = {
1445     SupportErrorInfo_QueryInterface,
1446     SupportErrorInfo_AddRef,
1447     SupportErrorInfo_Release,
1448     SupportErrorInfo_InterfaceSupportsErrorInfo
1449 };
1450
1451 #define DISPEX_THIS(iface) DEFINE_THIS(HTMLDocument, IDispatchEx, iface)
1452
1453 static HRESULT WINAPI DocDispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
1454 {
1455     HTMLDocument *This = DISPEX_THIS(iface);
1456
1457     return IHTMLDocument2_QueryInterface(HTMLDOC(This), riid, ppv);
1458 }
1459
1460 static ULONG WINAPI DocDispatchEx_AddRef(IDispatchEx *iface)
1461 {
1462     HTMLDocument *This = DISPEX_THIS(iface);
1463
1464     return IHTMLDocument2_AddRef(HTMLDOC(This));
1465 }
1466
1467 static ULONG WINAPI DocDispatchEx_Release(IDispatchEx *iface)
1468 {
1469     HTMLDocument *This = DISPEX_THIS(iface);
1470
1471     return IHTMLDocument2_Release(HTMLDOC(This));
1472 }
1473
1474 static HRESULT WINAPI DocDispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
1475 {
1476     HTMLDocument *This = DISPEX_THIS(iface);
1477
1478     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo);
1479 }
1480
1481 static HRESULT WINAPI DocDispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
1482                                                LCID lcid, ITypeInfo **ppTInfo)
1483 {
1484     HTMLDocument *This = DISPEX_THIS(iface);
1485
1486     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo);
1487 }
1488
1489 static HRESULT WINAPI DocDispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
1490                                                  LPOLESTR *rgszNames, UINT cNames,
1491                                                  LCID lcid, DISPID *rgDispId)
1492 {
1493     HTMLDocument *This = DISPEX_THIS(iface);
1494
1495     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId);
1496 }
1497
1498 static HRESULT WINAPI DocDispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
1499                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1500                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1501 {
1502     HTMLDocument *This = DISPEX_THIS(iface);
1503
1504     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
1505           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
1506
1507     switch(dispIdMember) {
1508     case DISPID_READYSTATE:
1509         TRACE("DISPID_READYSTATE\n");
1510
1511         if(!(wFlags & DISPATCH_PROPERTYGET))
1512             return E_INVALIDARG;
1513
1514         V_VT(pVarResult) = VT_I4;
1515         V_I4(pVarResult) = This->readystate;
1516         return S_OK;
1517     }
1518
1519     return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, wFlags, pDispParams,
1520                               pVarResult, pExcepInfo, puArgErr);
1521 }
1522
1523 static HRESULT WINAPI DocDispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
1524 {
1525     HTMLDocument *This = DISPEX_THIS(iface);
1526
1527     return IDispatchEx_GetDispID(DISPATCHEX(&This->dispex), bstrName, grfdex, pid);
1528 }
1529
1530 static HRESULT WINAPI DocDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
1531         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
1532 {
1533     HTMLDocument *This = DISPEX_THIS(iface);
1534
1535     return IDispatchEx_InvokeEx(DISPATCHEX(&This->dispex), id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1536 }
1537
1538 static HRESULT WINAPI DocDispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
1539 {
1540     HTMLDocument *This = DISPEX_THIS(iface);
1541
1542     return IDispatchEx_DeleteMemberByName(DISPATCHEX(&This->dispex), bstrName, grfdex);
1543 }
1544
1545 static HRESULT WINAPI DocDispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
1546 {
1547     HTMLDocument *This = DISPEX_THIS(iface);
1548
1549     return IDispatchEx_DeleteMemberByDispID(DISPATCHEX(&This->dispex), id);
1550 }
1551
1552 static HRESULT WINAPI DocDispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
1553 {
1554     HTMLDocument *This = DISPEX_THIS(iface);
1555
1556     return IDispatchEx_GetMemberProperties(DISPATCHEX(&This->dispex), id, grfdexFetch, pgrfdex);
1557 }
1558
1559 static HRESULT WINAPI DocDispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
1560 {
1561     HTMLDocument *This = DISPEX_THIS(iface);
1562
1563     return IDispatchEx_GetMemberName(DISPATCHEX(&This->dispex), id, pbstrName);
1564 }
1565
1566 static HRESULT WINAPI DocDispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
1567 {
1568     HTMLDocument *This = DISPEX_THIS(iface);
1569
1570     return IDispatchEx_GetNextDispID(DISPATCHEX(&This->dispex), grfdex, id, pid);
1571 }
1572
1573 static HRESULT WINAPI DocDispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
1574 {
1575     HTMLDocument *This = DISPEX_THIS(iface);
1576
1577     return IDispatchEx_GetNameSpaceParent(DISPATCHEX(&This->dispex), ppunk);
1578 }
1579
1580 #undef DISPEX_THIS
1581
1582 static const IDispatchExVtbl DocDispatchExVtbl = {
1583     DocDispatchEx_QueryInterface,
1584     DocDispatchEx_AddRef,
1585     DocDispatchEx_Release,
1586     DocDispatchEx_GetTypeInfoCount,
1587     DocDispatchEx_GetTypeInfo,
1588     DocDispatchEx_GetIDsOfNames,
1589     DocDispatchEx_Invoke,
1590     DocDispatchEx_GetDispID,
1591     DocDispatchEx_InvokeEx,
1592     DocDispatchEx_DeleteMemberByName,
1593     DocDispatchEx_DeleteMemberByDispID,
1594     DocDispatchEx_GetMemberProperties,
1595     DocDispatchEx_GetMemberName,
1596     DocDispatchEx_GetNextDispID,
1597     DocDispatchEx_GetNameSpaceParent
1598 };
1599
1600 static HRESULT htmldoc_qi(HTMLDocument *This, REFIID riid, void **ppv)
1601 {
1602     *ppv = NULL;
1603
1604     if(IsEqualGUID(&IID_IUnknown, riid)) {
1605         TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv);
1606         *ppv = HTMLDOC(This);
1607     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
1608         TRACE("(%p)->(IID_IDispatch, %p)\n", This, ppv);
1609         *ppv = DISPATCHEX(This);
1610     }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
1611         TRACE("(%p)->(IID_IDispatchEx, %p)\n", This, ppv);
1612         *ppv = DISPATCHEX(This);
1613     }else if(IsEqualGUID(&IID_IHTMLDocument, riid)) {
1614         TRACE("(%p)->(IID_IHTMLDocument, %p)\n", This, ppv);
1615         *ppv = HTMLDOC(This);
1616     }else if(IsEqualGUID(&IID_IHTMLDocument2, riid)) {
1617         TRACE("(%p)->(IID_IHTMLDocument2, %p)\n", This, ppv);
1618         *ppv = HTMLDOC(This);
1619     }else if(IsEqualGUID(&IID_IHTMLDocument3, riid)) {
1620         TRACE("(%p)->(IID_IHTMLDocument3, %p)\n", This, ppv);
1621         *ppv = HTMLDOC3(This);
1622     }else if(IsEqualGUID(&IID_IHTMLDocument4, riid)) {
1623         TRACE("(%p)->(IID_IHTMLDocument4, %p)\n", This, ppv);
1624         *ppv = HTMLDOC4(This);
1625     }else if(IsEqualGUID(&IID_IHTMLDocument5, riid)) {
1626         TRACE("(%p)->(IID_IHTMLDocument5, %p)\n", This, ppv);
1627         *ppv = HTMLDOC5(This);
1628     }else if(IsEqualGUID(&IID_IPersist, riid)) {
1629         TRACE("(%p)->(IID_IPersist, %p)\n", This, ppv);
1630         *ppv = PERSIST(This);
1631     }else if(IsEqualGUID(&IID_IPersistMoniker, riid)) {
1632         TRACE("(%p)->(IID_IPersistMoniker, %p)\n", This, ppv);
1633         *ppv = PERSISTMON(This);
1634     }else if(IsEqualGUID(&IID_IPersistFile, riid)) {
1635         TRACE("(%p)->(IID_IPersistFile, %p)\n", This, ppv);
1636         *ppv = PERSISTFILE(This);
1637     }else if(IsEqualGUID(&IID_IMonikerProp, riid)) {
1638         TRACE("(%p)->(IID_IMonikerProp, %p)\n", This, ppv);
1639         *ppv = MONPROP(This);
1640     }else if(IsEqualGUID(&IID_IOleObject, riid)) {
1641         TRACE("(%p)->(IID_IOleObject, %p)\n", This, ppv);
1642         *ppv = OLEOBJ(This);
1643     }else if(IsEqualGUID(&IID_IOleDocument, riid)) {
1644         TRACE("(%p)->(IID_IOleDocument, %p)\n", This, ppv);
1645         *ppv = OLEDOC(This);
1646     }else if(IsEqualGUID(&IID_IOleDocumentView, riid)) {
1647         TRACE("(%p)->(IID_IOleDocumentView, %p)\n", This, ppv);
1648         *ppv = DOCVIEW(This);
1649     }else if(IsEqualGUID(&IID_IOleInPlaceActiveObject, riid)) {
1650         TRACE("(%p)->(IID_IOleInPlaceActiveObject, %p)\n", This, ppv);
1651         *ppv = ACTOBJ(This);
1652     }else if(IsEqualGUID(&IID_IViewObject, riid)) {
1653         TRACE("(%p)->(IID_IViewObject, %p)\n", This, ppv);
1654         *ppv = VIEWOBJ(This);
1655     }else if(IsEqualGUID(&IID_IViewObject2, riid)) {
1656         TRACE("(%p)->(IID_IViewObject2, %p)\n", This, ppv);
1657         *ppv = VIEWOBJ2(This);
1658     }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
1659         TRACE("(%p)->(IID_IOleWindow, %p)\n", This, ppv);
1660         *ppv = OLEWIN(This);
1661     }else if(IsEqualGUID(&IID_IOleInPlaceObject, riid)) {
1662         TRACE("(%p)->(IID_IOleInPlaceObject, %p)\n", This, ppv);
1663         *ppv = INPLACEOBJ(This);
1664     }else if(IsEqualGUID(&IID_IOleInPlaceObjectWindowless, riid)) {
1665         TRACE("(%p)->(IID_IOleInPlaceObjectWindowless, %p)\n", This, ppv);
1666         *ppv = INPLACEWIN(This);
1667     }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
1668         TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv);
1669         *ppv = SERVPROV(This);
1670     }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
1671         TRACE("(%p)->(IID_IOleCommandTarget, %p)\n", This, ppv);
1672         *ppv = CMDTARGET(This);
1673     }else if(IsEqualGUID(&IID_IOleControl, riid)) {
1674         TRACE("(%p)->(IID_IOleControl, %p)\n", This, ppv);
1675         *ppv = CONTROL(This);
1676     }else if(IsEqualGUID(&IID_IHlinkTarget, riid)) {
1677         TRACE("(%p)->(IID_IHlinkTarget, %p)\n", This, ppv);
1678         *ppv = HLNKTARGET(This);
1679     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
1680         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
1681         *ppv = CONPTCONT(&This->cp_container);
1682     }else if(IsEqualGUID(&IID_IPersistStreamInit, riid)) {
1683         TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
1684         *ppv = PERSTRINIT(This);
1685     }else if(IsEqualGUID(&IID_ICustomDoc, riid)) {
1686         TRACE("(%p)->(IID_ICustomDoc %p)\n", This, ppv);
1687         *ppv = CUSTOMDOC(This);
1688     }else if(IsEqualGUID(&DIID_DispHTMLDocument, riid)) {
1689         TRACE("(%p)->(DIID_DispHTMLDocument %p)\n", This, ppv);
1690         *ppv = HTMLDOC(This);
1691     }else if(IsEqualGUID(&IID_ISupportErrorInfo, riid)) {
1692         TRACE("(%p)->(IID_ISupportErrorInfo %p)\n", This, ppv);
1693         *ppv = SUPPERRINFO(This);
1694     }else if(IsEqualGUID(&IID_IPersistHistory, riid)) {
1695         TRACE("(%p)->(IID_IPersistHistory %p)\n", This, ppv);
1696         *ppv = PERSISTHIST(This);
1697     }else if(IsEqualGUID(&CLSID_CMarkup, riid)) {
1698         FIXME("(%p)->(CLSID_CMarkup %p)\n", This, ppv);
1699         return E_NOINTERFACE;
1700     }else if(IsEqualGUID(&IID_IRunnableObject, riid)) {
1701         TRACE("(%p)->(IID_IRunnableObject %p) returning NULL\n", This, ppv);
1702         return E_NOINTERFACE;
1703     }else if(IsEqualGUID(&IID_IPersistPropertyBag, riid)) {
1704         TRACE("(%p)->(IID_IPersistPropertyBag %p) returning NULL\n", This, ppv);
1705         return E_NOINTERFACE;
1706     }else if(IsEqualGUID(&IID_IMarshal, riid)) {
1707         TRACE("(%p)->(IID_IMarshal %p) returning NULL\n", This, ppv);
1708         return E_NOINTERFACE;
1709     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
1710         return *ppv ? S_OK : E_NOINTERFACE;
1711     }else {
1712         FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
1713         return E_NOINTERFACE;
1714     }
1715
1716     IUnknown_AddRef((IUnknown*)*ppv);
1717     return S_OK;
1718 }
1719
1720 static const tid_t HTMLDocument_iface_tids[] = {
1721     IHTMLDocument2_tid,
1722     IHTMLDocument3_tid,
1723     IHTMLDocument4_tid,
1724     IHTMLDocument5_tid,
1725     0
1726 };
1727 static dispex_static_data_t HTMLDocument_dispex = {
1728     NULL,
1729     DispHTMLDocument_tid,
1730     NULL,
1731     HTMLDocument_iface_tids
1732 };
1733
1734 static void init_doc(HTMLDocument *doc, const htmldoc_vtbl_t *vtbl)
1735 {
1736     doc->vtbl = vtbl;
1737     doc->lpHTMLDocument2Vtbl = &HTMLDocumentVtbl;
1738     doc->lpIDispatchExVtbl = &DocDispatchExVtbl;
1739     doc->lpSupportErrorInfoVtbl = &SupportErrorInfoVtbl;
1740     doc->readystate = READYSTATE_UNINITIALIZED;
1741
1742     HTMLDocument_HTMLDocument3_Init(doc);
1743     HTMLDocument_HTMLDocument5_Init(doc);
1744     HTMLDocument_Persist_Init(doc);
1745     HTMLDocument_OleCmd_Init(doc);
1746     HTMLDocument_OleObj_Init(doc);
1747     HTMLDocument_View_Init(doc);
1748     HTMLDocument_Window_Init(doc);
1749     HTMLDocument_Service_Init(doc);
1750     HTMLDocument_Hlink_Init(doc);
1751
1752     ConnectionPointContainer_Init(&doc->cp_container, (IUnknown*)HTMLDOC(doc));
1753     ConnectionPoint_Init(&doc->cp_propnotif, &doc->cp_container, &IID_IPropertyNotifySink);
1754     ConnectionPoint_Init(&doc->cp_htmldocevents, &doc->cp_container, &DIID_HTMLDocumentEvents);
1755     ConnectionPoint_Init(&doc->cp_htmldocevents2, &doc->cp_container, &DIID_HTMLDocumentEvents2);
1756
1757     init_dispex(&doc->dispex, (IUnknown*)HTMLDOC(doc), &HTMLDocument_dispex);
1758 }
1759
1760 static void destroy_htmldoc(HTMLDocument *This)
1761 {
1762     remove_doc_tasks(This);
1763
1764     if(This->event_target)
1765         release_event_target(This->event_target);
1766
1767     heap_free(This->mime);
1768     release_nodes(This);
1769     release_dispex(&This->dispex);
1770
1771     ConnectionPointContainer_Destroy(&This->cp_container);
1772
1773     if(This->nsdoc)
1774         nsIDOMHTMLDocument_Release(This->nsdoc);
1775 }
1776
1777 #define HTMLDOCNODE_THIS(base) DEFINE_THIS2(HTMLDocumentNode, basedoc, base)
1778
1779 static HRESULT HTMLDocumentNode_QueryInterface(HTMLDocument *base, REFIID riid, void **ppv)
1780 {
1781     HTMLDocumentNode *This = HTMLDOCNODE_THIS(base);
1782
1783     return htmldoc_qi(&This->basedoc, riid, ppv);
1784 }
1785
1786 static ULONG HTMLDocumentNode_AddRef(HTMLDocument *base)
1787 {
1788     HTMLDocumentNode *This = HTMLDOCNODE_THIS(base);
1789     ULONG ref = InterlockedIncrement(&This->ref);
1790
1791     TRACE("(%p) ref = %u\n", This, ref);
1792
1793     return ref;
1794 }
1795
1796 static ULONG HTMLDocumentNode_Release(HTMLDocument *base)
1797 {
1798     HTMLDocumentNode *This = HTMLDOCNODE_THIS(base);
1799     ULONG ref = InterlockedDecrement(&This->ref);
1800
1801     TRACE("(%p) ref = %u\n", This, ref);
1802
1803     if(!ref) {
1804         detach_selection(This);
1805         detach_ranges(This);
1806         destroy_htmldoc(&This->basedoc);
1807         heap_free(This);
1808     }
1809
1810     return ref;
1811 }
1812
1813 #undef HTMLDOCNODE_THIS
1814
1815 static const htmldoc_vtbl_t HTMLDocumentNodeVtbl = {
1816     HTMLDocumentNode_QueryInterface,
1817     HTMLDocumentNode_AddRef,
1818     HTMLDocumentNode_Release
1819 };
1820
1821 HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocumentObj *doc_obj, HTMLWindow *window, HTMLDocumentNode **ret)
1822 {
1823     HTMLDocumentNode *doc;
1824
1825     doc = heap_alloc_zero(sizeof(HTMLDocumentNode));
1826     if(!doc)
1827         return E_OUTOFMEMORY;
1828
1829     doc->basedoc.doc_node = doc;
1830     doc->basedoc.doc_obj = doc_obj;
1831
1832     init_doc(&doc->basedoc, &HTMLDocumentNodeVtbl);
1833     doc->ref = 1;
1834
1835     nsIDOMHTMLDocument_AddRef(nsdoc);
1836     doc->basedoc.nsdoc = nsdoc;
1837
1838     doc->basedoc.window = window;
1839
1840     list_init(&doc->selection_list);
1841     list_init(&doc->range_list);
1842
1843     *ret = doc;
1844     return S_OK;
1845 }
1846
1847 #define HTMLDOCOBJ_THIS(base) DEFINE_THIS2(HTMLDocumentObj, basedoc, base)
1848
1849 static HRESULT HTMLDocumentObj_QueryInterface(HTMLDocument *base, REFIID riid, void **ppv)
1850 {
1851     HTMLDocumentObj *This = HTMLDOCOBJ_THIS(base);
1852
1853     return htmldoc_qi(&This->basedoc, riid, ppv);
1854 }
1855
1856 static ULONG HTMLDocumentObj_AddRef(HTMLDocument *base)
1857 {
1858     HTMLDocumentObj *This = HTMLDOCOBJ_THIS(base);
1859     ULONG ref = InterlockedIncrement(&This->ref);
1860
1861     TRACE("(%p) ref = %u\n", This, ref);
1862
1863     return ref;
1864 }
1865
1866 static ULONG HTMLDocumentObj_Release(HTMLDocument *base)
1867 {
1868     HTMLDocumentObj *This = HTMLDOCOBJ_THIS(base);
1869     ULONG ref = InterlockedDecrement(&This->ref);
1870
1871     TRACE("(%p) ref = %u\n", This, ref);
1872
1873     if(!ref) {
1874         set_document_bscallback(&This->basedoc, NULL);
1875         set_current_mon(&This->basedoc, NULL);
1876         if(This->basedoc.doc_node) {
1877             This->basedoc.doc_node->basedoc.doc_obj = NULL;
1878             IHTMLDocument2_Release(HTMLDOC(&This->basedoc.doc_node->basedoc));
1879         }
1880         if(This->basedoc.window) {
1881             This->basedoc.window->doc_obj = NULL;
1882             IHTMLWindow2_Release(HTMLWINDOW2(This->basedoc.window));
1883         }
1884
1885         if(This->client)
1886             IOleObject_SetClientSite(OLEOBJ(&This->basedoc), NULL);
1887         if(This->in_place_active)
1888             IOleInPlaceObjectWindowless_InPlaceDeactivate(INPLACEWIN(&This->basedoc));
1889         if(This->ipsite)
1890             IOleDocumentView_SetInPlaceSite(DOCVIEW(&This->basedoc), NULL);
1891         if(This->undomgr)
1892             IOleUndoManager_Release(This->undomgr);
1893         if(This->tooltips_hwnd)
1894             DestroyWindow(This->tooltips_hwnd);
1895
1896         if(This->hwnd)
1897             DestroyWindow(This->hwnd);
1898
1899         destroy_htmldoc(&This->basedoc);
1900
1901         if(This->basedoc.nsdoc)
1902             remove_mutation_observer(This->nscontainer, This->basedoc.nsdoc);
1903         if(This->nscontainer)
1904             NSContainer_Release(This->nscontainer);
1905         heap_free(This);
1906     }
1907
1908     return ref;
1909 }
1910
1911 #undef HTMLDOCOBJ_THIS
1912
1913 static const htmldoc_vtbl_t HTMLDocumentObjVtbl = {
1914     HTMLDocumentObj_QueryInterface,
1915     HTMLDocumentObj_AddRef,
1916     HTMLDocumentObj_Release
1917 };
1918
1919 HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
1920 {
1921     HTMLDocumentObj *doc;
1922     nsIDOMWindow *nswindow = NULL;
1923     HRESULT hres;
1924
1925     TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppvObject);
1926
1927     doc = heap_alloc_zero(sizeof(HTMLDocumentObj));
1928     if(!doc)
1929         return E_OUTOFMEMORY;
1930
1931     init_doc(&doc->basedoc, &HTMLDocumentObjVtbl);
1932
1933     doc->ref = 1;
1934     doc->basedoc.doc_obj = doc;
1935
1936     hres = htmldoc_query_interface(&doc->basedoc, riid, ppvObject);
1937     htmldoc_release(&doc->basedoc);
1938     if(FAILED(hres))
1939         return hres;
1940
1941     doc->nscontainer = NSContainer_Create(doc, NULL);
1942     list_init(&doc->bindings);
1943     doc->usermode = UNKNOWN_USERMODE;
1944
1945     if(doc->nscontainer) {
1946         nsresult nsres;
1947
1948         nsres = nsIWebBrowser_GetContentDOMWindow(doc->nscontainer->webbrowser, &nswindow);
1949         if(NS_FAILED(nsres))
1950             ERR("GetContentDOMWindow failed: %08x\n", nsres);
1951     }
1952
1953     hres = HTMLWindow_Create(doc, nswindow, &doc->basedoc.window);
1954     if(nswindow)
1955         nsIDOMWindow_Release(nswindow);
1956     if(FAILED(hres)) {
1957         IHTMLDocument_Release(HTMLDOC(&doc->basedoc));
1958         return hres;
1959     }
1960
1961     update_nsdocument(doc);
1962     get_thread_hwnd();
1963
1964     return S_OK;
1965 }