htmlbody.c 22.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Copyright 2006 Jacek Caban for CodeWeavers
 *
 * 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 29 30 31 32 33 34 35
 */

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

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"

#include "wine/debug.h"

#include "mshtml_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(mshtml);

typedef struct {
36
    HTMLTextContainer textcont;
37

38 39
    const IHTMLBodyElementVtbl *lpHTMLBodyElementVtbl;

40
    ConnectionPoint cp_propnotif;
41

42 43 44
    nsIDOMHTMLBodyElement *nsbody;
} HTMLBodyElement;

45
#define HTMLBODY(x)  (&(x)->lpHTMLBodyElementVtbl)
46

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
static const WCHAR aquaW[] = {'a','q','u','a',0};
static const WCHAR blackW[] = {'b','l','a','c','k',0};
static const WCHAR blueW[] = {'b','l','u','e',0};
static const WCHAR fuchsiaW[] = {'f','u','s','h','s','i','a',0};
static const WCHAR grayW[] = {'g','r','a','y',0};
static const WCHAR greenW[] = {'g','r','e','e','n',0};
static const WCHAR limeW[] = {'l','i','m','e',0};
static const WCHAR maroonW[] = {'m','a','r','o','o','n',0};
static const WCHAR navyW[] = {'n','a','v','y',0};
static const WCHAR oliveW[] = {'o','l','i','v','e',0};
static const WCHAR purpleW[] = {'p','u','r','p','l','e',0};
static const WCHAR redW[] = {'r','e','d',0};
static const WCHAR silverW[] = {'s','i','l','v','e','r',0};
static const WCHAR tealW[] = {'t','e','a','l',0};
static const WCHAR whiteW[] = {'w','h','i','t','e',0};
static const WCHAR yellowW[] = {'y','e','l','l','o','w',0};

static const struct {
    LPCWSTR keyword;
    const WCHAR hexstr[8];
} keyword_table[] = {
    {aquaW,     {'#','0','0','f','f','f','f',0}},
    {blackW,    {'#','0','0','0','0','0','0',0}},
    {blueW,     {'#','0','0','0','0','f','f',0}},
    {fuchsiaW,  {'#','f','f','0','0','f','f',0}},
    {grayW,     {'#','8','0','8','0','8','0',0}},
    {greenW,    {'#','0','0','8','0','0','0',0}},
    {limeW,     {'#','0','0','f','f','0','0',0}},
    {maroonW,   {'#','8','0','0','0','0','0',0}},
    {navyW,     {'#','0','0','0','0','8','0',0}},
    {oliveW,    {'#','8','0','8','0','0','0',0}},
    {purpleW,   {'#','8','0','0','0','8','0',0}},
    {redW,      {'#','f','f','0','0','0','0',0}},
    {silverW,   {'#','c','0','c','0','c','0',0}},
    {tealW,     {'#','0','0','8','0','8','0',0}},
    {whiteW,    {'#','f','f','f','f','f','f',0}},
    {yellowW,   {'#','f','f','f','f','0','0',0}}
};

static BSTR nscolor_to_str(LPCWSTR color)
{
    int i;

    if(!color || *color == '#')
        return SysAllocString(color);

    for(i=0; i < sizeof(keyword_table)/sizeof(keyword_table[0]); i++) {
        if(!strcmpiW(color, keyword_table[i].keyword))
            return SysAllocString(keyword_table[i].hexstr);
    }

    WARN("unknown color %s\n", debugstr_w(color));
    return SysAllocString(color);
}

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
static BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr)
{
    switch(V_VT(v)) {
    case VT_BSTR:
        nsAString_Init(nsstr, V_BSTR(v));
        return TRUE;

    case VT_I4: {
        PRUnichar buf[10];
        static const WCHAR formatW[] = {'#','%','x',0};

        wsprintfW(buf, formatW, V_I4(v));
        nsAString_Init(nsstr, buf);
        return TRUE;
    }

    default:
        FIXME("invalid vt=%d\n", V_VT(v));
    }

    return FALSE;

}

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
static void nscolor_to_variant(const nsAString *nsstr, VARIANT *p)
{
    const PRUnichar *color;

    nsAString_GetData(nsstr, &color);

    if(*color == '#') {
        V_VT(p) = VT_I4;
        V_I4(p) = strtolW(color+1, NULL, 16);
    }else {
        V_VT(p) = VT_BSTR;
        V_BSTR(p) = SysAllocString(color);
    }
}

