htmldoc.c 67.2 KB
Newer Older
1
/*
2
 * Copyright 2005-2009 Jacek Caban for CodeWeavers
3 4 5 6 7 8 9 10 11 12 13 14 15
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * 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 20 21 22 23 24 25 26 27 28
 */

#include "config.h"

#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
29
#include "wininet.h"
30
#include "ole2.h"
31
#include "perhist.h"
32
#include "mshtmdid.h"
33 34 35 36

#include "wine/debug.h"

#include "mshtml_private.h"
37
#include "htmlevent.h"
38
#include "pluginhost.h"
39 40 41

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

42 43 44 45
static inline HTMLDocument *impl_from_IHTMLDocument2(IHTMLDocument2 *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument2_iface);
}
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 55
}

static ULONG WINAPI HTMLDocument_AddRef(IHTMLDocument2 *iface)
{
56
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
57 58

    return htmldoc_addref(This);
59 60 61 62
}

static ULONG WINAPI HTMLDocument_Release(IHTMLDocument2 *iface)
{
63
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
64

65
    return htmldoc_release(This);
66 67 68 69
}

static HRESULT WINAPI HTMLDocument_GetTypeInfoCount(IHTMLDocument2 *iface, UINT *pctinfo)
{
70
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
71

72
    return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
73 74 75 76 77
}

static HRESULT WINAPI HTMLDocument_GetTypeInfo(IHTMLDocument2 *iface, UINT iTInfo,
                                                LCID lcid, ITypeInfo **ppTInfo)
{
78
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
79

80
    return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
81 82 83 84 85 86
}

static HRESULT WINAPI HTMLDocument_GetIDsOfNames(IHTMLDocument2 *iface, REFIID riid,
                                                LPOLESTR *rgszNames, UINT cNames,
                                                LCID lcid, DISPID *rgDispId)
{
87
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
88

89 90
    return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
            rgDispId);
91 92 93 94 95 96
}

static HRESULT WINAPI HTMLDocument_Invoke(IHTMLDocument2 *iface, DISPID dispIdMember,
                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
97
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
98

99 100
    return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
            pDispParams, pVarResult, pExcepInfo, puArgErr);
101 102 103 104
}

static HRESULT WINAPI HTMLDocument_get_Script(IHTMLDocument2 *iface, IDispatch **p)
{
105
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
106 107 108

    TRACE("(%p)->(%p)\n", This, p);

109
    *p = (IDispatch*)&This->window->IHTMLWindow2_iface;
110 111
    IDispatch_AddRef(*p);
    return S_OK;
112 113 114 115
}

static HRESULT WINAPI HTMLDocument_get_all(IHTMLDocument2 *iface, IHTMLElementCollection **p)
{
116
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
117
    nsIDOMElement *nselem = NULL;
118
    HTMLDOMNode *node;
119
    nsresult nsres;
120
    HRESULT hres;
121 122 123

    TRACE("(%p)->(%p)\n", This, p);

124
    if(!This->doc_node->nsdoc) {
125 126
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
127 128
    }

129
    nsres = nsIDOMHTMLDocument_GetDocumentElement(This->doc_node->nsdoc, &nselem);
130 131 132
    if(NS_FAILED(nsres)) {
        ERR("GetDocumentElement failed: %08x\n", nsres);
        return E_FAIL;
133 134
    }

135
    if(!nselem) {
136
        *p = NULL;
137
        return S_OK;
138
    }
139

140 141 142 143 144
    hres = get_node(This->doc_node, (nsIDOMNode*)nselem, TRUE, &node);
    if(SUCCEEDED(hres))
        *p = create_all_collection(node, TRUE);
    nsIDOMElement_Release(nselem);
    return hres;
145 146 147 148
}

static HRESULT WINAPI HTMLDocument_get_body(IHTMLDocument2 *iface, IHTMLElement **p)
{
149
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
150 151
    nsIDOMHTMLElement *nsbody = NULL;
    HTMLDOMNode *node;
152
    HRESULT hres;
153 154 155

    TRACE("(%p)->(%p)\n", This, p);

156 157
    if(This->doc_node->nsdoc) {
        nsresult nsres;
158

159 160 161 162 163
        nsres = nsIDOMHTMLDocument_GetBody(This->doc_node->nsdoc, &nsbody);
        if(NS_FAILED(nsres)) {
            TRACE("Could not get body: %08x\n", nsres);
            return E_UNEXPECTED;
        }
164 165
    }

166
    if(!nsbody) {
167
        *p = NULL;
168
        return S_OK;
169
    }
170

171 172 173 174 175
    hres = get_node(This->doc_node, (nsIDOMNode*)nsbody, TRUE, &node);
    nsIDOMHTMLElement_Release(nsbody);
    if(FAILED(hres))
        return hres;

176
    return IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)p);
177 178 179 180
}

