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