mshtml: COM cleanup for the IViewObjectEx iface.
[wine] / dlls / mshtml / htmlscript.c
1 /*
2  * Copyright 2008 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
21 #define COBJMACROS
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winuser.h"
26 #include "ole2.h"
27
28 #include "wine/debug.h"
29
30 #include "mshtml_private.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
33
34 typedef struct {
35     HTMLElement element;
36
37     IHTMLScriptElement IHTMLScriptElement_iface;
38
39     nsIDOMHTMLScriptElement *nsscript;
40 } HTMLScriptElement;
41
42 static inline HTMLScriptElement *impl_from_IHTMLScriptElement(IHTMLScriptElement *iface)
43 {
44     return CONTAINING_RECORD(iface, HTMLScriptElement, IHTMLScriptElement_iface);
45 }
46
47 static HRESULT WINAPI HTMLScriptElement_QueryInterface(IHTMLScriptElement *iface,
48         REFIID riid, void **ppv)
49 {
50     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
51
52     return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->element.node), riid, ppv);
53 }
54
55 static ULONG WINAPI HTMLScriptElement_AddRef(IHTMLScriptElement *iface)
56 {
57     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
58
59     return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->element.node));
60 }
61
62 static ULONG WINAPI HTMLScriptElement_Release(IHTMLScriptElement *iface)
63 {
64     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
65
66     return IHTMLDOMNode_Release(HTMLDOMNODE(&This->element.node));
67 }
68
69 static HRESULT WINAPI HTMLScriptElement_GetTypeInfoCount(IHTMLScriptElement *iface, UINT *pctinfo)
70 {
71     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
72     return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->element.node.dispex), pctinfo);
73 }
74
75 static HRESULT WINAPI HTMLScriptElement_GetTypeInfo(IHTMLScriptElement *iface, UINT iTInfo,
76                                               LCID lcid, ITypeInfo **ppTInfo)
77 {
78     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
79     return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->element.node.dispex), iTInfo, lcid, ppTInfo);
80 }
81
82 static HRESULT WINAPI HTMLScriptElement_GetIDsOfNames(IHTMLScriptElement *iface, REFIID riid,
83                                                 LPOLESTR *rgszNames, UINT cNames,
84                                                 LCID lcid, DISPID *rgDispId)
85 {
86     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
87     return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->element.node.dispex), riid, rgszNames, cNames, lcid, rgDispId);
88 }
89
90 static HRESULT WINAPI HTMLScriptElement_Invoke(IHTMLScriptElement *iface, DISPID dispIdMember,
91                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
92                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
93 {
94     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
95     return IDispatchEx_Invoke(DISPATCHEX(&This->element.node.dispex), dispIdMember, riid, lcid, wFlags, pDispParams,
96             pVarResult, pExcepInfo, puArgErr);
97 }
98
99 static HRESULT WINAPI HTMLScriptElement_put_src(IHTMLScriptElement *iface, BSTR v)
100 {
101     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
102     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
103     return E_NOTIMPL;
104 }
105
106 static HRESULT WINAPI HTMLScriptElement_get_src(IHTMLScriptElement *iface, BSTR *p)
107 {
108     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
109     nsAString src_str;
110     nsresult nsres;
111
112     TRACE("(%p)->(%p)\n", This, p);
113
114     nsAString_Init(&src_str, NULL);
115     nsres = nsIDOMHTMLScriptElement_GetSrc(This->nsscript, &src_str);
116     return return_nsstr(nsres, &src_str, p);
117 }
118
119 static HRESULT WINAPI HTMLScriptElement_put_htmlFor(IHTMLScriptElement *iface, BSTR v)
120 {
121     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
122     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
123     return E_NOTIMPL;
124 }
125
126 static HRESULT WINAPI HTMLScriptElement_get_htmlFor(IHTMLScriptElement *iface, BSTR *p)
127 {
128     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
129     FIXME("(%p)->(%p)\n", This, p);
130     return E_NOTIMPL;
131 }
132
133 static HRESULT WINAPI HTMLScriptElement_put_event(IHTMLScriptElement *iface, BSTR v)
134 {
135     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
136     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
137     return E_NOTIMPL;
138 }
139
140 static HRESULT WINAPI HTMLScriptElement_get_event(IHTMLScriptElement *iface, BSTR *p)
141 {
142     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
143     FIXME("(%p)->(%p)\n", This, p);
144     return E_NOTIMPL;
145 }
146
147 static HRESULT WINAPI HTMLScriptElement_put_text(IHTMLScriptElement *iface, BSTR v)
148 {
149     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
150     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
151     return E_NOTIMPL;
152 }
153
154 static HRESULT WINAPI HTMLScriptElement_get_text(IHTMLScriptElement *iface, BSTR *p)
155 {
156     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
157     FIXME("(%p)->(%p)\n", This, p);
158     return E_NOTIMPL;
159 }
160
161 static HRESULT WINAPI HTMLScriptElement_put_defer(IHTMLScriptElement *iface, VARIANT_BOOL v)
162 {
163     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
164     HRESULT hr = S_OK;
165     nsresult nsres;
166
167     TRACE("(%p)->(%x)\n", This, v);
168
169     nsres = nsIDOMHTMLScriptElement_SetDefer(This->nsscript, v != VARIANT_FALSE);
170     if(NS_FAILED(nsres))
171     {
172         hr = E_FAIL;
173     }
174
175     return hr;
176 }
177
178 static HRESULT WINAPI HTMLScriptElement_get_defer(IHTMLScriptElement *iface, VARIANT_BOOL *p)
179 {
180     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
181     PRBool defer = FALSE;
182     nsresult nsres;
183
184     TRACE("(%p)->(%p)\n", This, p);
185
186     if(!p)
187         return E_INVALIDARG;
188
189     nsres = nsIDOMHTMLScriptElement_GetDefer(This->nsscript, &defer);
190     if(NS_FAILED(nsres)) {
191         ERR("GetSrc failed: %08x\n", nsres);
192     }
193
194     *p = defer ? VARIANT_TRUE : VARIANT_FALSE;
195
196     TRACE("*p = %d\n", *p);
197     return S_OK;
198 }
199
200 static HRESULT WINAPI HTMLScriptElement_get_readyState(IHTMLScriptElement *iface, BSTR *p)
201 {
202     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
203     FIXME("(%p)->(%p)\n", This, p);
204     return E_NOTIMPL;
205 }
206
207 static HRESULT WINAPI HTMLScriptElement_put_onerror(IHTMLScriptElement *iface, VARIANT v)
208 {
209     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
210     FIXME("(%p)->(v(%d))\n", This, V_VT(&v));
211     return E_NOTIMPL;
212 }
213
214 static HRESULT WINAPI HTMLScriptElement_get_onerror(IHTMLScriptElement *iface, VARIANT *p)
215 {
216     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
217     FIXME("(%p)->(%p)\n", This, p);
218     return E_NOTIMPL;
219 }
220
221 static HRESULT WINAPI HTMLScriptElement_put_type(IHTMLScriptElement *iface, BSTR v)
222 {
223     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
224     nsAString nstype_str;
225     nsresult nsres;
226
227     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
228
229     nsAString_Init(&nstype_str, v);
230     nsres = nsIDOMHTMLScriptElement_SetType(This->nsscript, &nstype_str);
231     if (NS_FAILED(nsres))
232         ERR("SetType failed: %08x\n", nsres);
233     nsAString_Finish (&nstype_str);
234
235     return S_OK;
236 }
237
238 static HRESULT WINAPI HTMLScriptElement_get_type(IHTMLScriptElement *iface, BSTR *p)
239 {
240     HTMLScriptElement *This = impl_from_IHTMLScriptElement(iface);
241     const PRUnichar *nstype;
242     nsAString nstype_str;
243     nsresult nsres;
244
245     TRACE("(%p)->(%p)\n", This, p);
246
247     nsAString_Init(&nstype_str, NULL);
248     nsres = nsIDOMHTMLScriptElement_GetType(This->nsscript, &nstype_str);
249     if(NS_FAILED(nsres))
250         ERR("GetType failed: %08x\n", nsres);
251
252     nsAString_GetData(&nstype_str, &nstype);
253     *p = *nstype ? SysAllocString(nstype) : NULL;
254     nsAString_Finish(&nstype_str);
255
256     return S_OK;
257 }
258
259 static const IHTMLScriptElementVtbl HTMLScriptElementVtbl = {
260     HTMLScriptElement_QueryInterface,
261     HTMLScriptElement_AddRef,
262     HTMLScriptElement_Release,
263     HTMLScriptElement_GetTypeInfoCount,
264     HTMLScriptElement_GetTypeInfo,
265     HTMLScriptElement_GetIDsOfNames,
266     HTMLScriptElement_Invoke,
267     HTMLScriptElement_put_src,
268     HTMLScriptElement_get_src,
269     HTMLScriptElement_put_htmlFor,
270     HTMLScriptElement_get_htmlFor,
271     HTMLScriptElement_put_event,
272     HTMLScriptElement_get_event,
273     HTMLScriptElement_put_text,
274     HTMLScriptElement_get_text,
275     HTMLScriptElement_put_defer,
276     HTMLScriptElement_get_defer,
277     HTMLScriptElement_get_readyState,
278     HTMLScriptElement_put_onerror,
279     HTMLScriptElement_get_onerror,
280     HTMLScriptElement_put_type,
281     HTMLScriptElement_get_type
282 };
283
284 #define HTMLSCRIPT_NODE_THIS(iface) DEFINE_THIS2(HTMLScriptElement, element.node, iface)
285
286 static HRESULT HTMLScriptElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
287 {
288     HTMLScriptElement *This = HTMLSCRIPT_NODE_THIS(iface);
289
290     *ppv = NULL;
291
292     if(IsEqualGUID(&IID_IUnknown, riid)) {
293         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
294         *ppv = &This->IHTMLScriptElement_iface;
295     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
296         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
297         *ppv = &This->IHTMLScriptElement_iface;
298     }else if(IsEqualGUID(&IID_IHTMLScriptElement, riid)) {
299         TRACE("(%p)->(IID_IHTMLScriptElement %p)\n", This, ppv);
300         *ppv = &This->IHTMLScriptElement_iface;
301     }
302
303     if(*ppv) {
304         IUnknown_AddRef((IUnknown*)*ppv);
305         return S_OK;
306     }
307
308     return HTMLElement_QI(&This->element.node, riid, ppv);
309 }
310
311 static void HTMLScriptElement_destructor(HTMLDOMNode *iface)
312 {
313     HTMLScriptElement *This = HTMLSCRIPT_NODE_THIS(iface);
314     HTMLElement_destructor(&This->element.node);
315 }
316
317 static HRESULT HTMLScriptElement_get_readystate(HTMLDOMNode *iface, BSTR *p)
318 {
319     HTMLScriptElement *This = HTMLSCRIPT_NODE_THIS(iface);
320
321     return IHTMLScriptElement_get_readyState(&This->IHTMLScriptElement_iface, p);
322 }
323
324 #undef HTMLSCRIPT_NODE_THIS
325
326 static const NodeImplVtbl HTMLScriptElementImplVtbl = {
327     HTMLScriptElement_QI,
328     HTMLScriptElement_destructor,
329     HTMLElement_clone,
330     NULL,
331     NULL,
332     NULL,
333     NULL,
334     NULL,
335     HTMLScriptElement_get_readystate
336 };
337
338 static const tid_t HTMLScriptElement_iface_tids[] = {
339     HTMLELEMENT_TIDS,
340     IHTMLScriptElement_tid,
341     0
342 };
343
344 static dispex_static_data_t HTMLScriptElement_dispex = {
345     NULL,
346     DispHTMLScriptElement_tid,
347     NULL,
348     HTMLScriptElement_iface_tids
349 };
350
351 HRESULT HTMLScriptElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
352 {
353     HTMLScriptElement *ret;
354     nsresult nsres;
355
356     ret = heap_alloc_zero(sizeof(HTMLScriptElement));
357     if(!ret)
358         return E_OUTOFMEMORY;
359
360     ret->IHTMLScriptElement_iface.lpVtbl = &HTMLScriptElementVtbl;
361     ret->element.node.vtbl = &HTMLScriptElementImplVtbl;
362
363     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLScriptElement, (void**)&ret->nsscript);
364     if(NS_FAILED(nsres)) {
365         ERR("Could not get nsIDOMHTMLScriptElement: %08x\n", nsres);
366         heap_free(ret);
367         return E_FAIL;
368     }
369
370     HTMLElement_Init(&ret->element, doc, nselem, &HTMLScriptElement_dispex);
371
372     *elem = &ret->element;
373     return S_OK;
374 }