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