141 142 143 144 145 146 147
#define HTMLBODY_THIS(iface) DEFINE_THIS(HTMLBodyElement, HTMLBodyElement, iface)

static HRESULT WINAPI HTMLBodyElement_QueryInterface(IHTMLBodyElement *iface,
                                                     REFIID riid, void **ppv)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);

148
    return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->textcont.element.node), riid, ppv);
149 150 151 152 153 154
}

static ULONG WINAPI HTMLBodyElement_AddRef(IHTMLBodyElement *iface)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);

155
    return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->textcont.element.node));
156 157 158 159 160 161
}

static ULONG WINAPI HTMLBodyElement_Release(IHTMLBodyElement *iface)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);

162
    return IHTMLDOMNode_Release(HTMLDOMNODE(&This->textcont.element.node));
163 164 165 166 167
}

static HRESULT WINAPI HTMLBodyElement_GetTypeInfoCount(IHTMLBodyElement *iface, UINT *pctinfo)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
168
    return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->textcont.element.node.dispex), pctinfo);
169 170 171 172 173 174
}

static HRESULT WINAPI HTMLBodyElement_GetTypeInfo(IHTMLBodyElement *iface, UINT iTInfo,
                                              LCID lcid, ITypeInfo **ppTInfo)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
175
    return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->textcont.element.node.dispex), iTInfo, lcid, ppTInfo);
176 177 178 179 180 181 182
}

static HRESULT WINAPI HTMLBodyElement_GetIDsOfNames(IHTMLBodyElement *iface, REFIID riid,
                                                LPOLESTR *rgszNames, UINT cNames,
                                                LCID lcid, DISPID *rgDispId)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
183
    return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->textcont.element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId);
184 185 186 187 188 189 190
}

static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dispIdMember,
                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                            VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
191 192
    return IDispatchEx_Invoke(DISPATCHEX(&This->textcont.element.node.dispex), dispIdMember, riid, lcid,
            wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
193 194 195 196 197
}

static HRESULT WINAPI HTMLBodyElement_put_background(IHTMLBodyElement *iface, BSTR v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
    HRESULT hr = S_OK;
    nsAString nsstr;
    nsresult nsres;

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

    nsAString_Init(&nsstr, v);

    nsres = nsIDOMHTMLBodyElement_SetBackground(This->nsbody, &nsstr);
    if(!NS_SUCCEEDED(nsres))
    {
        hr = E_FAIL;
    }

    nsAString_Finish(&nsstr);

    return hr;
215 216 217 218 219
}

static HRESULT WINAPI HTMLBodyElement_get_background(IHTMLBodyElement *iface, BSTR *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
220 221 222 223 224 225 226 227 228 229
    nsAString background_str;
    nsresult nsres;

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

    nsAString_Init(&background_str, NULL);

    nsres = nsIDOMHTMLBodyElement_GetBackground(This->nsbody, &background_str);
    if(NS_SUCCEEDED(nsres)) {
        const PRUnichar *background;
230
        nsAString_GetData(&background_str, &background);
231
        *p = *background ? SysAllocString(background) : NULL;
232 233 234 235 236 237 238 239 240
    }else {
        ERR("GetBackground failed: %08x\n", nsres);
        *p = NULL;
    }

    nsAString_Finish(&background_str);

    TRACE("*p = %s\n", debugstr_w(*p));
    return S_OK;
241 242 243 244 245
}

