mshtml: Use vtbl for node destructors.
[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 "config.h"
20
21 #include <stdarg.h>
22 #include <stdio.h>
23
24 #define COBJMACROS
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winnls.h"
30 #include "ole2.h"
31
32 #include "wine/debug.h"
33
34 #include "mshtml_private.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
37
38 typedef struct {
39     HTMLTextContainer textcont;
40
41     const IHTMLBodyElementVtbl *lpHTMLBodyElementVtbl;
42
43     ConnectionPointContainer cp_container;
44     ConnectionPoint cp_propnotif;
45     ConnectionPoint cp_txtcontevents;
46
47     nsIDOMHTMLBodyElement *nsbody;
48 } HTMLBodyElement;
49
50 #define HTMLBODY(x)  ((IHTMLBodyElement*)  &(x)->lpHTMLBodyElementVtbl)
51
52 #define HTMLBODY_THIS(iface) DEFINE_THIS(HTMLBodyElement, HTMLBodyElement, iface)
53
54 static HRESULT WINAPI HTMLBodyElement_QueryInterface(IHTMLBodyElement *iface,
55                                                      REFIID riid, void **ppv)
56 {
57     HTMLBodyElement *This = HTMLBODY_THIS(iface);
58     HRESULT hres;
59
60     *ppv = NULL;
61
62     if(IsEqualGUID(&IID_IUnknown, riid)) {
63         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
64         *ppv = HTMLBODY(This);
65     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
66         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
67         *ppv = HTMLBODY(This);
68     }else if(IsEqualGUID(&IID_IHTMLBodyElement, riid)) {
69         TRACE("(%p)->(IID_IHTMLBodyElement %p)\n", This, ppv);
70         *ppv = HTMLBODY(This);
71     }else if(IsEqualGUID(&IID_IHTMLTextContainer, riid)) {
72         TRACE("(%p)->(IID_IHTMLTextContainer %p)\n", &This->textcont, ppv);
73         *ppv = HTMLTEXTCONT(&This->textcont);
74     }else if(IsEqualGUID(&IID_IConnectionPointContainer, riid)) {
75         TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
76         *ppv = CONPTCONT(&This->cp_container);
77     }
78
79     if(*ppv) {
80         IUnknown_AddRef((IUnknown*)*ppv);
81         return S_OK;
82     }
83
84     hres = HTMLElement_QI(&This->textcont.element, riid, ppv);
85     if(FAILED(hres))
86         WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
87
88     return hres;
89 }
90
91 static ULONG WINAPI HTMLBodyElement_AddRef(IHTMLBodyElement *iface)
92 {
93     HTMLBodyElement *This = HTMLBODY_THIS(iface);
94
95     return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->textcont.element.node));
96 }
97
98 static ULONG WINAPI HTMLBodyElement_Release(IHTMLBodyElement *iface)
99 {
100     HTMLBodyElement *This = HTMLBODY_THIS(iface);
101
102     return IHTMLDOMNode_Release(HTMLDOMNODE(&This->textcont.element.node));
103 }
104
105 static HRESULT WINAPI HTMLBodyElement_GetTypeInfoCount(IHTMLBodyElement *iface, UINT *pctinfo)
106 {
107     HTMLBodyElement *This = HTMLBODY_THIS(iface);
108     FIXME("(%p)->(%p)\n", This, pctinfo);
109     return E_NOTIMPL;
110 }
111
112 static HRESULT WINAPI HTMLBodyElement_GetTypeInfo(IHTMLBodyElement *iface, UINT iTInfo,
113                                               LCID lcid, ITypeInfo **ppTInfo)
114 {
115     HTMLBodyElement *This = HTMLBODY_THIS(iface);
116     FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
117     return E_NOTIMPL;
118 }
119
120 static HRESULT WINAPI HTMLBodyElement_GetIDsOfNames(IHTMLBodyElement *iface, REFIID riid,
121                                                 LPOLESTR *rgszNames, UINT cNames,
122                                                 LCID lcid, DISPID *rgDispId)
123 {
124     HTMLBodyElement *This = HTMLBODY_THIS(iface);
125     FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
126                                         lcid, rgDispId);
127     return E_NOTIMPL;
128 }
129
130 static HRESULT WINAPI HTMLBodyElement_Invoke(IHTMLBodyElement *iface, DISPID dispIdMember,
131                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
132                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
133 {
134     HTMLBodyElement *This = HTMLBODY_THIS(iface);
135     FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
136             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
137     return E_NOTIMPL;
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, NULL);
161         *p = SysAllocString(background);
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     FIXME("(%p)->()\n", This);
289     return E_NOTIMPL;
290 }
291
292 static HRESULT WINAPI HTMLBodyElement_get_link(IHTMLBodyElement *iface, VARIANT *p)
293 {
294     HTMLBodyElement *This = HTMLBODY_THIS(iface);
295     FIXME("(%p)->(%p)\n", This, p);
296     return E_NOTIMPL;
297 }
298
299 static HRESULT WINAPI HTMLBodyElement_put_vLink(IHTMLBodyElement *iface, VARIANT v)
300 {
301     HTMLBodyElement *This = HTMLBODY_THIS(iface);
302     FIXME("(%p)->()\n", This);
303     return E_NOTIMPL;
304 }
305
306 static HRESULT WINAPI HTMLBodyElement_get_vLink(IHTMLBodyElement *iface, VARIANT *p)
307 {
308     HTMLBodyElement *This = HTMLBODY_THIS(iface);
309     FIXME("(%p)->(%p)\n", This, p);
310     return E_NOTIMPL;
311 }
312
313 static HRESULT WINAPI HTMLBodyElement_put_aLink(IHTMLBodyElement *iface, VARIANT v)
314 {
315     HTMLBodyElement *This = HTMLBODY_THIS(iface);
316     FIXME("(%p)->()\n", This);
317     return E_NOTIMPL;
318 }
319
320 static HRESULT WINAPI HTMLBodyElement_get_aLink(IHTMLBodyElement *iface, VARIANT *p)
321 {
322     HTMLBodyElement *This = HTMLBODY_THIS(iface);
323     FIXME("(%p)->(%p)\n", This, p);
324     return E_NOTIMPL;
325 }
326
327 static HRESULT WINAPI HTMLBodyElement_put_onload(IHTMLBodyElement *iface, VARIANT v)
328 {
329     HTMLBodyElement *This = HTMLBODY_THIS(iface);
330     FIXME("(%p)->()\n", This);
331     return E_NOTIMPL;
332 }
333
334 static HRESULT WINAPI HTMLBodyElement_get_onload(IHTMLBodyElement *iface, VARIANT *p)
335 {
336     HTMLBodyElement *This = HTMLBODY_THIS(iface);
337     FIXME("(%p)->(%p)\n", This, p);
338     return E_NOTIMPL;
339 }
340
341 static HRESULT WINAPI HTMLBodyElement_put_onunload(IHTMLBodyElement *iface, VARIANT v)
342 {
343     HTMLBodyElement *This = HTMLBODY_THIS(iface);
344     FIXME("(%p)->()\n", This);
345     return E_NOTIMPL;
346 }
347
348 static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARIANT *p)
349 {
350     HTMLBodyElement *This = HTMLBODY_THIS(iface);
351     FIXME("(%p)->(%p)\n", This, p);
352     return E_NOTIMPL;
353 }
354
355 static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v)
356 {
357     HTMLBodyElement *This = HTMLBODY_THIS(iface);
358     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
359     return E_NOTIMPL;
360 }
361
362 static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p)
363 {
364     HTMLBodyElement *This = HTMLBODY_THIS(iface);
365     FIXME("(%p)->(%p)\n", This, p);
366     return E_NOTIMPL;
367 }
368
369 static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v)
370 {
371     HTMLBodyElement *This = HTMLBODY_THIS(iface);
372     FIXME("(%p)->()\n", This);
373     return E_NOTIMPL;
374 }
375
376 static HRESULT WINAPI HTMLBodyElement_get_onselect(IHTMLBodyElement *iface, VARIANT *p)
377 {
378     HTMLBodyElement *This = HTMLBODY_THIS(iface);
379     FIXME("(%p)->(%p)\n", This, p);
380     return E_NOTIMPL;
381 }
382
383 static HRESULT WINAPI HTMLBodyElement_put_onbeforeunload(IHTMLBodyElement *iface, VARIANT v)
384 {
385     HTMLBodyElement *This = HTMLBODY_THIS(iface);
386     FIXME("(%p)->()\n", This);
387     return E_NOTIMPL;
388 }
389
390 static HRESULT WINAPI HTMLBodyElement_get_onbeforeunload(IHTMLBodyElement *iface, VARIANT *p)
391 {
392     HTMLBodyElement *This = HTMLBODY_THIS(iface);
393     FIXME("(%p)->(%p)\n", This, p);
394     return E_NOTIMPL;
395 }
396
397 static HRESULT WINAPI HTMLBodyElement_createTextRange(IHTMLBodyElement *iface, IHTMLTxtRange **range)
398 {
399     HTMLBodyElement *This = HTMLBODY_THIS(iface);
400     nsIDOMRange *nsrange = NULL;
401
402     TRACE("(%p)->(%p)\n", This, range);
403
404     if(This->textcont.element.node.doc->nscontainer) {
405         nsIDOMDocument *nsdoc;
406         nsIDOMDocumentRange *nsdocrange;
407         nsresult nsres;
408
409         nsIWebNavigation_GetDocument(This->textcont.element.node.doc->nscontainer->navigation, &nsdoc);
410         nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMDocumentRange, (void**)&nsdocrange);
411         nsIDOMDocument_Release(nsdoc);
412
413         nsres = nsIDOMDocumentRange_CreateRange(nsdocrange, &nsrange);
414         if(NS_SUCCEEDED(nsres)) {
415             nsres = nsIDOMRange_SelectNodeContents(nsrange, This->textcont.element.node.nsnode);
416             if(NS_FAILED(nsres))
417                 ERR("SelectNodeContents failed: %08x\n", nsres);
418         }else {
419             ERR("CreateRange failed: %08x\n", nsres);
420         }
421
422         nsIDOMDocumentRange_Release(nsdocrange);
423     }
424
425     *range = HTMLTxtRange_Create(This->textcont.element.node.doc, nsrange);
426     return S_OK;
427 }
428
429 #undef HTMLBODY_THIS
430
431 static const IHTMLBodyElementVtbl HTMLBodyElementVtbl = {
432     HTMLBodyElement_QueryInterface,
433     HTMLBodyElement_AddRef,
434     HTMLBodyElement_Release,
435     HTMLBodyElement_GetTypeInfoCount,
436     HTMLBodyElement_GetTypeInfo,
437     HTMLBodyElement_GetIDsOfNames,
438     HTMLBodyElement_Invoke,
439     HTMLBodyElement_put_background,
440     HTMLBodyElement_get_background,
441     HTMLBodyElement_put_bgProperties,
442     HTMLBodyElement_get_bgProperties,
443     HTMLBodyElement_put_leftMargin,
444     HTMLBodyElement_get_leftMargin,
445     HTMLBodyElement_put_topMargin,
446     HTMLBodyElement_get_topMargin,
447     HTMLBodyElement_put_rightMargin,
448     HTMLBodyElement_get_rightMargin,
449     HTMLBodyElement_put_bottomMargin,
450     HTMLBodyElement_get_bottomMargin,
451     HTMLBodyElement_put_noWrap,
452     HTMLBodyElement_get_noWrap,
453     HTMLBodyElement_put_bgColor,
454     HTMLBodyElement_get_bgColor,
455     HTMLBodyElement_put_text,
456     HTMLBodyElement_get_text,
457     HTMLBodyElement_put_link,
458     HTMLBodyElement_get_link,
459     HTMLBodyElement_put_vLink,
460     HTMLBodyElement_get_vLink,
461     HTMLBodyElement_put_aLink,
462     HTMLBodyElement_get_aLink,
463     HTMLBodyElement_put_onload,
464     HTMLBodyElement_get_onload,
465     HTMLBodyElement_put_onunload,
466     HTMLBodyElement_get_onunload,
467     HTMLBodyElement_put_scroll,
468     HTMLBodyElement_get_scroll,
469     HTMLBodyElement_put_onselect,
470     HTMLBodyElement_get_onselect,
471     HTMLBodyElement_put_onbeforeunload,
472     HTMLBodyElement_get_onbeforeunload,
473     HTMLBodyElement_createTextRange
474 };
475
476 #define HTMLBODY_NODE_THIS(iface) DEFINE_THIS2(HTMLBodyElement, textcont.element.node, iface)
477
478 static void HTMLBodyElement_destructor(HTMLDOMNode *iface)
479 {
480     HTMLBodyElement *This = HTMLBODY_NODE_THIS(iface);
481
482     ConnectionPointContainer_Destroy(&This->cp_container);
483     nsIDOMHTMLBodyElement_Release(This->nsbody);
484
485     HTMLElement_destructor(&This->textcont.element.node);
486 }
487
488 #undef HTMLBODY_NODE_THIS
489
490 static const NodeImplVtbl HTMLBodyElementImplVtbl = {
491     HTMLBodyElement_destructor
492 };
493
494 HTMLElement *HTMLBodyElement_Create(nsIDOMHTMLElement *nselem)
495 {
496     HTMLBodyElement *ret = mshtml_alloc(sizeof(HTMLBodyElement));
497     nsresult nsres;
498
499     TRACE("(%p)->(%p)\n", ret, nselem);
500
501     ret->lpHTMLBodyElementVtbl = &HTMLBodyElementVtbl;
502     ret->textcont.element.node.vtbl = &HTMLBodyElementImplVtbl;
503
504     HTMLTextContainer_Init(&ret->textcont);
505
506     ConnectionPoint_Init(&ret->cp_propnotif, CONPTCONT(&ret->cp_container),
507             &IID_IPropertyNotifySink, NULL);
508     ConnectionPoint_Init(&ret->cp_txtcontevents, CONPTCONT(&ret->cp_container),
509             &DIID_HTMLTextContainerEvents, &ret->cp_propnotif);
510     ConnectionPointContainer_Init(&ret->cp_container, &ret->cp_propnotif, (IUnknown*)HTMLBODY(ret));
511
512     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLBodyElement,
513                                              (void**)&ret->nsbody);
514     if(NS_FAILED(nsres))
515         ERR("Could not get nsDOMHTMLBodyElement: %08x\n", nsres);
516
517     ret->textcont.element.impl = (IUnknown*)HTMLBODY(ret);
518
519     return &ret->textcont.element;
520 }