mscoree: COM cleanup in metahost.c.
[wine.git] / dlls / mshtml / htmlbody.c
blob8789200dd74448c815274b14e433b9b4a6b8312c
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"
29 #include "wine/debug.h"
31 #include "mshtml_private.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
35 typedef struct {
36 HTMLTextContainer textcont;
38 IHTMLBodyElement IHTMLBodyElement_iface;
40 ConnectionPoint cp_propnotif;
42 nsIDOMHTMLBodyElement *nsbody;
43 } HTMLBodyElement;
45 static const WCHAR aquaW[] = {'a','q','u','a',0};
46 static const WCHAR blackW[] = {'b','l','a','c','k',0};
47 static const WCHAR blueW[] = {'b','l','u','e',0};
48 static const WCHAR fuchsiaW[] = {'f','u','s','h','s','i','a',0};
49 static const WCHAR grayW[] = {'g','r','a','y',0};
50 static const WCHAR greenW[] = {'g','r','e','e','n',0};
51 static const WCHAR limeW[] = {'l','i','m','e',0};
52 static const WCHAR maroonW[] = {'m','a','r','o','o','n',0};
53 static const WCHAR navyW[] = {'n','a','v','y',0};
54 static const WCHAR oliveW[] = {'o','l','i','v','e',0};
55 static const WCHAR purpleW[] = {'p','u','r','p','l','e',0};
56 static const WCHAR redW[] = {'r','e','d',0};
57 static const WCHAR silverW[] = {'s','i','l','v','e','r',0};
58 static const WCHAR tealW[] = {'t','e','a','l',0};
59 static const WCHAR whiteW[] = {'w','h','i','t','e',0};
60 static const WCHAR yellowW[] = {'y','e','l','l','o','w',0};
62 static const struct {
63 LPCWSTR keyword;
64 DWORD rgb;
65 } keyword_table[] = {
66 {aquaW, 0x00ffff},
67 {blackW, 0x000000},
68 {blueW, 0x0000ff},
69 {fuchsiaW, 0xff00ff},
70 {grayW, 0x808080},
71 {greenW, 0x008000},
72 {limeW, 0x00ff00},
73 {maroonW, 0x800000},
74 {navyW, 0x000080},
75 {oliveW, 0x808000},
76 {purpleW, 0x800080},
77 {redW, 0xff0000},
78 {silverW, 0xc0c0c0},
79 {tealW, 0x008080},
80 {whiteW, 0xffffff},
81 {yellowW, 0xffff00}
84 static int comp_value(const WCHAR *ptr, int dpc)
86 int ret = 0;
87 WCHAR ch;
89 if(dpc > 2)
90 dpc = 2;
92 while(dpc--) {
93 if(!*ptr)
94 ret *= 16;
95 else if(isdigitW(ch = *ptr++))
96 ret = ret*16 + (ch-'0');
97 else if('a' <= ch && ch <= 'f')
98 ret = ret*16 + (ch-'a') + 10;
99 else if('A' <= ch && ch <= 'F')
100 ret = ret*16 + (ch-'A') + 10;
101 else
102 ret *= 16;
105 return ret;
108 /* Based on Gecko NS_LooseHexToRGB */
109 static int loose_hex_to_rgb(const WCHAR *hex)
111 int len, dpc;
113 len = strlenW(hex);
114 if(*hex == '#') {
115 hex++;
116 len--;
118 if(len <= 3)
119 return 0;
121 dpc = min(len/3 + (len%3 ? 1 : 0), 4);
122 return (comp_value(hex, dpc) << 16)
123 | (comp_value(hex+dpc, dpc) << 8)
124 | comp_value(hex+2*dpc, dpc);
127 static HRESULT nscolor_to_str(LPCWSTR color, BSTR *ret)
129 int i, rgb = -1;
131 static const WCHAR formatW[] = {'#','%','0','2','x','%','0','2','x','%','0','2','x',0};
133 if(!color || !*color) {
134 *ret = NULL;
135 return S_OK;
138 if(*color != '#') {
139 for(i=0; i < sizeof(keyword_table)/sizeof(keyword_table[0]); i++) {
140 if(!strcmpiW(color, keyword_table[i].keyword))
141 rgb = keyword_table[i].rgb;
144 if(rgb == -1)
145 rgb = loose_hex_to_rgb(color);
147 *ret = SysAllocStringLen(NULL, 7);
148 if(!*ret)
149 return E_OUTOFMEMORY;
151 sprintfW(*ret, formatW, rgb>>16, (rgb>>8)&0xff, rgb&0xff);
153 TRACE("%s -> %s\n", debugstr_w(color), debugstr_w(*ret));
154 return S_OK;
157 static BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr)
159 switch(V_VT(v)) {
160 case VT_BSTR:
161 nsAString_Init(nsstr, V_BSTR(v));
162 return TRUE;
164 case VT_I4: {
165 PRUnichar buf[10];
166 static const WCHAR formatW[] = {'#','%','x',0};
168 wsprintfW(buf, formatW, V_I4(v));
169 nsAString_Init(nsstr, buf);
170 return TRUE;
173 default:
174 FIXME("invalid vt=%d\n", V_VT(v));
177 return FALSE;
181 static void nscolor_to_variant(const nsAString *nsstr, VARIANT *p)
183 const PRUnichar *color;
185 nsAString_GetData(nsstr, &color);
187 if(*color == '#') {
188 V_VT(p) = VT_I4;
189 V_I4(p) = strtolW(color+1, NULL, 16);
190 }else {
191 V_VT(p) = VT_BSTR;
192 V_BSTR(p) = SysAllocString(color);
196 static inline HTMLBodyElement *impl_from_IHTMLBodyElement(IHTMLBodyElement *iface)
198 return CONTAINING_RECORD(iface, HTMLBodyElement, IHTMLBodyElement_iface);
201 static HRESULT WINAPI HTMLBodyElement_QueryInterface(IHTMLBodyElement *iface,
202 REFIID riid, void **ppv)
204 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
206 return IHTMLDOMNode_QueryInterface(&This->textcont.element.node.IHTMLDOMNode_iface, riid, ppv);
209 static ULONG WINAPI HTMLBodyElement_AddRef(IHTMLBodyElement *iface)
211 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
213 return IHTMLDOMNode_AddRef(&This->textcont.element.node.IHTMLDOMNode_iface);
216 static ULONG WINAPI HTMLBodyElement_Release(IHTMLBodyElement *iface)
218 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
220 return IHTMLDOMNode_Release(&This->textcont.element.node.IHTMLDOMNode_iface);
223 static HRESULT WINAPI HTMLBodyElement_GetTypeInfoCount(IHTMLBodyElement *iface, UINT *pctinfo)
225 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
226 return IDispatchEx_GetTypeInfoCount(&This->textcont.element.node.dispex.IDispatchEx_iface,
227 pctinfo);
230 static HRESULT WINAPI HTMLBodyElement_GetTypeInfo(IHTMLBodyElement *iface, UINT iTInfo,
231 LCID lcid, ITypeInfo **ppTInfo)
233 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
234 return IDispatchEx_GetTypeInfo(&This->textcont.element.node.dispex.IDispatchEx_iface, iTInfo,
235 lcid, ppTInfo);
238 static HRESULT WINAPI HTMLBodyElement_GetIDsOfNames(IHTMLBodyElement *iface, REFIID riid,
239 LPOLESTR *rgszNames, UINT cNames,
240 LCID lcid, DISPID *rgDispId)
242 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
243 return IDispatchEx_GetIDsOfNames(&This->textcont.element.node.dispex.IDispatchEx_iface, riid,
244 rgszNames, cNames, lcid, rgDispId);
247 static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dispIdMember,
248 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
249 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
251 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
252 return IDispatchEx_Invoke(&This->textcont.element.node.dispex.IDispatchEx_iface, dispIdMember,
253 riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
256 static HRESULT WINAPI HTMLBodyElement_put_background(IHTMLBodyElement *iface, BSTR v)
258 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
259 nsAString nsstr;
260 nsresult nsres;
262 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
264 nsAString_InitDepend(&nsstr, v);
265 nsres = nsIDOMHTMLBodyElement_SetBackground(This->nsbody, &nsstr);
266 nsAString_Finish(&nsstr);
267 if(NS_FAILED(nsres))
268 return E_FAIL;
270 return S_OK;
273 static HRESULT WINAPI HTMLBodyElement_get_background(IHTMLBodyElement *iface, BSTR *p)
275 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
276 nsAString background_str;
277 nsresult nsres;
279 TRACE("(%p)->(%p)\n", This, p);
281 nsAString_Init(&background_str, NULL);
283 nsres = nsIDOMHTMLBodyElement_GetBackground(This->nsbody, &background_str);
284 if(NS_SUCCEEDED(nsres)) {
285 const PRUnichar *background;
286 nsAString_GetData(&background_str, &background);
287 *p = *background ? SysAllocString(background) : NULL;
288 }else {
289 ERR("GetBackground failed: %08x\n", nsres);
290 *p = NULL;
293 nsAString_Finish(&background_str);
295 TRACE("*p = %s\n", debugstr_w(*p));
296 return S_OK;
299 static HRESULT WINAPI HTMLBodyElement_put_bgProperties(IHTMLBodyElement *iface, BSTR v)
301 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
302 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
303 return E_NOTIMPL;
306 static HRESULT WINAPI HTMLBodyElement_get_bgProperties(IHTMLBodyElement *iface, BSTR *p)
308 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
309 FIXME("(%p)->(%p)\n", This, p);
310 return E_NOTIMPL;
313 static HRESULT WINAPI HTMLBodyElement_put_leftMargin(IHTMLBodyElement *iface, VARIANT v)
315 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
316 FIXME("(%p)->()\n", This);
317 return E_NOTIMPL;
320 static HRESULT WINAPI HTMLBodyElement_get_leftMargin(IHTMLBodyElement *iface, VARIANT *p)
322 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
323 FIXME("(%p)->(%p)\n", This, p);
324 return E_NOTIMPL;
327 static HRESULT WINAPI HTMLBodyElement_put_topMargin(IHTMLBodyElement *iface, VARIANT v)
329 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
330 FIXME("(%p)->()\n", This);
331 return E_NOTIMPL;
334 static HRESULT WINAPI HTMLBodyElement_get_topMargin(IHTMLBodyElement *iface, VARIANT *p)
336 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
337 FIXME("(%p)->(%p)\n", This, p);
338 return E_NOTIMPL;
341 static HRESULT WINAPI HTMLBodyElement_put_rightMargin(IHTMLBodyElement *iface, VARIANT v)
343 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
344 FIXME("(%p)->()\n", This);
345 return E_NOTIMPL;
348 static HRESULT WINAPI HTMLBodyElement_get_rightMargin(IHTMLBodyElement *iface, VARIANT *p)
350 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
351 FIXME("(%p)->(%p)\n", This, p);
352 return E_NOTIMPL;
355 static HRESULT WINAPI HTMLBodyElement_put_bottomMargin(IHTMLBodyElement *iface, VARIANT v)
357 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
358 FIXME("(%p)->()\n", This);
359 return E_NOTIMPL;
362 static HRESULT WINAPI HTMLBodyElement_get_bottomMargin(IHTMLBodyElement *iface, VARIANT *p)
364 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
365 FIXME("(%p)->(%p)\n", This, p);
366 return E_NOTIMPL;
369 static HRESULT WINAPI HTMLBodyElement_put_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL v)
371 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
372 FIXME("(%p)->(%x)\n", This, v);
373 return E_NOTIMPL;
376 static HRESULT WINAPI HTMLBodyElement_get_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL *p)
378 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
379 FIXME("(%p)->(%p)\n", This, p);
380 return E_NOTIMPL;
383 static HRESULT WINAPI HTMLBodyElement_put_bgColor(IHTMLBodyElement *iface, VARIANT v)
385 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
386 nsAString strColor;
387 nsresult nsres;
389 TRACE("(%p)->()\n", This);
391 if(!variant_to_nscolor(&v, &strColor))
392 return S_OK;
394 nsres = nsIDOMHTMLBodyElement_SetBgColor(This->nsbody, &strColor);
395 nsAString_Finish(&strColor);
396 if(NS_FAILED(nsres))
397 ERR("SetBgColor failed: %08x\n", nsres);
399 return S_OK;
402 static HRESULT WINAPI HTMLBodyElement_get_bgColor(IHTMLBodyElement *iface, VARIANT *p)
404 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
405 nsAString strColor;
406 nsresult nsres;
407 HRESULT hres;
409 TRACE("(%p)->(%p)\n", This, p);
411 nsAString_Init(&strColor, NULL);
412 nsres = nsIDOMHTMLBodyElement_GetBgColor(This->nsbody, &strColor);
413 if(NS_SUCCEEDED(nsres)) {
414 const PRUnichar *color;
416 nsAString_GetData(&strColor, &color);
417 V_VT(p) = VT_BSTR;
418 hres = nscolor_to_str(color, &V_BSTR(p));
419 }else {
420 ERR("SetBgColor failed: %08x\n", nsres);
421 hres = E_FAIL;
424 nsAString_Finish(&strColor);
425 return hres;
428 static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT v)
430 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
431 nsAString text;
432 nsresult nsres;
434 TRACE("(%p)->(v%d)\n", This, V_VT(&v));
436 if(!variant_to_nscolor(&v, &text))
437 return S_OK;
439 nsres = nsIDOMHTMLBodyElement_SetText(This->nsbody, &text);
440 nsAString_Finish(&text);
441 if(NS_FAILED(nsres)) {
442 ERR("SetText failed: %08x\n", nsres);
443 return E_FAIL;
446 return S_OK;
449 static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT *p)
451 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
452 nsAString text;
453 nsresult nsres;
454 HRESULT hres;
456 TRACE("(%p)->(%p)\n", This, p);
458 nsAString_Init(&text, NULL);
459 nsres = nsIDOMHTMLBodyElement_GetText(This->nsbody, &text);
460 if(NS_SUCCEEDED(nsres)) {
461 const PRUnichar *color;
463 nsAString_GetData(&text, &color);
464 V_VT(p) = VT_BSTR;
465 hres = nscolor_to_str(color, &V_BSTR(p));
466 }else {
467 ERR("GetText failed: %08x\n", nsres);
468 hres = E_FAIL;
471 nsAString_Finish(&text);
473 return hres;
476 static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v)
478 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
479 nsAString link_str;
480 nsresult nsres;
482 TRACE("(%p)->(v%d)\n", This, V_VT(&v));
484 if(!variant_to_nscolor(&v, &link_str))
485 return S_OK;
487 nsres = nsIDOMHTMLBodyElement_SetLink(This->nsbody, &link_str);
488 nsAString_Finish(&link_str);
489 if(NS_FAILED(nsres))
490 ERR("SetLink failed: %08x\n", nsres);
492 return S_OK;
495 static HRESULT WINAPI HTMLBodyElement_get_link(IHTMLBodyElement *iface, VARIANT *p)
497 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
498 nsAString link_str;
499 nsresult nsres;
501 TRACE("(%p)->(%p)\n", This, p);
503 nsAString_Init(&link_str, NULL);
504 nsres = nsIDOMHTMLBodyElement_GetLink(This->nsbody, &link_str);
505 if(NS_FAILED(nsres))
506 ERR("GetLink failed: %08x\n", nsres);
508 nscolor_to_variant(&link_str, p);
509 nsAString_Finish(&link_str);
511 return S_OK;
514 static HRESULT WINAPI HTMLBodyElement_put_vLink(IHTMLBodyElement *iface, VARIANT v)
516 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
517 nsAString vlink_str;
518 nsresult nsres;
520 TRACE("(%p)->(v%d)\n", This, V_VT(&v));
522 if(!variant_to_nscolor(&v, &vlink_str))
523 return S_OK;
525 nsres = nsIDOMHTMLBodyElement_SetVLink(This->nsbody, &vlink_str);
526 nsAString_Finish(&vlink_str);
527 if(NS_FAILED(nsres))
528 ERR("SetLink failed: %08x\n", nsres);
530 return S_OK;
533 static HRESULT WINAPI HTMLBodyElement_get_vLink(IHTMLBodyElement *iface, VARIANT *p)
535 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
536 nsAString vlink_str;
537 nsresult nsres;
539 TRACE("(%p)->(%p)\n", This, p);
541 nsAString_Init(&vlink_str, NULL);
542 nsres = nsIDOMHTMLBodyElement_GetVLink(This->nsbody, &vlink_str);
543 if(NS_FAILED(nsres))
544 ERR("GetLink failed: %08x\n", nsres);
546 nscolor_to_variant(&vlink_str, p);
547 nsAString_Finish(&vlink_str);
549 return S_OK;
552 static HRESULT WINAPI HTMLBodyElement_put_aLink(IHTMLBodyElement *iface, VARIANT v)
554 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
555 nsAString alink_str;
556 nsresult nsres;
558 TRACE("(%p)->(v%d)\n", This, V_VT(&v));
560 if(!variant_to_nscolor(&v, &alink_str))
561 return S_OK;
563 nsres = nsIDOMHTMLBodyElement_SetALink(This->nsbody, &alink_str);
564 nsAString_Finish(&alink_str);
565 if(NS_FAILED(nsres))
566 ERR("SetALink failed: %08x\n", nsres);
568 return S_OK;
571 static HRESULT WINAPI HTMLBodyElement_get_aLink(IHTMLBodyElement *iface, VARIANT *p)
573 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
574 nsAString alink_str;
575 nsresult nsres;
577 TRACE("(%p)->(%p)\n", This, p);
579 nsAString_Init(&alink_str, NULL);
580 nsres = nsIDOMHTMLBodyElement_GetALink(This->nsbody, &alink_str);
581 if(NS_FAILED(nsres))
582 ERR("GetALink failed: %08x\n", nsres);
584 nscolor_to_variant(&alink_str, p);
585 nsAString_Finish(&alink_str);
587 return S_OK;
590 static HRESULT WINAPI HTMLBodyElement_put_onload(IHTMLBodyElement *iface, VARIANT v)
592 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
593 FIXME("(%p)->()\n", This);
594 return E_NOTIMPL;
597 static HRESULT WINAPI HTMLBodyElement_get_onload(IHTMLBodyElement *iface, VARIANT *p)
599 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
600 FIXME("(%p)->(%p)\n", This, p);
601 return E_NOTIMPL;
604 static HRESULT WINAPI HTMLBodyElement_put_onunload(IHTMLBodyElement *iface, VARIANT v)
606 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
607 FIXME("(%p)->()\n", This);
608 return E_NOTIMPL;
611 static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARIANT *p)
613 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
614 FIXME("(%p)->(%p)\n", This, p);
615 return E_NOTIMPL;
618 static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v)
620 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
621 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
622 return E_NOTIMPL;
625 static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p)
627 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
628 FIXME("(%p)->(%p)\n", This, p);
629 return E_NOTIMPL;
632 static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v)
634 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
635 FIXME("(%p)->()\n", This);
636 return E_NOTIMPL;
639 static HRESULT WINAPI HTMLBodyElement_get_onselect(IHTMLBodyElement *iface, VARIANT *p)
641 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
642 FIXME("(%p)->(%p)\n", This, p);
643 return E_NOTIMPL;
646 static HRESULT WINAPI HTMLBodyElement_put_onbeforeunload(IHTMLBodyElement *iface, VARIANT v)
648 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
649 FIXME("(%p)->()\n", This);
650 return E_NOTIMPL;
653 static HRESULT WINAPI HTMLBodyElement_get_onbeforeunload(IHTMLBodyElement *iface, VARIANT *p)
655 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
656 FIXME("(%p)->(%p)\n", This, p);
657 return E_NOTIMPL;
660 static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, IHTMLTxtRange **range)
662 HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface);
663 nsIDOMDocumentRange *nsdocrange;
664 nsIDOMRange *nsrange = NULL;
665 nsresult nsres;
666 HRESULT hres;
668 TRACE("(%p)->(%p)\n", This, range);
670 if(!This->textcont.element.node.doc->nsdoc) {
671 WARN("No nsdoc\n");
672 return E_UNEXPECTED;
675 nsres = nsIDOMDocument_QueryInterface(This->textcont.element.node.doc->nsdoc, &IID_nsIDOMDocumentRange,
676 (void**)&nsdocrange);
677 if(NS_FAILED(nsres)) {
678 ERR("Could not get nsIDOMDocumentRabge iface: %08x\n", nsres);
679 return E_FAIL;
682 nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &nsrange);
683 if(NS_SUCCEEDED(nsres)) {
684 nsres = nsIDOMRange_SelectNodeContents(nsrange, This->textcont.element.node.nsnode);
685 if(NS_FAILED(nsres))
686 ERR("SelectNodeContents failed: %08x\n", nsres);
687 }else {
688 ERR("CreateRange failed: %08x\n", nsres);
691 nsIDOMDocumentRange_Release(nsdocrange);
693 hres = HTMLTxtRange_Create(This->textcont.element.node.doc->basedoc.doc_node, nsrange, range);
695 nsIDOMRange_Release(nsrange);
696 return hres;
699 static const IHTMLBodyElementVtbl HTMLBodyElementVtbl = {
700 HTMLBodyElement_QueryInterface,
701 HTMLBodyElement_AddRef,
702 HTMLBodyElement_Release,
703 HTMLBodyElement_GetTypeInfoCount,
704 HTMLBodyElement_GetTypeInfo,
705 HTMLBodyElement_GetIDsOfNames,
706 HTMLBodyElement_Invoke,
707 HTMLBodyElement_put_background,
708 HTMLBodyElement_get_background,
709 HTMLBodyElement_put_bgProperties,
710 HTMLBodyElement_get_bgProperties,
711 HTMLBodyElement_put_leftMargin,
712 HTMLBodyElement_get_leftMargin,
713 HTMLBodyElement_put_topMargin,
714 HTMLBodyElement_get_topMargin,
715 HTMLBodyElement_put_rightMargin,
716 HTMLBodyElement_get_rightMargin,
717 HTMLBodyElement_put_bottomMargin,
718 HTMLBodyElement_get_bottomMargin,
719 HTMLBodyElement_put_noWrap,
720 HTMLBodyElement_get_noWrap,
721 HTMLBodyElement_put_bgColor,
722 HTMLBodyElement_get_bgColor,
723 HTMLBodyElement_put_text,
724 HTMLBodyElement_get_text,
725 HTMLBodyElement_put_link,
726 HTMLBodyElement_get_link,
727 HTMLBodyElement_put_vLink,
728 HTMLBodyElement_get_vLink,
729 HTMLBodyElement_put_aLink,
730 HTMLBodyElement_get_aLink,
731 HTMLBodyElement_put_onload,
732 HTMLBodyElement_get_onload,
733 HTMLBodyElement_put_onunload,
734 HTMLBodyElement_get_onunload,
735 HTMLBodyElement_put_scroll,
736 HTMLBodyElement_get_scroll,
737 HTMLBodyElement_put_onselect,
738 HTMLBodyElement_get_onselect,
739 HTMLBodyElement_put_onbeforeunload,
740 HTMLBodyElement_get_onbeforeunload,
741 HTMLBodyElement_createTextRange
744 static inline HTMLBodyElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
746 return CONTAINING_RECORD(iface, HTMLBodyElement, textcont.element.node);
749 static HRESULT HTMLBodyElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
751 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
753 *ppv = NULL;
755 if(IsEqualGUID(&IID_IUnknown, riid)) {
756 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
757 *ppv = &This->IHTMLBodyElement_iface;
758 }else if(IsEqualGUID(&IID_IDispatch, riid)) {
759 TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
760 *ppv = &This->IHTMLBodyElement_iface;
761 }else if(IsEqualGUID(&IID_IHTMLBodyElement, riid)) {
762 TRACE("(%p)->(IID_IHTMLBodyElement %p)\n", This, ppv);
763 *ppv = &This->IHTMLBodyElement_iface;
764 }else if(IsEqualGUID(&IID_IHTMLTextContainer, riid)) {
765 TRACE("(%p)->(IID_IHTMLTextContainer %p)\n", &This->textcont, ppv);
766 *ppv = &This->textcont.IHTMLTextContainer_iface;
769 if(*ppv) {
770 IUnknown_AddRef((IUnknown*)*ppv);
771 return S_OK;
774 return HTMLElement_QI(&This->textcont.element.node, riid, ppv);
777 static void HTMLBodyElement_destructor(HTMLDOMNode *iface)
779 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
781 nsIDOMHTMLBodyElement_Release(This->nsbody);
783 HTMLElement_destructor(&This->textcont.element.node);
786 static event_target_t **HTMLBodyElement_get_event_target(HTMLDOMNode *iface)
788 HTMLBodyElement *This = impl_from_HTMLDOMNode(iface);
790 return This->textcont.element.node.doc
791 ? &This->textcont.element.node.doc->body_event_target
792 : &This->textcont.element.node.event_target;
795 static const NodeImplVtbl HTMLBodyElementImplVtbl = {
796 HTMLBodyElement_QI,
797 HTMLBodyElement_destructor,
798 HTMLElement_clone,
799 HTMLBodyElement_get_event_target
802 static const tid_t HTMLBodyElement_iface_tids[] = {
803 IHTMLBodyElement_tid,
804 IHTMLBodyElement2_tid,
805 HTMLELEMENT_TIDS,
806 IHTMLTextContainer_tid,
807 IHTMLUniqueName_tid,
811 static dispex_static_data_t HTMLBodyElement_dispex = {
812 NULL,
813 DispHTMLBody_tid,
814 NULL,
815 HTMLBodyElement_iface_tids
818 HRESULT HTMLBodyElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
820 HTMLBodyElement *ret;
821 nsresult nsres;
823 ret = heap_alloc_zero(sizeof(HTMLBodyElement));
824 if(!ret)
825 return E_OUTOFMEMORY;
827 ret->IHTMLBodyElement_iface.lpVtbl = &HTMLBodyElementVtbl;
828 ret->textcont.element.node.vtbl = &HTMLBodyElementImplVtbl;
830 nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLBodyElement, (void**)&ret->nsbody);
831 if(NS_FAILED(nsres)) {
832 ERR("Could not get nsDOMHTMLBodyElement: %08x\n", nsres);
833 heap_free(ret);
834 return E_OUTOFMEMORY;
837 HTMLTextContainer_Init(&ret->textcont, doc, nselem, &HTMLBodyElement_dispex);
839 ConnectionPoint_Init(&ret->cp_propnotif, &ret->textcont.element.cp_container, &IID_IPropertyNotifySink, NULL);
841 *elem = &ret->textcont.element;
842 return S_OK;