static HRESULT WINAPI HTMLDocument_get_activeElement(IHTMLDocument2 *iface, IHTMLElement **p)
{
181
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
182
    FIXME("(%p)->(%p)\n", This, p);
183 184 185 186 187
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_images(IHTMLDocument2 *iface, IHTMLElementCollection **p)
{
188
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
189 190 191 192 193 194 195 196 197 198
    nsIDOMHTMLCollection *nscoll = NULL;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    if(!p)
        return E_INVALIDARG;

    *p = NULL;

199
    if(!This->doc_node->nsdoc) {
200 201 202 203
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
    }

204
    nsres = nsIDOMHTMLDocument_GetImages(This->doc_node->nsdoc, &nscoll);
205 206 207 208 209 210
    if(NS_FAILED(nsres)) {
        ERR("GetImages failed: %08x\n", nsres);
        return E_FAIL;
    }

    if(nscoll) {
211
        *p = create_collection_from_htmlcol(This->doc_node, (IUnknown*)&This->IHTMLDocument2_iface, nscoll);
212 213 214 215
        nsIDOMElement_Release(nscoll);
    }

    return S_OK;
216 217 218 219
}

static HRESULT WINAPI HTMLDocument_get_applets(IHTMLDocument2 *iface, IHTMLElementCollection **p)
{
220
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
221 222 223 224 225 226 227 228 229 230
    nsIDOMHTMLCollection *nscoll = NULL;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    if(!p)
        return E_INVALIDARG;

    *p = NULL;

231
    if(!This->doc_node->nsdoc) {
232 233 234 235
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
    }

236
    nsres = nsIDOMHTMLDocument_GetApplets(This->doc_node->nsdoc, &nscoll);
237 238 239 240 241 242
    if(NS_FAILED(nsres)) {
        ERR("GetApplets failed: %08x\n", nsres);
        return E_FAIL;
    }

    if(nscoll) {
243
        *p = create_collection_from_htmlcol(This->doc_node, (IUnknown*)&This->IHTMLDocument2_iface, nscoll);
244 245 246 247
        nsIDOMElement_Release(nscoll);
    }

    return S_OK;
248 249 250 251
}

static HRESULT WINAPI HTMLDocument_get_links(IHTMLDocument2 *iface, IHTMLElementCollection **p)
{
252
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
253 254 255 256 257 258 259 260 261 262
    nsIDOMHTMLCollection *nscoll = NULL;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    if(!p)
        return E_INVALIDARG;

    *p = NULL;

263
    if(!This->doc_node->nsdoc) {
264 265 266 267
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
    }

268
    nsres = nsIDOMHTMLDocument_GetLinks(This->doc_node->nsdoc, &nscoll);
269 270 271 272 273 274
    if(NS_FAILED(nsres)) {
        ERR("GetLinks failed: %08x\n", nsres);
        return E_FAIL;
    }

    if(nscoll) {
275
        *p = create_collection_from_htmlcol(This->doc_node, (IUnknown*)&This->IHTMLDocument2_iface, nscoll);
276 277 278 279
        nsIDOMElement_Release(nscoll);
    }

    return S_OK;
280 281 282 283
}

static HRESULT WINAPI HTMLDocument_get_forms(IHTMLDocument2 *iface, IHTMLElementCollection **p)
{
284
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
285 286 287 288 289 290 291 292 293 294
    nsIDOMHTMLCollection *nscoll = NULL;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    if(!p)
        return E_INVALIDARG;

    *p = NULL;

295
    if(!This->doc_node->nsdoc) {
296 297 298 299
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
    }

300
    nsres = nsIDOMHTMLDocument_GetForms(This->doc_node->nsdoc, &nscoll);
301 302 303 304 305 306
    if(NS_FAILED(nsres)) {
        ERR("GetForms failed: %08x\n", nsres);
        return E_FAIL;
    }

    if(nscoll) {
307
        *p = create_collection_from_htmlcol(This->doc_node, (IUnknown*)&This->IHTMLDocument2_iface, nscoll);
308 309 310 311
        nsIDOMElement_Release(nscoll);
    }

    return S_OK;
312 313 314 315
}

static HRESULT WINAPI HTMLDocument_get_anchors(IHTMLDocument2 *iface, IHTMLElementCollection **p)
{
316
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
317 318 319 320 321 322 323 324 325 326
    nsIDOMHTMLCollection *nscoll = NULL;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    if(!p)
        return E_INVALIDARG;

    *p = NULL;

327
    if(!This->doc_node->nsdoc) {
328 329 330 331
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
    }

332
    nsres = nsIDOMHTMLDocument_GetAnchors(This->doc_node->nsdoc, &nscoll);
333 334 335 336 337 338
    if(NS_FAILED(nsres)) {
        ERR("GetAnchors failed: %08x\n", nsres);
        return E_FAIL;
    }

    if(nscoll) {
339
        *p = create_collection_from_htmlcol(This->doc_node, (IUnknown*)&This->IHTMLDocument2_iface, nscoll);
340 341 342 343
        nsIDOMElement_Release(nscoll);
    }

    return S_OK;
344 345 346 347
}

static HRESULT WINAPI HTMLDocument_put_title(IHTMLDocument2 *iface, BSTR v)
{
348
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
349 350 351 352 353
    nsAString nsstr;
    nsresult nsres;

    TRACE("(%p)->(%s)\n", This, debugstr_w(v));

354
    if(!This->doc_node->nsdoc) {
355 356
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
357 358
    }

359
    nsAString_InitDepend(&nsstr, v);
360
    nsres = nsIDOMHTMLDocument_SetTitle(This->doc_node->nsdoc, &nsstr);
361 362 363 364 365
    nsAString_Finish(&nsstr);
    if(NS_FAILED(nsres))
        ERR("SetTitle failed: %08x\n", nsres);

    return S_OK;
366 367 368 369
}

static HRESULT WINAPI HTMLDocument_get_title(IHTMLDocument2 *iface, BSTR *p)
{
370
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
371 372 373 374 375 376
    const PRUnichar *ret;
    nsAString nsstr;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

377
    if(!This->doc_node->nsdoc) {
378 379
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
380 381 382 383
    }


    nsAString_Init(&nsstr, NULL);
384
    nsres = nsIDOMHTMLDocument_GetTitle(This->doc_node->nsdoc, &nsstr);
385 386 387 388 389
    if (NS_SUCCEEDED(nsres)) {
        nsAString_GetData(&nsstr, &ret);
        *p = SysAllocString(ret);
    }
    nsAString_Finish(&nsstr);
390

391
    if(NS_FAILED(nsres)) {
392
        ERR("GetTitle failed: %08x\n", nsres);
393 394
        return E_FAIL;
    }
395 396

    return S_OK;
397 398 399 400
}

static HRESULT WINAPI HTMLDocument_get_scripts(IHTMLDocument2 *iface, IHTMLElementCollection **p)
{
401
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
402
    FIXME("(%p)->(%p)\n", This, p);
403 404 405 406 407
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_designMode(IHTMLDocument2 *iface, BSTR v)
{
408
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
409
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
410 411 412 413 414
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_designMode(IHTMLDocument2 *iface, BSTR *p)
{
415
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
416 417 418 419 420 421 422 423 424
    static WCHAR szOff[] = {'O','f','f',0};
    FIXME("(%p)->(%p) always returning Off\n", This, p);

    if(!p)
        return E_INVALIDARG;

    *p = SysAllocString(szOff);

    return S_OK;
425 426 427 428
}

static HRESULT WINAPI HTMLDocument_get_selection(IHTMLDocument2 *iface, IHTMLSelectionObject **p)
{
429
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
430 431
    nsISelection *nsselection;
    nsresult nsres;
432 433 434

    TRACE("(%p)->(%p)\n", This, p);

435 436 437 438
    nsres = nsIDOMWindow_GetSelection(This->window->nswindow, &nsselection);
    if(NS_FAILED(nsres)) {
        ERR("GetSelection failed: %08x\n", nsres);
        return E_FAIL;
439 440
    }

441
    return HTMLSelectionObject_Create(This->doc_node, nsselection, p);
442 443 444 445
}

static HRESULT WINAPI HTMLDocument_get_readyState(IHTMLDocument2 *iface, BSTR *p)
{
446
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466

    static const WCHAR wszUninitialized[] = {'u','n','i','n','i','t','i','a','l','i','z','e','d',0};
    static const WCHAR wszLoading[] = {'l','o','a','d','i','n','g',0};
    static const WCHAR wszLoaded[] = {'l','o','a','d','e','d',0};
    static const WCHAR wszInteractive[] = {'i','n','t','e','r','a','c','t','i','v','e',0};
    static const WCHAR wszComplete[] = {'c','o','m','p','l','e','t','e',0};

    static const LPCWSTR readystate_str[] = {
        wszUninitialized,
        wszLoading,
        wszLoaded,
        wszInteractive,
        wszComplete
    };

    TRACE("(%p)->(%p)\n", iface, p);

    if(!p)
        return E_POINTER;

467
    *p = SysAllocString(readystate_str[This->window->readystate]);
468
    return S_OK;
469 470 471 472
}

static HRESULT WINAPI HTMLDocument_get_frames(IHTMLDocument2 *iface, IHTMLFramesCollection2 **p)
{
473
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
474
    FIXME("(%p)->(%p)\n", This, p);
475 476 477 478 479
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_embeds(IHTMLDocument2 *iface, IHTMLElementCollection **p)
{
480
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
481
    FIXME("(%p)->(%p)\n", This, p);
482 483 484 485 486
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_plugins(IHTMLDocument2 *iface, IHTMLElementCollection **p)
{
487
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
488
    FIXME("(%p)->(%p)\n", This, p);
489 490 491 492 493
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_alinkColor(IHTMLDocument2 *iface, VARIANT v)
{
494
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
495
    FIXME("(%p)\n", This);
496 497 498 499 500
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_alinkColor(IHTMLDocument2 *iface, VARIANT *p)
{
501
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
502
    FIXME("(%p)->(%p)\n", This, p);
503 504 505 506 507
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_bgColor(IHTMLDocument2 *iface, VARIANT v)
{
508
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
509
    FIXME("(%p)\n", This);
510 511 512 513 514
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_bgColor(IHTMLDocument2 *iface, VARIANT *p)
{
515
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
516
    FIXME("(%p)->(%p)\n", This, p);
517 518 519 520 521
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_fgColor(IHTMLDocument2 *iface, VARIANT v)
{
522
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
523
    FIXME("(%p)\n", This);
524 525 526 527 528
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_fgColor(IHTMLDocument2 *iface, VARIANT *p)
{
529
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
530
    FIXME("(%p)->(%p)\n", This, p);
531 532 533 534 535
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_linkColor(IHTMLDocument2 *iface, VARIANT v)
{
536
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
537
    FIXME("(%p)->()\n", This);
538 539 540 541 542
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_linkColor(IHTMLDocument2 *iface, VARIANT *p)
{
543
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
544
    FIXME("(%p)->(%p)\n", This, p);
545 546 547 548 549
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_vlinkColor(IHTMLDocument2 *iface, VARIANT v)
{
550
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
551
    FIXME("(%p)\n", This);
552 553 554 555 556
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_vlinkColor(IHTMLDocument2 *iface, VARIANT *p)
{
557
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
558
    FIXME("(%p)->(%p)\n", This, p);
559 560 561 562 563
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_referrer(IHTMLDocument2 *iface, BSTR *p)
{
564
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
565

566
    FIXME("(%p)->(%p)\n", This, p);
567 568 569 570

    *p = NULL;
    return S_OK;
 }
571 572 573

static HRESULT WINAPI HTMLDocument_get_location(IHTMLDocument2 *iface, IHTMLLocation **p)
{
574
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
575 576 577

    TRACE("(%p)->(%p)\n", This, p);

578 579 580 581 582
    if(!This->doc_node->nsdoc) {
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
    }

583
    return IHTMLWindow2_get_location(&This->window->IHTMLWindow2_iface, p);
584 585 586 587
}

static HRESULT WINAPI HTMLDocument_get_lastModified(IHTMLDocument2 *iface, BSTR *p)
{
588
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
589
    FIXME("(%p)->(%p)\n", This, p);
590 591 592 593 594
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_URL(IHTMLDocument2 *iface, BSTR v)
{
595
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
596
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
597 598 599 600 601
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_URL(IHTMLDocument2 *iface, BSTR *p)
{
602
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
603 604 605 606 607 608

    static const WCHAR about_blank_url[] =
        {'a','b','o','u','t',':','b','l','a','n','k',0};

    TRACE("(%p)->(%p)\n", iface, p);

609
    *p = SysAllocString(This->window->url ? This->window->url : about_blank_url);
610
    return *p ? S_OK : E_OUTOFMEMORY;
611 612 613 614
}

static HRESULT WINAPI HTMLDocument_put_domain(IHTMLDocument2 *iface, BSTR v)
{
615
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
616
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
617 618 619 620 621
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_domain(IHTMLDocument2 *iface, BSTR *p)
{
622
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
623
    FIXME("(%p)->(%p)\n", This, p);
624 625 626 627 628
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_cookie(IHTMLDocument2 *iface, BSTR v)
{
629
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
630 631 632 633 634 635 636 637 638 639 640
    BOOL bret;

    TRACE("(%p)->(%s)\n", This, debugstr_w(v));

    bret = InternetSetCookieExW(This->window->url, NULL, v, 0, 0);
    if(!bret) {
        FIXME("InternetSetCookieExW failed: %u\n", GetLastError());
        return HRESULT_FROM_WIN32(GetLastError());
    }

    return S_OK;
641 642 643 644
}

static HRESULT WINAPI HTMLDocument_get_cookie(IHTMLDocument2 *iface, BSTR *p)
{
645
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
    DWORD size;
    BOOL bret;

    TRACE("(%p)->(%p)\n", This, p);

    size = 0;
    bret = InternetGetCookieExW(This->window->url, NULL, NULL, &size, 0, NULL);
    if(!bret) {
        switch(GetLastError()) {
        case ERROR_INSUFFICIENT_BUFFER:
            break;
        case ERROR_NO_MORE_ITEMS:
            *p = NULL;
            return S_OK;
        default:
            FIXME("InternetGetCookieExW failed: %u\n", GetLastError());
            return HRESULT_FROM_WIN32(GetLastError());
        }
    }

    if(!size) {
        *p = NULL;
        return S_OK;
    }

    *p = SysAllocStringLen(NULL, size-1);
    if(!*p)
        return E_OUTOFMEMORY;

    bret = InternetGetCookieExW(This->window->url, NULL, *p, &size, 0, NULL);
    if(!bret) {
        ERR("InternetGetCookieExW failed: %u\n", GetLastError());
        return E_FAIL;
    }

    return S_OK;
682 683 684 685
}

static HRESULT WINAPI HTMLDocument_put_expando(IHTMLDocument2 *iface, VARIANT_BOOL v)
{
686
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
687
    FIXME("(%p)->(%x)\n", This, v);
688 689 690 691 692
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_expando(IHTMLDocument2 *iface, VARIANT_BOOL *p)
{
693
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
694
    FIXME("(%p)->(%p)\n", This, p);
695 696 697 698 699
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_charset(IHTMLDocument2 *iface, BSTR v)
{
700
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
701
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
702 703 704 705 706
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_charset(IHTMLDocument2 *iface, BSTR *p)
{
707
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
708
    FIXME("(%p)->(%p)\n", This, p);
709 710 711 712 713
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_defaultCharset(IHTMLDocument2 *iface, BSTR v)
{
714
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
715
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
716 717 718 719 720
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_defaultCharset(IHTMLDocument2 *iface, BSTR *p)
{
721
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
722
    FIXME("(%p)->(%p)\n", This, p);
723 724 725 726 727
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
{
728
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
729
    FIXME("(%p)->(%p)\n", This, p);
730 731 732 733 734
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_fileSize(IHTMLDocument2 *iface, BSTR *p)
{
735
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
736
    FIXME("(%p)->(%p)\n", This, p);
737 738 739 740 741
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_fileCreatedDate(IHTMLDocument2 *iface, BSTR *p)
{
742
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
743
    FIXME("(%p)->(%p)\n", This, p);
744 745 746 747 748
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_fileModifiedDate(IHTMLDocument2 *iface, BSTR *p)
{
749
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
750
    FIXME("(%p)->(%p)\n", This, p);
751 752 753 754 755
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_fileUpdatedDate(IHTMLDocument2 *iface, BSTR *p)
{
756
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
757
    FIXME("(%p)->(%p)\n", This, p);
758 759 760 761 762
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_security(IHTMLDocument2 *iface, BSTR *p)
{
763
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
764
    FIXME("(%p)->(%p)\n", This, p);
765 766 767 768 769
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_protocol(IHTMLDocument2 *iface, BSTR *p)
{
770
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
771
    FIXME("(%p)->(%p)\n", This, p);
772 773 774 775 776
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_nameProp(IHTMLDocument2 *iface, BSTR *p)
{
777
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
778
    FIXME("(%p)->(%p)\n", This, p);
779 780 781
    return E_NOTIMPL;
}

782
static HRESULT document_write(HTMLDocument *This, SAFEARRAY *psarray, BOOL ln)
783
{
784 785
    nsAString nsstr;
    VARIANT *var;
786
    ULONG i, argc;
787 788 789
    nsresult nsres;
    HRESULT hres;

790
    if(!This->doc_node->nsdoc) {
791 792 793 794
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
    }

795 796 797
    if (!psarray)
        return S_OK;

798 799 800 801 802 803 804 805 806 807 808 809 810
    if(psarray->cDims != 1) {
        FIXME("cDims=%d\n", psarray->cDims);
        return E_INVALIDARG;
    }

    hres = SafeArrayAccessData(psarray, (void**)&var);
    if(FAILED(hres)) {
        WARN("SafeArrayAccessData failed: %08x\n", hres);
        return hres;
    }

    nsAString_Init(&nsstr, NULL);

811 812
    argc = psarray->rgsabound[0].cElements;
    for(i=0; i < argc; i++) {
813 814
        if(V_VT(var+i) == VT_BSTR) {
            nsAString_SetData(&nsstr, V_BSTR(var+i));
815
            if(!ln || i != argc-1)
816
                nsres = nsIDOMHTMLDocument_Write(This->doc_node->nsdoc, &nsstr);
817
            else
818
                nsres = nsIDOMHTMLDocument_Writeln(This->doc_node->nsdoc, &nsstr);
819 820 821 822 823 824 825 826 827 828 829
            if(NS_FAILED(nsres))
                ERR("Write failed: %08x\n", nsres);
        }else {
            FIXME("vt=%d\n", V_VT(var+i));
        }
    }

    nsAString_Finish(&nsstr);
    SafeArrayUnaccessData(psarray);

    return S_OK;
830 831
}

832 833
static HRESULT WINAPI HTMLDocument_write(IHTMLDocument2 *iface, SAFEARRAY *psarray)
{
834
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
835 836 837 838 839 840

    TRACE("(%p)->(%p)\n", iface, psarray);

    return document_write(This, psarray, FALSE);
}

841 842
static HRESULT WINAPI HTMLDocument_writeln(IHTMLDocument2 *iface, SAFEARRAY *psarray)
{
843
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
844 845 846 847

    TRACE("(%p)->(%p)\n", This, psarray);

    return document_write(This, psarray, TRUE);
848 849 850 851 852
}

static HRESULT WINAPI HTMLDocument_open(IHTMLDocument2 *iface, BSTR url, VARIANT name,
                        VARIANT features, VARIANT replace, IDispatch **pomWindowResult)
{
853
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
854 855 856 857 858 859 860
    nsresult nsres;

    static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0};

    TRACE("(%p)->(%s %s %s %s %p)\n", This, debugstr_w(url), debugstr_variant(&name),
          debugstr_variant(&features), debugstr_variant(&replace), pomWindowResult);

861
    if(!This->doc_node->nsdoc) {
862 863 864 865 866 867 868 869
        ERR("!nsdoc\n");
        return E_NOTIMPL;
    }

    if(!url || strcmpW(url, text_htmlW) || V_VT(&name) != VT_ERROR
       || V_VT(&features) != VT_ERROR || V_VT(&replace) != VT_ERROR)
        FIXME("unsupported args\n");

870
    nsres = nsIDOMHTMLDocument_Open(This->doc_node->nsdoc);
871 872 873 874 875
    if(NS_FAILED(nsres)) {
        ERR("Open failed: %08x\n", nsres);
        return E_FAIL;
    }

876 877
    *pomWindowResult = (IDispatch*)&This->window->IHTMLWindow2_iface;
    IHTMLWindow2_AddRef(&This->window->IHTMLWindow2_iface);
878
    return S_OK;
879 880 881 882
}

static HRESULT WINAPI HTMLDocument_close(IHTMLDocument2 *iface)
{
883
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
884 885 886 887
    nsresult nsres;

    TRACE("(%p)\n", This);

888
    if(!This->doc_node->nsdoc) {
889 890 891 892
        ERR("!nsdoc\n");
        return E_NOTIMPL;
    }

893
    nsres = nsIDOMHTMLDocument_Close(This->doc_node->nsdoc);
894 895 896 897 898 899
    if(NS_FAILED(nsres)) {
        ERR("Close failed: %08x\n", nsres);
        return E_FAIL;
    }

    return S_OK;
900 901 902 903
}

static HRESULT WINAPI HTMLDocument_clear(IHTMLDocument2 *iface)
{
904
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923
    nsIDOMNSHTMLDocument *nsdoc;
    nsresult nsres;

    TRACE("(%p)\n", This);

    nsres = nsIDOMHTMLDocument_QueryInterface(This->doc_node->nsdoc, &IID_nsIDOMNSHTMLDocument, (void**)&nsdoc);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIDOMNSHTMLDocument iface: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIDOMNSHTMLDocument_Clear(nsdoc);
    nsIDOMNSHTMLDocument_Release(nsdoc);
    if(NS_FAILED(nsres)) {
        ERR("Clear failed: %08x\n", nsres);
        return E_FAIL;
    }

    return S_OK;
924 925 926 927 928
}

static HRESULT WINAPI HTMLDocument_queryCommandSupported(IHTMLDocument2 *iface, BSTR cmdID,
                                                        VARIANT_BOOL *pfRet)
{
929
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
930
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
931 932 933 934 935 936
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_queryCommandEnabled(IHTMLDocument2 *iface, BSTR cmdID,
                                                        VARIANT_BOOL *pfRet)
{
937
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
938
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
939 940 941 942 943 944
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_queryCommandState(IHTMLDocument2 *iface, BSTR cmdID,
                                                        VARIANT_BOOL *pfRet)
{
945
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
946
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
947 948 949 950 951 952
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_queryCommandIndeterm(IHTMLDocument2 *iface, BSTR cmdID,
                                                        VARIANT_BOOL *pfRet)
{
953
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
954
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
955 956 957 958 959 960
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_queryCommandText(IHTMLDocument2 *iface, BSTR cmdID,
                                                        BSTR *pfRet)
{
961
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
962
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
963 964 965 966 967 968
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_queryCommandValue(IHTMLDocument2 *iface, BSTR cmdID,
                                                        VARIANT *pfRet)
{
969
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
970
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
971 972 973 974 975 976
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_execCommand(IHTMLDocument2 *iface, BSTR cmdID,
                                VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
{
977
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
978
    FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(cmdID), showUI, pfRet);
979 980 981 982 983 984
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_execCommandShowHelp(IHTMLDocument2 *iface, BSTR cmdID,
                                                        VARIANT_BOOL *pfRet)
{
985
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
986
    FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
987 988 989 990
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_createElement(IHTMLDocument2 *iface, BSTR eTag,
991
                                                 IHTMLElement **newElem)
992
{
993
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
994
    nsIDOMHTMLElement *nselem;
995
    HTMLElement *elem;
996
    HRESULT hres;
997 998 999

    TRACE("(%p)->(%s %p)\n", This, debugstr_w(eTag), newElem);

1000 1001 1002
    hres = create_nselem(This->doc_node, eTag, &nselem);
    if(FAILED(hres))
        return hres;
1003

1004
    hres = HTMLElement_Create(This->doc_node, (nsIDOMNode*)nselem, TRUE, &elem);
1005
    nsIDOMHTMLElement_Release(nselem);
1006 1007
    if(FAILED(hres))
        return hres;
1008

1009 1010
    *newElem = &elem->IHTMLElement_iface;
    IHTMLElement_AddRef(&elem->IHTMLElement_iface);
1011
    return S_OK;
1012 1013 1014 1015
}

static HRESULT WINAPI HTMLDocument_put_onhelp(IHTMLDocument2 *iface, VARIANT v)
{
1016
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1017
    FIXME("(%p)\n", This);
1018 1019 1020 1021 1022
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_onhelp(IHTMLDocument2 *iface, VARIANT *p)
{
1023
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1024
    FIXME("(%p)->(%p)\n", This, p);
1025 1026 1027 1028 1029
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_onclick(IHTMLDocument2 *iface, VARIANT v)
{
1030
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1031 1032 1033 1034

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    return set_doc_event(This, EVENTID_CLICK, &v);
1035 1036 1037 1038
}

static HRESULT WINAPI HTMLDocument_get_onclick(IHTMLDocument2 *iface, VARIANT *p)
{
1039
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1040 1041 1042 1043

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_CLICK, p);
1044 1045 1046 1047
}

static HRESULT WINAPI HTMLDocument_put_ondblclick(IHTMLDocument2 *iface, VARIANT v)
{
1048
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1049
    FIXME("(%p)\n", This);
1050 1051 1052 1053 1054
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_ondblclick(IHTMLDocument2 *iface, VARIANT *p)
{
1055
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1056
    FIXME("(%p)->(%p)\n", This, p);
1057 1058 1059 1060 1061
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_onkeyup(IHTMLDocument2 *iface, VARIANT v)
{
1062
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1063 1064 1065 1066

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    return set_doc_event(This, EVENTID_KEYUP, &v);
1067 1068 1069 1070
}

static HRESULT WINAPI HTMLDocument_get_onkeyup(IHTMLDocument2 *iface, VARIANT *p)
{
1071
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1072 1073 1074 1075

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_KEYUP, p);
1076 1077 1078 1079
}

static HRESULT WINAPI HTMLDocument_put_onkeydown(IHTMLDocument2 *iface, VARIANT v)
{
1080
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1081 1082 1083 1084

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    return set_doc_event(This, EVENTID_KEYDOWN, &v);
1085 1086 1087 1088
}

static HRESULT WINAPI HTMLDocument_get_onkeydown(IHTMLDocument2 *iface, VARIANT *p)
{
1089
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1090 1091 1092 1093

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_KEYDOWN, p);
1094 1095 1096 1097
}

static HRESULT WINAPI HTMLDocument_put_onkeypress(IHTMLDocument2 *iface, VARIANT v)
{
1098
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1099
    FIXME("(%p)\n", This);
1100 1101 1102 1103 1104
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_onkeypress(IHTMLDocument2 *iface, VARIANT *p)
{
1105
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1106
    FIXME("(%p)->(%p)\n", This, p);
1107 1108 1109 1110 1111
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_onmouseup(IHTMLDocument2 *iface, VARIANT v)
{
1112
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1113 1114 1115 1116

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    return set_doc_event(This, EVENTID_MOUSEUP, &v);
1117 1118 1119 1120
}

static HRESULT WINAPI HTMLDocument_get_onmouseup(IHTMLDocument2 *iface, VARIANT *p)
{
1121
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1122 1123 1124 1125

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_MOUSEUP, p);
1126 1127 1128 1129
}

static HRESULT WINAPI HTMLDocument_put_onmousedown(IHTMLDocument2 *iface, VARIANT v)
{
1130
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1131 1132 1133 1134

    TRACE("(%p)->()\n", This);

    return set_doc_event(This, EVENTID_MOUSEDOWN, &v);
1135 1136 1137 1138
}

static HRESULT WINAPI HTMLDocument_get_onmousedown(IHTMLDocument2 *iface, VARIANT *p)
{
1139
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1140 1141 1142 1143

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_MOUSEDOWN, p);
1144 1145 1146 1147
}

static HRESULT WINAPI HTMLDocument_put_onmousemove(IHTMLDocument2 *iface, VARIANT v)
{
1148
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1149 1150 1151 1152

    TRACE("(%p)->()\n", This);

    return set_doc_event(This, EVENTID_MOUSEMOVE, &v);
1153 1154 1155 1156
}

static HRESULT WINAPI HTMLDocument_get_onmousemove(IHTMLDocument2 *iface, VARIANT *p)
{
1157
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1158 1159 1160 1161

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_MOUSEMOVE, p);
1162 1163 1164 1165
}

static HRESULT WINAPI HTMLDocument_put_onmouseout(IHTMLDocument2 *iface, VARIANT v)
{
1166
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1167 1168 1169 1170

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    return set_doc_event(This, EVENTID_MOUSEOUT, &v);
1171 1172 1173 1174
}

static HRESULT WINAPI HTMLDocument_get_onmouseout(IHTMLDocument2 *iface, VARIANT *p)
{
1175
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1176 1177 1178 1179

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_MOUSEOUT, p);
1180 1181 1182 1183
}

static HRESULT WINAPI HTMLDocument_put_onmouseover(IHTMLDocument2 *iface, VARIANT v)
{
1184
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1185 1186 1187 1188

    TRACE("(%p)\n", This);

    return set_doc_event(This, EVENTID_MOUSEOVER, &v);
1189 1190 1191 1192
}

static HRESULT WINAPI HTMLDocument_get_onmouseover(IHTMLDocument2 *iface, VARIANT *p)
{
1193
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1194 1195 1196 1197

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_MOUSEOVER, p);
1198 1199 1200 1201
}

static HRESULT WINAPI HTMLDocument_put_onreadystatechange(IHTMLDocument2 *iface, VARIANT v)
{
1202
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1203 1204 1205 1206

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    return set_doc_event(This, EVENTID_READYSTATECHANGE, &v);
1207 1208 1209 1210
}

static HRESULT WINAPI HTMLDocument_get_onreadystatechange(IHTMLDocument2 *iface, VARIANT *p)
{
1211
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1212 1213 1214 1215

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_READYSTATECHANGE, p);
1216 1217 1218 1219
}

static HRESULT WINAPI HTMLDocument_put_onafterupdate(IHTMLDocument2 *iface, VARIANT v)
{
1220
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1221
    FIXME("(%p)\n", This);
1222 1223 1224 1225 1226
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_onafterupdate(IHTMLDocument2 *iface, VARIANT *p)
{
1227
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1228
    FIXME("(%p)->(%p)\n", This, p);
1229 1230 1231 1232 1233
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_onrowexit(IHTMLDocument2 *iface, VARIANT v)
{
1234
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1235
    FIXME("(%p)\n", This);
1236 1237 1238 1239 1240
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_onrowexit(IHTMLDocument2 *iface, VARIANT *p)
{
1241
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1242
    FIXME("(%p)->(%p)\n", This, p);
1243 1244 1245 1246 1247
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_onrowenter(IHTMLDocument2 *iface, VARIANT v)
{
1248
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1249
    FIXME("(%p)\n", This);
1250 1251 1252 1253 1254
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_onrowenter(IHTMLDocument2 *iface, VARIANT *p)
{
1255
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1256
    FIXME("(%p)->(%p)\n", This, p);
1257 1258 1259 1260 1261
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_ondragstart(IHTMLDocument2 *iface, VARIANT v)
{
1262
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1263 1264 1265 1266

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    return set_doc_event(This, EVENTID_DRAGSTART, &v);
1267 1268 1269 1270
}

static HRESULT WINAPI HTMLDocument_get_ondragstart(IHTMLDocument2 *iface, VARIANT *p)
{
1271
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1272 1273 1274 1275

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_DRAGSTART, p);
1276 1277 1278 1279
}

static HRESULT WINAPI HTMLDocument_put_onselectstart(IHTMLDocument2 *iface, VARIANT v)
{
1280
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1281 1282 1283 1284

    TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));

    return set_doc_event(This, EVENTID_SELECTSTART, &v);
1285 1286 1287 1288
}

static HRESULT WINAPI HTMLDocument_get_onselectstart(IHTMLDocument2 *iface, VARIANT *p)
{
1289
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1290 1291 1292 1293

    TRACE("(%p)->(%p)\n", This, p);

    return get_doc_event(This, EVENTID_SELECTSTART, p);
1294 1295
}

1296
static HRESULT WINAPI HTMLDocument_elementFromPoint(IHTMLDocument2 *iface, LONG x, LONG y,
1297 1298
                                                        IHTMLElement **elementHit)
{
1299
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1300
    FIXME("(%p)->(%d %d %p)\n", This, x, y, elementHit);
1301 1302 1303 1304 1305
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_parentWindow(IHTMLDocument2 *iface, IHTMLWindow2 **p)
{
1306
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1307 1308 1309

    TRACE("(%p)->(%p)\n", This, p);

1310
    *p = &This->window->IHTMLWindow2_iface;
1311 1312
    IHTMLWindow2_AddRef(*p);
    return S_OK;
1313 1314 1315
}

static HRESULT WINAPI HTMLDocument_get_styleSheets(IHTMLDocument2 *iface,
1316
                                                   IHTMLStyleSheetsCollection **p)
1317
{
1318
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1319 1320 1321 1322 1323 1324 1325 1326
    nsIDOMStyleSheetList *nsstylelist;
    nsIDOMDocumentStyle *nsdocstyle;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    *p = NULL;

1327
    if(!This->doc_node->nsdoc) {
1328 1329
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
1330 1331
    }

1332
    nsIDOMHTMLDocument_QueryInterface(This->doc_node->nsdoc, &IID_nsIDOMDocumentStyle, (void**)&nsdocstyle);
1333
    nsres = nsIDOMDocumentStyle_GetStyleSheets(nsdocstyle, &nsstylelist);
1334
    nsIDOMDocumentStyle_Release(nsdocstyle);
1335 1336 1337 1338
    if(NS_FAILED(nsres)) {
        ERR("GetStyleSheets failed: %08x\n", nsres);
        return E_FAIL;
    }
1339 1340 1341 1342 1343

    *p = HTMLStyleSheetsCollection_Create(nsstylelist);
    nsIDOMDocumentStyle_Release(nsstylelist);

    return S_OK;
1344 1345 1346 1347
}

static HRESULT WINAPI HTMLDocument_put_onbeforeupdate(IHTMLDocument2 *iface, VARIANT v)
{
1348
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1349
    FIXME("(%p)\n", This);
1350 1351 1352 1353 1354
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_onbeforeupdate(IHTMLDocument2 *iface, VARIANT *p)
{
1355
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1356
    FIXME("(%p)->(%p)\n", This, p);
1357 1358 1359 1360 1361
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_put_onerrorupdate(IHTMLDocument2 *iface, VARIANT v)
{
1362
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1363
    FIXME("(%p)\n", This);
1364 1365 1366 1367 1368
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_get_onerrorupdate(IHTMLDocument2 *iface, VARIANT *p)
{
1369
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1370
    FIXME("(%p)->(%p)\n", This, p);
1371 1372 1373 1374 1375
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_toString(IHTMLDocument2 *iface, BSTR *String)
{
1376
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1377
    FIXME("(%p)->(%p)\n", This, String);
1378 1379 1380 1381
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLDocument_createStyleSheet(IHTMLDocument2 *iface, BSTR bstrHref,
1382
                                            LONG lIndex, IHTMLStyleSheet **ppnewStyleSheet)
1383
{
1384
    HTMLDocument *This = impl_from_IHTMLDocument2(iface);
1385

1386
    FIXME("(%p)->(%s %d %p) semi-stub\n", This, debugstr_w(bstrHref), lIndex, ppnewStyleSheet);
1387

1388
    *ppnewStyleSheet = HTMLStyleSheet_Create(NULL);
1389
    return S_OK;
1390 1391
}

1392
static const IHTMLDocument2Vtbl HTMLDocumentVtbl = {
1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510
    HTMLDocument_QueryInterface,
    HTMLDocument_AddRef,
    HTMLDocument_Release,
    HTMLDocument_GetTypeInfoCount,
    HTMLDocument_GetTypeInfo,
    HTMLDocument_GetIDsOfNames,
    HTMLDocument_Invoke,
    HTMLDocument_get_Script,
    HTMLDocument_get_all,
    HTMLDocument_get_body,
    HTMLDocument_get_activeElement,
    HTMLDocument_get_images,
    HTMLDocument_get_applets,
    HTMLDocument_get_links,
    HTMLDocument_get_forms,
    HTMLDocument_get_anchors,
    HTMLDocument_put_title,
    HTMLDocument_get_title,
    HTMLDocument_get_scripts,
    HTMLDocument_put_designMode,
    HTMLDocument_get_designMode,
    HTMLDocument_get_selection,
    HTMLDocument_get_readyState,
    HTMLDocument_get_frames,
    HTMLDocument_get_embeds,
    HTMLDocument_get_plugins,
    HTMLDocument_put_alinkColor,
    HTMLDocument_get_alinkColor,
    HTMLDocument_put_bgColor,
    HTMLDocument_get_bgColor,
    HTMLDocument_put_fgColor,
    HTMLDocument_get_fgColor,
    HTMLDocument_put_linkColor,
    HTMLDocument_get_linkColor,
    HTMLDocument_put_vlinkColor,
    HTMLDocument_get_vlinkColor,
    HTMLDocument_get_referrer,
    HTMLDocument_get_location,
    HTMLDocument_get_lastModified,
    HTMLDocument_put_URL,
    HTMLDocument_get_URL,
    HTMLDocument_put_domain,
    HTMLDocument_get_domain,
    HTMLDocument_put_cookie,
    HTMLDocument_get_cookie,
    HTMLDocument_put_expando,
    HTMLDocument_get_expando,
    HTMLDocument_put_charset,
    HTMLDocument_get_charset,
    HTMLDocument_put_defaultCharset,
    HTMLDocument_get_defaultCharset,
    HTMLDocument_get_mimeType,
    HTMLDocument_get_fileSize,
    HTMLDocument_get_fileCreatedDate,
    HTMLDocument_get_fileModifiedDate,
    HTMLDocument_get_fileUpdatedDate,
    HTMLDocument_get_security,
    HTMLDocument_get_protocol,
    HTMLDocument_get_nameProp,
    HTMLDocument_write,
    HTMLDocument_writeln,
    HTMLDocument_open,
    HTMLDocument_close,
    HTMLDocument_clear,
    HTMLDocument_queryCommandSupported,
    HTMLDocument_queryCommandEnabled,
    HTMLDocument_queryCommandState,
    HTMLDocument_queryCommandIndeterm,
    HTMLDocument_queryCommandText,
    HTMLDocument_queryCommandValue,
    HTMLDocument_execCommand,
    HTMLDocument_execCommandShowHelp,
    HTMLDocument_createElement,
    HTMLDocument_put_onhelp,
    HTMLDocument_get_onhelp,
    HTMLDocument_put_onclick,
    HTMLDocument_get_onclick,
    HTMLDocument_put_ondblclick,
    HTMLDocument_get_ondblclick,
    HTMLDocument_put_onkeyup,
    HTMLDocument_get_onkeyup,
    HTMLDocument_put_onkeydown,
    HTMLDocument_get_onkeydown,
    HTMLDocument_put_onkeypress,
    HTMLDocument_get_onkeypress,
    HTMLDocument_put_onmouseup,
    HTMLDocument_get_onmouseup,
    HTMLDocument_put_onmousedown,
    HTMLDocument_get_onmousedown,
    HTMLDocument_put_onmousemove,
    HTMLDocument_get_onmousemove,
    HTMLDocument_put_onmouseout,
    HTMLDocument_get_onmouseout,
    HTMLDocument_put_onmouseover,
    HTMLDocument_get_onmouseover,
    HTMLDocument_put_onreadystatechange,
    HTMLDocument_get_onreadystatechange,
    HTMLDocument_put_onafterupdate,
    HTMLDocument_get_onafterupdate,
    HTMLDocument_put_onrowexit,
    HTMLDocument_get_onrowexit,
    HTMLDocument_put_onrowenter,
    HTMLDocument_get_onrowenter,
    HTMLDocument_put_ondragstart,
    HTMLDocument_get_ondragstart,
    HTMLDocument_put_onselectstart,
    HTMLDocument_get_onselectstart,
    HTMLDocument_elementFromPoint,
    HTMLDocument_get_parentWindow,
    HTMLDocument_get_styleSheets,
    HTMLDocument_put_onbeforeupdate,
    HTMLDocument_get_onbeforeupdate,
    HTMLDocument_put_onerrorupdate,
    HTMLDocument_get_onerrorupdate,
    HTMLDocument_toString,
    HTMLDocument_createStyleSheet
};

1511 1512
static void HTMLDocument_on_advise(IUnknown *iface, cp_static_data_t *cp)
{
1513
    HTMLDocument *This = impl_from_IHTMLDocument2((IHTMLDocument2*)iface);
1514 1515

    if(This->window)
1516
        update_cp_events(This->window, &This->doc_node->node.event_target, cp, This->doc_node->node.nsnode);
1517 1518
}

1519 1520 1521 1522
static inline HTMLDocument *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, ISupportErrorInfo_iface);
}
1523 1524 1525

static HRESULT WINAPI SupportErrorInfo_QueryInterface(ISupportErrorInfo *iface, REFIID riid, void **ppv)
{
1526
    HTMLDocument *This = impl_from_ISupportErrorInfo(iface);
1527
    return htmldoc_query_interface(This, riid, ppv);
1528 1529 1530 1531
}

static ULONG WINAPI SupportErrorInfo_AddRef(ISupportErrorInfo *iface)
{
1532
    HTMLDocument *This = impl_from_ISupportErrorInfo(iface);
1533
    return htmldoc_addref(This);
1534 1535 1536 1537
}

static ULONG WINAPI SupportErrorInfo_Release(ISupportErrorInfo *iface)
{
1538
    HTMLDocument *This = impl_from_ISupportErrorInfo(iface);
1539
    return htmldoc_release(This);
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554
}

static HRESULT WINAPI SupportErrorInfo_InterfaceSupportsErrorInfo(ISupportErrorInfo *iface, REFIID riid)
{
    FIXME("(%p)->(%s)\n", iface, debugstr_guid(riid));
    return S_FALSE;
}

static const ISupportErrorInfoVtbl SupportErrorInfoVtbl = {
    SupportErrorInfo_QueryInterface,
    SupportErrorInfo_AddRef,
    SupportErrorInfo_Release,
    SupportErrorInfo_InterfaceSupportsErrorInfo
};

1555 1556 1557 1558
static inline HTMLDocument *impl_from_IDispatchEx(IDispatchEx *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocument, IDispatchEx_iface);
}
1559 1560 1561

static HRESULT WINAPI DocDispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
{
1562
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1563

1564
    return htmldoc_query_interface(This, riid, ppv);
1565 1566 1567 1568
}

static ULONG WINAPI DocDispatchEx_AddRef(IDispatchEx *iface)
{
1569
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1570

1571
    return htmldoc_addref(This);
1572 1573 1574 1575
}

static ULONG WINAPI DocDispatchEx_Release(IDispatchEx *iface)
{
1576
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1577

1578
    return htmldoc_release(This);
1579 1580 1581 1582
}

static HRESULT WINAPI DocDispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
{
1583
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1584

1585
    return IDispatchEx_GetTypeInfoCount(This->dispex, pctinfo);
1586 1587 1588 1589 1590
}

static HRESULT WINAPI DocDispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
                                               LCID lcid, ITypeInfo **ppTInfo)
{
1591
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1592

1593
    return IDispatchEx_GetTypeInfo(This->dispex, iTInfo, lcid, ppTInfo);
1594 1595 1596 1597 1598 1599
}

static HRESULT WINAPI DocDispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
                                                 LPOLESTR *rgszNames, UINT cNames,
                                                 LCID lcid, DISPID *rgDispId)
{
1600
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1601

1602
    return IDispatchEx_GetIDsOfNames(This->dispex, riid, rgszNames, cNames, lcid, rgDispId);
1603 1604 1605 1606 1607 1608
}

static HRESULT WINAPI DocDispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
1609
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621

    TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
          lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);

    switch(dispIdMember) {
    case DISPID_READYSTATE:
        TRACE("DISPID_READYSTATE\n");

        if(!(wFlags & DISPATCH_PROPERTYGET))
            return E_INVALIDARG;

        V_VT(pVarResult) = VT_I4;
1622
        V_I4(pVarResult) = This->window->readystate;
1623 1624 1625
        return S_OK;
    }

1626
    return IDispatchEx_Invoke(This->dispex, dispIdMember, riid, lcid, wFlags, pDispParams,
1627 1628 1629 1630 1631
                              pVarResult, pExcepInfo, puArgErr);
}

static HRESULT WINAPI DocDispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
{
1632
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1633

1634
    return IDispatchEx_GetDispID(This->dispex, bstrName, grfdex, pid);
1635 1636 1637 1638 1639
}

static HRESULT WINAPI DocDispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
1640
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1641

1642
    if(This->window && id == DISPID_IHTMLDOCUMENT2_LOCATION && (wFlags & DISPATCH_PROPERTYPUT))
1643 1644
        return IDispatchEx_InvokeEx(&This->window->IDispatchEx_iface, DISPID_IHTMLWINDOW2_LOCATION,
                lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1645 1646


1647
    return IDispatchEx_InvokeEx(This->dispex, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
1648 1649 1650 1651
}

static HRESULT WINAPI DocDispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
{
1652
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1653

1654
    return IDispatchEx_DeleteMemberByName(This->dispex, bstrName, grfdex);
1655 1656 1657 1658
}

static HRESULT WINAPI DocDispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
{
1659
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1660

1661
    return IDispatchEx_DeleteMemberByDispID(This->dispex, id);
1662 1663 1664 1665
}

static HRESULT WINAPI DocDispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
{
1666
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1667

1668
    return IDispatchEx_GetMemberProperties(This->dispex, id, grfdexFetch, pgrfdex);
1669 1670 1671 1672
}

static HRESULT WINAPI DocDispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
{
1673
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1674

1675
    return IDispatchEx_GetMemberName(This->dispex, id, pbstrName);
1676 1677 1678 1679
}

static HRESULT WINAPI DocDispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
{
1680
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1681

1682
    return IDispatchEx_GetNextDispID(This->dispex, grfdex, id, pid);
1683 1684 1685 1686
}

static HRESULT WINAPI DocDispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
{
1687
    HTMLDocument *This = impl_from_IDispatchEx(iface);
1688

1689
    return IDispatchEx_GetNameSpaceParent(This->dispex, ppunk);
1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709
}

static const IDispatchExVtbl DocDispatchExVtbl = {
    DocDispatchEx_QueryInterface,
    DocDispatchEx_AddRef,
    DocDispatchEx_Release,
    DocDispatchEx_GetTypeInfoCount,
    DocDispatchEx_GetTypeInfo,
    DocDispatchEx_GetIDsOfNames,
    DocDispatchEx_Invoke,
    DocDispatchEx_GetDispID,
    DocDispatchEx_InvokeEx,
    DocDispatchEx_DeleteMemberByName,
    DocDispatchEx_DeleteMemberByDispID,
    DocDispatchEx_GetMemberProperties,
    DocDispatchEx_GetMemberName,
    DocDispatchEx_GetNextDispID,
    DocDispatchEx_GetNameSpaceParent
};

1710
static BOOL htmldoc_qi(HTMLDocument *This, REFIID riid, void **ppv)
1711 1712 1713 1714 1715
{
    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown, %p)\n", This, ppv);
1716
        *ppv = &This->IHTMLDocument2_iface;
1717 1718
    }else if(IsEqualGUID(&IID_IDispatch, riid)) {
        TRACE("(%p)->(IID_IDispatch, %p)\n", This, ppv);
1719
        *ppv = &This->IDispatchEx_iface;
1720 1721
    }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
        TRACE("(%p)->(IID_IDispatchEx, %p)\n", This, ppv);
1722
        *ppv = &This->IDispatchEx_iface;
1723 1724
    }else if(IsEqualGUID(&IID_IHTMLDocument, riid)) {
        TRACE("(%p)->(IID_IHTMLDocument, %p)\n", This, ppv);
1725
        *ppv = &This->IHTMLDocument2_iface;
1726 1727
    }else if(IsEqualGUID(&IID_IHTMLDocument2, riid)) {
        TRACE("(%p)->(IID_IHTMLDocument2, %p)\n", This, ppv);
1728
        *ppv = &This->IHTMLDocument2_iface;
1729 1730
    }else if(IsEqualGUID(&IID_IHTMLDocument3, riid)) {
        TRACE("(%p)->(IID_IHTMLDocument3, %p)\n", This, ppv);
1731
        *ppv = &This->IHTMLDocument3_iface;
1732 1733
    }else if(IsEqualGUID(&IID_IHTMLDocument4, riid)) {
        TRACE("(%p)->(IID_IHTMLDocument4, %p)\n", This, ppv);
1734
        *ppv = &This->IHTMLDocument4_iface;
1735 1736
    }else if(IsEqualGUID(&IID_IHTMLDocument5, riid)) {
        TRACE("(%p)->(IID_IHTMLDocument5, %p)\n", This, ppv);
1737
        *ppv = &This->IHTMLDocument5_iface;
1738 1739
    }else if(IsEqualGUID(&IID_IHTMLDocument6, riid)) {
        TRACE("(%p)->(IID_IHTMLDocument6, %p)\n", This, ppv);
1740
        *ppv = &This->IHTMLDocument6_iface;
1741 1742
    }else if(IsEqualGUID(&IID_IPersist, riid)) {
        TRACE("(%p)->(IID_IPersist, %p)\n", This, ppv);
1743
        *ppv = &This->IPersistFile_iface;
1744 1745
    }else if(IsEqualGUID(&IID_IPersistMoniker, riid)) {
        TRACE("(%p)->(IID_IPersistMoniker, %p)\n", This, ppv);
1746
        *ppv = &This->IPersistMoniker_iface;
1747 1748
    }else if(IsEqualGUID(&IID_IPersistFile, riid)) {
        TRACE("(%p)->(IID_IPersistFile, %p)\n", This, ppv);
1749
        *ppv = &This->IPersistFile_iface;
1750 1751
    }else if(IsEqualGUID(&IID_IMonikerProp, riid)) {
        TRACE("(%p)->(IID_IMonikerProp, %p)\n", This, ppv);
1752
        *ppv = &This->IMonikerProp_iface;
1753 1754
    }else if(IsEqualGUID(&IID_IOleObject, riid)) {
        TRACE("(%p)->(IID_IOleObject, %p)\n", This, ppv);
1755
        *ppv = &This->IOleObject_iface;
1756 1757
    }else if(IsEqualGUID(&IID_IOleDocument, riid)) {
        TRACE("(%p)->(IID_IOleDocument, %p)\n", This, ppv);
1758
        *ppv = &This->IOleDocument_iface;
1759 1760
    }else if(IsEqualGUID(&IID_IOleDocumentView, riid)) {
        TRACE("(%p)->(IID_IOleDocumentView, %p)\n", This, ppv);
1761
        *ppv = &This->IOleDocumentView_iface;
1762 1763
    }else if(IsEqualGUID(&IID_IOleInPlaceActiveObject, riid)) {
        TRACE("(%p)->(IID_IOleInPlaceActiveObject, %p)\n", This, ppv);
1764
        *ppv = &This->IOleInPlaceActiveObject_iface;
1765 1766
    }else if(IsEqualGUID(&IID_IViewObject, riid)) {
        TRACE("(%p)->(IID_IViewObject, %p)\n", This, ppv);
1767
        *ppv = &This->IViewObjectEx_iface;
1768 1769
    }else if(IsEqualGUID(&IID_IViewObject2, riid)) {
        TRACE("(%p)->(IID_IViewObject2, %p)\n", This, ppv);
1770
        *ppv = &This->IViewObjectEx_iface;
1771 1772
    }else if(IsEqualGUID(&IID_IViewObjectEx, riid)) {
        TRACE("(%p)->(IID_IViewObjectEx, %p)\n", This, ppv);
1773
        *ppv = &This->IViewObjectEx_iface;
1774 1775
    }else if(IsEqualGUID(&IID_IOleWindow, riid)) {
        TRACE("(%p)->(IID_IOleWindow, %p)\n", This, ppv);
1776
        *ppv = &This->IOleInPlaceActiveObject_iface;
1777 1778
    }else if(IsEqualGUID(&IID_IOleInPlaceObject, riid)) {
        TRACE("(%p)->(IID_IOleInPlaceObject, %p)\n", This, ppv);
1779
        *ppv = &This->IOleInPlaceObjectWindowless_iface;
1780 1781
    }else if(IsEqualGUID(&IID_IOleInPlaceObjectWindowless, riid)) {
        TRACE("(%p)->(IID_IOleInPlaceObjectWindowless, %p)\n", This, ppv);
1782
        *ppv = &This->IOleInPlaceObjectWindowless_iface;
1783 1784
    }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
        TRACE("(%p)->(IID_IServiceProvider, %p)\n", This, ppv);
1785
        *ppv = &This->IServiceProvider_iface;
1786 1787
    }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
        TRACE("(%p)->(IID_IOleCommandTarget, %p)\n", This, ppv);
1788
        *ppv = &This->IOleCommandTarget_iface;
1789 1790
    }else if(IsEqualGUID(&IID_IOleControl, riid)) {
        TRACE("(%p)->(IID_IOleControl, %p)\n", This, ppv);
1791
        *ppv = &This->IOleControl_iface;
1792 1793
    }else if(IsEqualGUID(&IID_IHlinkTarget, riid)) {
        TRACE("(%p)->(IID_IHlinkTarget, %p)\n", This, ppv);
1794
        *ppv = &This->IHlinkTarget_iface;
1795 1796
    }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
        TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
1797
        *ppv = &This->cp_container.IConnectionPointContainer_iface;
1798 1799
    }else if(IsEqualGUID(&IID_IPersistStreamInit, riid)) {
        TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
1800
        *ppv = &This->IPersistStreamInit_iface;
1801 1802
    }else if(IsEqualGUID(&DIID_DispHTMLDocument, riid)) {
        TRACE("(%p)->(DIID_DispHTMLDocument %p)\n", This, ppv);
1803
        *ppv = &This->IHTMLDocument2_iface;
1804 1805
    }else if(IsEqualGUID(&IID_ISupportErrorInfo, riid)) {
        TRACE("(%p)->(IID_ISupportErrorInfo %p)\n", This, ppv);
1806
        *ppv = &This->ISupportErrorInfo_iface;
1807 1808
    }else if(IsEqualGUID(&IID_IPersistHistory, riid)) {
        TRACE("(%p)->(IID_IPersistHistory %p)\n", This, ppv);
1809
        *ppv = &This->IPersistHistory_iface;
1810 1811
    }else if(IsEqualGUID(&CLSID_CMarkup, riid)) {
        FIXME("(%p)->(CLSID_CMarkup %p)\n", This, ppv);
1812
        *ppv = NULL;
1813 1814
    }else if(IsEqualGUID(&IID_IRunnableObject, riid)) {
        TRACE("(%p)->(IID_IRunnableObject %p) returning NULL\n", This, ppv);
1815
        *ppv = NULL;
1816 1817
    }else if(IsEqualGUID(&IID_IPersistPropertyBag, riid)) {
        TRACE("(%p)->(IID_IPersistPropertyBag %p) returning NULL\n", This, ppv);
1818
        *ppv = NULL;
1819 1820
    }else if(IsEqualGUID(&IID_IMarshal, riid)) {
        TRACE("(%p)->(IID_IMarshal %p) returning NULL\n", This, ppv);
1821
        *ppv = NULL;
1822 1823 1824
    }else if(IsEqualGUID(&IID_IExternalConnection, riid)) {
        TRACE("(%p)->(IID_IExternalConnection %p) returning NULL\n", This, ppv);
        *ppv = NULL;
1825 1826 1827
    }else if(IsEqualGUID(&IID_IStdMarshalInfo, riid)) {
        TRACE("(%p)->(IID_IStdMarshalInfo %p) returning NULL\n", This, ppv);
        *ppv = NULL;
1828 1829
    }else if(IsEqualGUID(&IID_IObjectWithSite, riid)) {
        TRACE("(%p)->(IID_IObjectWithSite %p)\n", This, ppv);
1830
        *ppv = &This->IObjectWithSite_iface;
1831 1832 1833
    }else if(IsEqualGUID(&IID_IOleContainer, riid)) {
        TRACE("(%p)->(IID_IOleContainer %p)\n", This, ppv);
        *ppv = &This->IOleContainer_iface;
1834 1835 1836
    }else if(IsEqualGUID(&IID_IObjectSafety, riid)) {
        TRACE("(%p)->(IID_IObjectSafety %p)\n", This, ppv);
        *ppv = &This->IObjectSafety_iface;
1837
    }else {
1838
        return FALSE;
1839 1840
    }

1841 1842 1843
    if(*ppv)
        IUnknown_AddRef((IUnknown*)*ppv);
    return TRUE;
1844 1845
}

1846
static cp_static_data_t HTMLDocumentEvents_data = { HTMLDocumentEvents_tid, HTMLDocument_on_advise };
1847

1848
static void init_doc(HTMLDocument *doc, IUnknown *unk_impl, IDispatchEx *dispex)
1849
{
1850
    doc->IHTMLDocument2_iface.lpVtbl = &HTMLDocumentVtbl;
1851
    doc->IDispatchEx_iface.lpVtbl = &DocDispatchExVtbl;
1852
    doc->ISupportErrorInfo_iface.lpVtbl = &SupportErrorInfoVtbl;
1853

1854
    doc->unk_impl = unk_impl;
1855
    doc->dispex = dispex;
1856
    doc->task_magic = get_task_target_magic();
1857

1858 1859 1860 1861 1862 1863 1864 1865 1866 1867
    HTMLDocument_HTMLDocument3_Init(doc);
    HTMLDocument_HTMLDocument5_Init(doc);
    HTMLDocument_Persist_Init(doc);
    HTMLDocument_OleCmd_Init(doc);
    HTMLDocument_OleObj_Init(doc);
    HTMLDocument_View_Init(doc);
    HTMLDocument_Window_Init(doc);
    HTMLDocument_Service_Init(doc);
    HTMLDocument_Hlink_Init(doc);

1868
    ConnectionPointContainer_Init(&doc->cp_container, (IUnknown*)&doc->IHTMLDocument2_iface);
1869
    ConnectionPoint_Init(&doc->cp_dispatch, &doc->cp_container, &IID_IDispatch, &HTMLDocumentEvents_data);
1870 1871 1872
    ConnectionPoint_Init(&doc->cp_propnotif, &doc->cp_container, &IID_IPropertyNotifySink, NULL);
    ConnectionPoint_Init(&doc->cp_htmldocevents, &doc->cp_container, &DIID_HTMLDocumentEvents, &HTMLDocumentEvents_data);
    ConnectionPoint_Init(&doc->cp_htmldocevents2, &doc->cp_container, &DIID_HTMLDocumentEvents2, NULL);
1873
}
1874

1875 1876
static void destroy_htmldoc(HTMLDocument *This)
{
1877
    remove_target_tasks(This->task_magic);
1878 1879 1880 1881

    ConnectionPointContainer_Destroy(&This->cp_container);
}

1882 1883 1884 1885
static inline HTMLDocumentNode *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocumentNode, node);
}
1886 1887 1888

static HRESULT HTMLDocumentNode_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
{
1889
    HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface);
1890 1891 1892 1893

    if(htmldoc_qi(&This->basedoc, riid, ppv))
        return *ppv ? S_OK : E_NOINTERFACE;

1894 1895
    if(IsEqualGUID(&IID_IInternetHostSecurityManager, riid)) {
        TRACE("(%p)->(IID_IInternetHostSecurityManager %p)\n", This, ppv);
1896
        *ppv = &This->IInternetHostSecurityManager_iface;
1897 1898 1899 1900 1901 1902
    }else {
        return HTMLDOMNode_QI(&This->node, riid, ppv);
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
1903 1904
}

1905
static void HTMLDocumentNode_destructor(HTMLDOMNode *iface)
1906
{
1907
    HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface);
1908

1909 1910
    if(This->body_event_target)
        release_event_target(This->body_event_target);
1911 1912
    if(This->nsevent_listener)
        release_nsevents(This);
1913 1914
    if(This->catmgr)
        ICatInformation_Release(This->catmgr);
1915

1916 1917 1918
    detach_selection(This);
    detach_ranges(This);
    release_nodes(This);
1919

1920 1921 1922
    while(!list_empty(&This->plugin_hosts))
        detach_plugin_host(LIST_ENTRY(list_head(&This->plugin_hosts), PluginHost, entry));

1923
    if(This->nsdoc) {
1924
        release_document_mutation(This);
1925
        nsIDOMHTMLDocument_Release(This->nsdoc);
1926
    }
1927

1928
    heap_free(This->event_vector);
1929 1930 1931
    destroy_htmldoc(&This->basedoc);
}

1932 1933
static HRESULT HTMLDocumentNode_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode **ret)
{
1934
    HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface);
1935 1936 1937 1938
    FIXME("%p\n", This);
    return E_NOTIMPL;
}

1939 1940
static const NodeImplVtbl HTMLDocumentNodeImplVtbl = {
    HTMLDocumentNode_QI,
1941 1942
    HTMLDocumentNode_destructor,
    HTMLDocumentNode_clone
1943 1944
};

1945 1946
static HRESULT HTMLDocumentFragment_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode **ret)
{
1947
    HTMLDocumentNode *This = impl_from_HTMLDOMNode(iface);
1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964
    HTMLDocumentNode *new_node;
    HRESULT hres;

    hres = create_document_fragment(nsnode, This->node.doc, &new_node);
    if(FAILED(hres))
        return hres;

    *ret = &new_node->node;
    return S_OK;
}

static const NodeImplVtbl HTMLDocumentFragmentImplVtbl = {
    HTMLDocumentNode_QI,
    HTMLDocumentNode_destructor,
    HTMLDocumentFragment_clone
};

1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981
static const tid_t HTMLDocumentNode_iface_tids[] = {
    IHTMLDOMNode_tid,
    IHTMLDOMNode2_tid,
    IHTMLDocument2_tid,
    IHTMLDocument3_tid,
    IHTMLDocument4_tid,
    IHTMLDocument5_tid,
    0
};

static dispex_static_data_t HTMLDocumentNode_dispex = {
    NULL,
    DispHTMLDocument_tid,
    NULL,
    HTMLDocumentNode_iface_tids
};

1982
static HTMLDocumentNode *alloc_doc_node(HTMLDocumentObj *doc_obj, HTMLWindow *window)
1983 1984
{
    HTMLDocumentNode *doc;
1985

1986 1987
    doc = heap_alloc_zero(sizeof(HTMLDocumentNode));
    if(!doc)
1988
        return NULL;
1989

1990
    doc->ref = 1;
1991 1992
    doc->basedoc.doc_node = doc;
    doc->basedoc.doc_obj = doc_obj;
1993
    doc->basedoc.window = window;
1994

1995 1996 1997
    init_dispex(&doc->node.dispex, (IUnknown*)&doc->node.IHTMLDOMNode_iface,
            &HTMLDocumentNode_dispex);
    init_doc(&doc->basedoc, (IUnknown*)&doc->node.IHTMLDOMNode_iface,
1998
            &doc->node.dispex.IDispatchEx_iface);
1999
    HTMLDocumentNode_SecMgr_Init(doc);
2000

2001 2002 2003 2004 2005
    init_nsevents(doc);

    list_init(&doc->bindings);
    list_init(&doc->selection_list);
    list_init(&doc->range_list);
2006
    list_init(&doc->plugin_hosts);
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018

    return doc;
}

HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocumentObj *doc_obj, HTMLWindow *window, HTMLDocumentNode **ret)
{
    HTMLDocumentNode *doc;

    doc = alloc_doc_node(doc_obj, window);
    if(!doc)
        return E_OUTOFMEMORY;

2019
    if(!doc_obj->basedoc.window || window == doc_obj->basedoc.window)
2020
        doc->basedoc.cp_container.forward_container = &doc_obj->basedoc.cp_container;
2021

2022
    nsIDOMHTMLDocument_AddRef(nsdoc);
2023
    doc->nsdoc = nsdoc;
2024
    init_document_mutation(doc);
2025

2026 2027
    HTMLDOMNode_Init(doc, &doc->node, (nsIDOMNode*)nsdoc);
    doc->node.vtbl = &HTMLDocumentNodeImplVtbl;
2028
    doc->node.cp_container = &doc->basedoc.cp_container;
2029

2030 2031 2032
    *ret = doc;
    return S_OK;
}
2033

2034 2035 2036 2037 2038 2039 2040 2041 2042
HRESULT create_document_fragment(nsIDOMNode *nsnode, HTMLDocumentNode *doc_node, HTMLDocumentNode **ret)
{
    HTMLDocumentNode *doc_frag;

    doc_frag = alloc_doc_node(doc_node->basedoc.doc_obj, doc_node->basedoc.window);
    if(!doc_frag)
        return E_OUTOFMEMORY;

    HTMLDOMNode_Init(doc_node, &doc_frag->node, nsnode);
2043
    doc_frag->node.vtbl = &HTMLDocumentFragmentImplVtbl;
2044 2045 2046 2047 2048 2049 2050
    doc_frag->node.cp_container = &doc_frag->basedoc.cp_container;

    htmldoc_addref(&doc_frag->basedoc);
    *ret = doc_frag;
    return S_OK;
}

2051 2052 2053 2054
/**********************************************************
 * ICustomDoc implementation
 */

2055 2056 2057 2058
static inline HTMLDocumentObj *impl_from_ICustomDoc(ICustomDoc *iface)
{
    return CONTAINING_RECORD(iface, HTMLDocumentObj, ICustomDoc_iface);
}
2059 2060 2061

static HRESULT WINAPI CustomDoc_QueryInterface(ICustomDoc *iface, REFIID riid, void **ppv)
{
2062
    HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
2063

2064 2065 2066
    if(htmldoc_qi(&This->basedoc, riid, ppv))
        return *ppv ? S_OK : E_NOINTERFACE;

2067 2068
    if(IsEqualGUID(&IID_ICustomDoc, riid)) {
        TRACE("(%p)->(IID_ICustomDoc %p)\n", This, ppv);
2069
        *ppv = &This->ICustomDoc_iface;
2070 2071
    }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
        return *ppv ? S_OK : E_NOINTERFACE;
2072 2073 2074 2075 2076 2077 2078 2079
    }else {
        FIXME("Unimplemented interface %s\n", debugstr_guid(riid));
        *ppv = NULL;
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
2080 2081
}

2082
static ULONG WINAPI CustomDoc_AddRef(ICustomDoc *iface)
2083
{
2084
    HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
2085 2086 2087 2088 2089 2090 2091
    ULONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref = %u\n", This, ref);

    return ref;
}

2092
static ULONG WINAPI CustomDoc_Release(ICustomDoc *iface)
2093
{
2094
    HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
2095 2096 2097 2098 2099
    ULONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref = %u\n", This, ref);

    if(!ref) {
2100 2101
        if(This->basedoc.doc_node) {
            This->basedoc.doc_node->basedoc.doc_obj = NULL;
2102
            htmldoc_release(&This->basedoc.doc_node->basedoc);
2103
        }
2104 2105
        if(This->basedoc.window) {
            This->basedoc.window->doc_obj = NULL;
2106
            IHTMLWindow2_Release(&This->basedoc.window->IHTMLWindow2_iface);
2107
        }
2108 2109
        if(This->basedoc.advise_holder)
            IOleAdviseHolder_Release(This->basedoc.advise_holder);
2110

2111 2112
        if(This->view_sink)
            IAdviseSink_Release(This->view_sink);
2113
        if(This->client)
2114
            IOleObject_SetClientSite(&This->basedoc.IOleObject_iface, NULL);
2115
        if(This->hostui)
2116
            ICustomDoc_SetUIHandler(&This->ICustomDoc_iface, NULL);
2117
        if(This->in_place_active)
2118
            IOleInPlaceObjectWindowless_InPlaceDeactivate(&This->basedoc.IOleInPlaceObjectWindowless_iface);
2119
        if(This->ipsite)
2120
            IOleDocumentView_SetInPlaceSite(&This->basedoc.IOleDocumentView_iface, NULL);
2121 2122
        if(This->undomgr)
            IOleUndoManager_Release(This->undomgr);
2123 2124 2125 2126 2127
        if(This->tooltips_hwnd)
            DestroyWindow(This->tooltips_hwnd);

        if(This->hwnd)
            DestroyWindow(This->hwnd);
2128
        heap_free(This->mime);
2129

2130
        destroy_htmldoc(&This->basedoc);
2131
        release_dispex(&This->dispex);
2132

2133 2134
        if(This->nscontainer)
            NSContainer_Release(This->nscontainer);
2135 2136 2137 2138 2139 2140
        heap_free(This);
    }

    return ref;
}

2141 2142
static HRESULT WINAPI CustomDoc_SetUIHandler(ICustomDoc *iface, IDocHostUIHandler *pUIHandler)
{
2143
    HTMLDocumentObj *This = impl_from_ICustomDoc(iface);
2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168
    IOleCommandTarget *cmdtrg;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, pUIHandler);

    if(This->custom_hostui && This->hostui == pUIHandler)
        return S_OK;

    This->custom_hostui = TRUE;

    if(This->hostui)
        IDocHostUIHandler_Release(This->hostui);
    if(pUIHandler)
        IDocHostUIHandler_AddRef(pUIHandler);
    This->hostui = pUIHandler;
    if(!pUIHandler)
        return S_OK;

    hres = IDocHostUIHandler_QueryInterface(pUIHandler, &IID_IOleCommandTarget, (void**)&cmdtrg);
    if(SUCCEEDED(hres)) {
        FIXME("custom UI handler supports IOleCommandTarget\n");
        IOleCommandTarget_Release(cmdtrg);
    }

    return S_OK;
2169 2170 2171 2172 2173 2174 2175
}

static const ICustomDocVtbl CustomDocVtbl = {
    CustomDoc_QueryInterface,
    CustomDoc_AddRef,
    CustomDoc_Release,
    CustomDoc_SetUIHandler
2176 2177
};

2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191
static const tid_t HTMLDocumentObj_iface_tids[] = {
    IHTMLDocument2_tid,
    IHTMLDocument3_tid,
    IHTMLDocument4_tid,
    IHTMLDocument5_tid,
    0
};
static dispex_static_data_t HTMLDocumentObj_dispex = {
    NULL,
    DispHTMLDocument_tid,
    NULL,
    HTMLDocumentObj_iface_tids
};

2192 2193
HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
{
2194
    HTMLDocumentObj *doc;
2195
    nsIDOMWindow *nswindow = NULL;
2196
    nsresult nsres;
2197 2198 2199
    HRESULT hres;

    TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppvObject);
2200

2201 2202 2203 2204
    doc = heap_alloc_zero(sizeof(HTMLDocumentObj));
    if(!doc)
        return E_OUTOFMEMORY;

2205 2206
    init_dispex(&doc->dispex, (IUnknown*)&doc->ICustomDoc_iface, &HTMLDocumentObj_dispex);
    init_doc(&doc->basedoc, (IUnknown*)&doc->ICustomDoc_iface, &doc->dispex.IDispatchEx_iface);
2207

2208
    doc->ICustomDoc_iface.lpVtbl = &CustomDocVtbl;
2209
    doc->ref = 1;
2210
    doc->basedoc.doc_obj = doc;
2211

2212 2213 2214 2215 2216 2217 2218 2219 2220
    doc->usermode = UNKNOWN_USERMODE;

    doc->nscontainer = NSContainer_Create(doc, NULL);
    if(!doc->nscontainer) {
        ERR("Failed to init Gecko, returning CLASS_E_CLASSNOTAVAILABLE\n");
        htmldoc_release(&doc->basedoc);
        return CLASS_E_CLASSNOTAVAILABLE;
    }

2221 2222
    hres = htmldoc_query_interface(&doc->basedoc, riid, ppvObject);
    htmldoc_release(&doc->basedoc);
2223 2224 2225
    if(FAILED(hres))
        return hres;

2226

2227 2228 2229
    nsres = nsIWebBrowser_GetContentDOMWindow(doc->nscontainer->webbrowser, &nswindow);
    if(NS_FAILED(nsres))
        ERR("GetContentDOMWindow failed: %08x\n", nsres);
2230

2231
    hres = HTMLWindow_Create(doc, nswindow, NULL /* FIXME */, &doc->basedoc.window);
2232 2233
    if(nswindow)
        nsIDOMWindow_Release(nswindow);
2234
    if(FAILED(hres)) {
2235
        htmldoc_release(&doc->basedoc);
2236 2237
        return hres;
    }
2238

2239 2240 2241 2242 2243
    if(!doc->basedoc.doc_node && doc->basedoc.window->doc) {
        doc->basedoc.doc_node = doc->basedoc.window->doc;
        htmldoc_addref(&doc->basedoc.doc_node->basedoc);
    }

2244 2245
    get_thread_hwnd();

2246
    return S_OK;
2247
}