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