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