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