mshtml: Send load event synchronously for img elements that loaded instantly in legac...
[wine.git] / dlls / mshtml / htmlbody.c
blob311bbca2257c2fc1151397d641e7e86d0a893e20
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 HTMLElement element;
41 IHTMLBodyElement IHTMLBodyElement_iface;
42 IHTMLTextContainer IHTMLTextContainer_iface;
44 nsIDOMHTMLBodyElement *nsbody;
45 } HTMLBodyElement;
47 static const struct {
48 LPCWSTR keyword;
49 DWORD rgb;
50 } keyword_table[] = {
51 {L"aqua", 0x00ffff},
52 {L"black", 0x000000},
53 {L"blue", 0x0000ff},
54 {L"fuchsia", 0xff00ff},
55 {L"gray", 0x808080},
56 {L"green", 0x008000},
57 {L"lime", 0x00ff00},
58 {L"maroon", 0x800000},
59 {L"navy", 0x000080},
60 {L"olive", 0x808000},
61 {L"purple", 0x800080},
62 {L"red", 0xff0000},
63 {L"silver", 0xc0c0c0},
64 {L"teal", 0x008080},
65 {L"white", 0xffffff},
66 {L"yellow", 0xffff00}
69 static int comp_value(const WCHAR *ptr, int dpc)
71 int ret = 0;
72 WCHAR ch;
74 if(dpc > 2)
75 dpc = 2;
77 while(dpc--) {
78 if(!*ptr)
79 ret *= 16;
80 else if(is_digit(ch = *ptr++))
81 ret = ret*16 + (ch-'0');
82 else if('a' <= ch && ch <= 'f')
83 ret = ret*16 + (ch-'a') + 10;
84 else if('A' <= ch && ch <= 'F')
85 ret = ret*16 + (ch-'A') + 10;
86 else
87 ret *= 16;
90 return ret;
93 /* Based on Gecko NS_LooseHexToRGB */
94 static int loose_hex_to_rgb(const WCHAR *hex)
96 int len, dpc;
98 len = lstrlenW(hex);
99 if(*hex == '#') {
100 hex++;
101 len--;
103 if(len <= 3)
104 return 0;
106 dpc = min(len/3 + (len%3 ? 1 : 0), 4);
107 return (comp_value(hex, dpc) << 16)
108 | (comp_value(hex+dpc, dpc) << 8)
109 | comp_value(hex+2*dpc, dpc);
112 HRESULT nscolor_to_str(LPCWSTR color, BSTR *ret)
114 unsigned int i;
115 int rgb = -1;
117 if(!color || !*color) {
118 *ret = NULL;
119 return S_OK;
122 if(*color != '#') {
123 for(i=0; i < ARRAY_SIZE(keyword_table); i++) {
124 if(!wcsicmp(color, keyword_table[i].keyword))
125 rgb = keyword_table[i].rgb;
128 if(rgb == -1)
129 rgb = loose_hex_to_rgb(color);
131 *ret = SysAllocStringLen(NULL, 7);
132 if(!*ret)
133 return E_OUTOFMEMORY;
135 swprintf(*ret, 8, L"#%02x%02x%02x", rgb>>16, (rgb>>8)&0xff, rgb&0xff);
137 TRACE("%s -> %s\n", debugstr_w(color), debugstr_w(*ret));
138 return S_OK;
141 BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr)
143 switch(V_VT(v)) {
144 case VT_BSTR:
145 nsAString_Init(nsstr, V_BSTR(v));
146 return TRUE;
148 case VT_I4: {
149 PRUnichar buf[10];
151 wsprintfW(buf, L"#%x", V_I4(v));
152 nsAString_Init(nsstr, buf);
153 return TRUE;
156 default:
157 FIXME("invalid color %s\n", debugstr_variant(v));
160 return FALSE;
164 static HRESULT return_nscolor(nsresult nsres, nsAString *nsstr, VARIANT *p)
166 const PRUnichar *color;
168 if(NS_FAILED(nsres)) {
169 ERR("failed: %08lx\n", nsres);
170 nsAString_Finish(nsstr);
171 return E_FAIL;
174 nsAString_GetData(nsstr, &color);
176 if(*color == '#') {
177 V_VT(p) = VT_I4;
178 V_I4(p) = wcstol(color+1, NULL, 16);
179 }else {
180 V_VT(p) = VT_BSTR;
181 V_BSTR(p) = SysAllocString(color);
182 if(!V_BSTR(p)) {
183 nsAString_Finish(nsstr);
184 return E_OUTOFMEMORY;
188 nsAString_Finish(nsstr);
189 TRACE("ret %s\n", debugstr_variant(p));
190 return S_OK;
193 static inline HTMLBodyElement *impl_from_IHTMLBodyElement(IHTMLBodyElement *iface)
195 return CONTAINING_RECORD(iface, HTMLBodyElement, IHTMLBodyElement_iface);
198 static HRESULT WINAPI HTMLBodyElement_QueryInterface(IHTMLBodyElement *iface,
199 REFIID riid, void **ppv)
201 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
203 return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
206 static ULONG WINAPI HTMLBodyElement_AddRef(IHTMLBodyElement *iface)
208 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
210 return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
213 static ULONG WINAPI HTMLBodyElement_Release(IHTMLBodyElement *iface)
215 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
217 return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
220 static HRESULT WINAPI HTMLBodyElement_GetTypeInfoCount(IHTMLBodyElement *iface, UINT *pctinfo)
222 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
223 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface,
224 pctinfo);
227 static HRESULT WINAPI HTMLBodyElement_GetTypeInfo(IHTMLBodyElement *iface, UINT iTInfo,
228 LCID lcid, ITypeInfo **ppTInfo)
230 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
231 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo,
232 lcid, ppTInfo);
235 static HRESULT WINAPI HTMLBodyElement_GetIDsOfNames(IHTMLBodyElement *iface, REFIID riid,
236 LPOLESTR *rgszNames, UINT cNames,
237 LCID lcid, DISPID *rgDispId)
239 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
240 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid,
241 rgszNames, cNames, lcid, rgDispId);
244 static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dispIdMember,
245 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
246 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
248 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
249 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember,
250 riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
253 static HRESULT WINAPI HTMLBodyElement_put_background(IHTMLBodyElement *iface, BSTR v)
255 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
256 nsAString nsstr;
257 nsresult nsres;
259 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
261 nsAString_InitDepend(&nsstr, v);
262 nsres = nsIDOMHTMLBodyElement_SetBackground(This->nsbody, &nsstr);
263 nsAString_Finish(&nsstr);
264 if(NS_FAILED(nsres))
265 return E_FAIL;
267 return S_OK;
270 static HRESULT WINAPI HTMLBodyElement_get_background(IHTMLBodyElement *iface, BSTR *p)
272 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
273 nsAString background_str;
274 nsresult nsres;
276 TRACE("(%p)->(%p)\n", This, p);
278 nsAString_Init(&background_str, NULL);
279 nsres = nsIDOMHTMLBodyElement_GetBackground(This->nsbody, &background_str);
280 return return_nsstr(nsres, &background_str, p);
283 static HRESULT WINAPI HTMLBodyElement_put_bgProperties(IHTMLBodyElement *iface, BSTR v)
285 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
286 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
287 return E_NOTIMPL;
290 static HRESULT WINAPI HTMLBodyElement_get_bgProperties(IHTMLBodyElement *iface, BSTR *p)
292 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
293 FIXME("(%p)->(%p)\n", This, p);
294 return E_NOTIMPL;
297 static HRESULT WINAPI HTMLBodyElement_put_leftMargin(IHTMLBodyElement *iface, VARIANT v)
299 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
300 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
301 return E_NOTIMPL;
304 static HRESULT WINAPI HTMLBodyElement_get_leftMargin(IHTMLBodyElement *iface, VARIANT *p)
306 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
307 FIXME("(%p)->(%p)\n", This, p);
308 return E_NOTIMPL;
311 static HRESULT WINAPI HTMLBodyElement_put_topMargin(IHTMLBodyElement *iface, VARIANT v)
313 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
314 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
315 return E_NOTIMPL;
318 static HRESULT WINAPI HTMLBodyElement_get_topMargin(IHTMLBodyElement *iface, VARIANT *p)
320 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
321 FIXME("(%p)->(%p)\n", This, p);
322 return E_NOTIMPL;
325 static HRESULT WINAPI HTMLBodyElement_put_rightMargin(IHTMLBodyElement *iface, VARIANT v)
327 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
328 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
329 return E_NOTIMPL;
332 static HRESULT WINAPI HTMLBodyElement_get_rightMargin(IHTMLBodyElement *iface, VARIANT *p)
334 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
335 FIXME("(%p)->(%p)\n", This, p);
336 return E_NOTIMPL;
339 static HRESULT WINAPI HTMLBodyElement_put_bottomMargin(IHTMLBodyElement *iface, VARIANT v)
341 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
342 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
343 return E_NOTIMPL;
346 static HRESULT WINAPI HTMLBodyElement_get_bottomMargin(IHTMLBodyElement *iface, VARIANT *p)
348 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
349 FIXME("(%p)->(%p)\n", This, p);
350 return E_NOTIMPL;
353 static HRESULT WINAPI HTMLBodyElement_put_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL v)
355 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
356 FIXME("(%p)->(%x)\n", This, v);
357 return E_NOTIMPL;
360 static HRESULT WINAPI HTMLBodyElement_get_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL *p)
362 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
363 FIXME("(%p)->(%p)\n", This, p);
364 return E_NOTIMPL;
367 static HRESULT WINAPI HTMLBodyElement_put_bgColor(IHTMLBodyElement *iface, VARIANT v)
369 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
370 nsAString strColor;
371 nsresult nsres;
373 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
375 if(!variant_to_nscolor(&v, &strColor))
376 return S_OK;
378 nsres = nsIDOMHTMLBodyElement_SetBgColor(This->nsbody, &strColor);
379 nsAString_Finish(&strColor);
380 if(NS_FAILED(nsres))
381 ERR("SetBgColor failed: %08lx\n", nsres);
383 return S_OK;
386 static HRESULT WINAPI HTMLBodyElement_get_bgColor(IHTMLBodyElement *iface, VARIANT *p)
388 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
389 nsAString nsstr;
390 nsresult nsres;
392 TRACE("(%p)->(%p)\n", This, p);
394 nsAString_Init(&nsstr, NULL);
395 nsres = nsIDOMHTMLBodyElement_GetBgColor(This->nsbody, &nsstr);
396 return return_nsstr_variant(nsres, &nsstr, NSSTR_COLOR, p);
399 static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT v)
401 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
402 nsAString text;
403 nsresult nsres;
405 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
407 if(!variant_to_nscolor(&v, &text))
408 return S_OK;
410 nsres = nsIDOMHTMLBodyElement_SetText(This->nsbody, &text);
411 nsAString_Finish(&text);
412 if(NS_FAILED(nsres)) {
413 ERR("SetText failed: %08lx\n", nsres);
414 return E_FAIL;
417 return S_OK;
420 static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT *p)
422 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
423 nsAString text;
424 nsresult nsres;
425 HRESULT hres;
427 TRACE("(%p)->(%p)\n", This, p);
429 nsAString_Init(&text, NULL);
430 nsres = nsIDOMHTMLBodyElement_GetText(This->nsbody, &text);
431 if(NS_SUCCEEDED(nsres)) {
432 const PRUnichar *color;
434 nsAString_GetData(&text, &color);
435 V_VT(p) = VT_BSTR;
436 hres = nscolor_to_str(color, &V_BSTR(p));
437 }else {
438 ERR("GetText failed: %08lx\n", nsres);
439 hres = E_FAIL;
442 nsAString_Finish(&text);
444 return hres;
447 static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v)
449 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
450 nsAString link_str;
451 nsresult nsres;
453 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
455 if(!variant_to_nscolor(&v, &link_str))
456 return S_OK;
458 nsres = nsIDOMHTMLBodyElement_SetLink(This->nsbody, &link_str);
459 nsAString_Finish(&link_str);
460 if(NS_FAILED(nsres))
461 ERR("SetLink failed: %08lx\n", nsres);
463 return S_OK;
466 static HRESULT WINAPI HTMLBodyElement_get_link(IHTMLBodyElement *iface, VARIANT *p)
468 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
469 nsAString link_str;
470 nsresult nsres;
472 TRACE("(%p)->(%p)\n", This, p);
474 nsAString_Init(&link_str, NULL);
475 nsres = nsIDOMHTMLBodyElement_GetLink(This->nsbody, &link_str);
476 return return_nscolor(nsres, &link_str, p);
479 static HRESULT WINAPI HTMLBodyElement_put_vLink(IHTMLBodyElement *iface, VARIANT v)
481 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
482 nsAString vlink_str;
483 nsresult nsres;
485 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
487 if(!variant_to_nscolor(&v, &vlink_str))
488 return S_OK;
490 nsres = nsIDOMHTMLBodyElement_SetVLink(This->nsbody, &vlink_str);
491 nsAString_Finish(&vlink_str);
492 if(NS_FAILED(nsres))
493 ERR("SetLink failed: %08lx\n", nsres);
495 return S_OK;
498 static HRESULT WINAPI HTMLBodyElement_get_vLink(IHTMLBodyElement *iface, VARIANT *p)
500 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
501 nsAString vlink_str;
502 nsresult nsres;
504 TRACE("(%p)->(%p)\n", This, p);
506 nsAString_Init(&vlink_str, NULL);
507 nsres = nsIDOMHTMLBodyElement_GetVLink(This->nsbody, &vlink_str);
508 return return_nscolor(nsres, &vlink_str, p);
511 static HRESULT WINAPI HTMLBodyElement_put_aLink(IHTMLBodyElement *iface, VARIANT v)
513 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
514 nsAString alink_str;
515 nsresult nsres;
517 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
519 if(!variant_to_nscolor(&v, &alink_str))
520 return S_OK;
522 nsres = nsIDOMHTMLBodyElement_SetALink(This->nsbody, &alink_str);
523 nsAString_Finish(&alink_str);
524 if(NS_FAILED(nsres))
525 ERR("SetALink failed: %08lx\n", nsres);
527 return S_OK;
530 static HRESULT WINAPI HTMLBodyElement_get_aLink(IHTMLBodyElement *iface, VARIANT *p)
532 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
533 nsAString alink_str;
534 nsresult nsres;
536 TRACE("(%p)->(%p)\n", This, p);
538 nsAString_Init(&alink_str, NULL);
539 nsres = nsIDOMHTMLBodyElement_GetALink(This->nsbody, &alink_str);
540 return return_nscolor(nsres, &alink_str, p);
543 static HRESULT WINAPI HTMLBodyElement_put_onload(IHTMLBodyElement *iface, VARIANT v)
545 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
547 TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
549 return set_node_event(&This->element.node, EVENTID_LOAD, &v);
552 static HRESULT WINAPI HTMLBodyElement_get_onload(IHTMLBodyElement *iface, VARIANT *p)
554 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
556 TRACE("(%p)->(%p)\n", This, p);
558 return get_node_event(&This->element.node, EVENTID_LOAD, p);
561 static HRESULT WINAPI HTMLBodyElement_put_onunload(IHTMLBodyElement *iface, VARIANT v)
563 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
564 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
565 return E_NOTIMPL;
568 static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARIANT *p)
570 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
571 FIXME("(%p)->(%p)\n", This, p);
572 return E_NOTIMPL;
575 static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v)
577 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
578 static const WCHAR *val;
580 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
582 /* Emulate with CSS visibility attribute */
583 if(!wcscmp(v, L"yes")) {
584 val = L"scroll";
585 }else if(!wcscmp(v, L"auto")) {
586 val = L"visible";
587 }else if(!wcscmp(v, L"no")) {
588 val = L"hidden";
589 }else {
590 WARN("Invalid argument %s\n", debugstr_w(v));
591 return E_INVALIDARG;
594 return set_elem_style(&This->element, STYLEID_OVERFLOW, val);
597 static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p)
599 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
600 const WCHAR *ret = NULL;
601 BSTR overflow;
602 HRESULT hres;
604 TRACE("(%p)->(%p)\n", This, p);
606 /* Emulate with CSS visibility attribute */
607 hres = get_elem_style(&This->element, STYLEID_OVERFLOW, &overflow);
608 if(FAILED(hres))
609 return hres;
611 if(!overflow || !*overflow) {
612 *p = NULL;
613 hres = S_OK;
614 }else if(!wcscmp(overflow, L"visible") || !wcscmp(overflow, L"auto")) {
615 ret = L"auto";
616 }else if(!wcscmp(overflow, L"scroll")) {
617 ret = L"yes";
618 }else if(!wcscmp(overflow, L"hidden")) {
619 ret = L"no";
620 }else {
621 TRACE("Defaulting %s to NULL\n", debugstr_w(overflow));
622 *p = NULL;
623 hres = S_OK;
626 SysFreeString(overflow);
627 if(ret) {
628 *p = SysAllocString(ret);
629 hres = *p ? S_OK : E_OUTOFMEMORY;
632 return hres;
635 static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v)
637 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
638 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
639 return E_NOTIMPL;
642 static HRESULT WINAPI HTMLBodyElement_get_onselect(IHTMLBodyElement *iface, VARIANT *p)
644 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
645 FIXME("(%p)->(%p)\n", This, p);
646 return E_NOTIMPL;
649 static HRESULT WINAPI HTMLBodyElement_put_onbeforeunload(IHTMLBodyElement *iface, VARIANT v)
651 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
652 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
653 return E_NOTIMPL;
656 static HRESULT WINAPI HTMLBodyElement_get_onbeforeunload(IHTMLBodyElement *iface, VARIANT *p)
658 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
659 FIXME("(%p)->(%p)\n", This, p);
660 return E_NOTIMPL;
663 static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, IHTMLTxtRange **range)
665 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
666 nsIDOMRange *nsrange = NULL;
667 nsresult nsres;
668 HRESULT hres;
670 TRACE("(%p)->(%p)\n", This, range);
672 if(!This->element.node.doc->dom_document) {
673 WARN("No dom_document\n");
674 return E_UNEXPECTED;
677 nsres = nsIDOMDocument_CreateRange(This->element.node.doc->dom_document, &nsrange);
678 if(NS_SUCCEEDED(nsres)) {
679 nsres = nsIDOMRange_SelectNodeContents(nsrange, This->element.node.nsnode);
680 if(NS_FAILED(nsres))
681 ERR("SelectNodeContents failed: %08lx\n", nsres);
682 }else {
683 ERR("CreateRange failed: %08lx\n", nsres);
686 hres = HTMLTxtRange_Create(This->element.node.doc, nsrange, range);
688 nsIDOMRange_Release(nsrange);
689 return hres;
692 static const IHTMLBodyElementVtbl HTMLBodyElementVtbl = {
693 HTMLBodyElement_QueryInterface,
694 HTMLBodyElement_AddRef,
695 HTMLBodyElement_Release,
696 HTMLBodyElement_GetTypeInfoCount,
697 HTMLBodyElement_GetTypeInfo,
698 HTMLBodyElement_GetIDsOfNames,
699 HTMLBodyElement_Invoke,
700 HTMLBodyElement_put_background,
701 HTMLBodyElement_get_background,
702 HTMLBodyElement_put_bgProperties,
703 HTMLBodyElement_get_bgProperties,
704 HTMLBodyElement_put_leftMargin,
705 HTMLBodyElement_get_leftMargin,
706 HTMLBodyElement_put_topMargin,
707 HTMLBodyElement_get_topMargin,
708 HTMLBodyElement_put_rightMargin,
709 HTMLBodyElement_get_rightMargin,
710 HTMLBodyElement_put_bottomMargin,
711 HTMLBodyElement_get_bottomMargin,
712 HTMLBodyElement_put_noWrap,
713 HTMLBodyElement_get_noWrap,
714 HTMLBodyElement_put_bgColor,
715 HTMLBodyElement_get_bgColor,
716 HTMLBodyElement_put_text,
717 HTMLBodyElement_get_text,
718 HTMLBodyElement_put_link,
719 HTMLBodyElement_get_link,
720 HTMLBodyElement_put_vLink,
721 HTMLBodyElement_get_vLink,
722 HTMLBodyElement_put_aLink,
723 HTMLBodyElement_get_aLink,
724 HTMLBodyElement_put_onload,
725 HTMLBodyElement_get_onload,
726 HTMLBodyElement_put_onunload,
727 HTMLBodyElement_get_onunload,
728 HTMLBodyElement_put_scroll,
729 HTMLBodyElement_get_scroll,
730 HTMLBodyElement_put_onselect,
731 HTMLBodyElement_get_onselect,
732 HTMLBodyElement_put_onbeforeunload,
733 HTMLBodyElement_get_onbeforeunload,
734 HTMLBodyElement_createTextRange
737 static inline HTMLBodyElement *impl_from_IHTMLTextContainer(IHTMLTextContainer *iface)
739 return CONTAINING_RECORD(iface, HTMLBodyElement, IHTMLTextContainer_iface);
742 static HRESULT WINAPI HTMLTextContainer_QueryInterface(IHTMLTextContainer *iface,
743 REFIID riid, void **ppv)
745 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
746 return IHTMLElement_QueryInterface(&This->element.IHTMLElement_iface, riid, ppv);
749 static ULONG WINAPI HTMLTextContainer_AddRef(IHTMLTextContainer *iface)
751 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
752 return IHTMLElement_AddRef(&This->element.IHTMLElement_iface);
755 static ULONG WINAPI HTMLTextContainer_Release(IHTMLTextContainer *iface)
757 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
758 return IHTMLElement_Release(&This->element.IHTMLElement_iface);
761 static HRESULT WINAPI HTMLTextContainer_GetTypeInfoCount(IHTMLTextContainer *iface, UINT *pctinfo)
763 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
764 return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo);
767 static HRESULT WINAPI HTMLTextContainer_GetTypeInfo(IHTMLTextContainer *iface, UINT iTInfo,
768 LCID lcid, ITypeInfo **ppTInfo)
770 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
771 return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid,
772 ppTInfo);
775 static HRESULT WINAPI HTMLTextContainer_GetIDsOfNames(IHTMLTextContainer *iface, REFIID riid,
776 LPOLESTR *rgszNames, UINT cNames,
777 LCID lcid, DISPID *rgDispId)
779 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
780 return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames,
781 cNames, lcid, rgDispId);
784 static HRESULT WINAPI HTMLTextContainer_Invoke(IHTMLTextContainer *iface, DISPID dispIdMember,
785 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
786 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
788 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
789 return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid,
790 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
793 static HRESULT WINAPI HTMLTextContainer_createControlRange(IHTMLTextContainer *iface,
794 IDispatch **range)
796 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
797 FIXME("(%p)->(%p)\n", This, range);
798 return E_NOTIMPL;
801 static HRESULT WINAPI HTMLTextContainer_get_scrollHeight(IHTMLTextContainer *iface, LONG *p)
803 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
805 TRACE("(%p)->(%p)\n", This, p);
807 return IHTMLElement2_get_scrollHeight(&This->element.IHTMLElement2_iface, p);
810 static HRESULT WINAPI HTMLTextContainer_get_scrollWidth(IHTMLTextContainer *iface, LONG *p)
812 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
814 TRACE("(%p)->(%p)\n", This, p);
816 return IHTMLElement2_get_scrollWidth(&This->element.IHTMLElement2_iface, p);
819 static HRESULT WINAPI HTMLTextContainer_put_scrollTop(IHTMLTextContainer *iface, LONG v)
821 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
823 TRACE("(%p)->(%ld)\n", This, v);
825 return IHTMLElement2_put_scrollTop(&This->element.IHTMLElement2_iface, v);
828 static HRESULT WINAPI HTMLTextContainer_get_scrollTop(IHTMLTextContainer *iface, LONG *p)
830 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
832 TRACE("(%p)->(%p)\n", This, p);
834 return IHTMLElement2_get_scrollTop(&This->element.IHTMLElement2_iface, p);
837 static HRESULT WINAPI HTMLTextContainer_put_scrollLeft(IHTMLTextContainer *iface, LONG v)
839 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
841 TRACE("(%p)->(%ld)\n", This, v);
843 return IHTMLElement2_put_scrollLeft(&This->element.IHTMLElement2_iface, v);
846 static HRESULT WINAPI HTMLTextContainer_get_scrollLeft(IHTMLTextContainer *iface, LONG *p)
848 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
850 TRACE("(%p)->(%p)\n", This, p);
852 return IHTMLElement2_get_scrollLeft(&This->element.IHTMLElement2_iface, p);
855 static HRESULT WINAPI HTMLTextContainer_put_onscroll(IHTMLTextContainer *iface, VARIANT v)
857 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
858 FIXME("(%p)->()\n", This);
859 return E_NOTIMPL;
862 static HRESULT WINAPI HTMLTextContainer_get_onscroll(IHTMLTextContainer *iface, VARIANT *p)
864 HTMLBodyElement *This = impl_from_IHTMLTextContainer(iface);
865 FIXME("(%p)->(%p)\n", This, p);
866 return E_NOTIMPL;
869 static const IHTMLTextContainerVtbl HTMLTextContainerVtbl = {
870 HTMLTextContainer_QueryInterface,
871 HTMLTextContainer_AddRef,
872 HTMLTextContainer_Release,
873 HTMLTextContainer_GetTypeInfoCount,
874 HTMLTextContainer_GetTypeInfo,
875 HTMLTextContainer_GetIDsOfNames,
876 HTMLTextContainer_Invoke,
877 HTMLTextContainer_createControlRange,
878 HTMLTextContainer_get_scrollHeight,
879 HTMLTextContainer_get_scrollWidth,
880 HTMLTextContainer_put_scrollTop,
881 HTMLTextContainer_get_scrollTop,
882 HTMLTextContainer_put_scrollLeft,
883 HTMLTextContainer_get_scrollLeft,
884 HTMLTextContainer_put_onscroll,
885 HTMLTextContainer_get_onscroll
888 static inline HTMLBodyElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
890 return CONTAINING_RECORD(iface, HTMLBodyElement, element.node);
893 static HRESULT HTMLBodyElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
895 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
897 *ppv = NULL;
899 if(IsEqualGUID(&IID_IUnknown, riid)) {
900 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
901 *ppv = &This->IHTMLBodyElement_iface;
902 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
903 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
904 *ppv = &This->IHTMLBodyElement_iface;
905 }else if(IsEqualGUID(&IID_IHTMLBodyElement, riid)) {
906 TRACE("(%p)->(IID_IHTMLBodyElement %p)\n", This, ppv);
907 *ppv = &This->IHTMLBodyElement_iface;
908 }else if(IsEqualGUID(&IID_IHTMLTextContainer, riid)) {
909 TRACE("(%p)->(IID_IHTMLTextContainer %p)\n", This, ppv);
910 *ppv = &This->IHTMLTextContainer_iface;
913 if(*ppv) {
914 IUnknown_AddRef((IUnknown*)*ppv);
915 return S_OK;
918 return HTMLElement_QI(&This->element.node, riid, ppv);
921 static void HTMLBodyElement_traverse(HTMLDOMNode *iface, nsCycleCollectionTraversalCallback *cb)
923 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
925 if(This->nsbody)
926 note_cc_edge((nsISupports*)This->nsbody, "This->nsbody", cb);
929 static void HTMLBodyElement_unlink(HTMLDOMNode *iface)
931 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
933 if(This->nsbody) {
934 nsIDOMHTMLBodyElement *nsbody = This->nsbody;
935 This->nsbody = NULL;
936 nsIDOMHTMLBodyElement_Release(nsbody);
940 static EventTarget *HTMLBodyElement_get_event_prop_target(HTMLDOMNode *iface, int event_id)
942 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
944 switch(event_id) {
945 case EVENTID_BLUR:
946 case EVENTID_ERROR:
947 case EVENTID_FOCUS:
948 case EVENTID_LOAD:
949 case EVENTID_SCROLL:
950 return This->element.node.doc && This->element.node.doc->window
951 ? &This->element.node.doc->window->event_target
952 : &This->element.node.event_target;
953 default:
954 return &This->element.node.event_target;
958 static BOOL HTMLBodyElement_is_text_edit(HTMLDOMNode *iface)
960 return TRUE;
963 static BOOL HTMLBodyElement_is_settable(HTMLDOMNode *iface, DISPID dispid)
965 switch(dispid) {
966 case DISPID_IHTMLELEMENT_OUTERTEXT:
967 return FALSE;
968 default:
969 return TRUE;
973 static const cpc_entry_t HTMLBodyElement_cpc[] = {
974 {&DIID_HTMLTextContainerEvents},
975 {&IID_IPropertyNotifySink},
976 HTMLELEMENT_CPC,
977 {NULL}
980 static const NodeImplVtbl HTMLBodyElementImplVtbl = {
981 &CLSID_HTMLBody,
982 HTMLBodyElement_QI,
983 HTMLElement_destructor,
984 HTMLBodyElement_cpc,
985 HTMLElement_clone,
986 HTMLElement_dispatch_nsevent_hook,
987 HTMLElement_handle_event,
988 HTMLElement_get_attr_col,
989 HTMLBodyElement_get_event_prop_target,
990 NULL,
991 NULL,
992 NULL,
993 NULL,
994 NULL,
995 NULL,
996 NULL,
997 NULL,
998 HTMLBodyElement_traverse,
999 HTMLBodyElement_unlink,
1000 HTMLBodyElement_is_text_edit,
1001 HTMLBodyElement_is_settable
1004 static const tid_t HTMLBodyElement_iface_tids[] = {
1005 IHTMLBodyElement_tid,
1006 IHTMLBodyElement2_tid,
1007 HTMLELEMENT_TIDS,
1008 IHTMLTextContainer_tid,
1012 static dispex_static_data_t HTMLBodyElement_dispex = {
1013 L"HTMLBodyElement",
1014 NULL,
1015 DispHTMLBody_tid,
1016 HTMLBodyElement_iface_tids,
1017 HTMLElement_init_dispex_info
1020 HRESULT HTMLBodyElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTMLElement **elem)
1022 HTMLBodyElement *ret;
1023 nsresult nsres;
1025 ret = calloc(1, sizeof(HTMLBodyElement));
1026 if(!ret)
1027 return E_OUTOFMEMORY;
1029 ret->IHTMLBodyElement_iface.lpVtbl = &HTMLBodyElementVtbl;
1030 ret->IHTMLTextContainer_iface.lpVtbl = &HTMLTextContainerVtbl;
1031 ret->element.node.vtbl = &HTMLBodyElementImplVtbl;
1033 HTMLElement_Init(&ret->element, doc, nselem, &HTMLBodyElement_dispex);
1035 nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMHTMLBodyElement, (void**)&ret->nsbody);
1036 assert(nsres == NS_OK);
1038 *elem = &ret->element;
1039 return S_OK;