1 /* 2 * Copyright 2006 Jacek Caban for CodeWeavers 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #include <stdarg.h> 20 #include <stdio.h> 21 22 #define COBJMACROS 23 24 #include "windef.h" 25 #include "winbase.h" 26 #include "winuser.h" 27 #include "ole2.h" 28 29 #include "wine/debug.h" 30 31 #include "mshtml_private.h" 32 33 WINE_DEFAULT_DEBUG_CHANNEL(mshtml); 34 35 typedef struct { 36 HTMLTextContainer textcont; 37 38 const IHTMLBodyElementVtbl *lpHTMLBodyElementVtbl; 39 40 ConnectionPoint cp_propnotif; 41 42 nsIDOMHTMLBodyElement *nsbody; 43 } HTMLBodyElement; 44 45 #define HTMLBODY(x) (&(x)->lpHTMLBodyElementVtbl) 46 47 static const WCHAR aquaW[] = {'a','q','u','a',0}; 48 static const WCHAR blackW[] = {'b','l','a','c','k',0}; 49 static const WCHAR blueW[] = {'b','l','u','e',0}; 50 static const WCHAR fuchsiaW[] = {'f','u','s','h','s','i','a',0}; 51 static const WCHAR grayW[] = {'g','r','a','y',0}; 52 static const WCHAR greenW[] = {'g','r','e','e','n',0}; 53 static const WCHAR limeW[] = {'l','i','m','e',0}; 54 static const WCHAR maroonW[] = {'m','a','r','o','o','n',0}; 55 static const WCHAR navyW[] = {'n','a','v','y',0}; 56 static const WCHAR oliveW[] = {'o','l','i','v','e',0}; 57 static const WCHAR purpleW[] = {'p','u','r','p','l','e',0}; 58 static const WCHAR redW[] = {'r','e','d',0}; 59 static const WCHAR silverW[] = {'s','i','l','v','e','r',0}; 60 static const WCHAR tealW[] = {'t','e','a','l',0}; 61 static const WCHAR whiteW[] = {'w','h','i','t','e',0}; 62 static const WCHAR yellowW[] = {'y','e','l','l','o','w',0}; 63 64 static const struct { 65 LPCWSTR keyword; 66 DWORD rgb; 67 } keyword_table[] = { 68 {aquaW, 0x00ffff}, 69 {blackW, 0x000000}, 70 {blueW, 0x0000ff}, 71 {fuchsiaW, 0xff00ff}, 72 {grayW, 0x808080}, 73 {greenW, 0x008000}, 74 {limeW, 0x00ff00}, 75 {maroonW, 0x800000}, 76 {navyW, 0x000080}, 77 {oliveW, 0x808000}, 78 {purpleW, 0x800080}, 79 {redW, 0xff0000}, 80 {silverW, 0xc0c0c0}, 81 {tealW, 0x008080}, 82 {whiteW, 0xffffff}, 83 {yellowW, 0xffff00} 84 }; 85 86 static int comp_value(const WCHAR *ptr, int dpc) 87 { 88 int ret = 0; 89 WCHAR ch; 90 91 if(dpc > 2) 92 dpc = 2; 93 94 while(dpc--) { 95 if(!*ptr) 96 ret *= 16; 97 else if(isdigitW(ch = *ptr++)) 98 ret = ret*16 + (ch-'0'); 99 else if('a' <= ch && ch <= 'f') 100 ret = ret*16 + (ch-'a') + 10; 101 else if('A' <= ch && ch <= 'F') 102 ret = ret*16 + (ch-'A') + 10; 103 else 104 ret *= 16; 105 } 106 107 return ret; 108 } 109 110 /* Based on Gecko NS_LooseHexToRGB */ 111 static int loose_hex_to_rgb(const WCHAR *hex) 112 { 113 int len, dpc; 114 115 len = strlenW(hex); 116 if(*hex == '#') { 117 hex++; 118 len--; 119 } 120 if(len <= 3) 121 return 0; 122 123 dpc = min(len/3 + (len%3 ? 1 : 0), 4); 124 return (comp_value(hex, dpc) << 16) 125 | (comp_value(hex+dpc, dpc) << 8) 126 | comp_value(hex+2*dpc, dpc); 127 } 128 129 static HRESULT nscolor_to_str(LPCWSTR color, BSTR *ret) 130 { 131 int i, rgb = -1; 132 133 static const WCHAR formatW[] = {'#','%','0','2','x','%','0','2','x','%','0','2','x',0}; 134 135 if(!color || !*color) { 136 *ret = NULL; 137 return S_OK; 138 } 139 140 if(*color != '#') { 141 for(i=0; i < sizeof(keyword_table)/sizeof(keyword_table[0]); i++) { 142 if(!strcmpiW(color, keyword_table[i].keyword)) 143 rgb = keyword_table[i].rgb; 144 } 145 } 146 if(rgb == -1) 147 rgb = loose_hex_to_rgb(color); 148 149 *ret = SysAllocStringLen(NULL, 7); 150 if(!*ret) 151 return E_OUTOFMEMORY; 152 153 sprintfW(*ret, formatW, rgb>>16, (rgb>>8)&0xff, rgb&0xff); 154 155 TRACE("%s -> %s\n", debugstr_w(color), debugstr_w(*ret)); 156 return S_OK; 157 } 158 159 static BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr) 160 { 161 switch(V_VT(v)) { 162 case VT_BSTR: 163 nsAString_Init(nsstr, V_BSTR(v)); 164 return TRUE; 165 166 case VT_I4: { 167 PRUnichar buf[10]; 168 static const WCHAR formatW[] = {'#','%','x',0}; 169 170 wsprintfW(buf, formatW, V_I4(v)); 171 nsAString_Init(nsstr, buf); 172 return TRUE; 173 } 174 175 default: 176 FIXME("invalid vt=%d\n", V_VT(v)); 177 } 178 179 return FALSE; 180 181 } 182 183 static void nscolor_to_variant(const nsAString *nsstr, VARIANT *p) 184 { 185 const PRUnichar *color; 186 187 nsAString_GetData(nsstr, &color); 188 189 if(*color == '#') { 190 V_VT(p) = VT_I4; 191 V_I4(p) = strtolW(color+1, NULL, 16); 192 }else { 193 V_VT(p) = VT_BSTR; 194 V_BSTR(p) = SysAllocString(color); 195 } 196 } 197 198 #define HTMLBODY_THIS(iface) DEFINE_THIS(HTMLBodyElement, HTMLBodyElement, iface) 199 200 static HRESULT WINAPI HTMLBodyElement_QueryInterface(IHTMLBodyElement *iface, 201 REFIID riid, void **ppv) 202 { 203 HTMLBodyElement *This = HTMLBODY_THIS(iface); 204 205 return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->textcont.element.node), riid, ppv); 206 } 207 208 static ULONG WINAPI HTMLBodyElement_AddRef(IHTMLBodyElement *iface) 209 { 210 HTMLBodyElement *This = HTMLBODY_THIS(iface); 211 212 return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->textcont.element.node)); 213 } 214 215 static ULONG WINAPI HTMLBodyElement_Release(IHTMLBodyElement *iface) 216 { 217 HTMLBodyElement *This = HTMLBODY_THIS(iface); 218 219 return IHTMLDOMNode_Release(HTMLDOMNODE(&This->textcont.element.node)); 220 } 221 222 static HRESULT WINAPI HTMLBodyElement_GetTypeInfoCount(IHTMLBodyElement *iface, UINT *pctinfo) 223 { 224 HTMLBodyElement *This = HTMLBODY_THIS(iface); 225 return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->textcont.element.node.dispex), pctinfo); 226 } 227 228 static HRESULT WINAPI HTMLBodyElement_GetTypeInfo(IHTMLBodyElement *iface, UINT iTInfo, 229 LCID lcid, ITypeInfo **ppTInfo) 230 { 231 HTMLBodyElement *This = HTMLBODY_THIS(iface); 232 return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->textcont.element.node.dispex), iTInfo, lcid, ppTInfo); 233 } 234 235 static HRESULT WINAPI HTMLBodyElement_GetIDsOfNames(IHTMLBodyElement *iface, REFIID riid, 236 LPOLESTR *rgszNames, UINT cNames, 237 LCID lcid, DISPID *rgDispId) 238 { 239 HTMLBodyElement *This = HTMLBODY_THIS(iface); 240 return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->textcont.element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId); 241 } 242 243 static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dispIdMember, 244 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, 245 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 246 { 247 HTMLBodyElement *This = HTMLBODY_THIS(iface); 248 return IDispatchEx_Invoke(DISPATCHEX(&This->textcont.element.node.dispex), dispIdMember, riid, lcid, 249 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 250 } 251 252 static HRESULT WINAPI HTMLBodyElement_put_background(IHTMLBodyElement *iface, BSTR v) 253 { 254 HTMLBodyElement *This = HTMLBODY_THIS(iface); 255 nsAString nsstr; 256 nsresult nsres; 257 258 TRACE("(%p)->(%s)\n", This, debugstr_w(v)); 259 260 nsAString_InitDepend(&nsstr, v); 261 nsres = nsIDOMHTMLBodyElement_SetBackground(This->nsbody, &nsstr); 262 nsAString_Finish(&nsstr); 263 if(NS_FAILED(nsres)) 264 return E_FAIL; 265 266 return S_OK; 267 } 268 269 static HRESULT WINAPI HTMLBodyElement_get_background(IHTMLBodyElement *iface, BSTR *p) 270 { 271 HTMLBodyElement *This = HTMLBODY_THIS(iface); 272 nsAString background_str; 273 nsresult nsres; 274 275 TRACE("(%p)->(%p)\n", This, p); 276 277 nsAString_Init(&background_str, NULL); 278 279 nsres = nsIDOMHTMLBodyElement_GetBackground(This->nsbody, &background_str); 280 if(NS_SUCCEEDED(nsres)) { 281 const PRUnichar *background; 282 nsAString_GetData(&background_str, &background); 283 *p = *background ? SysAllocString(background) : NULL; 284 }else { 285 ERR("GetBackground failed: %08x\n", nsres); 286 *p = NULL; 287 } 288 289 nsAString_Finish(&background_str); 290 291 TRACE("*p = %s\n", debugstr_w(*p)); 292 return S_OK; 293 } 294 295 static HRESULT WINAPI HTMLBodyElement_put_bgProperties(IHTMLBodyElement *iface, BSTR v) 296 { 297 HTMLBodyElement *This = HTMLBODY_THIS(iface); 298 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 299 return E_NOTIMPL; 300 } 301 302 static HRESULT WINAPI HTMLBodyElement_get_bgProperties(IHTMLBodyElement *iface, BSTR *p) 303 { 304 HTMLBodyElement *This = HTMLBODY_THIS(iface); 305 FIXME("(%p)->(%p)\n", This, p); 306 return E_NOTIMPL; 307 } 308 309 static HRESULT WINAPI HTMLBodyElement_put_leftMargin(IHTMLBodyElement *iface, VARIANT v) 310 { 311 HTMLBodyElement *This = HTMLBODY_THIS(iface); 312 FIXME("(%p)->()\n", This); 313 return E_NOTIMPL; 314 } 315 316 static HRESULT WINAPI HTMLBodyElement_get_leftMargin(IHTMLBodyElement *iface, VARIANT *p) 317 { 318 HTMLBodyElement *This = HTMLBODY_THIS(iface); 319 FIXME("(%p)->(%p)\n", This, p); 320 return E_NOTIMPL; 321 } 322 323 static HRESULT WINAPI HTMLBodyElement_put_topMargin(IHTMLBodyElement *iface, VARIANT v) 324 { 325 HTMLBodyElement *This = HTMLBODY_THIS(iface); 326 FIXME("(%p)->()\n", This); 327 return E_NOTIMPL; 328 } 329 330 static HRESULT WINAPI HTMLBodyElement_get_topMargin(IHTMLBodyElement *iface, VARIANT *p) 331 { 332 HTMLBodyElement *This = HTMLBODY_THIS(iface); 333 FIXME("(%p)->(%p)\n", This, p); 334 return E_NOTIMPL; 335 } 336 337 static HRESULT WINAPI HTMLBodyElement_put_rightMargin(IHTMLBodyElement *iface, VARIANT v) 338 { 339 HTMLBodyElement *This = HTMLBODY_THIS(iface); 340 FIXME("(%p)->()\n", This); 341 return E_NOTIMPL; 342 } 343 344 static HRESULT WINAPI HTMLBodyElement_get_rightMargin(IHTMLBodyElement *iface, VARIANT *p) 345 { 346 HTMLBodyElement *This = HTMLBODY_THIS(iface); 347 FIXME("(%p)->(%p)\n", This, p); 348 return E_NOTIMPL; 349 } 350 351 static HRESULT WINAPI HTMLBodyElement_put_bottomMargin(IHTMLBodyElement *iface, VARIANT v) 352 { 353 HTMLBodyElement *This = HTMLBODY_THIS(iface); 354 FIXME("(%p)->()\n", This); 355 return E_NOTIMPL; 356 } 357 358 static HRESULT WINAPI HTMLBodyElement_get_bottomMargin(IHTMLBodyElement *iface, VARIANT *p) 359 { 360 HTMLBodyElement *This = HTMLBODY_THIS(iface); 361 FIXME("(%p)->(%p)\n", This, p); 362 return E_NOTIMPL; 363 } 364 365 static HRESULT WINAPI HTMLBodyElement_put_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL v) 366 { 367 HTMLBodyElement *This = HTMLBODY_THIS(iface); 368 FIXME("(%p)->(%x)\n", This, v); 369 return E_NOTIMPL; 370 } 371 372 static HRESULT WINAPI HTMLBodyElement_get_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL *p) 373 { 374 HTMLBodyElement *This = HTMLBODY_THIS(iface); 375 FIXME("(%p)->(%p)\n", This, p); 376 return E_NOTIMPL; 377 } 378 379 static HRESULT WINAPI HTMLBodyElement_put_bgColor(IHTMLBodyElement *iface, VARIANT v) 380 { 381 HTMLBodyElement *This = HTMLBODY_THIS(iface); 382 nsAString strColor; 383 nsresult nsres; 384 385 TRACE("(%p)->()\n", This); 386 387 if(!variant_to_nscolor(&v, &strColor)) 388 return S_OK; 389 390 nsres = nsIDOMHTMLBodyElement_SetBgColor(This->nsbody, &strColor); 391 nsAString_Finish(&strColor); 392 if(NS_FAILED(nsres)) 393 ERR("SetBgColor failed: %08x\n", nsres); 394 395 return S_OK; 396 } 397 398 static HRESULT WINAPI HTMLBodyElement_get_bgColor(IHTMLBodyElement *iface, VARIANT *p) 399 { 400 HTMLBodyElement *This = HTMLBODY_THIS(iface); 401 nsAString strColor; 402 nsresult nsres; 403 HRESULT hres; 404 405 TRACE("(%p)->(%p)\n", This, p); 406 407 nsAString_Init(&strColor, NULL); 408 nsres = nsIDOMHTMLBodyElement_GetBgColor(This->nsbody, &strColor); 409 if(NS_SUCCEEDED(nsres)) { 410 const PRUnichar *color; 411 412 nsAString_GetData(&strColor, &color); 413 V_VT(p) = VT_BSTR; 414 hres = nscolor_to_str(color, &V_BSTR(p)); 415 }else { 416 ERR("SetBgColor failed: %08x\n", nsres); 417 hres = E_FAIL; 418 } 419 420 nsAString_Finish(&strColor); 421 return hres; 422 } 423 424 static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT v) 425 { 426 HTMLBodyElement *This = HTMLBODY_THIS(iface); 427 nsAString text; 428 nsresult nsres; 429 430 TRACE("(%p)->(v%d)\n", This, V_VT(&v)); 431 432 if(!variant_to_nscolor(&v, &text)) 433 return S_OK; 434 435 nsres = nsIDOMHTMLBodyElement_SetText(This->nsbody, &text); 436 nsAString_Finish(&text); 437 if(NS_FAILED(nsres)) { 438 ERR("SetText failed: %08x\n", nsres); 439 return E_FAIL; 440 } 441 442 return S_OK; 443 } 444 445 static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT *p) 446 { 447 HTMLBodyElement *This = HTMLBODY_THIS(iface); 448 nsAString text; 449 nsresult nsres; 450 HRESULT hres; 451 452 TRACE("(%p)->(%p)\n", This, p); 453 454 nsAString_Init(&text, NULL); 455 nsres = nsIDOMHTMLBodyElement_GetText(This->nsbody, &text); 456 if(NS_SUCCEEDED(nsres)) { 457 const PRUnichar *color; 458 459 nsAString_GetData(&text, &color); 460 V_VT(p) = VT_BSTR; 461 hres = nscolor_to_str(color, &V_BSTR(p)); 462 }else { 463 ERR("GetText failed: %08x\n", nsres); 464 hres = E_FAIL; 465 } 466 467 nsAString_Finish(&text); 468 469 return hres; 470 } 471 472 static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v) 473 { 474 HTMLBodyElement *This = HTMLBODY_THIS(iface); 475 nsAString link_str; 476 nsresult nsres; 477 478 TRACE("(%p)->(v%d)\n", This, V_VT(&v)); 479 480 if(!variant_to_nscolor(&v, &link_str)) 481 return S_OK; 482 483 nsres = nsIDOMHTMLBodyElement_SetLink(This->nsbody, &link_str); 484 nsAString_Finish(&link_str); 485 if(NS_FAILED(nsres)) 486 ERR("SetLink failed: %08x\n", nsres); 487 488 return S_OK; 489 } 490 491 static HRESULT WINAPI HTMLBodyElement_get_link(IHTMLBodyElement *iface, VARIANT *p) 492 { 493 HTMLBodyElement *This = HTMLBODY_THIS(iface); 494 nsAString link_str; 495 nsresult nsres; 496 497 TRACE("(%p)->(%p)\n", This, p); 498 499 nsAString_Init(&link_str, NULL); 500 nsres = nsIDOMHTMLBodyElement_GetLink(This->nsbody, &link_str); 501 if(NS_FAILED(nsres)) 502 ERR("GetLink failed: %08x\n", nsres); 503 504 nscolor_to_variant(&link_str, p); 505 nsAString_Finish(&link_str); 506 507 return S_OK; 508 } 509 510 static HRESULT WINAPI HTMLBodyElement_put_vLink(IHTMLBodyElement *iface, VARIANT v) 511 { 512 HTMLBodyElement *This = HTMLBODY_THIS(iface); 513 nsAString vlink_str; 514 nsresult nsres; 515 516 TRACE("(%p)->(v%d)\n", This, V_VT(&v)); 517 518 if(!variant_to_nscolor(&v, &vlink_str)) 519 return S_OK; 520 521 nsres = nsIDOMHTMLBodyElement_SetVLink(This->nsbody, &vlink_str); 522 nsAString_Finish(&vlink_str); 523 if(NS_FAILED(nsres)) 524 ERR("SetLink failed: %08x\n", nsres); 525 526 return S_OK; 527 } 528 529 static HRESULT WINAPI HTMLBodyElement_get_vLink(IHTMLBodyElement *iface, VARIANT *p) 530 { 531 HTMLBodyElement *This = HTMLBODY_THIS(iface); 532 nsAString vlink_str; 533 nsresult nsres; 534 535 TRACE("(%p)->(%p)\n", This, p); 536 537 nsAString_Init(&vlink_str, NULL); 538 nsres = nsIDOMHTMLBodyElement_GetVLink(This->nsbody, &vlink_str); 539 if(NS_FAILED(nsres)) 540 ERR("GetLink failed: %08x\n", nsres); 541 542 nscolor_to_variant(&vlink_str, p); 543 nsAString_Finish(&vlink_str); 544 545 return S_OK; 546 } 547 548 static HRESULT WINAPI HTMLBodyElement_put_aLink(IHTMLBodyElement *iface, VARIANT v) 549 { 550 HTMLBodyElement *This = HTMLBODY_THIS(iface); 551 nsAString alink_str; 552 nsresult nsres; 553 554 TRACE("(%p)->(v%d)\n", This, V_VT(&v)); 555 556 if(!variant_to_nscolor(&v, &alink_str)) 557 return S_OK; 558 559 nsres = nsIDOMHTMLBodyElement_SetALink(This->nsbody, &alink_str); 560 nsAString_Finish(&alink_str); 561 if(NS_FAILED(nsres)) 562 ERR("SetALink failed: %08x\n", nsres); 563 564 return S_OK; 565 } 566 567 static HRESULT WINAPI HTMLBodyElement_get_aLink(IHTMLBodyElement *iface, VARIANT *p) 568 { 569 HTMLBodyElement *This = HTMLBODY_THIS(iface); 570 nsAString alink_str; 571 nsresult nsres; 572 573 TRACE("(%p)->(%p)\n", This, p); 574 575 nsAString_Init(&alink_str, NULL); 576 nsres = nsIDOMHTMLBodyElement_GetALink(This->nsbody, &alink_str); 577 if(NS_FAILED(nsres)) 578 ERR("GetALink failed: %08x\n", nsres); 579 580 nscolor_to_variant(&alink_str, p); 581 nsAString_Finish(&alink_str); 582 583 return S_OK; 584 } 585 586 static HRESULT WINAPI HTMLBodyElement_put_onload(IHTMLBodyElement *iface, VARIANT v) 587 { 588 HTMLBodyElement *This = HTMLBODY_THIS(iface); 589 FIXME("(%p)->()\n", This); 590 return E_NOTIMPL; 591 } 592 593 static HRESULT WINAPI HTMLBodyElement_get_onload(IHTMLBodyElement *iface, VARIANT *p) 594 { 595 HTMLBodyElement *This = HTMLBODY_THIS(iface); 596 FIXME("(%p)->(%p)\n", This, p); 597 return E_NOTIMPL; 598 } 599 600 static HRESULT WINAPI HTMLBodyElement_put_onunload(IHTMLBodyElement *iface, VARIANT v) 601 { 602 HTMLBodyElement *This = HTMLBODY_THIS(iface); 603 FIXME("(%p)->()\n", This); 604 return E_NOTIMPL; 605 } 606 607 static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARIANT *p) 608 { 609 HTMLBodyElement *This = HTMLBODY_THIS(iface); 610 FIXME("(%p)->(%p)\n", This, p); 611 return E_NOTIMPL; 612 } 613 614 static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v) 615 { 616 HTMLBodyElement *This = HTMLBODY_THIS(iface); 617 FIXME("(%p)->(%s)\n", This, debugstr_w(v)); 618 return E_NOTIMPL; 619 } 620 621 static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p) 622 { 623 HTMLBodyElement *This = HTMLBODY_THIS(iface); 624 FIXME("(%p)->(%p)\n", This, p); 625 return E_NOTIMPL; 626 } 627 628 static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v) 629 { 630 HTMLBodyElement *This = HTMLBODY_THIS(iface); 631 FIXME("(%p)->()\n", This); 632 return E_NOTIMPL; 633 } 634 635 static HRESULT WINAPI HTMLBodyElement_get_onselect(IHTMLBodyElement *iface, VARIANT *p) 636 { 637 HTMLBodyElement *This = HTMLBODY_THIS(iface); 638 FIXME("(%p)->(%p)\n", This, p); 639 return E_NOTIMPL; 640 } 641 642 static HRESULT WINAPI HTMLBodyElement_put_onbeforeunload(IHTMLBodyElement *iface, VARIANT v) 643 { 644 HTMLBodyElement *This = HTMLBODY_THIS(iface); 645 FIXME("(%p)->()\n", This); 646 return E_NOTIMPL; 647 } 648 649 static HRESULT WINAPI HTMLBodyElement_get_onbeforeunload(IHTMLBodyElement *iface, VARIANT *p) 650 { 651 HTMLBodyElement *This = HTMLBODY_THIS(iface); 652 FIXME("(%p)->(%p)\n", This, p); 653 return E_NOTIMPL; 654 } 655 656 static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, IHTMLTxtRange **range) 657 { 658 HTMLBodyElement *This = HTMLBODY_THIS(iface); 659 nsIDOMDocumentRange *nsdocrange; 660 nsIDOMRange *nsrange = NULL; 661 nsresult nsres; 662 HRESULT hres; 663 664 TRACE("(%p)->(%p)\n", This, range); 665 666 if(!This->textcont.element.node.doc->nsdoc) { 667 WARN("No nsdoc\n"); 668 return E_UNEXPECTED; 669 } 670 671 nsres = nsIDOMDocument_QueryInterface(This->textcont.element.node.doc->nsdoc, &IID_nsIDOMDocumentRange, 672 (void**)&nsdocrange); 673 if(NS_FAILED(nsres)) { 674 ERR("Could not get nsIDOMDocumentRabge iface: %08x\n", nsres); 675 return E_FAIL; 676 } 677 678 nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &nsrange); 679 if(NS_SUCCEEDED(nsres)) { 680 nsres = nsIDOMRange_SelectNodeContents(nsrange, This->textcont.element.node.nsnode); 681 if(NS_FAILED(nsres)) 682 ERR("SelectNodeContents failed: %08x\n", nsres); 683 }else { 684 ERR("CreateRange failed: %08x\n", nsres); 685 } 686 687 nsIDOMDocumentRange_Release(nsdocrange); 688 689 hres = HTMLTxtRange_Create(This->textcont.element.node.doc->basedoc.doc_node, nsrange, range); 690 691 nsIDOMRange_Release(nsrange); 692 return hres; 693 } 694 695 #undef HTMLBODY_THIS 696 697 static const IHTMLBodyElementVtbl HTMLBodyElementVtbl = { 698 HTMLBodyElement_QueryInterface, 699 HTMLBodyElement_AddRef, 700 HTMLBodyElement_Release, 701 HTMLBodyElement_GetTypeInfoCount, 702 HTMLBodyElement_GetTypeInfo, 703 HTMLBodyElement_GetIDsOfNames, 704 HTMLBodyElement_Invoke, 705 HTMLBodyElement_put_background, 706 HTMLBodyElement_get_background, 707 HTMLBodyElement_put_bgProperties, 708 HTMLBodyElement_get_bgProperties, 709 HTMLBodyElement_put_leftMargin, 710 HTMLBodyElement_get_leftMargin, 711 HTMLBodyElement_put_topMargin, 712 HTMLBodyElement_get_topMargin, 713 HTMLBodyElement_put_rightMargin, 714 HTMLBodyElement_get_rightMargin, 715 HTMLBodyElement_put_bottomMargin, 716 HTMLBodyElement_get_bottomMargin, 717 HTMLBodyElement_put_noWrap, 718 HTMLBodyElement_get_noWrap, 719 HTMLBodyElement_put_bgColor, 720 HTMLBodyElement_get_bgColor, 721 HTMLBodyElement_put_text, 722 HTMLBodyElement_get_text, 723 HTMLBodyElement_put_link, 724 HTMLBodyElement_get_link, 725 HTMLBodyElement_put_vLink, 726 HTMLBodyElement_get_vLink, 727 HTMLBodyElement_put_aLink, 728 HTMLBodyElement_get_aLink, 729 HTMLBodyElement_put_onload, 730 HTMLBodyElement_get_onload, 731 HTMLBodyElement_put_onunload, 732 HTMLBodyElement_get_onunload, 733 HTMLBodyElement_put_scroll, 734 HTMLBodyElement_get_scroll, 735 HTMLBodyElement_put_onselect, 736 HTMLBodyElement_get_onselect, 737 HTMLBodyElement_put_onbeforeunload, 738 HTMLBodyElement_get_onbeforeunload, 739 HTMLBodyElement_createTextRange 740 }; 741 742 #define HTMLBODY_NODE_THIS(iface) DEFINE_THIS2(HTMLBodyElement, textcont.element.node, iface) 743 744 static HRESULT HTMLBodyElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) 745 { 746 HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface); 747 748 *ppv = NULL; 749 750 if(IsEqualGUID(&IID_IUnknown, riid)) { 751 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); 752 *ppv = HTMLBODY(This); 753 }else if(IsEqualGUID(&IID_IDispatch, riid)) { 754 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); 755 *ppv = HTMLBODY(This); 756 }else if(IsEqualGUID(&IID_IHTMLBodyElement, riid)) { 757 TRACE("(%p)->(IID_IHTMLBodyElement %p)\n", This, ppv); 758 *ppv = HTMLBODY(This); 759 }else if(IsEqualGUID(&IID_IHTMLTextContainer, riid)) { 760 TRACE("(%p)->(IID_IHTMLTextContainer %p)\n", &This->textcont, ppv); 761 *ppv = HTMLTEXTCONT(&This->textcont); 762 } 763 764 if(*ppv) { 765 IUnknown_AddRef((IUnknown*)*ppv); 766 return S_OK; 767 } 768 769 return HTMLElement_QI(&This->textcont.element.node, riid, ppv); 770 } 771 772 static void HTMLBodyElement_destructor(HTMLDOMNode *iface) 773 { 774 HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface); 775 776 nsIDOMHTMLBodyElement_Release(This->nsbody); 777 778 HTMLElement_destructor(&This->textcont.element.node); 779 } 780 781 static event_target_t **HTMLBodyElement_get_event_target(HTMLDOMNode *iface) 782 { 783 HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface); 784 785 return This->textcont.element.node.doc 786 ? &This->textcont.element.node.doc->body_event_target 787 : &This->textcont.element.node.event_target; 788 } 789 790 #undef HTMLBODY_NODE_THIS 791 792 static const NodeImplVtbl HTMLBodyElementImplVtbl = { 793 HTMLBodyElement_QI, 794 HTMLBodyElement_destructor, 795 HTMLBodyElement_get_event_target 796 }; 797 798 static const tid_t HTMLBodyElement_iface_tids[] = { 799 IHTMLBodyElement_tid, 800 IHTMLBodyElement2_tid, 801 HTMLELEMENT_TIDS, 802 IHTMLTextContainer_tid, 803 IHTMLUniqueName_tid, 804 0 805 }; 806 807 static dispex_static_data_t HTMLBodyElement_dispex = { 808 NULL, 809 DispHTMLBody_tid, 810 NULL, 811 HTMLBodyElement_iface_tids 812 }; 813 814 HTMLElement *HTMLBodyElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) 815 { 816 HTMLBodyElement *ret = heap_alloc_zero(sizeof(HTMLBodyElement)); 817 nsresult nsres; 818 819 TRACE("(%p)->(%p)\n", ret, nselem); 820 821 ret->lpHTMLBodyElementVtbl = &HTMLBodyElementVtbl; 822 ret->textcont.element.node.vtbl = &HTMLBodyElementImplVtbl; 823 824 HTMLTextContainer_Init(&ret->textcont, doc, nselem, &HTMLBodyElement_dispex); 825 826 ConnectionPoint_Init(&ret->cp_propnotif, &ret->textcont.element.cp_container, &IID_IPropertyNotifySink, NULL); 827 828 nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLBodyElement, 829 (void**)&ret->nsbody); 830 if(NS_FAILED(nsres)) 831 ERR("Could not get nsDOMHTMLBodyElement: %08x\n", nsres); 832 833 return &ret->textcont.element; 834 } 835