static HRESULT WINAPI HTMLBodyElement_put_bgProperties(IHTMLBodyElement *iface, BSTR v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
246
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
247 248 249 250 251 252
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_bgProperties(IHTMLBodyElement *iface, BSTR *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
253
    FIXME("(%p)->(%p)\n", This, p);
254 255 256 257 258 259
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_leftMargin(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
260
    FIXME("(%p)->()\n", This);
261 262 263 264 265 266
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_leftMargin(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
267
    FIXME("(%p)->(%p)\n", This, p);
268 269 270 271 272 273
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_topMargin(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
274
    FIXME("(%p)->()\n", This);
275 276 277 278 279 280
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_topMargin(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
281
    FIXME("(%p)->(%p)\n", This, p);
282 283 284 285 286 287
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_rightMargin(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
288
    FIXME("(%p)->()\n", This);
289 290 291 292 293 294
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_rightMargin(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
295
    FIXME("(%p)->(%p)\n", This, p);
296 297 298 299 300 301
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_bottomMargin(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
302
    FIXME("(%p)->()\n", This);
303 304 305 306 307 308
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_bottomMargin(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
309
    FIXME("(%p)->(%p)\n", This, p);
310 311 312 313 314 315
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
316
    FIXME("(%p)->(%x)\n", This, v);
317 318 319 320 321 322
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
323
    FIXME("(%p)->(%p)\n", This, p);
324 325 326 327 328 329
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_bgColor(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
330 331 332 333 334 335 336 337 338 339 340 341 342 343
    nsAString strColor;
    nsresult nsres;

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

    if(!variant_to_nscolor(&v, &strColor))
        return S_OK;

    nsres = nsIDOMHTMLBodyElement_SetBgColor(This->nsbody, &strColor);
    nsAString_Finish(&strColor);
    if(NS_FAILED(nsres))
        ERR("SetBgColor failed: %08x\n", nsres);

    return S_OK;
344 345 346 347 348
}

static HRESULT WINAPI HTMLBodyElement_get_bgColor(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
349 350 351 352 353 354 355 356 357 358 359 360 361 362
    nsAString strColor;
    nsresult nsres;
    const PRUnichar *color;

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

    nsAString_Init(&strColor, NULL);
    nsres = nsIDOMHTMLBodyElement_GetBgColor(This->nsbody, &strColor);
    if(NS_FAILED(nsres))
        ERR("SetBgColor failed: %08x\n", nsres);

    nsAString_GetData(&strColor, &color);

    V_VT(p) = VT_BSTR;
363
    V_BSTR(p) = nscolor_to_str(color);
364 365 366 367

    nsAString_Finish(&strColor);

    return S_OK;
368 369 370 371 372
}

static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
373 374 375 376 377 378 379 380 381 382 383 384
    nsAString text;
    nsresult nsres;

    TRACE("(%p)->(v%d)\n", This, V_VT(&v));

    if(!variant_to_nscolor(&v, &text))
        return S_OK;

    nsres = nsIDOMHTMLBodyElement_SetText(This->nsbody, &text);
    nsAString_Finish(&text);

    return S_OK;
385 386 387 388 389
}

static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412
    nsAString text;
    nsresult nsres;

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

    nsAString_Init(&text, NULL);

    V_VT(p) = VT_BSTR;
    V_BSTR(p) = NULL;

    nsres = nsIDOMHTMLBodyElement_GetText(This->nsbody, &text);
    if(NS_SUCCEEDED(nsres))
    {
        const PRUnichar *sText;
        nsAString_GetData(&text, &sText);

        V_VT(p) = VT_BSTR;
        V_BSTR(p) = SysAllocString(sText);
    }

    nsAString_Finish(&text);

    return S_OK;
413 414 415 416 417
}

static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
418 419 420 421 422 423 424 425 426 427 428 429 430 431
    nsAString link_str;
    nsresult nsres;

    TRACE("(%p)->(v%d)\n", This, V_VT(&v));

    if(!variant_to_nscolor(&v, &link_str))
        return S_OK;

    nsres = nsIDOMHTMLBodyElement_SetLink(This->nsbody, &link_str);
    nsAString_Finish(&link_str);
    if(NS_FAILED(nsres))
        ERR("SetLink failed: %08x\n", nsres);

    return S_OK;
432 433 434 435 436
}

static HRESULT WINAPI HTMLBodyElement_get_link(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
437 438 439 440 441 442 443 444 445 446 447 448 449 450
    nsAString link_str;
    nsresult nsres;

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

    nsAString_Init(&link_str, NULL);
    nsres = nsIDOMHTMLBodyElement_GetLink(This->nsbody, &link_str);
    if(NS_FAILED(nsres))
        ERR("GetLink failed: %08x\n", nsres);

    nscolor_to_variant(&link_str, p);
    nsAString_Finish(&link_str);

    return S_OK;
451 452 453 454 455
}

static HRESULT WINAPI HTMLBodyElement_put_vLink(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
456 457 458 459 460 461 462 463 464 465 466 467 468 469
    nsAString vlink_str;
    nsresult nsres;

    TRACE("(%p)->(v%d)\n", This, V_VT(&v));

    if(!variant_to_nscolor(&v, &vlink_str))
        return S_OK;

    nsres = nsIDOMHTMLBodyElement_SetVLink(This->nsbody, &vlink_str);
    nsAString_Finish(&vlink_str);
    if(NS_FAILED(nsres))
        ERR("SetLink failed: %08x\n", nsres);

    return S_OK;
470 471 472 473 474
}

static HRESULT WINAPI HTMLBodyElement_get_vLink(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
475 476 477 478 479 480 481 482 483 484 485 486 487 488
    nsAString vlink_str;
    nsresult nsres;

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

    nsAString_Init(&vlink_str, NULL);
    nsres = nsIDOMHTMLBodyElement_GetVLink(This->nsbody, &vlink_str);
    if(NS_FAILED(nsres))
        ERR("GetLink failed: %08x\n", nsres);

    nscolor_to_variant(&vlink_str, p);
    nsAString_Finish(&vlink_str);

    return S_OK;
489 490 491 492 493
}

static HRESULT WINAPI HTMLBodyElement_put_aLink(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
494 495 496 497 498 499 500 501 502 503 504 505 506 507
    nsAString alink_str;
    nsresult nsres;

    TRACE("(%p)->(v%d)\n", This, V_VT(&v));

    if(!variant_to_nscolor(&v, &alink_str))
        return S_OK;

    nsres = nsIDOMHTMLBodyElement_SetALink(This->nsbody, &alink_str);
    nsAString_Finish(&alink_str);
    if(NS_FAILED(nsres))
        ERR("SetALink failed: %08x\n", nsres);

    return S_OK;
508 509 510 511 512
}

static HRESULT WINAPI HTMLBodyElement_get_aLink(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
513 514 515 516 517 518 519 520 521 522 523 524 525 526
    nsAString alink_str;
    nsresult nsres;

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

    nsAString_Init(&alink_str, NULL);
    nsres = nsIDOMHTMLBodyElement_GetALink(This->nsbody, &alink_str);
    if(NS_FAILED(nsres))
        ERR("GetALink failed: %08x\n", nsres);

    nscolor_to_variant(&alink_str, p);
    nsAString_Finish(&alink_str);

    return S_OK;
527 528 529 530 531
}

static HRESULT WINAPI HTMLBodyElement_put_onload(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
532
    FIXME("(%p)->()\n", This);
533 534 535 536 537 538
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_onload(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
539
    FIXME("(%p)->(%p)\n", This, p);
540 541 542 543 544 545
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_onunload(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
546
    FIXME("(%p)->()\n", This);
547 548 549 550 551 552
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
553
    FIXME("(%p)->(%p)\n", This, p);
554 555 556 557 558 559
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
560
    FIXME("(%p)->(%s)\n", This, debugstr_w(v));
561 562 563 564 565 566
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
567
    FIXME("(%p)->(%p)\n", This, p);
568 569 570 571 572 573
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
574
    FIXME("(%p)->()\n", This);
575 576 577 578 579 580
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_onselect(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
581
    FIXME("(%p)->(%p)\n", This, p);
582 583 584 585 586 587
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_put_onbeforeunload(IHTMLBodyElement *iface, VARIANT v)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
588
    FIXME("(%p)->()\n", This);
589 590 591 592 593 594
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_get_onbeforeunload(IHTMLBodyElement *iface, VARIANT *p)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
595
    FIXME("(%p)->(%p)\n", This, p);
596 597 598 599 600 601
    return E_NOTIMPL;
}

static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, IHTMLTxtRange **range)
{
    HTMLBodyElement *This = HTMLBODY_THIS(iface);
602
    nsIDOMDocumentRange *nsdocrange;
603
    nsIDOMRange *nsrange = NULL;
604
    nsresult nsres;
605
    HRESULT hres;
606 607 608

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

609
    if(!This->textcont.element.node.doc->basedoc.nsdoc) {
610 611 612 613
        WARN("No nsdoc\n");
        return E_UNEXPECTED;
    }

614
    nsres = nsIDOMDocument_QueryInterface(This->textcont.element.node.doc->basedoc.nsdoc, &IID_nsIDOMDocumentRange,
615 616 617 618 619 620 621 622 623 624 625 626 627
            (void**)&nsdocrange);
    if(NS_FAILED(nsres)) {
        ERR("Could not get nsIDOMDocumentRabge iface: %08x\n", nsres);
        return E_FAIL;
    }

    nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &nsrange);
    if(NS_SUCCEEDED(nsres)) {
        nsres = nsIDOMRange_SelectNodeContents(nsrange, This->textcont.element.node.nsnode);
        if(NS_FAILED(nsres))
            ERR("SelectNodeContents failed: %08x\n", nsres);
    }else {
        ERR("CreateRange failed: %08x\n", nsres);
628 629
    }

630 631
    nsIDOMDocumentRange_Release(nsdocrange);

632
    hres = HTMLTxtRange_Create(This->textcont.element.node.doc->basedoc.doc_node, nsrange, range);
633 634 635

    nsIDOMRange_Release(nsrange);
    return hres;
636 637
}

638
#undef HTMLBODY_THIS
639 640 641 642 643 644 645 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 682 683 684

static const IHTMLBodyElementVtbl HTMLBodyElementVtbl = {
    HTMLBodyElement_QueryInterface,
    HTMLBodyElement_AddRef,
    HTMLBodyElement_Release,
    HTMLBodyElement_GetTypeInfoCount,
    HTMLBodyElement_GetTypeInfo,
    HTMLBodyElement_GetIDsOfNames,
    HTMLBodyElement_Invoke,
    HTMLBodyElement_put_background,
    HTMLBodyElement_get_background,
    HTMLBodyElement_put_bgProperties,
    HTMLBodyElement_get_bgProperties,
    HTMLBodyElement_put_leftMargin,
    HTMLBodyElement_get_leftMargin,
    HTMLBodyElement_put_topMargin,
    HTMLBodyElement_get_topMargin,
    HTMLBodyElement_put_rightMargin,
    HTMLBodyElement_get_rightMargin,
    HTMLBodyElement_put_bottomMargin,
    HTMLBodyElement_get_bottomMargin,
    HTMLBodyElement_put_noWrap,
    HTMLBodyElement_get_noWrap,
    HTMLBodyElement_put_bgColor,
    HTMLBodyElement_get_bgColor,
    HTMLBodyElement_put_text,
    HTMLBodyElement_get_text,
    HTMLBodyElement_put_link,
    HTMLBodyElement_get_link,
    HTMLBodyElement_put_vLink,
    HTMLBodyElement_get_vLink,
    HTMLBodyElement_put_aLink,
    HTMLBodyElement_get_aLink,
    HTMLBodyElement_put_onload,
    HTMLBodyElement_get_onload,
    HTMLBodyElement_put_onunload,
    HTMLBodyElement_get_onunload,
    HTMLBodyElement_put_scroll,
    HTMLBodyElement_get_scroll,
    HTMLBodyElement_put_onselect,
    HTMLBodyElement_get_onselect,
    HTMLBodyElement_put_onbeforeunload,
    HTMLBodyElement_get_onbeforeunload,
    HTMLBodyElement_createTextRange
};

685 686
#define HTMLBODY_NODE_THIS(iface) DEFINE_THIS2(HTMLBodyElement, textcont.element.node, iface)

687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714
static HRESULT HTMLBodyElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
{
    HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface);

    *ppv = NULL;

    if(IsEqualGUID(&IID_IUnknown, riid)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = HTMLBODY(This);
    }else if(IsEqualGUID(&IID_IDispatch, riid)) {
        TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
        *ppv = HTMLBODY(This);
    }else if(IsEqualGUID(&IID_IHTMLBodyElement, riid)) {
        TRACE("(%p)->(IID_IHTMLBodyElement %p)\n", This, ppv);
        *ppv = HTMLBODY(This);
    }else if(IsEqualGUID(&IID_IHTMLTextContainer, riid)) {
        TRACE("(%p)->(IID_IHTMLTextContainer %p)\n", &This->textcont, ppv);
        *ppv = HTMLTEXTCONT(&This->textcont);
    }

    if(*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }

    return HTMLElement_QI(&This->textcont.element.node, riid, ppv);
}

715 716 717 718 719
static void HTMLBodyElement_destructor(HTMLDOMNode *iface)
{
    HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface);

    nsIDOMHTMLBodyElement_Release(This->nsbody);
720 721

    HTMLElement_destructor(&This->textcont.element.node);
722 723
}

724 725 726 727
static event_target_t **HTMLBodyElement_get_event_target(HTMLDOMNode *iface)
{
    HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface);

728 729
    return This->textcont.element.node.doc && This->textcont.element.node.doc->basedoc.window
        ? &This->textcont.element.node.doc->basedoc.window->event_target
730 731 732
        : &This->textcont.element.node.event_target;
}

733 734
#undef HTMLBODY_NODE_THIS

735
static const NodeImplVtbl HTMLBodyElementImplVtbl = {
736
    HTMLBodyElement_QI,
737 738
    HTMLBodyElement_destructor,
    HTMLBodyElement_get_event_target
739 740
};

741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
static const tid_t HTMLBodyElement_iface_tids[] = {
    IHTMLBodyElement_tid,
    IHTMLBodyElement2_tid,
    IHTMLDOMNode_tid,
    IHTMLDOMNode2_tid,
    IHTMLElement_tid,
    IHTMLElement2_tid,
    IHTMLElement3_tid,
    IHTMLElement4_tid,
    IHTMLTextContainer_tid,
    IHTMLUniqueName_tid,
    0
};

static dispex_static_data_t HTMLBodyElement_dispex = {
    NULL,
    DispHTMLBody_tid,
    NULL,
    HTMLBodyElement_iface_tids
};

762
HTMLElement *HTMLBodyElement_Create(nsIDOMHTMLElement *nselem)
763
{
764
    HTMLBodyElement *ret = heap_alloc_zero(sizeof(HTMLBodyElement));
765 766
    nsresult nsres;

767 768
    TRACE("(%p)->(%p)\n", ret, nselem);

769
    ret->lpHTMLBodyElementVtbl = &HTMLBodyElementVtbl;
770
    ret->textcont.element.node.vtbl = &HTMLBodyElementImplVtbl;
771

772 773
    HTMLTextContainer_Init(&ret->textcont, &HTMLBodyElement_dispex);

774
    ConnectionPoint_Init(&ret->cp_propnotif, &ret->textcont.element.cp_container, &IID_IPropertyNotifySink);
775

776
    nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLBodyElement,
777 778
                                             (void**)&ret->nsbody);
    if(NS_FAILED(nsres))
779
        ERR("Could not get nsDOMHTMLBodyElement: %08x\n", nsres);
780

781
    return &ret->textcont.element;
782
}