comctl32: Fix a typo in comment.
[wine.git] / dlls / mshtml / htmlbody.c
blob1c40c52d68eadf7d7e534ced8ea6b9a2ddcdbca3
1 /*
2 * Copyright 2006 Jacek Caban for CodeWeavers
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.
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.
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
19 #include <stdarg.h>
20 #include <stdio.h>
22 #define COBJMACROS
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "ole2.h"
28 #include "mshtmdid.h"
30 #include "wine/debug.h"
32 #include "mshtml_private.h"
33 #include "htmlevent.h"
34 #include "htmlstyle.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38 typedef struct {
39 HTMLTextContainer textcont;
41 IHTMLBodyElement IHTMLBodyElement_iface;
43 nsIDOMHTMLBodyElement *nsbody;
44 } HTMLBodyElement;
46 static const WCHAR aquaW[] = {'a','q','u','a',0};
47 static const WCHAR blackW[] = {'b','l','a','c','k',0};
48 static const WCHAR blueW[] = {'b','l','u','e',0};
49 static const WCHAR fuchsiaW[] = {'f','u','s','h','s','i','a',0};
50 static const WCHAR grayW[] = {'g','r','a','y',0};
51 static const WCHAR greenW[] = {'g','r','e','e','n',0};
52 static const WCHAR limeW[] = {'l','i','m','e',0};
53 static const WCHAR maroonW[] = {'m','a','r','o','o','n',0};
54 static const WCHAR navyW[] = {'n','a','v','y',0};
55 static const WCHAR oliveW[] = {'o','l','i','v','e',0};
56 static const WCHAR purpleW[] = {'p','u','r','p','l','e',0};
57 static const WCHAR redW[] = {'r','e','d',0};
58 static const WCHAR silverW[] = {'s','i','l','v','e','r',0};
59 static const WCHAR tealW[] = {'t','e','a','l',0};
60 static const WCHAR whiteW[] = {'w','h','i','t','e',0};
61 static const WCHAR yellowW[] = {'y','e','l','l','o','w',0};
63 static const struct {
64 LPCWSTR keyword;
65 DWORD rgb;
66 } keyword_table[] = {
67 {aquaW, 0x00ffff},
68 {blackW, 0x000000},
69 {blueW, 0x0000ff},
70 {fuchsiaW, 0xff00ff},
71 {grayW, 0x808080},
72 {greenW, 0x008000},
73 {limeW, 0x00ff00},
74 {maroonW, 0x800000},
75 {navyW, 0x000080},
76 {oliveW, 0x808000},
77 {purpleW, 0x800080},
78 {redW, 0xff0000},
79 {silverW, 0xc0c0c0},
80 {tealW, 0x008080},
81 {whiteW, 0xffffff},
82 {yellowW, 0xffff00}
85 static int comp_value(const WCHAR *ptr, int dpc)
87 int ret = 0;
88 WCHAR ch;
90 if(dpc > 2)
91 dpc = 2;
93 while(dpc--) {
94 if(!*ptr)
95 ret *= 16;
96 else if(isdigitW(ch = *ptr++))
97 ret = ret*16 + (ch-'0');
98 else if('a' <= ch && ch <= 'f')
99 ret = ret*16 + (ch-'a') + 10;
100 else if('A' <= ch && ch <= 'F')
101 ret = ret*16 + (ch-'A') + 10;
102 else
103 ret *= 16;
106 return ret;
109 /* Based on Gecko NS_LooseHexToRGB */
110 static int loose_hex_to_rgb(const WCHAR *hex)
112 int len, dpc;
114 len = strlenW(hex);
115 if(*hex == '#') {
116 hex++;
117 len--;
119 if(len <= 3)
120 return 0;
122 dpc = min(len/3 + (len%3 ? 1 : 0), 4);
123 return (comp_value(hex, dpc) << 16)
124 | (comp_value(hex+dpc, dpc) << 8)
125 | comp_value(hex+2*dpc, dpc);
128 HRESULT nscolor_to_str(LPCWSTR color, BSTR *ret)
130 unsigned int i;
131 int rgb = -1;
133 static const WCHAR formatW[] = {'#','%','0','2','x','%','0','2','x','%','0','2','x',0};
135 if(!color || !*color) {
136 *ret = NULL;
137 return S_OK;
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;
146 if(rgb == -1)
147 rgb = loose_hex_to_rgb(color);
149 *ret = SysAllocStringLen(NULL, 7);
150 if(!*ret)
151 return E_OUTOFMEMORY;
153 sprintfW(*ret, formatW, rgb>>16, (rgb>>8)&0xff, rgb&0xff);
155 TRACE("%s -> %s\n", debugstr_w(color), debugstr_w(*ret));
156 return S_OK;
159 BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr)
161 switch(V_VT(v)) {
162 case VT_BSTR:
163 nsAString_Init(nsstr, V_BSTR(v));
164 return TRUE;
166 case VT_I4: {
167 PRUnichar buf[10];
168 static const WCHAR formatW[] = {'#','%','x',0};
170 wsprintfW(buf, formatW, V_I4(v));
171 nsAString_Init(nsstr, buf);
172 return TRUE;
175 default:
176 FIXME("invalid color %s\n", debugstr_variant(v));
179 return FALSE;
183 static HRESULT return_nscolor(nsresult nsres, nsAString *nsstr, VARIANT *p)
185 const PRUnichar *color;
187 if(NS_FAILED(nsres)) {
188 ERR("failed: %08x\n", nsres);
189 nsAString_Finish(nsstr);
190 return E_FAIL;
193 nsAString_GetData(nsstr, &color);
195 if(*color == '#') {
196 V_VT(p) = VT_I4;
197 V_I4(p) = strtolW(color+1, NULL, 16);
198 }else {
199 V_VT(p) = VT_BSTR;
200 V_BSTR(p) = SysAllocString(color);
201 if(!V_BSTR(p)) {
202 nsAString_Finish(nsstr);
203 return E_OUTOFMEMORY;
207 nsAString_Finish(nsstr);
208 TRACE("ret %s\n", debugstr_variant(p));
209 return S_OK;
212 static inline HTMLBodyElement *impl_from_IHTMLBodyElement(IHTMLBodyElement *iface)
214 return CONTAINING_RECORD(iface, HTMLBodyElement, IHTMLBodyElement_iface);
217 static HRESULT WINAPI HTMLBodyElement_QueryInterface(IHTMLBodyElement *iface,
218 REFIID riid, void **ppv)
220 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
222 return IHTMLDOMNode_QueryInterface(&This->textcont.element.node.IHTMLDOMNode_iface, riid, ppv);
225 static ULONG WINAPI HTMLBodyElement_AddRef(IHTMLBodyElement *iface)
227 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
229 return IHTMLDOMNode_AddRef(&This->textcont.element.node.IHTMLDOMNode_iface);
232 static ULONG WINAPI HTMLBodyElement_Release(IHTMLBodyElement *iface)
234 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
236 return IHTMLDOMNode_Release(&This->textcont.element.node.IHTMLDOMNode_iface);
239 static HRESULT WINAPI HTMLBodyElement_GetTypeInfoCount(IHTMLBodyElement *iface, UINT *pctinfo)
241 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
242 return IDispatchEx_GetTypeInfoCount(&This->textcont.element.node.event_target.dispex.IDispatchEx_iface,
243 pctinfo);
246 static HRESULT WINAPI HTMLBodyElement_GetTypeInfo(IHTMLBodyElement *iface, UINT iTInfo,
247 LCID lcid, ITypeInfo **ppTInfo)
249 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
250 return IDispatchEx_GetTypeInfo(&This->textcont.element.node.event_target.dispex.IDispatchEx_iface, iTInfo,
251 lcid, ppTInfo);
254 static HRESULT WINAPI HTMLBodyElement_GetIDsOfNames(IHTMLBodyElement *iface, REFIID riid,
255 LPOLESTR *rgszNames, UINT cNames,
256 LCID lcid, DISPID *rgDispId)
258 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
259 return IDispatchEx_GetIDsOfNames(&This->textcont.element.node.event_target.dispex.IDispatchEx_iface, riid,
260 rgszNames, cNames, lcid, rgDispId);
263 static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dispIdMember,
264 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
265 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
267 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
268 return IDispatchEx_Invoke(&This->textcont.element.node.event_target.dispex.IDispatchEx_iface, dispIdMember,
269 riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
272 static HRESULT WINAPI HTMLBodyElement_put_background(IHTMLBodyElement *iface, BSTR v)
274 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
275 nsAString nsstr;
276 nsresult nsres;
278 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
280 nsAString_InitDepend(&nsstr, v);
281 nsres = nsIDOMHTMLBodyElement_SetBackground(This->nsbody, &nsstr);
282 nsAString_Finish(&nsstr);
283 if(NS_FAILED(nsres))
284 return E_FAIL;
286 return S_OK;
289 static HRESULT WINAPI HTMLBodyElement_get_background(IHTMLBodyElement *iface, BSTR *p)
291 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
292 nsAString background_str;
293 nsresult nsres;
295 TRACE("(%p)->(%p)\n", This, p);
297 nsAString_Init(&background_str, NULL);
298 nsres = nsIDOMHTMLBodyElement_GetBackground(This->nsbody, &background_str);
299 return return_nsstr(nsres, &background_str, p);
302 static HRESULT WINAPI HTMLBodyElement_put_bgProperties(IHTMLBodyElement *iface, BSTR v)
304 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
305 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
306 return E_NOTIMPL;
309 static HRESULT WINAPI HTMLBodyElement_get_bgProperties(IHTMLBodyElement *iface, BSTR *p)
311 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
312 FIXME("(%p)->(%p)\n", This, p);
313 return E_NOTIMPL;
316 static HRESULT WINAPI HTMLBodyElement_put_leftMargin(IHTMLBodyElement *iface, VARIANT v)
318 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
319 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
320 return E_NOTIMPL;
323 static HRESULT WINAPI HTMLBodyElement_get_leftMargin(IHTMLBodyElement *iface, VARIANT *p)
325 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
326 FIXME("(%p)->(%p)\n", This, p);
327 return E_NOTIMPL;
330 static HRESULT WINAPI HTMLBodyElement_put_topMargin(IHTMLBodyElement *iface, VARIANT v)
332 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
333 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
334 return E_NOTIMPL;
337 static HRESULT WINAPI HTMLBodyElement_get_topMargin(IHTMLBodyElement *iface, VARIANT *p)
339 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
340 FIXME("(%p)->(%p)\n", This, p);
341 return E_NOTIMPL;
344 static HRESULT WINAPI HTMLBodyElement_put_rightMargin(IHTMLBodyElement *iface, VARIANT v)
346 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
347 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
348 return E_NOTIMPL;
351 static HRESULT WINAPI HTMLBodyElement_get_rightMargin(IHTMLBodyElement *iface, VARIANT *p)
353 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
354 FIXME("(%p)->(%p)\n", This, p);
355 return E_NOTIMPL;
358 static HRESULT WINAPI HTMLBodyElement_put_bottomMargin(IHTMLBodyElement *iface, VARIANT v)
360 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
361 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
362 return E_NOTIMPL;
365 static HRESULT WINAPI HTMLBodyElement_get_bottomMargin(IHTMLBodyElement *iface, VARIANT *p)
367 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
368 FIXME("(%p)->(%p)\n", This, p);
369 return E_NOTIMPL;
372 static HRESULT WINAPI HTMLBodyElement_put_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL v)
374 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
375 FIXME("(%p)->(%x)\n", This, v);
376 return E_NOTIMPL;
379 static HRESULT WINAPI HTMLBodyElement_get_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL *p)
381 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
382 FIXME("(%p)->(%p)\n", This, p);
383 return E_NOTIMPL;
386 static HRESULT WINAPI HTMLBodyElement_put_bgColor(IHTMLBodyElement *iface, VARIANT v)
388 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
389 nsAString strColor;
390 nsresult nsres;
392 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
394 if(!variant_to_nscolor(&v, &strColor))
395 return S_OK;
397 nsres = nsIDOMHTMLBodyElement_SetBgColor(This->nsbody, &strColor);
398 nsAString_Finish(&strColor);
399 if(NS_FAILED(nsres))
400 ERR("SetBgColor failed: %08x\n", nsres);
402 return S_OK;
405 static HRESULT WINAPI HTMLBodyElement_get_bgColor(IHTMLBodyElement *iface, VARIANT *p)
407 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
408 nsAString strColor;
409 nsresult nsres;
410 HRESULT hres;
412 TRACE("(%p)->(%p)\n", This, p);
414 nsAString_Init(&strColor, NULL);
415 nsres = nsIDOMHTMLBodyElement_GetBgColor(This->nsbody, &strColor);
416 if(NS_SUCCEEDED(nsres)) {
417 const PRUnichar *color;
419 nsAString_GetData(&strColor, &color);
420 V_VT(p) = VT_BSTR;
421 hres = nscolor_to_str(color, &V_BSTR(p));
422 }else {
423 ERR("SetBgColor failed: %08x\n", nsres);
424 hres = E_FAIL;
427 nsAString_Finish(&strColor);
428 return hres;
431 static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT v)
433 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
434 nsAString text;
435 nsresult nsres;
437 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
439 if(!variant_to_nscolor(&v, &text))
440 return S_OK;
442 nsres = nsIDOMHTMLBodyElement_SetText(This->nsbody, &text);
443 nsAString_Finish(&text);
444 if(NS_FAILED(nsres)) {
445 ERR("SetText failed: %08x\n", nsres);
446 return E_FAIL;
449 return S_OK;
452 static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT *p)
454 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
455 nsAString text;
456 nsresult nsres;
457 HRESULT hres;
459 TRACE("(%p)->(%p)\n", This, p);
461 nsAString_Init(&text, NULL);
462 nsres = nsIDOMHTMLBodyElement_GetText(This->nsbody, &text);
463 if(NS_SUCCEEDED(nsres)) {
464 const PRUnichar *color;
466 nsAString_GetData(&text, &color);
467 V_VT(p) = VT_BSTR;
468 hres = nscolor_to_str(color, &V_BSTR(p));
469 }else {
470 ERR("GetText failed: %08x\n", nsres);
471 hres = E_FAIL;
474 nsAString_Finish(&text);
476 return hres;
479 static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v)
481 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
482 nsAString link_str;
483 nsresult nsres;
485 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
487 if(!variant_to_nscolor(&v, &link_str))
488 return S_OK;
490 nsres = nsIDOMHTMLBodyElement_SetLink(This->nsbody, &link_str);
491 nsAString_Finish(&link_str);
492 if(NS_FAILED(nsres))
493 ERR("SetLink failed: %08x\n", nsres);
495 return S_OK;
498 static HRESULT WINAPI HTMLBodyElement_get_link(IHTMLBodyElement *iface, VARIANT *p)
500 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
501 nsAString link_str;
502 nsresult nsres;
504 TRACE("(%p)->(%p)\n", This, p);
506 nsAString_Init(&link_str, NULL);
507 nsres = nsIDOMHTMLBodyElement_GetLink(This->nsbody, &link_str);
508 return return_nscolor(nsres, &link_str, p);
511 static HRESULT WINAPI HTMLBodyElement_put_vLink(IHTMLBodyElement *iface, VARIANT v)
513 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
514 nsAString vlink_str;
515 nsresult nsres;
517 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
519 if(!variant_to_nscolor(&v, &vlink_str))
520 return S_OK;
522 nsres = nsIDOMHTMLBodyElement_SetVLink(This->nsbody, &vlink_str);
523 nsAString_Finish(&vlink_str);
524 if(NS_FAILED(nsres))
525 ERR("SetLink failed: %08x\n", nsres);
527 return S_OK;
530 static HRESULT WINAPI HTMLBodyElement_get_vLink(IHTMLBodyElement *iface, VARIANT *p)
532 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
533 nsAString vlink_str;
534 nsresult nsres;
536 TRACE("(%p)->(%p)\n", This, p);
538 nsAString_Init(&vlink_str, NULL);
539 nsres = nsIDOMHTMLBodyElement_GetVLink(This->nsbody, &vlink_str);
540 return return_nscolor(nsres, &vlink_str, p);
543 static HRESULT WINAPI HTMLBodyElement_put_aLink(IHTMLBodyElement *iface, VARIANT v)
545 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
546 nsAString alink_str;
547 nsresult nsres;
549 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
551 if(!variant_to_nscolor(&v, &alink_str))
552 return S_OK;
554 nsres = nsIDOMHTMLBodyElement_SetALink(This->nsbody, &alink_str);
555 nsAString_Finish(&alink_str);
556 if(NS_FAILED(nsres))
557 ERR("SetALink failed: %08x\n", nsres);
559 return S_OK;
562 static HRESULT WINAPI HTMLBodyElement_get_aLink(IHTMLBodyElement *iface, VARIANT *p)
564 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
565 nsAString alink_str;
566 nsresult nsres;
568 TRACE("(%p)->(%p)\n", This, p);
570 nsAString_Init(&alink_str, NULL);
571 nsres = nsIDOMHTMLBodyElement_GetALink(This->nsbody, &alink_str);
572 return return_nscolor(nsres, &alink_str, p);
575 static HRESULT WINAPI HTMLBodyElement_put_onload(IHTMLBodyElement *iface, VARIANT v)
577 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
579 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
581 return set_node_event(&This->textcont.element.node, EVENTID_LOAD, &v);
584 static HRESULT WINAPI HTMLBodyElement_get_onload(IHTMLBodyElement *iface, VARIANT *p)
586 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
588 TRACE("(%p)->(%p)\n", This, p);
590 return get_node_event(&This->textcont.element.node, EVENTID_LOAD, p);
593 static HRESULT WINAPI HTMLBodyElement_put_onunload(IHTMLBodyElement *iface, VARIANT v)
595 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
596 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
597 return E_NOTIMPL;
600 static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARIANT *p)
602 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
603 FIXME("(%p)->(%p)\n", This, p);
604 return E_NOTIMPL;
607 static const WCHAR autoW[] = {'a','u','t','o',0};
608 static const WCHAR hiddenW[] = {'h','i','d','d','e','n',0};
609 static const WCHAR scrollW[] = {'s','c','r','o','l','l',0};
610 static const WCHAR visibleW[] = {'v','i','s','i','b','l','e',0};
611 static const WCHAR yesW[] = {'y','e','s',0};
612 static const WCHAR noW[] = {'n','o',0};
614 static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v)
616 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
617 static const WCHAR *val;
619 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
621 /* Emulate with CSS visibility attribute */
622 if(!strcmpW(v, yesW)) {
623 val = scrollW;
624 }else if(!strcmpW(v, autoW)) {
625 val = visibleW;
626 }else if(!strcmpW(v, noW)) {
627 val = hiddenW;
628 }else {
629 WARN("Invalid argument %s\n", debugstr_w(v));
630 return E_INVALIDARG;
633 return set_elem_style(&This->textcont.element, STYLEID_OVERFLOW, val);
636 static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p)
638 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
639 const WCHAR *ret = NULL;
640 BSTR overflow;
641 HRESULT hres;
643 TRACE("(%p)->(%p)\n", This, p);
645 /* Emulate with CSS visibility attribute */
646 hres = get_elem_style(&This->textcont.element, STYLEID_OVERFLOW, &overflow);
647 if(FAILED(hres))
648 return hres;
650 if(!overflow || !*overflow) {
651 *p = NULL;
652 hres = S_OK;
653 }else if(!strcmpW(overflow, visibleW) || !strcmpW(overflow, autoW)) {
654 ret = autoW;
655 }else if(!strcmpW(overflow, scrollW)) {
656 ret = yesW;
657 }else if(!strcmpW(overflow, hiddenW)) {
658 ret = noW;
659 }else {
660 TRACE("Defaulting %s to NULL\n", debugstr_w(overflow));
661 *p = NULL;
662 hres = S_OK;
665 SysFreeString(overflow);
666 if(ret) {
667 *p = SysAllocString(ret);
668 hres = *p ? S_OK : E_OUTOFMEMORY;
671 return hres;
674 static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v)
676 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
677 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
678 return E_NOTIMPL;
681 static HRESULT WINAPI HTMLBodyElement_get_onselect(IHTMLBodyElement *iface, VARIANT *p)
683 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
684 FIXME("(%p)->(%p)\n", This, p);
685 return E_NOTIMPL;
688 static HRESULT WINAPI HTMLBodyElement_put_onbeforeunload(IHTMLBodyElement *iface, VARIANT v)
690 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
691 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
692 return E_NOTIMPL;
695 static HRESULT WINAPI HTMLBodyElement_get_onbeforeunload(IHTMLBodyElement *iface, VARIANT *p)
697 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
698 FIXME("(%p)->(%p)\n", This, p);
699 return E_NOTIMPL;
702 static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, IHTMLTxtRange **range)
704 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
705 nsIDOMRange *nsrange = NULL;
706 nsresult nsres;
707 HRESULT hres;
709 TRACE("(%p)->(%p)\n", This, range);
711 if(!This->textcont.element.node.doc->nsdoc) {
712 WARN("No nsdoc\n");
713 return E_UNEXPECTED;
716 nsres = nsIDOMHTMLDocument_CreateRange(This->textcont.element.node.doc->nsdoc, &nsrange);
717 if(NS_SUCCEEDED(nsres)) {
718 nsres = nsIDOMRange_SelectNodeContents(nsrange, This->textcont.element.node.nsnode);
719 if(NS_FAILED(nsres))
720 ERR("SelectNodeContents failed: %08x\n", nsres);
721 }else {
722 ERR("CreateRange failed: %08x\n", nsres);
725 hres = HTMLTxtRange_Create(This->textcont.element.node.doc->basedoc.doc_node, nsrange, range);
727 nsIDOMRange_Release(nsrange);
728 return hres;
731 static const IHTMLBodyElementVtbl HTMLBodyElementVtbl = {
732 HTMLBodyElement_QueryInterface,
733 HTMLBodyElement_AddRef,
734 HTMLBodyElement_Release,
735 HTMLBodyElement_GetTypeInfoCount,
736 HTMLBodyElement_GetTypeInfo,
737 HTMLBodyElement_GetIDsOfNames,
738 HTMLBodyElement_Invoke,
739 HTMLBodyElement_put_background,
740 HTMLBodyElement_get_background,
741 HTMLBodyElement_put_bgProperties,
742 HTMLBodyElement_get_bgProperties,
743 HTMLBodyElement_put_leftMargin,
744 HTMLBodyElement_get_leftMargin,
745 HTMLBodyElement_put_topMargin,
746 HTMLBodyElement_get_topMargin,
747 HTMLBodyElement_put_rightMargin,
748 HTMLBodyElement_get_rightMargin,
749 HTMLBodyElement_put_bottomMargin,
750 HTMLBodyElement_get_bottomMargin,
751 HTMLBodyElement_put_noWrap,
752 HTMLBodyElement_get_noWrap,
753 HTMLBodyElement_put_bgColor,
754 HTMLBodyElement_get_bgColor,
755 HTMLBodyElement_put_text,
756 HTMLBodyElement_get_text,
757 HTMLBodyElement_put_link,
758 HTMLBodyElement_get_link,
759 HTMLBodyElement_put_vLink,
760 HTMLBodyElement_get_vLink,
761 HTMLBodyElement_put_aLink,
762 HTMLBodyElement_get_aLink,
763 HTMLBodyElement_put_onload,
764 HTMLBodyElement_get_onload,
765 HTMLBodyElement_put_onunload,
766 HTMLBodyElement_get_onunload,
767 HTMLBodyElement_put_scroll,
768 HTMLBodyElement_get_scroll,
769 HTMLBodyElement_put_onselect,
770 HTMLBodyElement_get_onselect,
771 HTMLBodyElement_put_onbeforeunload,
772 HTMLBodyElement_get_onbeforeunload,
773 HTMLBodyElement_createTextRange
776 static inline HTMLBodyElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
778 return CONTAINING_RECORD(iface, HTMLBodyElement, textcont.element.node);
781 static HRESULT HTMLBodyElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
783 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
785 *ppv = NULL;
787 if(IsEqualGUID(&IID_IUnknown, riid)) {
788 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
789 *ppv = &This->IHTMLBodyElement_iface;
790 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
791 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
792 *ppv = &This->IHTMLBodyElement_iface;
793 }else if(IsEqualGUID(&IID_IHTMLBodyElement, riid)) {
794 TRACE("(%p)->(IID_IHTMLBodyElement %p)\n", This, ppv);
795 *ppv = &This->IHTMLBodyElement_iface;
796 }else if(IsEqualGUID(&IID_IHTMLTextContainer, riid)) {
797 TRACE("(%p)->(IID_IHTMLTextContainer %p)\n", &This->textcont, ppv);
798 *ppv = &This->textcont.IHTMLTextContainer_iface;
801 if(*ppv) {
802 IUnknown_AddRef((IUnknown*)*ppv);
803 return S_OK;
806 return HTMLElement_QI(&This->textcont.element.node, riid, ppv);
809 static void HTMLBodyElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
811 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
813 if(This->nsbody)
814 note_cc_edge((nsISupports*)This->nsbody, "This->nsbody", cb);
817 static void HTMLBodyElement_unlink(HTMLDOMNode *iface)
819 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
821 if(This->nsbody) {
822 nsIDOMHTMLBodyElement *nsbody = This->nsbody;
823 This->nsbody = NULL;
824 nsIDOMHTMLBodyElement_Release(nsbody);
828 static EventTarget *HTMLBodyElement_get_event_prop_target(HTMLDOMNode *iface, int event_id)
830 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
832 switch(event_id) {
833 case EVENTID_BLUR:
834 case EVENTID_ERROR:
835 case EVENTID_FOCUS:
836 case EVENTID_LOAD:
837 case EVENTID_SCROLL:
838 return This->textcont.element.node.doc && This->textcont.element.node.doc->window
839 ? &This->textcont.element.node.doc->window->event_target
840 : &This->textcont.element.node.event_target;
841 default:
842 return &This->textcont.element.node.event_target;
846 static BOOL HTMLBodyElement_is_text_edit(HTMLDOMNode *iface)
848 return TRUE;
851 static BOOL HTMLBodyElement_is_settable(HTMLDOMNode *iface, DISPID dispid)
853 switch(dispid) {
854 case DISPID_IHTMLELEMENT_OUTERTEXT:
855 return FALSE;
856 default:
857 return TRUE;
861 static const cpc_entry_t HTMLBodyElement_cpc[] = {
862 {&DIID_HTMLTextContainerEvents},
863 {&IID_IPropertyNotifySink},
864 HTMLELEMENT_CPC,
865 {NULL}
868 static const NodeImplVtbl HTMLBodyElementImplVtbl = {
869 &CLSID_HTMLBody,
870 HTMLBodyElement_QI,
871 HTMLElement_destructor,
872 HTMLBodyElement_cpc,
873 HTMLElement_clone,
874 HTMLElement_handle_event,
875 HTMLElement_get_attr_col,
876 HTMLBodyElement_get_event_prop_target,
877 NULL,
878 NULL,
879 NULL,
880 NULL,
881 NULL,
882 NULL,
883 NULL,
884 HTMLBodyElement_traverse,
885 HTMLBodyElement_unlink,
886 HTMLBodyElement_is_text_edit,
887 HTMLBodyElement_is_settable
890 static const tid_t HTMLBodyElement_iface_tids[] = {
891 IHTMLBodyElement_tid,
892 IHTMLBodyElement2_tid,
893 HTMLELEMENT_TIDS,
894 IHTMLTextContainer_tid,
898 static dispex_static_data_t HTMLBodyElement_dispex = {
899 NULL,
900 DispHTMLBody_tid,
901 HTMLBodyElement_iface_tids,
902 HTMLElement_init_dispex_info
905 HRESULT HTMLBodyElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
907 HTMLBodyElement *ret;
908 nsresult nsres;
910 ret = heap_alloc_zero(sizeof(HTMLBodyElement));
911 if(!ret)
912 return E_OUTOFMEMORY;
914 ret->IHTMLBodyElement_iface.lpVtbl = &HTMLBodyElementVtbl;
915 ret->textcont.element.node.vtbl = &HTMLBodyElementImplVtbl;
917 nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLBodyElement, (void**)&ret->nsbody);
918 if(NS_FAILED(nsres)) {
919 ERR("Could not get nsDOMHTMLBodyElement: %08x\n", nsres);
920 heap_free(ret);
921 return E_OUTOFMEMORY;
924 HTMLTextContainer_Init(&ret->textcont, doc, nselem, &HTMLBodyElement_dispex);
926 *elem = &ret->textcont.element;
927 return S_OK;