mscoree: Factor out common code for calling .NET methods.
[wine.git] / dlls / mshtml / htmlattr.c
blob420a275af47da66f6314cb6148af89d8eeb24b25
1 /*
2 * Copyright 2011 Jacek Caban 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
20 #include <stdarg.h>
21 #include <assert.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "ole2.h"
30 #include "mshtml_private.h"
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
36 static inline HTMLDOMAttribute *impl_from_IHTMLDOMAttribute(IHTMLDOMAttribute *iface)
38 return CONTAINING_RECORD(iface, HTMLDOMAttribute, IHTMLDOMAttribute_iface);
41 static HRESULT WINAPI HTMLDOMAttribute_QueryInterface(IHTMLDOMAttribute *iface,
42 REFIID riid, void **ppv)
44 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
46 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
48 if(IsEqualGUID(&IID_IUnknown, riid)) {
49 *ppv = &This->IHTMLDOMAttribute_iface;
50 }else if(IsEqualGUID(&IID_IHTMLDOMAttribute, riid)) {
51 *ppv = &This->IHTMLDOMAttribute_iface;
52 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
53 return *ppv ? S_OK : E_NOINTERFACE;
54 }else {
55 WARN("%s not supported\n", debugstr_mshtml_guid(riid));
56 *ppv = NULL;
57 return E_NOINTERFACE;
60 IUnknown_AddRef((IUnknown*)*ppv);
61 return S_OK;
64 static ULONG WINAPI HTMLDOMAttribute_AddRef(IHTMLDOMAttribute *iface)
66 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
67 LONG ref = InterlockedIncrement(&This->ref);
69 TRACE("(%p) ref=%d\n", This, ref);
71 return ref;
74 static ULONG WINAPI HTMLDOMAttribute_Release(IHTMLDOMAttribute *iface)
76 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
77 LONG ref = InterlockedDecrement(&This->ref);
79 TRACE("(%p) ref=%d\n", This, ref);
81 if(!ref) {
82 assert(!This->elem);
83 release_dispex(&This->dispex);
84 heap_free(This->name);
85 heap_free(This);
88 return ref;
91 static HRESULT WINAPI HTMLDOMAttribute_GetTypeInfoCount(IHTMLDOMAttribute *iface, UINT *pctinfo)
93 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
94 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
97 static HRESULT WINAPI HTMLDOMAttribute_GetTypeInfo(IHTMLDOMAttribute *iface, UINT iTInfo,
98 LCID lcid, ITypeInfo **ppTInfo)
100 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
101 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
104 static HRESULT WINAPI HTMLDOMAttribute_GetIDsOfNames(IHTMLDOMAttribute *iface, REFIID riid,
105 LPOLESTR *rgszNames, UINT cNames,
106 LCID lcid, DISPID *rgDispId)
108 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
109 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
110 lcid, rgDispId);
113 static HRESULT WINAPI HTMLDOMAttribute_Invoke(IHTMLDOMAttribute *iface, DISPID dispIdMember,
114 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
115 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
117 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
118 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
119 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
122 static HRESULT WINAPI HTMLDOMAttribute_get_nodeName(IHTMLDOMAttribute *iface, BSTR *p)
124 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
126 TRACE("(%p)->(%p)\n", This, p);
128 if(!This->elem) {
129 if(!This->name) {
130 FIXME("No name available\n");
131 return E_FAIL;
134 *p = SysAllocString(This->name);
135 return *p ? S_OK : E_OUTOFMEMORY;
138 return IDispatchEx_GetMemberName(&This->elem->node.dispex.IDispatchEx_iface, This->dispid, p);
141 static HRESULT WINAPI HTMLDOMAttribute_put_nodeName(IHTMLDOMAttribute *iface, VARIANT v)
143 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
144 FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
145 return E_NOTIMPL;
148 static HRESULT WINAPI HTMLDOMAttribute_get_nodeValue(IHTMLDOMAttribute *iface, VARIANT *p)
150 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
151 DISPPARAMS dp = {NULL, NULL, 0, 0};
152 EXCEPINFO ei;
154 TRACE("(%p)->(%p)\n", This, p);
156 if(!This->elem) {
157 FIXME("NULL This->elem\n");
158 return E_UNEXPECTED;
161 memset(&ei, 0, sizeof(ei));
162 return IDispatchEx_InvokeEx(&This->elem->node.dispex.IDispatchEx_iface, This->dispid, LOCALE_SYSTEM_DEFAULT,
163 DISPATCH_PROPERTYGET, &dp, p, &ei, NULL);
166 static HRESULT WINAPI HTMLDOMAttribute_get_specified(IHTMLDOMAttribute *iface, VARIANT_BOOL *p)
168 HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
169 nsIDOMAttr *nsattr;
170 nsAString nsname;
171 BSTR name;
172 nsresult nsres;
173 HRESULT hres;
175 TRACE("(%p)->(%p)\n", This, p);
177 if(!This->elem || !This->elem->nselem) {
178 FIXME("NULL This->elem\n");
179 return E_UNEXPECTED;
182 if(get_dispid_type(This->dispid) != DISPEXPROP_BUILTIN) {
183 *p = VARIANT_TRUE;
184 return S_OK;
187 hres = IDispatchEx_GetMemberName(&This->elem->node.dispex.IDispatchEx_iface, This->dispid, &name);
188 if(FAILED(hres))
189 return hres;
191 /* FIXME: This is not exactly right, we have some attributes that don't map directly to Gecko attributes. */
192 nsAString_InitDepend(&nsname, name);
193 nsres = nsIDOMHTMLElement_GetAttributeNode(This->elem->nselem, &nsname, &nsattr);
194 nsAString_Finish(&nsname);
195 SysFreeString(name);
196 if(NS_FAILED(nsres))
197 return E_FAIL;
199 /* If the Gecko attribute node can be found, we know that the attribute is specified.
200 There is no point in calling GetSpecified */
201 if(nsattr) {
202 nsIDOMAttr_Release(nsattr);
203 *p = VARIANT_TRUE;
204 }else {
205 *p = VARIANT_FALSE;
207 return S_OK;
210 static const IHTMLDOMAttributeVtbl HTMLDOMAttributeVtbl = {
211 HTMLDOMAttribute_QueryInterface,
212 HTMLDOMAttribute_AddRef,
213 HTMLDOMAttribute_Release,
214 HTMLDOMAttribute_GetTypeInfoCount,
215 HTMLDOMAttribute_GetTypeInfo,
216 HTMLDOMAttribute_GetIDsOfNames,
217 HTMLDOMAttribute_Invoke,
218 HTMLDOMAttribute_get_nodeName,
219 HTMLDOMAttribute_put_nodeName,
220 HTMLDOMAttribute_get_nodeValue,
221 HTMLDOMAttribute_get_specified
224 static const tid_t HTMLDOMAttribute_iface_tids[] = {
225 IHTMLDOMAttribute_tid,
228 static dispex_static_data_t HTMLDOMAttribute_dispex = {
229 NULL,
230 DispHTMLDOMAttribute_tid,
232 HTMLDOMAttribute_iface_tids
235 HRESULT HTMLDOMAttribute_Create(const WCHAR *name, HTMLElement *elem, DISPID dispid, HTMLDOMAttribute **attr)
237 HTMLAttributeCollection *col;
238 HTMLDOMAttribute *ret;
239 HRESULT hres;
241 ret = heap_alloc_zero(sizeof(*ret));
242 if(!ret)
243 return E_OUTOFMEMORY;
245 ret->IHTMLDOMAttribute_iface.lpVtbl = &HTMLDOMAttributeVtbl;
246 ret->ref = 1;
247 ret->dispid = dispid;
248 ret->elem = elem;
250 init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLDOMAttribute_iface,
251 &HTMLDOMAttribute_dispex);
253 /* For attributes attached to an element, (elem,dispid) pair should be valid used for its operation. */
254 if(elem) {
255 hres = HTMLElement_get_attr_col(&elem->node, &col);
256 if(FAILED(hres)) {
257 IHTMLDOMAttribute_Release(&ret->IHTMLDOMAttribute_iface);
258 return hres;
260 IHTMLAttributeCollection_Release(&col->IHTMLAttributeCollection_iface);
262 list_add_tail(&elem->attrs->attrs, &ret->entry);
265 /* For detached attributes we may still do most operations if we have its name available. */
266 if(name) {
267 ret->name = heap_strdupW(name);
268 if(!ret->name) {
269 IHTMLDOMAttribute_Release(&ret->IHTMLDOMAttribute_iface);
270 return E_OUTOFMEMORY;
274 *attr = ret;
275 return S_OK;