advapi32/tests: Allow ERROR_ACCESS_DENIED for newer Win10.
[wine.git] / dlls / mshtml / htmlbody.c
blob2cfd46dc504b75f5a99a4340c68dbd2b4e4bc87f
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>
21 #include <assert.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "ole2.h"
29 #include "mshtmdid.h"
31 #include "wine/debug.h"
33 #include "mshtml_private.h"
34 #include "htmlevent.h"
35 #include "htmlstyle.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
39 typedef struct {
40 HTMLElement element;
42 IHTMLBodyElement IHTMLBodyElement_iface;
43 IHTMLTextContainer IHTMLTextContainer_iface;
45 nsIDOMHTMLBodyElement *nsbody;
46 } HTMLBodyElement;
48 static const WCHAR aquaW[] = {'a','q','u','a',0};
49 static const WCHAR blackW[] = {'b','l','a','c','k',0};
50 static const WCHAR blueW[] = {'b','l','u','e',0};
51 static const WCHAR fuchsiaW[] = {'f','u','s','h','s','i','a',0};
52 static const WCHAR grayW[] = {'g','r','a','y',0};
53 static const WCHAR greenW[] = {'g','r','e','e','n',0};
54 static const WCHAR limeW[] = {'l','i','m','e',0};
55 static const WCHAR maroonW[] = {'m','a','r','o','o','n',0};
56 static const WCHAR navyW[] = {'n','a','v','y',0};
57 static const WCHAR oliveW[] = {'o','l','i','v','e',0};
58 static const WCHAR purpleW[] = {'p','u','r','p','l','e',0};
59 static const WCHAR redW[] = {'r','e','d',0};
60 static const WCHAR silverW[] = {'s','i','l','v','e','r',0};
61 static const WCHAR tealW[] = {'t','e','a','l',0};
62 static const WCHAR whiteW[] = {'w','h','i','t','e',0};
63 static const WCHAR yellowW[] = {'y','e','l','l','o','w',0};
65 static const struct {
66 LPCWSTR keyword;
67 DWORD rgb;
68 } keyword_table[] = {
69 {aquaW, 0x00ffff},
70 {blackW, 0x000000},
71 {blueW, 0x0000ff},
72 {fuchsiaW, 0xff00ff},
73 {grayW, 0x808080},
74 {greenW, 0x008000},
75 {limeW, 0x00ff00},
76 {maroonW, 0x800000},
77 {navyW, 0x000080},
78 {oliveW, 0x808000},
79 {purpleW, 0x800080},
80 {redW, 0xff0000},
81 {silverW, 0xc0c0c0},
82 {tealW, 0x008080},
83 {whiteW, 0xffffff},
84 {yellowW, 0xffff00}
87 static int comp_value(const WCHAR *ptr, int dpc)
89 int ret = 0;
90 WCHAR ch;
92 if(dpc > 2)
93 dpc = 2;
95 while(dpc--) {
96 if(!*ptr)
97 ret *= 16;
98 else if(isdigitW(ch = *ptr++))
99 ret = ret*16 + (ch-'0');
100 else if('a' <= ch && ch <= 'f')
101 ret = ret*16 + (ch-'a') + 10;
102 else if('A' <= ch && ch <= 'F')
103 ret = ret*16 + (ch-'A') + 10;
104 else
105 ret *= 16;
108 return ret;
111 /* Based on Gecko NS_LooseHexToRGB */
112 static int loose_hex_to_rgb(const WCHAR *hex)
114 int len, dpc;
116 len = strlenW(hex);
117 if(*hex == '#') {
118 hex++;
119 len--;
121 if(len <= 3)
122 return 0;
124 dpc = min(len/3 + (len%3 ? 1 : 0), 4);
125 return (comp_value(hex, dpc) << 16)
126 | (comp_value(hex+dpc, dpc) << 8)
127 | comp_value(hex+2*dpc, dpc);
130 HRESULT nscolor_to_str(LPCWSTR color, BSTR *ret)
132 unsigned int i;
133 int rgb = -1;
135 static const WCHAR formatW[] = {'#','%','0','2','x','%','0','2','x','%','0','2','x',0};
137 if(!color || !*color) {
138 *ret = NULL;
139 return S_OK;
142 if(*color != '#') {
143 for(i=0; i < ARRAY_SIZE(keyword_table); i++) {
144 if(!strcmpiW(color, keyword_table[i].keyword))
145 rgb = keyword_table[i].rgb;
148 if(rgb == -1)
149 rgb = loose_hex_to_rgb(color);
151 *ret = SysAllocStringLen(NULL, 7);
152 if(!*ret)
153 return E_OUTOFMEMORY;
155 sprintfW(*ret, formatW, rgb>>16, (rgb>>8)&0xff, rgb&0xff);
157 TRACE("%s -> %s\n", debugstr_w(color), debugstr_w(*ret));
158 return S_OK;
161 BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr)
163 switch(V_VT(v)) {
164 case VT_BSTR:
165 nsAString_Init(nsstr, V_BSTR(v));
166 return TRUE;
168 case VT_I4: {
169 PRUnichar buf[10];
170 static const WCHAR formatW[] = {'#','%','x',0};
172 wsprintfW(buf, formatW, V_I4(v));
173 nsAString_Init(nsstr, buf);
174 return TRUE;
177 default:
178 FIXME("invalid color %s\n", debugstr_variant(v));
181 return FALSE;
185 static HRESULT return_nscolor(nsresult nsres, nsAString *nsstr, VARIANT *p)
187 const PRUnichar *color;
189 if(NS_FAILED(nsres)) {
190 ERR("failed: %08x\n", nsres);
191 nsAString_Finish(nsstr);
192 return E_FAIL;
195 nsAString_GetData(nsstr, &color);
197 if(*color == '#') {
198 V_VT(p) = VT_I4;
199 V_I4(p) = strtolW(color+1, NULL, 16);
200 }else {
201 V_VT(p) = VT_BSTR;
202 V_BSTR(p) = SysAllocString(color);
203 if(!V_BSTR(p)) {
204 nsAString_Finish(nsstr);
205 return E_OUTOFMEMORY;
209 nsAString_Finish(nsstr);
210 TRACE("ret %s\n", debugstr_variant(p));
211 return S_OK;
214 static inline HTMLBodyElement *impl_from_IHTMLBodyElement(IHTMLBodyElement *iface)
216 return CONTAINING_RECORD(iface, HTMLBodyElement, IHTMLBodyElement_iface);
219 static HRESULT WINAPI HTMLBodyElement_QueryInterface(IHTMLBodyElement *iface,
220 REFIID riid, void **ppv)
222 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
224 return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
227 static ULONG WINAPI HTMLBodyElement_AddRef(IHTMLBodyElement *iface)
229 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
231 return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
234 static ULONG WINAPI HTMLBodyElement_Release(IHTMLBodyElement *iface)
236 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
238 return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
241 static HRESULT WINAPI HTMLBodyElement_GetTypeInfoCount(IHTMLBodyElement *iface, UINT *pctinfo)
243 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
244 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface,
245 pctinfo);
248 static HRESULT WINAPI HTMLBodyElement_GetTypeInfo(IHTMLBodyElement *iface, UINT iTInfo,
249 LCID lcid, ITypeInfo **ppTInfo)
251 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
252 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo,
253 lcid, ppTInfo);
256 static HRESULT WINAPI HTMLBodyElement_GetIDsOfNames(IHTMLBodyElement *iface, REFIID riid,
257 LPOLESTR *rgszNames, UINT cNames,
258 LCID lcid, DISPID *rgDispId)
260 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
261 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid,
262 rgszNames, cNames, lcid, rgDispId);
265 static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dispIdMember,
266 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
267 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
269 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
270 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember,
271 riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
274 static HRESULT WINAPI HTMLBodyElement_put_background(IHTMLBodyElement *iface, BSTR v)
276 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
277 nsAString nsstr;
278 nsresult nsres;
280 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
282 nsAString_InitDepend(&nsstr, v);
283 nsres = nsIDOMHTMLBodyElement_SetBackground(This->nsbody, &nsstr);
284 nsAString_Finish(&nsstr);
285 if(NS_FAILED(nsres))
286 return E_FAIL;
288 return S_OK;
291 static HRESULT WINAPI HTMLBodyElement_get_background(IHTMLBodyElement *iface, BSTR *p)
293 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
294 nsAString background_str;
295 nsresult nsres;
297 TRACE("(%p)->(%p)\n", This, p);
299 nsAString_Init(&background_str, NULL);
300 nsres = nsIDOMHTMLBodyElement_GetBackground(This->nsbody, &background_str);
301 return return_nsstr(nsres, &background_str, p);
304 static HRESULT WINAPI HTMLBodyElement_put_bgProperties(IHTMLBodyElement *iface, BSTR v)
306 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
307 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
308 return E_NOTIMPL;
311 static HRESULT WINAPI HTMLBodyElement_get_bgProperties(IHTMLBodyElement *iface, BSTR *p)
313 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
314 FIXME("(%p)->(%p)\n", This, p);
315 return E_NOTIMPL;
318 static HRESULT WINAPI HTMLBodyElement_put_leftMargin(IHTMLBodyElement *iface, VARIANT v)
320 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
321 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
322 return E_NOTIMPL;
325 static HRESULT WINAPI HTMLBodyElement_get_leftMargin(IHTMLBodyElement *iface, VARIANT *p)
327 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
328 FIXME("(%p)->(%p)\n", This, p);
329 return E_NOTIMPL;
332 static HRESULT WINAPI HTMLBodyElement_put_topMargin(IHTMLBodyElement *iface, VARIANT v)
334 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
335 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
336 return E_NOTIMPL;
339 static HRESULT WINAPI HTMLBodyElement_get_topMargin(IHTMLBodyElement *iface, VARIANT *p)
341 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
342 FIXME("(%p)->(%p)\n", This, p);
343 return E_NOTIMPL;
346 static HRESULT WINAPI HTMLBodyElement_put_rightMargin(IHTMLBodyElement *iface, VARIANT v)
348 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
349 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
350 return E_NOTIMPL;
353 static HRESULT WINAPI HTMLBodyElement_get_rightMargin(IHTMLBodyElement *iface, VARIANT *p)
355 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
356 FIXME("(%p)->(%p)\n", This, p);
357 return E_NOTIMPL;
360 static HRESULT WINAPI HTMLBodyElement_put_bottomMargin(IHTMLBodyElement *iface, VARIANT v)
362 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
363 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
364 return E_NOTIMPL;
367 static HRESULT WINAPI HTMLBodyElement_get_bottomMargin(IHTMLBodyElement *iface, VARIANT *p)
369 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
370 FIXME("(%p)->(%p)\n", This, p);
371 return E_NOTIMPL;
374 static HRESULT WINAPI HTMLBodyElement_put_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL v)
376 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
377 FIXME("(%p)->(%x)\n", This, v);
378 return E_NOTIMPL;
381 static HRESULT WINAPI HTMLBodyElement_get_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL *p)
383 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
384 FIXME("(%p)->(%p)\n", This, p);
385 return E_NOTIMPL;
388 static HRESULT WINAPI HTMLBodyElement_put_bgColor(IHTMLBodyElement *iface, VARIANT v)
390 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
391 nsAString strColor;
392 nsresult nsres;
394 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
396 if(!variant_to_nscolor(&v, &strColor))
397 return S_OK;
399 nsres = nsIDOMHTMLBodyElement_SetBgColor(This->nsbody, &strColor);
400 nsAString_Finish(&strColor);
401 if(NS_FAILED(nsres))
402 ERR("SetBgColor failed: %08x\n", nsres);
404 return S_OK;
407 static HRESULT WINAPI HTMLBodyElement_get_bgColor(IHTMLBodyElement *iface, VARIANT *p)
409 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
410 nsAString strColor;
411 nsresult nsres;
412 HRESULT hres;
414 TRACE("(%p)->(%p)\n", This, p);
416 nsAString_Init(&strColor, NULL);
417 nsres = nsIDOMHTMLBodyElement_GetBgColor(This->nsbody, &strColor);
418 if(NS_SUCCEEDED(nsres)) {
419 const PRUnichar *color;
421 nsAString_GetData(&strColor, &color);
422 V_VT(p) = VT_BSTR;
423 hres = nscolor_to_str(color, &V_BSTR(p));
424 }else {
425 ERR("SetBgColor failed: %08x\n", nsres);
426 hres = E_FAIL;
429 nsAString_Finish(&strColor);
430 return hres;
433 static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT v)
435 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
436 nsAString text;
437 nsresult nsres;
439 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
441 if(!variant_to_nscolor(&v, &text))
442 return S_OK;
444 nsres = nsIDOMHTMLBodyElement_SetText(This->nsbody, &text);
445 nsAString_Finish(&text);
446 if(NS_FAILED(nsres)) {
447 ERR("SetText failed: %08x\n", nsres);
448 return E_FAIL;
451 return S_OK;
454 static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT *p)
456 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
457 nsAString text;
458 nsresult nsres;
459 HRESULT hres;
461 TRACE("(%p)->(%p)\n", This, p);
463 nsAString_Init(&text, NULL);
464 nsres = nsIDOMHTMLBodyElement_GetText(This->nsbody, &text);
465 if(NS_SUCCEEDED(nsres)) {
466 const PRUnichar *color;
468 nsAString_GetData(&text, &color);
469 V_VT(p) = VT_BSTR;
470 hres = nscolor_to_str(color, &V_BSTR(p));
471 }else {
472 ERR("GetText failed: %08x\n", nsres);
473 hres = E_FAIL;
476 nsAString_Finish(&text);
478 return hres;
481 static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v)
483 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
484 nsAString link_str;
485 nsresult nsres;
487 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
489 if(!variant_to_nscolor(&v, &link_str))
490 return S_OK;
492 nsres = nsIDOMHTMLBodyElement_SetLink(This->nsbody, &link_str);
493 nsAString_Finish(&link_str);
494 if(NS_FAILED(nsres))
495 ERR("SetLink failed: %08x\n", nsres);
497 return S_OK;
500 static HRESULT WINAPI HTMLBodyElement_get_link(IHTMLBodyElement *iface, VARIANT *p)
502 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
503 nsAString link_str;
504 nsresult nsres;
506 TRACE("(%p)->(%p)\n", This, p);
508 nsAString_Init(&link_str, NULL);
509 nsres = nsIDOMHTMLBodyElement_GetLink(This->nsbody, &link_str);
510 return return_nscolor(nsres, &link_str, p);
513 static HRESULT WINAPI HTMLBodyElement_put_vLink(IHTMLBodyElement *iface, VARIANT v)
515 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
516 nsAString vlink_str;
517 nsresult nsres;
519 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
521 if(!variant_to_nscolor(&v, &vlink_str))
522 return S_OK;
524 nsres = nsIDOMHTMLBodyElement_SetVLink(This->nsbody, &vlink_str);
525 nsAString_Finish(&vlink_str);
526 if(NS_FAILED(nsres))
527 ERR("SetLink failed: %08x\n", nsres);
529 return S_OK;
532 static HRESULT WINAPI HTMLBodyElement_get_vLink(IHTMLBodyElement *iface, VARIANT *p)
534 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
535 nsAString vlink_str;
536 nsresult nsres;
538 TRACE("(%p)->(%p)\n", This, p);
540 nsAString_Init(&vlink_str, NULL);
541 nsres = nsIDOMHTMLBodyElement_GetVLink(This->nsbody, &vlink_str);
542 return return_nscolor(nsres, &vlink_str, p);
545 static HRESULT WINAPI HTMLBodyElement_put_aLink(IHTMLBodyElement *iface, VARIANT v)
547 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
548 nsAString alink_str;
549 nsresult nsres;
551 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
553 if(!variant_to_nscolor(&v, &alink_str))
554 return S_OK;
556 nsres = nsIDOMHTMLBodyElement_SetALink(This->nsbody, &alink_str);
557 nsAString_Finish(&alink_str);
558 if(NS_FAILED(nsres))
559 ERR("SetALink failed: %08x\n", nsres);
561 return S_OK;
564 static HRESULT WINAPI HTMLBodyElement_get_aLink(IHTMLBodyElement *iface, VARIANT *p)
566 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
567 nsAString alink_str;
568 nsresult nsres;
570 TRACE("(%p)->(%p)\n", This, p);
572 nsAString_Init(&alink_str, NULL);
573 nsres = nsIDOMHTMLBodyElement_GetALink(This->nsbody, &alink_str);
574 return return_nscolor(nsres, &alink_str, p);
577 static HRESULT WINAPI HTMLBodyElement_put_onload(IHTMLBodyElement *iface, VARIANT v)
579 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
581 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
583 return set_node_event(&This->element.node, EVENTID_LOAD, &v);
586 static HRESULT WINAPI HTMLBodyElement_get_onload(IHTMLBodyElement *iface, VARIANT *p)
588 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
590 TRACE("(%p)->(%p)\n", This, p);
592 return get_node_event(&This->element.node, EVENTID_LOAD, p);
595 static HRESULT WINAPI HTMLBodyElement_put_onunload(IHTMLBodyElement *iface, VARIANT v)
597 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
598 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
599 return E_NOTIMPL;
602 static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARIANT *p)
604 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
605 FIXME("(%p)->(%p)\n", This, p);
606 return E_NOTIMPL;
609 static const WCHAR autoW[] = {'a','u','t','o',0};
610 static const WCHAR hiddenW[] = {'h','i','d','d','e','n',0};
611 static const WCHAR scrollW[] = {'s','c','r','o','l','l',0};
612 static const WCHAR visibleW[] = {'v','i','s','i','b','l','e',0};
613 static const WCHAR yesW[] = {'y','e','s',0};
614 static const WCHAR noW[] = {'n','o',0};
616 static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v)
618 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
619 static const WCHAR *val;
621 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
623 /* Emulate with CSS visibility attribute */
624 if(!strcmpW(v, yesW)) {
625 val = scrollW;
626 }else if(!strcmpW(v, autoW)) {
627 val = visibleW;
628 }else if(!strcmpW(v, noW)) {
629 val = hiddenW;
630 }else {
631 WARN("Invalid argument %s\n", debugstr_w(v));
632 return E_INVALIDARG;
635 return set_elem_style(&This->element, STYLEID_OVERFLOW, val);
638 static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p)
640 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
641 const WCHAR *ret = NULL;
642 BSTR overflow;
643 HRESULT hres;
645 TRACE("(%p)->(%p)\n", This, p);
647 /* Emulate with CSS visibility attribute */
648 hres = get_elem_style(&This->element, STYLEID_OVERFLOW, &overflow);
649 if(FAILED(hres))
650 return hres;
652 if(!overflow || !*overflow) {
653 *p = NULL;
654 hres = S_OK;
655 }else if(!strcmpW(overflow, visibleW) || !strcmpW(overflow, autoW)) {
656 ret = autoW;
657 }else if(!strcmpW(overflow, scrollW)) {
658 ret = yesW;
659 }else if(!strcmpW(overflow, hiddenW)) {
660 ret = noW;
661 }else {
662 TRACE("Defaulting %s to NULL\n", debugstr_w(overflow));
663 *p = NULL;
664 hres = S_OK;
667 SysFreeString(overflow);
668 if(ret) {
669 *p = SysAllocString(ret);
670 hres = *p ? S_OK : E_OUTOFMEMORY;
673 return hres;
676 static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v)
678 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
679 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
680 return E_NOTIMPL;
683 static HRESULT WINAPI HTMLBodyElement_get_onselect(IHTMLBodyElement *iface, VARIANT *p)
685 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
686 FIXME("(%p)->(%p)\n", This, p);
687 return E_NOTIMPL;
690 static HRESULT WINAPI HTMLBodyElement_put_onbeforeunload(IHTMLBodyElement *iface, VARIANT v)
692 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
693 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
694 return E_NOTIMPL;
697 static HRESULT WINAPI HTMLBodyElement_get_onbeforeunload(IHTMLBodyElement *iface, VARIANT *p)
699 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
700 FIXME("(%p)->(%p)\n", This, p);
701 return E_NOTIMPL;
704 static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, IHTMLTxtRange **range)
706 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
707 nsIDOMRange *nsrange = NULL;
708 nsresult nsres;
709 HRESULT hres;
711 TRACE("(%p)->(%p)\n", This, range);
713 if(!This->element.node.doc->nsdoc) {
714 WARN("No nsdoc\n");
715 return E_UNEXPECTED;
718 nsres = nsIDOMHTMLDocument_CreateRange(This->element.node.doc->nsdoc, &nsrange);
719 if(NS_SUCCEEDED(nsres)) {
720 nsres = nsIDOMRange_SelectNodeContents(nsrange, This->element.node.nsnode);
721 if(NS_FAILED(nsres))
722 ERR("SelectNodeContents failed: %08x\n", nsres);
723 }else {
724 ERR("CreateRange failed: %08x\n", nsres);
727 hres = HTMLTxtRange_Create(This->element.node.doc->basedoc.doc_node, nsrange, range);
729 nsIDOMRange_Release(nsrange);
730 return hres;
733 static const IHTMLBodyElementVtbl HTMLBodyElementVtbl = {
734 HTMLBodyElement_QueryInterface,
735 HTMLBodyElement_AddRef,
736 HTMLBodyElement_Release,
737 HTMLBodyElement_GetTypeInfoCount,
738 HTMLBodyElement_GetTypeInfo,
739 HTMLBodyElement_GetIDsOfNames,
740 HTMLBodyElement_Invoke,
741 HTMLBodyElement_put_background,
742 HTMLBodyElement_get_background,
743 HTMLBodyElement_put_bgProperties,
744 HTMLBodyElement_get_bgProperties,
745 HTMLBodyElement_put_leftMargin,
746 HTMLBodyElement_get_leftMargin,
747 HTMLBodyElement_put_topMargin,
748 HTMLBodyElement_get_topMargin,
749 HTMLBodyElement_put_rightMargin,
750 HTMLBodyElement_get_rightMargin,
751 HTMLBodyElement_put_bottomMargin,
752 HTMLBodyElement_get_bottomMargin,
753 HTMLBodyElement_put_noWrap,
754 HTMLBodyElement_get_noWrap,
755 HTMLBodyElement_put_bgColor,
756 HTMLBodyElement_get_bgColor,
757 HTMLBodyElement_put_text,
758 HTMLBodyElement_get_text,
759 HTMLBodyElement_put_link,
760 HTMLBodyElement_get_link,
761 HTMLBodyElement_put_vLink,
762 HTMLBodyElement_get_vLink,
763 HTMLBodyElement_put_aLink,
764 HTMLBodyElement_get_aLink,
765 HTMLBodyElement_put_onload,
766 HTMLBodyElement_get_onload,
767 HTMLBodyElement_put_onunload,
768 HTMLBodyElement_get_onunload,
769 HTMLBodyElement_put_scroll,
770 HTMLBodyElement_get_scroll,
771 HTMLBodyElement_put_onselect,
772 HTMLBodyElement_get_onselect,
773 HTMLBodyElement_put_onbeforeunload,
774 HTMLBodyElement_get_onbeforeunload,
775 HTMLBodyElement_createTextRange
778 static inline HTMLBodyElement *impl_from_IHTMLTextContainer(IHTMLTextContainer *iface)
780 return CONTAINING_RECORD(iface, HTMLBodyElement, IHTMLTextContainer_iface);
783 static HRESULT WINAPI HTMLTextContainer_QueryInterface(IHTMLTextContainer *iface,
784 REFIID riid, void **ppv)
786 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
787 return IHTMLElement_QueryInterface(&This->element.IHTMLElement_iface, riid, ppv);
790 static ULONG WINAPI HTMLTextContainer_AddRef(IHTMLTextContainer *iface)
792 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
793 return IHTMLElement_AddRef(&This->element.IHTMLElement_iface);
796 static ULONG WINAPI HTMLTextContainer_Release(IHTMLTextContainer *iface)
798 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
799 return IHTMLElement_Release(&This->element.IHTMLElement_iface);
802 static HRESULT WINAPI HTMLTextContainer_GetTypeInfoCount(IHTMLTextContainer *iface, UINT *pctinfo)
804 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
805 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo);
808 static HRESULT WINAPI HTMLTextContainer_GetTypeInfo(IHTMLTextContainer *iface, UINT iTInfo,
809 LCID lcid, ITypeInfo **ppTInfo)
811 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
812 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid,
813 ppTInfo);
816 static HRESULT WINAPI HTMLTextContainer_GetIDsOfNames(IHTMLTextContainer *iface, REFIID riid,
817 LPOLESTR *rgszNames, UINT cNames,
818 LCID lcid, DISPID *rgDispId)
820 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
821 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames,
822 cNames, lcid, rgDispId);
825 static HRESULT WINAPI HTMLTextContainer_Invoke(IHTMLTextContainer *iface, DISPID dispIdMember,
826 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
827 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
829 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
830 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid,
831 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
834 static HRESULT WINAPI HTMLTextContainer_createControlRange(IHTMLTextContainer *iface,
835 IDispatch **range)
837 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
838 FIXME("(%p)->(%p)\n", This, range);
839 return E_NOTIMPL;
842 static HRESULT WINAPI HTMLTextContainer_get_scrollHeight(IHTMLTextContainer *iface, LONG *p)
844 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
846 TRACE("(%p)->(%p)\n", This, p);
848 return IHTMLElement2_get_scrollHeight(&This->element.IHTMLElement2_iface, p);
851 static HRESULT WINAPI HTMLTextContainer_get_scrollWidth(IHTMLTextContainer *iface, LONG *p)
853 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
855 TRACE("(%p)->(%p)\n", This, p);
857 return IHTMLElement2_get_scrollWidth(&This->element.IHTMLElement2_iface, p);
860 static HRESULT WINAPI HTMLTextContainer_put_scrollTop(IHTMLTextContainer *iface, LONG v)
862 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
864 TRACE("(%p)->(%d)\n", This, v);
866 return IHTMLElement2_put_scrollTop(&This->element.IHTMLElement2_iface, v);
869 static HRESULT WINAPI HTMLTextContainer_get_scrollTop(IHTMLTextContainer *iface, LONG *p)
871 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
873 TRACE("(%p)->(%p)\n", This, p);
875 return IHTMLElement2_get_scrollTop(&This->element.IHTMLElement2_iface, p);
878 static HRESULT WINAPI HTMLTextContainer_put_scrollLeft(IHTMLTextContainer *iface, LONG v)
880 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
882 TRACE("(%p)->(%d)\n", This, v);
884 return IHTMLElement2_put_scrollLeft(&This->element.IHTMLElement2_iface, v);
887 static HRESULT WINAPI HTMLTextContainer_get_scrollLeft(IHTMLTextContainer *iface, LONG *p)
889 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
891 TRACE("(%p)->(%p)\n", This, p);
893 return IHTMLElement2_get_scrollLeft(&This->element.IHTMLElement2_iface, p);
896 static HRESULT WINAPI HTMLTextContainer_put_onscroll(IHTMLTextContainer *iface, VARIANT v)
898 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
899 FIXME("(%p)->()\n", This);
900 return E_NOTIMPL;
903 static HRESULT WINAPI HTMLTextContainer_get_onscroll(IHTMLTextContainer *iface, VARIANT *p)
905 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
906 FIXME("(%p)->(%p)\n", This, p);
907 return E_NOTIMPL;
910 static const IHTMLTextContainerVtbl HTMLTextContainerVtbl = {
911 HTMLTextContainer_QueryInterface,
912 HTMLTextContainer_AddRef,
913 HTMLTextContainer_Release,
914 HTMLTextContainer_GetTypeInfoCount,
915 HTMLTextContainer_GetTypeInfo,
916 HTMLTextContainer_GetIDsOfNames,
917 HTMLTextContainer_Invoke,
918 HTMLTextContainer_createControlRange,
919 HTMLTextContainer_get_scrollHeight,
920 HTMLTextContainer_get_scrollWidth,
921 HTMLTextContainer_put_scrollTop,
922 HTMLTextContainer_get_scrollTop,
923 HTMLTextContainer_put_scrollLeft,
924 HTMLTextContainer_get_scrollLeft,
925 HTMLTextContainer_put_onscroll,
926 HTMLTextContainer_get_onscroll
929 static inline HTMLBodyElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
931 return CONTAINING_RECORD(iface, HTMLBodyElement, element.node);
934 static HRESULT HTMLBodyElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
936 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
938 *ppv = NULL;
940 if(IsEqualGUID(&IID_IUnknown, riid)) {
941 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
942 *ppv = &This->IHTMLBodyElement_iface;
943 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
944 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
945 *ppv = &This->IHTMLBodyElement_iface;
946 }else if(IsEqualGUID(&IID_IHTMLBodyElement, riid)) {
947 TRACE("(%p)->(IID_IHTMLBodyElement %p)\n", This, ppv);
948 *ppv = &This->IHTMLBodyElement_iface;
949 }else if(IsEqualGUID(&IID_IHTMLTextContainer, riid)) {
950 TRACE("(%p)->(IID_IHTMLTextContainer %p)\n", This, ppv);
951 *ppv = &This->IHTMLTextContainer_iface;
954 if(*ppv) {
955 IUnknown_AddRef((IUnknown*)*ppv);
956 return S_OK;
959 return HTMLElement_QI(&This->element.node, riid, ppv);
962 static void HTMLBodyElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
964 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
966 if(This->nsbody)
967 note_cc_edge((nsISupports*)This->nsbody, "This->nsbody", cb);
970 static void HTMLBodyElement_unlink(HTMLDOMNode *iface)
972 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
974 if(This->nsbody) {
975 nsIDOMHTMLBodyElement *nsbody = This->nsbody;
976 This->nsbody = NULL;
977 nsIDOMHTMLBodyElement_Release(nsbody);
981 static EventTarget *HTMLBodyElement_get_event_prop_target(HTMLDOMNode *iface, int event_id)
983 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
985 switch(event_id) {
986 case EVENTID_BLUR:
987 case EVENTID_ERROR:
988 case EVENTID_FOCUS:
989 case EVENTID_LOAD:
990 case EVENTID_SCROLL:
991 return This->element.node.doc && This->element.node.doc->window
992 ? &This->element.node.doc->window->event_target
993 : &This->element.node.event_target;
994 default:
995 return &This->element.node.event_target;
999 static BOOL HTMLBodyElement_is_text_edit(HTMLDOMNode *iface)
1001 return TRUE;
1004 static BOOL HTMLBodyElement_is_settable(HTMLDOMNode *iface, DISPID dispid)
1006 switch(dispid) {
1007 case DISPID_IHTMLELEMENT_OUTERTEXT:
1008 return FALSE;
1009 default:
1010 return TRUE;
1014 static const cpc_entry_t HTMLBodyElement_cpc[] = {
1015 {&DIID_HTMLTextContainerEvents},
1016 {&IID_IPropertyNotifySink},
1017 HTMLELEMENT_CPC,
1018 {NULL}
1021 static const NodeImplVtbl HTMLBodyElementImplVtbl = {
1022 &CLSID_HTMLBody,
1023 HTMLBodyElement_QI,
1024 HTMLElement_destructor,
1025 HTMLBodyElement_cpc,
1026 HTMLElement_clone,
1027 HTMLElement_handle_event,
1028 HTMLElement_get_attr_col,
1029 HTMLBodyElement_get_event_prop_target,
1030 NULL,
1031 NULL,
1032 NULL,
1033 NULL,
1034 NULL,
1035 NULL,
1036 NULL,
1037 HTMLBodyElement_traverse,
1038 HTMLBodyElement_unlink,
1039 HTMLBodyElement_is_text_edit,
1040 HTMLBodyElement_is_settable
1043 static const tid_t HTMLBodyElement_iface_tids[] = {
1044 IHTMLBodyElement_tid,
1045 IHTMLBodyElement2_tid,
1046 HTMLELEMENT_TIDS,
1047 IHTMLTextContainer_tid,
1051 static dispex_static_data_t HTMLBodyElement_dispex = {
1052 NULL,
1053 DispHTMLBody_tid,
1054 HTMLBodyElement_iface_tids,
1055 HTMLElement_init_dispex_info
1058 HRESULT HTMLBodyElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem)
1060 HTMLBodyElement *ret;
1061 nsresult nsres;
1063 ret = heap_alloc_zero(sizeof(HTMLBodyElement));
1064 if(!ret)
1065 return E_OUTOFMEMORY;
1067 ret->IHTMLBodyElement_iface.lpVtbl = &HTMLBodyElementVtbl;
1068 ret->IHTMLTextContainer_iface.lpVtbl = &HTMLTextContainerVtbl;
1069 ret->element.node.vtbl = &HTMLBodyElementImplVtbl;
1071 HTMLElement_Init(&ret->element, doc, nselem, &HTMLBodyElement_dispex);
1073 nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLBodyElement, (void**)&ret->nsbody);
1074 assert(nsres == NS_OK);
1076 *elem = &ret->element;
1077 return S_OK;