mshtml: Keep reference to document node in fire_event_obj.
[wine] / dlls / mshtml / htmltextarea.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 <assert.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     HTMLElement element;
37
38     IHTMLTextAreaElement IHTMLTextAreaElement_iface;
39
40     nsIDOMHTMLTextAreaElement *nstextarea;
41 } HTMLTextAreaElement;
42
43 static inline HTMLTextAreaElement *impl_from_IHTMLTextAreaElement(IHTMLTextAreaElement *iface)
44 {
45     return CONTAINING_RECORD(iface, HTMLTextAreaElement, IHTMLTextAreaElement_iface);
46 }
47
48 static HRESULT WINAPI HTMLTextAreaElement_QueryInterface(IHTMLTextAreaElement *iface,
49                                                          REFIID riid, void **ppv)
50 {
51     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
52
53     return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv);
54 }
55
56 static ULONG WINAPI HTMLTextAreaElement_AddRef(IHTMLTextAreaElement *iface)
57 {
58     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
59
60     return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface);
61 }
62
63 static ULONG WINAPI HTMLTextAreaElement_Release(IHTMLTextAreaElement *iface)
64 {
65     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
66
67     return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface);
68 }
69
70 static HRESULT WINAPI HTMLTextAreaElement_GetTypeInfoCount(IHTMLTextAreaElement *iface, UINT *pctinfo)
71 {
72     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
73     return IDispatchEx_GetTypeInfoCount(&This->element.node.dispex.IDispatchEx_iface, pctinfo);
74 }
75
76 static HRESULT WINAPI HTMLTextAreaElement_GetTypeInfo(IHTMLTextAreaElement *iface, UINT iTInfo,
77                                               LCID lcid, ITypeInfo **ppTInfo)
78 {
79     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
80     return IDispatchEx_GetTypeInfo(&This->element.node.dispex.IDispatchEx_iface, iTInfo, lcid,
81             ppTInfo);
82 }
83
84 static HRESULT WINAPI HTMLTextAreaElement_GetIDsOfNames(IHTMLTextAreaElement *iface, REFIID riid,
85                                                 LPOLESTR *rgszNames, UINT cNames,
86                                                 LCID lcid, DISPID *rgDispId)
87 {
88     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
89     return IDispatchEx_GetIDsOfNames(&This->element.node.dispex.IDispatchEx_iface, riid, rgszNames,
90             cNames, lcid, rgDispId);
91 }
92
93 static HRESULT WINAPI HTMLTextAreaElement_Invoke(IHTMLTextAreaElement *iface, DISPID dispIdMember,
94                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
95                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
96 {
97     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
98     return IDispatchEx_Invoke(&This->element.node.dispex.IDispatchEx_iface, dispIdMember, riid,
99             lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
100 }
101
102 static HRESULT WINAPI HTMLTextAreaElement_get_type(IHTMLTextAreaElement *iface, BSTR *p)
103 {
104     static const WCHAR textareaW[] = {'t','e','x','t','a','r','e','a',0};
105
106     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
107
108     TRACE("(%p)->(%p)\n", This, p);
109
110     *p = SysAllocString(textareaW);
111     if(!*p)
112         return E_OUTOFMEMORY;
113     return S_OK;
114 }
115
116 static HRESULT WINAPI HTMLTextAreaElement_put_value(IHTMLTextAreaElement *iface, BSTR v)
117 {
118     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
119     nsAString value_str;
120     nsresult nsres;
121
122     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
123
124     nsAString_InitDepend(&value_str, v);
125     nsres = nsIDOMHTMLTextAreaElement_SetValue(This->nstextarea, &value_str);
126     nsAString_Finish(&value_str);
127     if(NS_FAILED(nsres)) {
128         ERR("SetValue failed: %08x\n", nsres);
129         return E_FAIL;
130     }
131
132     return S_OK;
133 }
134
135 static HRESULT WINAPI HTMLTextAreaElement_get_value(IHTMLTextAreaElement *iface, BSTR *p)
136 {
137     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
138     nsAString value_str;
139     nsresult nsres;
140
141     TRACE("(%p)->(%p)\n", This, p);
142
143     nsAString_Init(&value_str, NULL);
144     nsres = nsIDOMHTMLTextAreaElement_GetValue(This->nstextarea, &value_str);
145     return return_nsstr(nsres, &value_str, p);
146 }
147
148 static HRESULT WINAPI HTMLTextAreaElement_put_name(IHTMLTextAreaElement *iface, BSTR v)
149 {
150     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
151     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
152     return E_NOTIMPL;
153 }
154
155 static HRESULT WINAPI HTMLTextAreaElement_get_name(IHTMLTextAreaElement *iface, BSTR *p)
156 {
157     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
158     nsAString name_str;
159     nsresult nsres;
160
161     TRACE("(%p)->(%p)\n", This, p);
162
163     nsAString_Init(&name_str, NULL);
164     nsres = nsIDOMHTMLTextAreaElement_GetName(This->nstextarea, &name_str);
165     return return_nsstr(nsres, &name_str, p);
166 }
167
168 static HRESULT WINAPI HTMLTextAreaElement_put_status(IHTMLTextAreaElement *iface, VARIANT v)
169 {
170     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
171     FIXME("(%p)->()\n", This);
172     return E_NOTIMPL;
173 }
174
175 static HRESULT WINAPI HTMLTextAreaElement_get_status(IHTMLTextAreaElement *iface, VARIANT *p)
176 {
177     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
178     FIXME("(%p)->(%p)\n", This, p);
179     return E_NOTIMPL;
180 }
181
182 static HRESULT WINAPI HTMLTextAreaElement_put_disabled(IHTMLTextAreaElement *iface, VARIANT_BOOL v)
183 {
184     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
185     FIXME("(%p)->(%x)\n", This, v);
186     return E_NOTIMPL;
187 }
188
189 static HRESULT WINAPI HTMLTextAreaElement_get_disabled(IHTMLTextAreaElement *iface, VARIANT_BOOL *p)
190 {
191     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
192     FIXME("(%p)->(%p)\n", This, p);
193     return E_NOTIMPL;
194 }
195
196 static HRESULT WINAPI HTMLTextAreaElement_get_form(IHTMLTextAreaElement *iface, IHTMLFormElement **p)
197 {
198     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
199     FIXME("(%p)->(%p)\n", This, p);
200     return E_NOTIMPL;
201 }
202
203 static HRESULT WINAPI HTMLTextAreaElement_put_defaultValue(IHTMLTextAreaElement *iface, BSTR v)
204 {
205     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
206     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
207     return E_NOTIMPL;
208 }
209
210 static HRESULT WINAPI HTMLTextAreaElement_get_defaultValue(IHTMLTextAreaElement *iface, BSTR *p)
211 {
212     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
213     FIXME("(%p)->(%p)\n", This, p);
214     return E_NOTIMPL;
215 }
216
217 static HRESULT WINAPI HTMLTextAreaElement_select(IHTMLTextAreaElement *iface)
218 {
219     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
220     FIXME("(%p)\n", This);
221     return E_NOTIMPL;
222 }
223
224 static HRESULT WINAPI HTMLTextAreaElement_put_onchange(IHTMLTextAreaElement *iface, VARIANT v)
225 {
226     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
227     FIXME("(%p)->()\n", This);
228     return E_NOTIMPL;
229 }
230
231 static HRESULT WINAPI HTMLTextAreaElement_get_onchange(IHTMLTextAreaElement *iface, VARIANT *p)
232 {
233     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
234     FIXME("(%p)->(%p)\n", This, p);
235     return E_NOTIMPL;
236 }
237
238 static HRESULT WINAPI HTMLTextAreaElement_put_onselect(IHTMLTextAreaElement *iface, VARIANT v)
239 {
240     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
241     FIXME("(%p)->()\n", This);
242     return E_NOTIMPL;
243 }
244
245 static HRESULT WINAPI HTMLTextAreaElement_get_onselect(IHTMLTextAreaElement *iface, VARIANT *p)
246 {
247     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
248     FIXME("(%p)->(%p)\n", This, p);
249     return E_NOTIMPL;
250 }
251
252 static HRESULT WINAPI HTMLTextAreaElement_put_readOnly(IHTMLTextAreaElement *iface, VARIANT_BOOL v)
253 {
254     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
255     nsresult nsres;
256
257     TRACE("(%p)->(%x)\n", This, v);
258
259     nsres = nsIDOMHTMLTextAreaElement_SetReadOnly(This->nstextarea, v != VARIANT_FALSE);
260     if(NS_FAILED(nsres)) {
261         ERR("SetReadOnly failed: %08x\n", nsres);
262         return E_FAIL;
263     }
264
265     return S_OK;
266 }
267
268 static HRESULT WINAPI HTMLTextAreaElement_get_readOnly(IHTMLTextAreaElement *iface, VARIANT_BOOL *p)
269 {
270     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
271     cpp_bool b;
272     nsresult nsres;
273
274     TRACE("(%p)->(%p)\n", This, p);
275
276     nsres = nsIDOMHTMLTextAreaElement_GetReadOnly(This->nstextarea, &b);
277     if(NS_FAILED(nsres)) {
278         ERR("GetReadOnly failed: %08x\n", nsres);
279         return E_FAIL;
280     }
281
282     *p = b ? VARIANT_TRUE : VARIANT_FALSE;
283     return S_OK;
284 }
285
286 static HRESULT WINAPI HTMLTextAreaElement_put_rows(IHTMLTextAreaElement *iface, LONG v)
287 {
288     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
289     FIXME("(%p)->(%d)\n", This, v);
290     return E_NOTIMPL;
291 }
292
293 static HRESULT WINAPI HTMLTextAreaElement_get_rows(IHTMLTextAreaElement *iface, LONG *p)
294 {
295     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
296     FIXME("(%p)->(%p)\n", This, p);
297     return E_NOTIMPL;
298 }
299
300 static HRESULT WINAPI HTMLTextAreaElement_put_cols(IHTMLTextAreaElement *iface, LONG v)
301 {
302     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
303     FIXME("(%p)->(%d)\n", This, v);
304     return E_NOTIMPL;
305 }
306
307 static HRESULT WINAPI HTMLTextAreaElement_get_cols(IHTMLTextAreaElement *iface, LONG *p)
308 {
309     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
310     FIXME("(%p)->(%p)\n", This, p);
311     return E_NOTIMPL;
312 }
313
314 static HRESULT WINAPI HTMLTextAreaElement_put_wrap(IHTMLTextAreaElement *iface, BSTR v)
315 {
316     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
317     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
318     return E_NOTIMPL;
319 }
320
321 static HRESULT WINAPI HTMLTextAreaElement_get_wrap(IHTMLTextAreaElement *iface, BSTR *p)
322 {
323     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
324     FIXME("(%p)->(%p)\n", This, p);
325     return E_NOTIMPL;
326 }
327
328 static HRESULT WINAPI HTMLTextAreaElement_createTextRange(IHTMLTextAreaElement *iface,
329                                                           IHTMLTxtRange **range)
330 {
331     HTMLTextAreaElement *This = impl_from_IHTMLTextAreaElement(iface);
332     FIXME("(%p)->(%p)\n", This, range);
333     return E_NOTIMPL;
334 }
335
336 static const IHTMLTextAreaElementVtbl HTMLTextAreaElementVtbl = {
337     HTMLTextAreaElement_QueryInterface,
338     HTMLTextAreaElement_AddRef,
339     HTMLTextAreaElement_Release,
340     HTMLTextAreaElement_GetTypeInfoCount,
341     HTMLTextAreaElement_GetTypeInfo,
342     HTMLTextAreaElement_GetIDsOfNames,
343     HTMLTextAreaElement_Invoke,
344     HTMLTextAreaElement_get_type,
345     HTMLTextAreaElement_put_value,
346     HTMLTextAreaElement_get_value,
347     HTMLTextAreaElement_put_name,
348     HTMLTextAreaElement_get_name,
349     HTMLTextAreaElement_put_status,
350     HTMLTextAreaElement_get_status,
351     HTMLTextAreaElement_put_disabled,
352     HTMLTextAreaElement_get_disabled,
353     HTMLTextAreaElement_get_form,
354     HTMLTextAreaElement_put_defaultValue,
355     HTMLTextAreaElement_get_defaultValue,
356     HTMLTextAreaElement_select,
357     HTMLTextAreaElement_put_onchange,
358     HTMLTextAreaElement_get_onchange,
359     HTMLTextAreaElement_put_onselect,
360     HTMLTextAreaElement_get_onselect,
361     HTMLTextAreaElement_put_readOnly,
362     HTMLTextAreaElement_get_readOnly,
363     HTMLTextAreaElement_put_rows,
364     HTMLTextAreaElement_get_rows,
365     HTMLTextAreaElement_put_cols,
366     HTMLTextAreaElement_get_cols,
367     HTMLTextAreaElement_put_wrap,
368     HTMLTextAreaElement_get_wrap,
369     HTMLTextAreaElement_createTextRange
370 };
371
372 static inline HTMLTextAreaElement *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
373 {
374     return CONTAINING_RECORD(iface, HTMLTextAreaElement, element.node);
375 }
376
377 static HRESULT HTMLTextAreaElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
378 {
379     HTMLTextAreaElement *This = impl_from_HTMLDOMNode(iface);
380
381     *ppv = NULL;
382
383     if(IsEqualGUID(&IID_IUnknown, riid)) {
384         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
385         *ppv = &This->IHTMLTextAreaElement_iface;
386     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
387         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
388         *ppv = &This->IHTMLTextAreaElement_iface;
389     }else if(IsEqualGUID(&IID_IHTMLTextAreaElement, riid)) {
390         TRACE("(%p)->(IID_IHTMLTextAreaElement %p)\n", This, ppv);
391         *ppv = &This->IHTMLTextAreaElement_iface;
392     }
393
394     if(*ppv) {
395         IUnknown_AddRef((IUnknown*)*ppv);
396         return S_OK;
397     }
398
399     return HTMLElement_QI(&This->element.node, riid, ppv);
400 }
401
402 static HRESULT HTMLTextAreaElementImpl_put_disabled(HTMLDOMNode *iface, VARIANT_BOOL v)
403 {
404     HTMLTextAreaElement *This = impl_from_HTMLDOMNode(iface);
405     return IHTMLTextAreaElement_put_disabled(&This->IHTMLTextAreaElement_iface, v);
406 }
407
408 static HRESULT HTMLTextAreaElementImpl_get_disabled(HTMLDOMNode *iface, VARIANT_BOOL *p)
409 {
410     HTMLTextAreaElement *This = impl_from_HTMLDOMNode(iface);
411     return IHTMLTextAreaElement_get_disabled(&This->IHTMLTextAreaElement_iface, p);
412 }
413
414 static const NodeImplVtbl HTMLTextAreaElementImplVtbl = {
415     HTMLTextAreaElement_QI,
416     HTMLElement_destructor,
417     HTMLElement_clone,
418     HTMLElement_handle_event,
419     HTMLElement_get_attr_col,
420     NULL,
421     NULL,
422     HTMLTextAreaElementImpl_put_disabled,
423     HTMLTextAreaElementImpl_get_disabled
424 };
425
426 static const tid_t HTMLTextAreaElement_iface_tids[] = {
427     HTMLELEMENT_TIDS,
428     IHTMLTextAreaElement_tid,
429     0
430 };
431
432 static dispex_static_data_t HTMLTextAreaElement_dispex = {
433     NULL,
434     DispHTMLTextAreaElement_tid,
435     NULL,
436     HTMLTextAreaElement_iface_tids
437 };
438
439 HRESULT HTMLTextAreaElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLElement **elem)
440 {
441     HTMLTextAreaElement *ret;
442     nsresult nsres;
443
444     ret = heap_alloc_zero(sizeof(HTMLTextAreaElement));
445     if(!ret)
446         return E_OUTOFMEMORY;
447
448     ret->IHTMLTextAreaElement_iface.lpVtbl = &HTMLTextAreaElementVtbl;
449     ret->element.node.vtbl = &HTMLTextAreaElementImplVtbl;
450
451     HTMLElement_Init(&ret->element, doc, nselem, &HTMLTextAreaElement_dispex);
452
453     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLTextAreaElement,
454                                              (void**)&ret->nstextarea);
455
456     /* Share nstextarea reference with nsnode */
457     assert(nsres == NS_OK && (nsIDOMNode*)ret->nstextarea == ret->element.node.nsnode);
458     nsIDOMNode_Release(ret->element.node.nsnode);
459
460     *elem = &ret->element;
461     return S_OK;
462 }