wined3d: Fix uploading higher transform matrices.
[wine] / dlls / mshtml / htmlbody.c
1 /*
2  * Copyright 2006 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <stdarg.h>
20 #include <stdio.h>
21
22 #define COBJMACROS
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "ole2.h"
28
29 #include "wine/debug.h"
30
31 #include "mshtml_private.h"
32
33 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
34
35 typedef struct {
36     HTMLTextContainer textcont;
37
38     const IHTMLBodyElementVtbl *lpHTMLBodyElementVtbl;
39
40     ConnectionPoint cp_propnotif;
41
42     nsIDOMHTMLBodyElement *nsbody;
43 } HTMLBodyElement;
44
45 #define HTMLBODY(x)  ((IHTMLBodyElement*)  &(x)->lpHTMLBodyElementVtbl)
46
47 static BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr)
48 {
49     switch(V_VT(v)) {
50     case VT_BSTR:
51         nsAString_Init(nsstr, V_BSTR(v));
52         return TRUE;
53
54     case VT_I4: {
55         PRUnichar buf[10];
56         static const WCHAR formatW[] = {'#','%','x',0};
57
58         wsprintfW(buf, formatW, V_I4(v));
59         nsAString_Init(nsstr, buf);
60         return TRUE;
61     }
62
63     default:
64         FIXME("invalid vt=%d\n", V_VT(v));
65     }
66
67     return FALSE;
68
69 }
70
71 static void nscolor_to_variant(const nsAString *nsstr, VARIANT *p)
72 {
73     const PRUnichar *color;
74
75     nsAString_GetData(nsstr, &color);
76
77     if(*color == '#') {
78         V_VT(p) = VT_I4;
79         V_I4(p) = strtolW(color+1, NULL, 16);
80     }else {
81         V_VT(p) = VT_BSTR;
82         V_BSTR(p) = SysAllocString(color);
83     }
84 }
85
86 #define HTMLBODY_THIS(iface) DEFINE_THIS(HTMLBodyElement, HTMLBodyElement, iface)
87
88 static HRESULT WINAPI HTMLBodyElement_QueryInterface(IHTMLBodyElement *iface,
89                                                      REFIID riid, void **ppv)
90 {
91     HTMLBodyElement *This = HTMLBODY_THIS(iface);
92
93     return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->textcont.element.node), riid, ppv);
94 }
95
96 static ULONG WINAPI HTMLBodyElement_AddRef(IHTMLBodyElement *iface)
97 {
98     HTMLBodyElement *This = HTMLBODY_THIS(iface);
99
100     return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->textcont.element.node));
101 }
102
103 static ULONG WINAPI HTMLBodyElement_Release(IHTMLBodyElement *iface)
104 {
105     HTMLBodyElement *This = HTMLBODY_THIS(iface);
106
107     return IHTMLDOMNode_Release(HTMLDOMNODE(&This->textcont.element.node));
108 }
109
110 static HRESULT WINAPI HTMLBodyElement_GetTypeInfoCount(IHTMLBodyElement *iface, UINT *pctinfo)
111 {
112     HTMLBodyElement *This = HTMLBODY_THIS(iface);
113     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->textcont.element.node.dispex), pctinfo);
114 }
115
116 static HRESULT WINAPI HTMLBodyElement_GetTypeInfo(IHTMLBodyElement *iface, UINT iTInfo,
117                                               LCID lcid, ITypeInfo **ppTInfo)
118 {
119     HTMLBodyElement *This = HTMLBODY_THIS(iface);
120     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->textcont.element.node.dispex), iTInfo, lcid, ppTInfo);
121 }
122
123 static HRESULT WINAPI HTMLBodyElement_GetIDsOfNames(IHTMLBodyElement *iface, REFIID riid,
124                                                 LPOLESTR *rgszNames, UINT cNames,
125                                                 LCID lcid, DISPID *rgDispId)
126 {
127     HTMLBodyElement *This = HTMLBODY_THIS(iface);
128     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->textcont.element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId);
129 }
130
131 static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dispIdMember,
132                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
133                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
134 {
135     HTMLBodyElement *This = HTMLBODY_THIS(iface);
136     return IDispatchEx_Invoke(DISPATCHEX(&This->textcont.element.node.dispex), dispIdMember, riid, lcid,
137             wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
138 }
139
140 static HRESULT WINAPI HTMLBodyElement_put_background(IHTMLBodyElement *iface, BSTR v)
141 {
142     HTMLBodyElement *This = HTMLBODY_THIS(iface);
143     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
144     return E_NOTIMPL;
145 }
146
147 static HRESULT WINAPI HTMLBodyElement_get_background(IHTMLBodyElement *iface, BSTR *p)
148 {
149     HTMLBodyElement *This = HTMLBODY_THIS(iface);
150     nsAString background_str;
151     nsresult nsres;
152
153     TRACE("(%p)->(%p)\n", This, p);
154
155     nsAString_Init(&background_str, NULL);
156
157     nsres = nsIDOMHTMLBodyElement_GetBackground(This->nsbody, &background_str);
158     if(NS_SUCCEEDED(nsres)) {
159         const PRUnichar *background;
160         nsAString_GetData(&background_str, &background);
161         *p = *background ? SysAllocString(background) : NULL;
162     }else {
163         ERR("GetBackground failed: %08x\n", nsres);
164         *p = NULL;
165     }
166
167     nsAString_Finish(&background_str);
168
169     TRACE("*p = %s\n", debugstr_w(*p));
170     return S_OK;
171 }
172
173 static HRESULT WINAPI HTMLBodyElement_put_bgProperties(IHTMLBodyElement *iface, BSTR v)
174 {
175     HTMLBodyElement *This = HTMLBODY_THIS(iface);
176     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
177     return E_NOTIMPL;
178 }
179
180 static HRESULT WINAPI HTMLBodyElement_get_bgProperties(IHTMLBodyElement *iface, BSTR *p)
181 {
182     HTMLBodyElement *This = HTMLBODY_THIS(iface);
183     FIXME("(%p)->(%p)\n", This, p);
184     return E_NOTIMPL;
185 }
186
187 static HRESULT WINAPI HTMLBodyElement_put_leftMargin(IHTMLBodyElement *iface, VARIANT v)
188 {
189     HTMLBodyElement *This = HTMLBODY_THIS(iface);
190     FIXME("(%p)->()\n", This);
191     return E_NOTIMPL;
192 }
193
194 static HRESULT WINAPI HTMLBodyElement_get_leftMargin(IHTMLBodyElement *iface, VARIANT *p)
195 {
196     HTMLBodyElement *This = HTMLBODY_THIS(iface);
197     FIXME("(%p)->(%p)\n", This, p);
198     return E_NOTIMPL;
199 }
200
201 static HRESULT WINAPI HTMLBodyElement_put_topMargin(IHTMLBodyElement *iface, VARIANT v)
202 {
203     HTMLBodyElement *This = HTMLBODY_THIS(iface);
204     FIXME("(%p)->()\n", This);
205     return E_NOTIMPL;
206 }
207
208 static HRESULT WINAPI HTMLBodyElement_get_topMargin(IHTMLBodyElement *iface, VARIANT *p)
209 {
210     HTMLBodyElement *This = HTMLBODY_THIS(iface);
211     FIXME("(%p)->(%p)\n", This, p);
212     return E_NOTIMPL;
213 }
214
215 static HRESULT WINAPI HTMLBodyElement_put_rightMargin(IHTMLBodyElement *iface, VARIANT v)
216 {
217     HTMLBodyElement *This = HTMLBODY_THIS(iface);
218     FIXME("(%p)->()\n", This);
219     return E_NOTIMPL;
220 }
221
222 static HRESULT WINAPI HTMLBodyElement_get_rightMargin(IHTMLBodyElement *iface, VARIANT *p)
223 {
224     HTMLBodyElement *This = HTMLBODY_THIS(iface);
225     FIXME("(%p)->(%p)\n", This, p);
226     return E_NOTIMPL;
227 }
228
229 static HRESULT WINAPI HTMLBodyElement_put_bottomMargin(IHTMLBodyElement *iface, VARIANT v)
230 {
231     HTMLBodyElement *This = HTMLBODY_THIS(iface);
232     FIXME("(%p)->()\n", This);
233     return E_NOTIMPL;
234 }
235
236 static HRESULT WINAPI HTMLBodyElement_get_bottomMargin(IHTMLBodyElement *iface, VARIANT *p)
237 {
238     HTMLBodyElement *This = HTMLBODY_THIS(iface);
239     FIXME("(%p)->(%p)\n", This, p);
240     return E_NOTIMPL;
241 }
242
243 static HRESULT WINAPI HTMLBodyElement_put_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL v)
244 {
245     HTMLBodyElement *This = HTMLBODY_THIS(iface);
246     FIXME("(%p)->(%x)\n", This, v);
247     return E_NOTIMPL;
248 }
249
250 static HRESULT WINAPI HTMLBodyElement_get_noWrap(IHTMLBodyElement *iface, VARIANT_BOOL *p)
251 {
252     HTMLBodyElement *This = HTMLBODY_THIS(iface);
253     FIXME("(%p)->(%p)\n", This, p);
254     return E_NOTIMPL;
255 }
256
257 static HRESULT WINAPI HTMLBodyElement_put_bgColor(IHTMLBodyElement *iface, VARIANT v)
258 {
259     HTMLBodyElement *This = HTMLBODY_THIS(iface);
260     FIXME("(%p)->()\n", This);
261     return E_NOTIMPL;
262 }
263
264 static HRESULT WINAPI HTMLBodyElement_get_bgColor(IHTMLBodyElement *iface, VARIANT *p)
265 {
266     HTMLBodyElement *This = HTMLBODY_THIS(iface);
267     FIXME("(%p)->(%p)\n", This, p);
268     return E_NOTIMPL;
269 }
270
271 static HRESULT WINAPI HTMLBodyElement_put_text(IHTMLBodyElement *iface, VARIANT v)
272 {
273     HTMLBodyElement *This = HTMLBODY_THIS(iface);
274     FIXME("(%p)->()\n", This);
275     return E_NOTIMPL;
276 }
277
278 static HRESULT WINAPI HTMLBodyElement_get_text(IHTMLBodyElement *iface, VARIANT *p)
279 {
280     HTMLBodyElement *This = HTMLBODY_THIS(iface);
281     FIXME("(%p)->(%p)\n", This, p);
282     return E_NOTIMPL;
283 }
284
285 static HRESULT WINAPI HTMLBodyElement_put_link(IHTMLBodyElement *iface, VARIANT v)
286 {
287     HTMLBodyElement *This = HTMLBODY_THIS(iface);
288     nsAString link_str;
289     nsresult nsres;
290
291     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
292
293     if(!variant_to_nscolor(&v, &link_str))
294         return S_OK;
295
296     nsres = nsIDOMHTMLBodyElement_SetLink(This->nsbody, &link_str);
297     nsAString_Finish(&link_str);
298     if(NS_FAILED(nsres))
299         ERR("SetLink failed: %08x\n", nsres);
300
301     return S_OK;
302 }
303
304 static HRESULT WINAPI HTMLBodyElement_get_link(IHTMLBodyElement *iface, VARIANT *p)
305 {
306     HTMLBodyElement *This = HTMLBODY_THIS(iface);
307     nsAString link_str;
308     nsresult nsres;
309
310     TRACE("(%p)->(%p)\n", This, p);
311
312     nsAString_Init(&link_str, NULL);
313     nsres = nsIDOMHTMLBodyElement_GetLink(This->nsbody, &link_str);
314     if(NS_FAILED(nsres))
315         ERR("GetLink failed: %08x\n", nsres);
316
317     nscolor_to_variant(&link_str, p);
318     nsAString_Finish(&link_str);
319
320     return S_OK;
321 }
322
323 static HRESULT WINAPI HTMLBodyElement_put_vLink(IHTMLBodyElement *iface, VARIANT v)
324 {
325     HTMLBodyElement *This = HTMLBODY_THIS(iface);
326     nsAString vlink_str;
327     nsresult nsres;
328
329     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
330
331     if(!variant_to_nscolor(&v, &vlink_str))
332         return S_OK;
333
334     nsres = nsIDOMHTMLBodyElement_SetVLink(This->nsbody, &vlink_str);
335     nsAString_Finish(&vlink_str);
336     if(NS_FAILED(nsres))
337         ERR("SetLink failed: %08x\n", nsres);
338
339     return S_OK;
340 }
341
342 static HRESULT WINAPI HTMLBodyElement_get_vLink(IHTMLBodyElement *iface, VARIANT *p)
343 {
344     HTMLBodyElement *This = HTMLBODY_THIS(iface);
345     nsAString vlink_str;
346     nsresult nsres;
347
348     TRACE("(%p)->(%p)\n", This, p);
349
350     nsAString_Init(&vlink_str, NULL);
351     nsres = nsIDOMHTMLBodyElement_GetVLink(This->nsbody, &vlink_str);
352     if(NS_FAILED(nsres))
353         ERR("GetLink failed: %08x\n", nsres);
354
355     nscolor_to_variant(&vlink_str, p);
356     nsAString_Finish(&vlink_str);
357
358     return S_OK;
359 }
360
361 static HRESULT WINAPI HTMLBodyElement_put_aLink(IHTMLBodyElement *iface, VARIANT v)
362 {
363     HTMLBodyElement *This = HTMLBODY_THIS(iface);
364     nsAString alink_str;
365     nsresult nsres;
366
367     TRACE("(%p)->(v%d)\n", This, V_VT(&v));
368
369     if(!variant_to_nscolor(&v, &alink_str))
370         return S_OK;
371
372     nsres = nsIDOMHTMLBodyElement_SetALink(This->nsbody, &alink_str);
373     nsAString_Finish(&alink_str);
374     if(NS_FAILED(nsres))
375         ERR("SetALink failed: %08x\n", nsres);
376
377     return S_OK;
378 }
379
380 static HRESULT WINAPI HTMLBodyElement_get_aLink(IHTMLBodyElement *iface, VARIANT *p)
381 {
382     HTMLBodyElement *This = HTMLBODY_THIS(iface);
383     nsAString alink_str;
384     nsresult nsres;
385
386     TRACE("(%p)->(%p)\n", This, p);
387
388     nsAString_Init(&alink_str, NULL);
389     nsres = nsIDOMHTMLBodyElement_GetALink(This->nsbody, &alink_str);
390     if(NS_FAILED(nsres))
391         ERR("GetALink failed: %08x\n", nsres);
392
393     nscolor_to_variant(&alink_str, p);
394     nsAString_Finish(&alink_str);
395
396     return S_OK;
397 }
398
399 static HRESULT WINAPI HTMLBodyElement_put_onload(IHTMLBodyElement *iface, VARIANT v)
400 {
401     HTMLBodyElement *This = HTMLBODY_THIS(iface);
402     FIXME("(%p)->()\n", This);
403     return E_NOTIMPL;
404 }
405
406 static HRESULT WINAPI HTMLBodyElement_get_onload(IHTMLBodyElement *iface, VARIANT *p)
407 {
408     HTMLBodyElement *This = HTMLBODY_THIS(iface);
409     FIXME("(%p)->(%p)\n", This, p);
410     return E_NOTIMPL;
411 }
412
413 static HRESULT WINAPI HTMLBodyElement_put_onunload(IHTMLBodyElement *iface, VARIANT v)
414 {
415     HTMLBodyElement *This = HTMLBODY_THIS(iface);
416     FIXME("(%p)->()\n", This);
417     return E_NOTIMPL;
418 }
419
420 static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARIANT *p)
421 {
422     HTMLBodyElement *This = HTMLBODY_THIS(iface);
423     FIXME("(%p)->(%p)\n", This, p);
424     return E_NOTIMPL;
425 }
426
427 static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v)
428 {
429     HTMLBodyElement *This = HTMLBODY_THIS(iface);
430     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
431     return E_NOTIMPL;
432 }
433
434 static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p)
435 {
436     HTMLBodyElement *This = HTMLBODY_THIS(iface);
437     FIXME("(%p)->(%p)\n", This, p);
438     return E_NOTIMPL;
439 }
440
441 static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v)
442 {
443     HTMLBodyElement *This = HTMLBODY_THIS(iface);
444     FIXME("(%p)->()\n", This);
445     return E_NOTIMPL;
446 }
447
448 static HRESULT WINAPI HTMLBodyElement_get_onselect(IHTMLBodyElement *iface, VARIANT *p)
449 {
450     HTMLBodyElement *This = HTMLBODY_THIS(iface);
451     FIXME("(%p)->(%p)\n", This, p);
452     return E_NOTIMPL;
453 }
454
455 static HRESULT WINAPI HTMLBodyElement_put_onbeforeunload(IHTMLBodyElement *iface, VARIANT v)
456 {
457     HTMLBodyElement *This = HTMLBODY_THIS(iface);
458     FIXME("(%p)->()\n", This);
459     return E_NOTIMPL;
460 }
461
462 static HRESULT WINAPI HTMLBodyElement_get_onbeforeunload(IHTMLBodyElement *iface, VARIANT *p)
463 {
464     HTMLBodyElement *This = HTMLBODY_THIS(iface);
465     FIXME("(%p)->(%p)\n", This, p);
466     return E_NOTIMPL;
467 }
468
469 static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, IHTMLTxtRange **range)
470 {
471     HTMLBodyElement *This = HTMLBODY_THIS(iface);
472     nsIDOMRange *nsrange = NULL;
473
474     TRACE("(%p)->(%p)\n", This, range);
475
476     if(This->textcont.element.node.doc->nscontainer) {
477         nsIDOMDocument *nsdoc;
478         nsIDOMDocumentRange *nsdocrange;
479         nsresult nsres;
480
481         nsIWebNavigation_GetDocument(This->textcont.element.node.doc->nscontainer->navigation, &nsdoc);
482         nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMDocumentRange, (void**)&nsdocrange);
483         nsIDOMDocument_Release(nsdoc);
484
485         nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &nsrange);
486         if(NS_SUCCEEDED(nsres)) {
487             nsres = nsIDOMRange_SelectNodeContents(nsrange, This->textcont.element.node.nsnode);
488             if(NS_FAILED(nsres))
489                 ERR("SelectNodeContents failed: %08x\n", nsres);
490         }else {
491             ERR("CreateRange failed: %08x\n", nsres);
492         }
493
494         nsIDOMDocumentRange_Release(nsdocrange);
495     }
496
497     *range = HTMLTxtRange_Create(This->textcont.element.node.doc, nsrange);
498     return S_OK;
499 }
500
501 #undef HTMLBODY_THIS
502
503 static const IHTMLBodyElementVtbl HTMLBodyElementVtbl = {
504     HTMLBodyElement_QueryInterface,
505     HTMLBodyElement_AddRef,
506     HTMLBodyElement_Release,
507     HTMLBodyElement_GetTypeInfoCount,
508     HTMLBodyElement_GetTypeInfo,
509     HTMLBodyElement_GetIDsOfNames,
510     HTMLBodyElement_Invoke,
511     HTMLBodyElement_put_background,
512     HTMLBodyElement_get_background,
513     HTMLBodyElement_put_bgProperties,
514     HTMLBodyElement_get_bgProperties,
515     HTMLBodyElement_put_leftMargin,
516     HTMLBodyElement_get_leftMargin,
517     HTMLBodyElement_put_topMargin,
518     HTMLBodyElement_get_topMargin,
519     HTMLBodyElement_put_rightMargin,
520     HTMLBodyElement_get_rightMargin,
521     HTMLBodyElement_put_bottomMargin,
522     HTMLBodyElement_get_bottomMargin,
523     HTMLBodyElement_put_noWrap,
524     HTMLBodyElement_get_noWrap,
525     HTMLBodyElement_put_bgColor,
526     HTMLBodyElement_get_bgColor,
527     HTMLBodyElement_put_text,
528     HTMLBodyElement_get_text,
529     HTMLBodyElement_put_link,
530     HTMLBodyElement_get_link,
531     HTMLBodyElement_put_vLink,
532     HTMLBodyElement_get_vLink,
533     HTMLBodyElement_put_aLink,
534     HTMLBodyElement_get_aLink,
535     HTMLBodyElement_put_onload,
536     HTMLBodyElement_get_onload,
537     HTMLBodyElement_put_onunload,
538     HTMLBodyElement_get_onunload,
539     HTMLBodyElement_put_scroll,
540     HTMLBodyElement_get_scroll,
541     HTMLBodyElement_put_onselect,
542     HTMLBodyElement_get_onselect,
543     HTMLBodyElement_put_onbeforeunload,
544     HTMLBodyElement_get_onbeforeunload,
545     HTMLBodyElement_createTextRange
546 };
547
548 #define HTMLBODY_NODE_THIS(iface) DEFINE_THIS2(HTMLBodyElement, textcont.element.node, iface)
549
550 static HRESULT HTMLBodyElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
551 {
552     HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface);
553
554     *ppv = NULL;
555
556     if(IsEqualGUID(&IID_IUnknown, riid)) {
557         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
558         *ppv = HTMLBODY(This);
559     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
560         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
561         *ppv = HTMLBODY(This);
562     }else if(IsEqualGUID(&IID_IHTMLBodyElement, riid)) {
563         TRACE("(%p)->(IID_IHTMLBodyElement %p)\n", This, ppv);
564         *ppv = HTMLBODY(This);
565     }else if(IsEqualGUID(&IID_IHTMLTextContainer, riid)) {
566         TRACE("(%p)->(IID_IHTMLTextContainer %p)\n", &This->textcont, ppv);
567         *ppv = HTMLTEXTCONT(&This->textcont);
568     }
569
570     if(*ppv) {
571         IUnknown_AddRef((IUnknown*)*ppv);
572         return S_OK;
573     }
574
575     return HTMLElement_QI(&This->textcont.element.node, riid, ppv);
576 }
577
578 static void HTMLBodyElement_destructor(HTMLDOMNode *iface)
579 {
580     HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface);
581
582     nsIDOMHTMLBodyElement_Release(This->nsbody);
583
584     HTMLElement_destructor(&This->textcont.element.node);
585 }
586
587 #undef HTMLBODY_NODE_THIS
588
589 static const NodeImplVtbl HTMLBodyElementImplVtbl = {
590     HTMLBodyElement_QI,
591     HTMLBodyElement_destructor
592 };
593
594 static const tid_t HTMLBodyElement_iface_tids[] = {
595     IHTMLBodyElement_tid,
596     IHTMLBodyElement2_tid,
597     IHTMLControlElement_tid,
598     IHTMLDOMNode_tid,
599     IHTMLDOMNode2_tid,
600     IHTMLElement_tid,
601     IHTMLElement2_tid,
602     IHTMLElement3_tid,
603     IHTMLElement4_tid,
604     IHTMLTextContainer_tid,
605     IHTMLUniqueName_tid,
606     0
607 };
608
609 static dispex_static_data_t HTMLBodyElement_dispex = {
610     NULL,
611     DispHTMLBody_tid,
612     NULL,
613     HTMLBodyElement_iface_tids
614 };
615
616 HTMLElement *HTMLBodyElement_Create(nsIDOMHTMLElement *nselem)
617 {
618     HTMLBodyElement *ret = heap_alloc_zero(sizeof(HTMLBodyElement));
619     nsresult nsres;
620
621     TRACE("(%p)->(%p)\n", ret, nselem);
622
623     HTMLTextContainer_Init(&ret->textcont);
624
625     ret->lpHTMLBodyElementVtbl = &HTMLBodyElementVtbl;
626
627     init_dispex(&ret->textcont.element.node.dispex, (IUnknown*)HTMLBODY(ret), &HTMLBodyElement_dispex);
628     ret->textcont.element.node.vtbl = &HTMLBodyElementImplVtbl;
629
630     ConnectionPoint_Init(&ret->cp_propnotif, &ret->textcont.element.cp_container, &IID_IPropertyNotifySink);
631
632     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLBodyElement,
633                                              (void**)&ret->nsbody);
634     if(NS_FAILED(nsres))
635         ERR("Could not get nsDOMHTMLBodyElement: %08x\n", nsres);
636
637     return &ret->textcont.element;
638 }