2 * Copyright 2009 Andrew Eikum for CodeWeavers
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.
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.
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
28 #include "wine/debug.h"
30 #include "mshtml_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
34 struct HTMLFormElement
{
37 const IHTMLFormElementVtbl
*lpHTMLFormElementVtbl
;
39 nsIDOMHTMLFormElement
*nsform
;
42 #define HTMLFORM(x) (&(x)->lpHTMLFormElementVtbl)
44 static HRESULT
htmlform_item(HTMLFormElement
*This
, int i
, IDispatch
**ret
)
46 nsIDOMHTMLCollection
*elements
;
52 nsres
= nsIDOMHTMLFormElement_GetElements(This
->nsform
, &elements
);
53 if(NS_FAILED(nsres
)) {
54 FIXME("GetElements failed: 0x%08x\n", nsres
);
58 nsres
= nsIDOMHTMLCollection_Item(elements
, i
, &item
);
59 nsIDOMHTMLCollection_Release(elements
);
60 if(NS_FAILED(nsres
)) {
61 FIXME("Item failed: 0x%08x\n", nsres
);
66 hres
= get_node(This
->element
.node
.doc
, item
, TRUE
, &node
);
70 IHTMLDOMNode_AddRef(HTMLDOMNODE(node
));
71 nsIDOMNode_Release(item
);
72 *ret
= (IDispatch
*)HTMLDOMNODE(node
);
80 #define HTMLFORM_THIS(iface) DEFINE_THIS(HTMLFormElement, HTMLFormElement, iface)
82 static HRESULT WINAPI
HTMLFormElement_QueryInterface(IHTMLFormElement
*iface
,
83 REFIID riid
, void **ppv
)
85 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
87 return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This
->element
.node
), riid
, ppv
);
90 static ULONG WINAPI
HTMLFormElement_AddRef(IHTMLFormElement
*iface
)
92 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
94 return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This
->element
.node
));
97 static ULONG WINAPI
HTMLFormElement_Release(IHTMLFormElement
*iface
)
99 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
101 return IHTMLDOMNode_Release(HTMLDOMNODE(&This
->element
.node
));
104 static HRESULT WINAPI
HTMLFormElement_GetTypeInfoCount(IHTMLFormElement
*iface
, UINT
*pctinfo
)
106 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
107 return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This
->element
.node
.dispex
), pctinfo
);
110 static HRESULT WINAPI
HTMLFormElement_GetTypeInfo(IHTMLFormElement
*iface
, UINT iTInfo
,
111 LCID lcid
, ITypeInfo
**ppTInfo
)
113 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
114 return IDispatchEx_GetTypeInfo(DISPATCHEX(&This
->element
.node
.dispex
), iTInfo
, lcid
, ppTInfo
);
117 static HRESULT WINAPI
HTMLFormElement_GetIDsOfNames(IHTMLFormElement
*iface
, REFIID riid
,
118 LPOLESTR
*rgszNames
, UINT cNames
,
119 LCID lcid
, DISPID
*rgDispId
)
121 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
122 return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This
->element
.node
.dispex
), riid
, rgszNames
, cNames
, lcid
, rgDispId
);
125 static HRESULT WINAPI
HTMLFormElement_Invoke(IHTMLFormElement
*iface
, DISPID dispIdMember
,
126 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
127 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
129 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
130 return IDispatchEx_Invoke(DISPATCHEX(&This
->element
.node
.dispex
), dispIdMember
, riid
, lcid
, wFlags
, pDispParams
,
131 pVarResult
, pExcepInfo
, puArgErr
);
134 static HRESULT WINAPI
HTMLFormElement_put_action(IHTMLFormElement
*iface
, BSTR v
)
136 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
137 nsAString action_str
;
140 TRACE("(%p)->(%s)\n", This
, wine_dbgstr_w(v
));
142 nsAString_InitDepend(&action_str
, v
);
143 nsres
= nsIDOMHTMLFormElement_SetAction(This
->nsform
, &action_str
);
144 nsAString_Finish(&action_str
);
145 if(NS_FAILED(nsres
)) {
146 ERR("SetAction failed: %08x\n", nsres
);
153 static HRESULT WINAPI
HTMLFormElement_get_action(IHTMLFormElement
*iface
, BSTR
*p
)
155 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
156 nsAString action_str
;
160 TRACE("(%p)->(%p)\n", This
, p
);
162 nsAString_Init(&action_str
, NULL
);
163 nsres
= nsIDOMHTMLFormElement_GetAction(This
->nsform
, &action_str
);
164 if(NS_SUCCEEDED(nsres
)) {
165 const PRUnichar
*action
;
166 nsAString_GetData(&action_str
, &action
);
167 hres
= nsuri_to_url(action
, FALSE
, p
);
169 ERR("GetAction failed: %08x\n", nsres
);
176 static HRESULT WINAPI
HTMLFormElement_put_dir(IHTMLFormElement
*iface
, BSTR v
)
178 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
179 FIXME("(%p)->(%s)\n", This
, wine_dbgstr_w(v
));
183 static HRESULT WINAPI
HTMLFormElement_get_dir(IHTMLFormElement
*iface
, BSTR
*p
)
185 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
186 FIXME("(%p)->(%p)\n", This
, p
);
190 static HRESULT WINAPI
HTMLFormElement_put_encoding(IHTMLFormElement
*iface
, BSTR v
)
192 static const WCHAR urlencodedW
[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
193 'x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
194 static const WCHAR dataW
[] = {'m','u','l','t','i','p','a','r','t','/',
195 'f','o','r','m','-','d','a','t','a',0};
196 static const WCHAR plainW
[] = {'t','e','x','t','/','p','l','a','i','n',0};
198 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
199 nsAString encoding_str
;
202 TRACE("(%p)->(%s)\n", This
, wine_dbgstr_w(v
));
204 if(lstrcmpiW(v
, urlencodedW
) && lstrcmpiW(v
, dataW
) && lstrcmpiW(v
, plainW
)) {
205 WARN("incorrect enctype\n");
209 nsAString_InitDepend(&encoding_str
, v
);
210 nsres
= nsIDOMHTMLFormElement_SetEnctype(This
->nsform
, &encoding_str
);
211 nsAString_Finish(&encoding_str
);
218 static HRESULT WINAPI
HTMLFormElement_get_encoding(IHTMLFormElement
*iface
, BSTR
*p
)
220 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
221 nsAString encoding_str
;
224 TRACE("(%p)->(%p)\n", This
, p
);
226 nsAString_Init(&encoding_str
, NULL
);
227 nsres
= nsIDOMHTMLFormElement_GetEnctype(This
->nsform
, &encoding_str
);
228 if(NS_SUCCEEDED(nsres
)) {
229 const PRUnichar
*encoding
;
230 nsAString_GetData(&encoding_str
, &encoding
);
232 *p
= SysAllocString(encoding
);
234 return E_OUTOFMEMORY
;
241 static HRESULT WINAPI
HTMLFormElement_put_method(IHTMLFormElement
*iface
, BSTR v
)
243 static const WCHAR postW
[] = {'P','O','S','T',0};
244 static const WCHAR getW
[] = {'G','E','T',0};
246 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
247 nsAString method_str
;
250 TRACE("(%p)->(%s)\n", This
, wine_dbgstr_w(v
));
252 if(lstrcmpiW(v
, postW
) && lstrcmpiW(v
, getW
)) {
253 WARN("unrecognized method\n");
257 nsAString_InitDepend(&method_str
, v
);
258 nsres
= nsIDOMHTMLFormElement_SetMethod(This
->nsform
, &method_str
);
259 nsAString_Finish(&method_str
);
266 static HRESULT WINAPI
HTMLFormElement_get_method(IHTMLFormElement
*iface
, BSTR
*p
)
268 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
269 nsAString method_str
;
272 TRACE("(%p)->(%p)\n", This
, p
);
274 nsAString_Init(&method_str
, NULL
);
275 nsres
= nsIDOMHTMLFormElement_GetMethod(This
->nsform
, &method_str
);
276 if(NS_SUCCEEDED(nsres
)) {
277 const PRUnichar
*method
;
278 nsAString_GetData(&method_str
, &method
);
280 *p
= SysAllocString(method
);
282 return E_OUTOFMEMORY
;
289 static HRESULT WINAPI
HTMLFormElement_get_elements(IHTMLFormElement
*iface
, IDispatch
**p
)
291 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
292 FIXME("(%p)->(%p)\n", This
, p
);
296 static HRESULT WINAPI
HTMLFormElement_put_target(IHTMLFormElement
*iface
, BSTR v
)
298 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
299 FIXME("(%p)->(%s)\n", This
, wine_dbgstr_w(v
));
303 static HRESULT WINAPI
HTMLFormElement_get_target(IHTMLFormElement
*iface
, BSTR
*p
)
305 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
306 FIXME("(%p)->(%p)\n", This
, p
);
310 static HRESULT WINAPI
HTMLFormElement_put_name(IHTMLFormElement
*iface
, BSTR v
)
312 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
316 TRACE("(%p)->(%s)\n", This
, wine_dbgstr_w(v
));
318 nsAString_InitDepend(&name_str
, v
);
319 nsres
= nsIDOMHTMLFormElement_SetName(This
->nsform
, &name_str
);
320 nsAString_Finish(&name_str
);
327 static HRESULT WINAPI
HTMLFormElement_get_name(IHTMLFormElement
*iface
, BSTR
*p
)
329 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
333 TRACE("(%p)->(%p)\n", This
, p
);
335 nsAString_Init(&name_str
, NULL
);
336 nsres
= nsIDOMHTMLFormElement_GetName(This
->nsform
, &name_str
);
337 if(NS_SUCCEEDED(nsres
)) {
338 const PRUnichar
*name
;
339 nsAString_GetData(&name_str
, &name
);
342 *p
= SysAllocString(name
);
344 return E_OUTOFMEMORY
;
353 static HRESULT WINAPI
HTMLFormElement_put_onsubmit(IHTMLFormElement
*iface
, VARIANT v
)
355 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
356 FIXME("(%p)->(v)\n", This
);
360 static HRESULT WINAPI
HTMLFormElement_get_onsubmit(IHTMLFormElement
*iface
, VARIANT
*p
)
362 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
363 FIXME("(%p)->(%p)\n", This
, p
);
367 static HRESULT WINAPI
HTMLFormElement_put_onreset(IHTMLFormElement
*iface
, VARIANT v
)
369 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
370 FIXME("(%p)->(v)\n", This
);
374 static HRESULT WINAPI
HTMLFormElement_get_onreset(IHTMLFormElement
*iface
, VARIANT
*p
)
376 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
377 FIXME("(%p)->(%p)\n", This
, p
);
381 static HRESULT WINAPI
HTMLFormElement_submit(IHTMLFormElement
*iface
)
383 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
384 FIXME("(%p)->()\n", This
);
388 static HRESULT WINAPI
HTMLFormElement_reset(IHTMLFormElement
*iface
)
390 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
391 FIXME("(%p)->()\n", This
);
395 static HRESULT WINAPI
HTMLFormElement_put_length(IHTMLFormElement
*iface
, LONG v
)
397 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
398 FIXME("(%p)->(%d)\n", This
, v
);
402 static HRESULT WINAPI
HTMLFormElement_get_length(IHTMLFormElement
*iface
, LONG
*p
)
404 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
408 TRACE("(%p)->(%p)\n", This
, p
);
410 nsres
= nsIDOMHTMLFormElement_GetLength(This
->nsform
, &length
);
411 if(NS_FAILED(nsres
)) {
412 ERR("GetLength failed: %08x\n", nsres
);
420 static HRESULT WINAPI
HTMLFormElement__newEnum(IHTMLFormElement
*iface
, IUnknown
**p
)
422 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
423 FIXME("(%p)->(%p)\n", This
, p
);
427 static HRESULT WINAPI
HTMLFormElement_item(IHTMLFormElement
*iface
, VARIANT name
,
428 VARIANT index
, IDispatch
**pdisp
)
430 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
432 TRACE("(%p)->(%s %s %p)\n", This
, debugstr_variant(&name
), debugstr_variant(&index
), pdisp
);
438 if(V_VT(&name
) == VT_I4
) {
441 return htmlform_item(This
, V_I4(&name
), pdisp
);
444 FIXME("Unsupported args\n");
448 static HRESULT WINAPI
HTMLFormElement_tags(IHTMLFormElement
*iface
, VARIANT tagName
,
451 HTMLFormElement
*This
= HTMLFORM_THIS(iface
);
452 FIXME("(%p)->(v %p)\n", This
, pdisp
);
458 static const IHTMLFormElementVtbl HTMLFormElementVtbl
= {
459 HTMLFormElement_QueryInterface
,
460 HTMLFormElement_AddRef
,
461 HTMLFormElement_Release
,
462 HTMLFormElement_GetTypeInfoCount
,
463 HTMLFormElement_GetTypeInfo
,
464 HTMLFormElement_GetIDsOfNames
,
465 HTMLFormElement_Invoke
,
466 HTMLFormElement_put_action
,
467 HTMLFormElement_get_action
,
468 HTMLFormElement_put_dir
,
469 HTMLFormElement_get_dir
,
470 HTMLFormElement_put_encoding
,
471 HTMLFormElement_get_encoding
,
472 HTMLFormElement_put_method
,
473 HTMLFormElement_get_method
,
474 HTMLFormElement_get_elements
,
475 HTMLFormElement_put_target
,
476 HTMLFormElement_get_target
,
477 HTMLFormElement_put_name
,
478 HTMLFormElement_get_name
,
479 HTMLFormElement_put_onsubmit
,
480 HTMLFormElement_get_onsubmit
,
481 HTMLFormElement_put_onreset
,
482 HTMLFormElement_get_onreset
,
483 HTMLFormElement_submit
,
484 HTMLFormElement_reset
,
485 HTMLFormElement_put_length
,
486 HTMLFormElement_get_length
,
487 HTMLFormElement__newEnum
,
488 HTMLFormElement_item
,
492 #define HTMLFORM_NODE_THIS(iface) DEFINE_THIS2(HTMLFormElement, element.node, iface)
494 static HRESULT
HTMLFormElement_QI(HTMLDOMNode
*iface
, REFIID riid
, void **ppv
)
496 HTMLFormElement
*This
= HTMLFORM_NODE_THIS(iface
);
500 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
501 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
502 *ppv
= HTMLFORM(This
);
503 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
504 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
505 *ppv
= HTMLFORM(This
);
506 }else if(IsEqualGUID(&IID_IHTMLFormElement
, riid
)) {
507 TRACE("(%p)->(IID_IHTMLFormElement %p)\n", This
, ppv
);
508 *ppv
= HTMLFORM(This
);
512 IUnknown_AddRef((IUnknown
*)*ppv
);
516 return HTMLElement_QI(&This
->element
.node
, riid
, ppv
);
519 static void HTMLFormElement_destructor(HTMLDOMNode
*iface
)
521 HTMLFormElement
*This
= HTMLFORM_NODE_THIS(iface
);
524 nsIDOMHTMLFormElement_Release(This
->nsform
);
526 HTMLElement_destructor(&This
->element
.node
);
529 static HRESULT
HTMLFormElement_get_dispid(HTMLDOMNode
*iface
,
530 BSTR name
, DWORD grfdex
, DISPID
*pid
)
532 HTMLFormElement
*This
= HTMLFORM_NODE_THIS(iface
);
533 nsIDOMHTMLCollection
*elements
;
534 nsAString nsname
, nsstr
;
537 HRESULT hres
= DISP_E_UNKNOWNNAME
;
539 static const PRUnichar nameW
[] = {'n','a','m','e',0};
541 TRACE("(%p)->(%s %x %p)\n", This
, wine_dbgstr_w(name
), grfdex
, pid
);
543 nsres
= nsIDOMHTMLFormElement_GetElements(This
->nsform
, &elements
);
544 if(NS_FAILED(nsres
)) {
545 FIXME("GetElements failed: 0x%08x\n", nsres
);
549 nsres
= nsIDOMHTMLCollection_GetLength(elements
, &len
);
550 if(NS_FAILED(nsres
)) {
551 FIXME("GetLength failed: 0x%08x\n", nsres
);
552 nsIDOMHTMLCollection_Release(elements
);
556 nsAString_InitDepend(&nsname
, nameW
);
557 nsAString_Init(&nsstr
, NULL
);
558 for(i
= 0; i
< len
; ++i
) {
560 nsIDOMHTMLElement
*nshtml_elem
;
561 const PRUnichar
*str
;
563 nsres
= nsIDOMHTMLCollection_Item(elements
, i
, &nsitem
);
564 if(NS_FAILED(nsres
)) {
565 FIXME("Item failed: 0x%08x\n", nsres
);
570 nsres
= nsIDOMNode_QueryInterface(nsitem
, &IID_nsIDOMHTMLElement
, (void**)&nshtml_elem
);
571 nsIDOMNode_Release(nsitem
);
572 if(NS_FAILED(nsres
)) {
573 FIXME("Failed to get nsIDOMHTMLNode interface: 0x%08x\n", nsres
);
578 /* compare by id attr */
579 nsres
= nsIDOMHTMLElement_GetId(nshtml_elem
, &nsstr
);
580 if(NS_FAILED(nsres
)) {
581 FIXME("GetId failed: 0x%08x\n", nsres
);
582 nsIDOMHTMLElement_Release(nshtml_elem
);
586 nsAString_GetData(&nsstr
, &str
);
587 if(!strcmpiW(str
, name
)) {
588 nsIDOMHTMLElement_Release(nshtml_elem
);
589 /* FIXME: using index for dispid */
590 *pid
= MSHTML_DISPID_CUSTOM_MIN
+ i
;
595 /* compare by name attr */
596 nsres
= nsIDOMHTMLElement_GetAttribute(nshtml_elem
, &nsname
, &nsstr
);
597 nsIDOMHTMLElement_Release(nshtml_elem
);
598 nsAString_GetData(&nsstr
, &str
);
599 if(!strcmpiW(str
, name
)) {
600 /* FIXME: using index for dispid */
601 *pid
= MSHTML_DISPID_CUSTOM_MIN
+ i
;
606 nsAString_Finish(&nsname
);
607 nsAString_Finish(&nsstr
);
609 nsIDOMHTMLCollection_Release(elements
);
614 static HRESULT
HTMLFormElement_invoke(HTMLDOMNode
*iface
,
615 DISPID id
, LCID lcid
, WORD flags
, DISPPARAMS
*params
, VARIANT
*res
,
616 EXCEPINFO
*ei
, IServiceProvider
*caller
)
618 HTMLFormElement
*This
= HTMLFORM_NODE_THIS(iface
);
622 TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This
, id
, lcid
, flags
, params
, res
, ei
, caller
);
624 hres
= htmlform_item(This
, id
- MSHTML_DISPID_CUSTOM_MIN
, &ret
);
629 V_VT(res
) = VT_DISPATCH
;
630 V_DISPATCH(res
) = ret
;
637 #undef HTMLFORM_NODE_THIS
639 static const NodeImplVtbl HTMLFormElementImplVtbl
= {
641 HTMLFormElement_destructor
,
649 HTMLFormElement_get_dispid
,
650 HTMLFormElement_invoke
653 static const tid_t HTMLFormElement_iface_tids
[] = {
655 IHTMLFormElement_tid
,
659 static dispex_static_data_t HTMLFormElement_dispex
= {
661 DispHTMLFormElement_tid
,
663 HTMLFormElement_iface_tids
666 HRESULT
HTMLFormElement_Create(HTMLDocumentNode
*doc
, nsIDOMHTMLElement
*nselem
, HTMLElement
**elem
)
668 HTMLFormElement
*ret
;
671 ret
= heap_alloc_zero(sizeof(HTMLFormElement
));
673 return E_OUTOFMEMORY
;
675 ret
->lpHTMLFormElementVtbl
= &HTMLFormElementVtbl
;
676 ret
->element
.node
.vtbl
= &HTMLFormElementImplVtbl
;
678 nsres
= nsIDOMHTMLElement_QueryInterface(nselem
, &IID_nsIDOMHTMLFormElement
, (void**)&ret
->nsform
);
679 if(NS_FAILED(nsres
)) {
680 ERR("Could not get nsIDOMHTMLFormElement interface: %08x\n", nsres
);
685 HTMLElement_Init(&ret
->element
, doc
, nselem
, &HTMLFormElement_dispex
);
687 *elem
= &ret
->element
;