mshtml: Better removeAttribute implementation.

This commit is contained in:
Jacek Caban 2014-11-28 16:19:04 +01:00 committed by Alexandre Julliard
parent 275a231fbb
commit 5f913d5afb
4 changed files with 71 additions and 26 deletions

View File

@ -1261,41 +1261,75 @@ static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD
return hres;
}
HRESULT remove_prop(DispatchEx *This, BSTR name, VARIANT_BOOL *success)
HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
{
dynamic_prop_t *prop;
DISPID id;
HRESULT hres;
switch(get_dispid_type(id)) {
case DISPEXPROP_CUSTOM:
FIXME("DISPEXPROP_CUSTOM not supported\n");
return E_NOTIMPL;
hres = get_builtin_id(This, name, 0, &id);
if(hres == S_OK) {
DISPID named_id = DISPID_PROPERTYPUT;
case DISPEXPROP_DYNAMIC: {
DWORD idx = id - DISPID_DYNPROP_0;
dynamic_prop_t *prop;
prop = This->dynamic_data->props+idx;
VariantClear(&prop->var);
prop->flags |= DYNPROP_DELETED;
*success = VARIANT_TRUE;
return S_OK;
}
case DISPEXPROP_BUILTIN: {
VARIANT var;
DISPPARAMS dp = {&var,&named_id,1,1};
EXCEPINFO ei;
DISPPARAMS dp = {&var,NULL,1,0};
dispex_data_t *data;
func_info_t *func;
HRESULT hres;
data = get_dispex_data(This);
if(!data)
return E_FAIL;
hres = get_builtin_func(data, id, &func);
if(FAILED(hres))
return hres;
/* For builtin functions, we set their value to the original function. */
if(func->func_disp_idx != -1) {
func_obj_entry_t *entry;
if(!This->dynamic_data || !This->dynamic_data->func_disps
|| !This->dynamic_data->func_disps[func->func_disp_idx].func_obj) {
*success = VARIANT_FALSE;
return S_OK;
}
entry = This->dynamic_data->func_disps + func->func_disp_idx;
if(V_VT(&entry->val) == VT_DISPATCH
&& V_DISPATCH(&entry->val) == (IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface) {
*success = VARIANT_FALSE;
return S_OK;
}
VariantClear(&entry->val);
V_VT(&entry->val) = VT_DISPATCH;
V_DISPATCH(&entry->val) = (IDispatch*)&entry->func_obj->dispex.IDispatchEx_iface;
IDispatch_AddRef(V_DISPATCH(&entry->val));
*success = VARIANT_TRUE;
return S_OK;
}
V_VT(&var) = VT_EMPTY;
memset(&ei, 0, sizeof(ei));
hres = invoke_builtin_prop(This, id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
hres = builtin_propput(This, func, &dp, NULL);
if(FAILED(hres))
return hres;
*success = VARIANT_TRUE;
return S_OK;
}
hres = get_dynamic_prop(This, name, 0, &prop);
if(FAILED(hres)) {
if(hres != DISP_E_UNKNOWNNAME)
return hres;
*success = VARIANT_FALSE;
return S_OK;
default:
assert(0);
return E_FAIL;
}
VariantClear(&prop->var);
prop->flags |= DYNPROP_DELETED;
*success = VARIANT_TRUE;
return S_OK;
}
static inline DispatchEx *impl_from_IDispatchEx(IDispatchEx *iface)

View File

@ -664,10 +664,21 @@ static HRESULT WINAPI HTMLElement_removeAttribute(IHTMLElement *iface, BSTR strA
LONG lFlags, VARIANT_BOOL *pfSuccess)
{
HTMLElement *This = impl_from_IHTMLElement(iface);
DISPID id;
HRESULT hres;
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(strAttributeName), lFlags, pfSuccess);
return remove_prop(&This->node.dispex, strAttributeName, pfSuccess);
hres = IDispatchEx_GetDispID(&This->node.dispex.IDispatchEx_iface, strAttributeName,
lFlags&1 ? fdexNameCaseSensitive : fdexNameCaseInsensitive, &id);
if(hres == DISP_E_UNKNOWNNAME) {
*pfSuccess = VARIANT_FALSE;
return S_OK;
}
if(FAILED(hres))
return hres;
return remove_attribute(&This->node.dispex, id, pfSuccess);
}
static HRESULT WINAPI HTMLElement_put_className(IHTMLElement *iface, BSTR v)

View File

@ -2915,7 +2915,7 @@ static HRESULT WINAPI HTMLStyle_removeAttribute(IHTMLStyle *iface, BSTR strAttri
}
if(i == sizeof(style_tbl)/sizeof(*style_tbl))
return remove_prop(&This->dispex, strAttributeName, pfSuccess);
return remove_attribute(&This->dispex, dispid, pfSuccess);
style_entry = style_tbl+i;
}

View File

@ -278,7 +278,7 @@ void release_dispex(DispatchEx*) DECLSPEC_HIDDEN;
BOOL dispex_query_interface(DispatchEx*,REFIID,void**) DECLSPEC_HIDDEN;
HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**) DECLSPEC_HIDDEN;
HRESULT get_dispids(tid_t,DWORD*,DISPID**) DECLSPEC_HIDDEN;
HRESULT remove_prop(DispatchEx*,BSTR,VARIANT_BOOL*) DECLSPEC_HIDDEN;
HRESULT remove_attribute(DispatchEx*,DISPID,VARIANT_BOOL*) DECLSPEC_HIDDEN;
HRESULT dispex_get_dynid(DispatchEx*,const WCHAR*,DISPID*) DECLSPEC_HIDDEN;
void dispex_traverse(DispatchEx*,nsCycleCollectionTraversalCallback*) DECLSPEC_HIDDEN;
void dispex_unlink(DispatchEx*) DECLSPEC_HIDDEN;