From 5f913d5afbe218bbba1ced89467540757a519c76 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 28 Nov 2014 16:19:04 +0100 Subject: [PATCH] mshtml: Better removeAttribute implementation. --- dlls/mshtml/dispex.c | 80 +++++++++++++++++++++++++++++++------------- dlls/mshtml/htmlelem.c | 13 ++++++- dlls/mshtml/htmlstyle.c | 2 +- dlls/mshtml/mshtml_private.h | 2 +- 4 files changed, 71 insertions(+), 26 deletions(-) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 1f1204ad618..707fe7f0200 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -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; + + case DISPEXPROP_DYNAMIC: { + DWORD idx = id - DISPID_DYNPROP_0; + dynamic_prop_t *prop; - hres = get_builtin_id(This, name, 0, &id); - if(hres == S_OK) { - DISPID named_id = DISPID_PROPERTYPUT; + 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) diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 1140776455a..a24d4971efa 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -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) diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index d9898a922fe..45e5b9a3e33 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -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; } diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 07d15640ec8..497a9e1512a 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -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; -- 2.11.4.GIT