2 * Copyright 2010 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
19 #include "mshtml_private.h"
22 IPropertyBag IPropertyBag_iface
;
23 IPropertyBag2 IPropertyBag2_iface
;
36 static void free_prop(param_prop_t
*prop
)
38 list_remove(&prop
->entry
);
40 heap_free(prop
->name
);
41 heap_free(prop
->value
);
45 static param_prop_t
*find_prop(PropertyBag
*prop_bag
, const WCHAR
*name
)
49 LIST_FOR_EACH_ENTRY(iter
, &prop_bag
->props
, param_prop_t
, entry
) {
50 if(!strcmpiW(iter
->name
, name
))
57 static HRESULT
add_prop(PropertyBag
*prop_bag
, const WCHAR
*name
, const WCHAR
*value
)
64 TRACE("%p %s %s\n", prop_bag
, debugstr_w(name
), debugstr_w(value
));
66 prop
= heap_alloc(sizeof(*prop
));
70 prop
->name
= heap_strdupW(name
);
71 prop
->value
= heap_strdupW(value
);
72 if(!prop
->name
|| !prop
->value
) {
73 list_init(&prop
->entry
);
78 list_add_tail(&prop_bag
->props
, &prop
->entry
);
82 static inline PropertyBag
*impl_from_IPropertyBag(IPropertyBag
*iface
)
84 return CONTAINING_RECORD(iface
, PropertyBag
, IPropertyBag_iface
);
87 static HRESULT WINAPI
PropertyBag_QueryInterface(IPropertyBag
*iface
, REFIID riid
, void **ppv
)
89 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
91 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
92 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
93 *ppv
= &This
->IPropertyBag_iface
;
94 }else if(IsEqualGUID(&IID_IPropertyBag
, riid
)) {
95 TRACE("(%p)->(IID_IPropertyBag %p)\n", This
, ppv
);
96 *ppv
= &This
->IPropertyBag_iface
;
97 }else if(IsEqualGUID(&IID_IPropertyBag2
, riid
)) {
98 TRACE("(%p)->(IID_IPropertyBag2 %p)\n", This
, ppv
);
99 *ppv
= &This
->IPropertyBag2_iface
;
101 WARN("Unsopported interface %s\n", debugstr_guid(riid
));
103 return E_NOINTERFACE
;
106 IUnknown_AddRef((IUnknown
*)*ppv
);
110 static ULONG WINAPI
PropertyBag_AddRef(IPropertyBag
*iface
)
112 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
113 LONG ref
= InterlockedIncrement(&This
->ref
);
115 TRACE("(%p) ref=%d\n", This
, ref
);
120 static ULONG WINAPI
PropertyBag_Release(IPropertyBag
*iface
)
122 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
123 LONG ref
= InterlockedDecrement(&This
->ref
);
125 TRACE("(%p) ref=%d\n", This
, ref
);
128 while(!list_empty(&This
->props
))
129 free_prop(LIST_ENTRY(This
->props
.next
, param_prop_t
, entry
));
136 static HRESULT WINAPI
PropertyBag_Read(IPropertyBag
*iface
, LPCOLESTR pszPropName
, VARIANT
*pVar
, IErrorLog
*pErrorLog
)
138 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
142 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(pszPropName
), pVar
, pErrorLog
);
144 prop
= find_prop(This
, pszPropName
);
146 TRACE("Not found\n");
150 V_BSTR(&v
) = SysAllocString(prop
->value
);
152 return E_OUTOFMEMORY
;
154 if(V_VT(pVar
) != VT_BSTR
) {
158 hres
= VariantChangeType(pVar
, &v
, 0, V_VT(pVar
));
159 SysFreeString(V_BSTR(&v
));
163 V_BSTR(pVar
) = V_BSTR(&v
);
167 static HRESULT WINAPI
PropertyBag_Write(IPropertyBag
*iface
, LPCOLESTR pszPropName
, VARIANT
*pVar
)
169 PropertyBag
*This
= impl_from_IPropertyBag(iface
);
170 FIXME("(%p)->(%s %s)\n", This
, debugstr_w(pszPropName
), debugstr_variant(pVar
));
174 static const IPropertyBagVtbl PropertyBagVtbl
= {
175 PropertyBag_QueryInterface
,
182 static inline PropertyBag
*impl_from_IPropertyBag2(IPropertyBag2
*iface
)
184 return CONTAINING_RECORD(iface
, PropertyBag
, IPropertyBag2_iface
);
187 static HRESULT WINAPI
PropertyBag2_QueryInterface(IPropertyBag2
*iface
, REFIID riid
, void **ppv
)
189 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
190 return IPropertyBag_QueryInterface(&This
->IPropertyBag_iface
, riid
, ppv
);
193 static ULONG WINAPI
PropertyBag2_AddRef(IPropertyBag2
*iface
)
195 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
196 return IPropertyBag_AddRef(&This
->IPropertyBag_iface
);
199 static ULONG WINAPI
PropertyBag2_Release(IPropertyBag2
*iface
)
201 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
202 return IPropertyBag_Release(&This
->IPropertyBag_iface
);
205 static HRESULT WINAPI
PropertyBag2_Read(IPropertyBag2
*iface
, ULONG cProperties
, PROPBAG2
*pPropBag
,
206 IErrorLog
*pErrLog
, VARIANT
*pvarValue
, HRESULT
*phrError
)
208 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
209 FIXME("(%p)->(%d %p %p %p %p)\n", This
, cProperties
, pPropBag
, pErrLog
, pvarValue
, phrError
);
213 static HRESULT WINAPI
PropertyBag2_Write(IPropertyBag2
*iface
, ULONG cProperties
, PROPBAG2
*pPropBag
, VARIANT
*pvarValue
)
215 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
216 FIXME("(%p)->(%d %p %s)\n", This
, cProperties
, pPropBag
, debugstr_variant(pvarValue
));
220 static HRESULT WINAPI
PropertyBag2_CountProperties(IPropertyBag2
*iface
, ULONG
*pcProperties
)
222 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
223 FIXME("(%p)->(%p)\n", This
, pcProperties
);
227 static HRESULT WINAPI
PropertyBag2_GetPropertyInfo(IPropertyBag2
*iface
, ULONG iProperty
, ULONG cProperties
,
228 PROPBAG2
*pPropBag
, ULONG
*pcProperties
)
230 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
231 FIXME("(%p)->(%u %u %p %p)\n", This
, iProperty
, cProperties
, pPropBag
, pcProperties
);
235 static HRESULT WINAPI
PropertyBag2_LoadObject(IPropertyBag2
*iface
, LPCOLESTR pstrName
, DWORD dwHint
,
236 IUnknown
*pUnkObject
, IErrorLog
*pErrLog
)
238 PropertyBag
*This
= impl_from_IPropertyBag2(iface
);
239 FIXME("(%p)->(%s %x %p %p)\n", This
, debugstr_w(pstrName
), dwHint
, pUnkObject
, pErrLog
);
243 static const IPropertyBag2Vtbl PropertyBag2Vtbl
= {
244 PropertyBag2_QueryInterface
,
246 PropertyBag2_Release
,
249 PropertyBag2_CountProperties
,
250 PropertyBag2_GetPropertyInfo
,
251 PropertyBag2_LoadObject
254 static HRESULT
fill_props(nsIDOMHTMLElement
*nselem
, PropertyBag
*prop_bag
)
256 const PRUnichar
*name
, *value
;
257 nsAString name_str
, value_str
;
258 nsIDOMHTMLCollection
*params
;
259 nsIDOMHTMLElement
*param_elem
;
265 static const PRUnichar nameW
[] = {'n','a','m','e',0};
266 static const PRUnichar paramW
[] = {'p','a','r','a','m',0};
267 static const PRUnichar valueW
[] = {'v','a','l','u','e',0};
269 nsAString_InitDepend(&name_str
, paramW
);
270 nsres
= nsIDOMHTMLElement_GetElementsByTagName(nselem
, &name_str
, ¶ms
);
271 nsAString_Finish(&name_str
);
275 nsres
= nsIDOMHTMLCollection_GetLength(params
, &length
);
279 for(i
=0; i
< length
; i
++) {
280 nsres
= nsIDOMHTMLCollection_Item(params
, i
, &nsnode
);
281 if(NS_FAILED(nsres
)) {
286 nsres
= nsIDOMNode_QueryInterface(nsnode
, &IID_nsIDOMHTMLElement
, (void**)¶m_elem
);
287 nsIDOMNode_Release(nsnode
);
288 if(NS_FAILED(nsres
)) {
293 nsres
= get_elem_attr_value(param_elem
, nameW
, &name_str
, &name
);
294 if(NS_SUCCEEDED(nsres
)) {
295 nsres
= get_elem_attr_value(param_elem
, valueW
, &value_str
, &value
);
296 if(NS_SUCCEEDED(nsres
)) {
297 hres
= add_prop(prop_bag
, name
, value
);
298 nsAString_Finish(&value_str
);
301 nsAString_Finish(&name_str
);
304 nsIDOMHTMLElement_Release(param_elem
);
307 if(NS_FAILED(nsres
)) {
313 nsIDOMHTMLCollection_Release(params
);
317 HRESULT
create_param_prop_bag(nsIDOMHTMLElement
*nselem
, IPropertyBag
**ret
)
319 PropertyBag
*prop_bag
;
322 prop_bag
= heap_alloc(sizeof(*prop_bag
));
324 return E_OUTOFMEMORY
;
326 prop_bag
->IPropertyBag_iface
.lpVtbl
= &PropertyBagVtbl
;
327 prop_bag
->IPropertyBag2_iface
.lpVtbl
= &PropertyBag2Vtbl
;
330 list_init(&prop_bag
->props
);
331 hres
= fill_props(nselem
, prop_bag
);
332 if(FAILED(hres
) || list_empty(&prop_bag
->props
)) {
333 IPropertyBag_Release(&prop_bag
->IPropertyBag_iface
);
338 *ret
= &prop_bag
->IPropertyBag_iface
;