Jacek Caban : mshtml: Better removeAttribute implementation.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Nov 28 12:49:04 CST 2014
Module: wine
Branch: master
Commit: 5f913d5afbe218bbba1ced89467540757a519c76
URL: http://source.winehq.org/git/wine.git/?a=commit;h=5f913d5afbe218bbba1ced89467540757a519c76
Author: Jacek Caban <jacek at codeweavers.com>
Date: Fri Nov 28 16:19:04 2014 +0100
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 1f1204a..707fe7f 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 1140776..a24d497 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 d9898a9..45e5b9a 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 07d1564..497a9e1 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;
More information about the wine-cvs
mailing list