Jacek Caban : mshtml: Added IHTMLElement::removeAttribute implementation.

Alexandre Julliard julliard at winehq.org
Wed Mar 24 15:54:45 CDT 2010


Module: wine
Branch: master
Commit: 00293e9b0bcee3768fe8a142bd1b73ae9bb92c52
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=00293e9b0bcee3768fe8a142bd1b73ae9bb92c52

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Mar 24 20:34:17 2010 +0100

mshtml: Added IHTMLElement::removeAttribute implementation.

---

 dlls/mshtml/dispex.c         |   96 ++++++++++++++++++++++++++++++++++--------
 dlls/mshtml/htmlelem.c       |    6 ++-
 dlls/mshtml/mshtml_private.h |    1 +
 3 files changed, 83 insertions(+), 20 deletions(-)

diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
index c5e6de2..3917b30 100644
--- a/dlls/mshtml/dispex.c
+++ b/dlls/mshtml/dispex.c
@@ -52,8 +52,11 @@ struct dispex_data_t {
 typedef struct {
     VARIANT var;
     LPWSTR name;
+    DWORD flags;
 } dynamic_prop_t;
 
+#define DYNPROP_DELETED    0x01
+
 typedef struct {
     DispatchEx dispex;
     const IUnknownVtbl *lpIUnknownVtbl;
@@ -442,7 +445,7 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags
 {
     const BOOL alloc = flags & fdexNameEnsure;
     dispex_dynamic_data_t *data;
-    unsigned i;
+    dynamic_prop_t *prop;
 
     data = get_dynamic_data(This, alloc);
     if(!data) {
@@ -453,9 +456,14 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags
         return DISP_E_UNKNOWNNAME;
     }
 
-    for(i=0; i < data->prop_cnt; i++) {
-        if(flags & fdexNameCaseInsensitive ? !strcmpiW(data->props[i].name, name) : !strcmpW(data->props[i].name, name)) {
-            *ret = data->props+i;
+    for(prop = data->props; prop < data->props+data->prop_cnt; prop++) {
+        if(flags & fdexNameCaseInsensitive ? !strcmpiW(prop->name, name) : !strcmpW(prop->name, name)) {
+            if(prop->flags & DYNPROP_DELETED) {
+                if(!alloc)
+                    return DISP_E_UNKNOWNNAME;
+                prop->flags &= ~DYNPROP_DELETED;
+            }
+            *ret = prop;
             return S_OK;
         }
     }
@@ -481,10 +489,16 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags
         data->buf_size <<= 1;
     }
 
-    data->props[data->prop_cnt].name = heap_strdupW(name);
-    VariantInit(&data->props[data->prop_cnt].var);
-    *ret = data->props + data->prop_cnt++;
+    prop = data->props + data->prop_cnt;
 
+    prop->name = heap_strdupW(name);
+    if(!prop->name)
+        return E_OUTOFMEMORY;
+
+    VariantInit(&prop->var);
+    prop->flags = 0;
+    data->prop_cnt++;
+    *ret = prop;
     return S_OK;
 }
 
@@ -795,6 +809,43 @@ static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD
     return hres;
 }
 
+HRESULT remove_prop(DispatchEx *This, BSTR name, VARIANT_BOOL *success)
+{
+    dynamic_prop_t *prop;
+    DISPID id;
+    HRESULT hres;
+
+    hres = get_builtin_id(This, name, 0, &id);
+    if(hres == S_OK) {
+        DISPID named_id = DISPID_PROPERTYPUT;
+        VARIANT var;
+        DISPPARAMS dp = {&var,&named_id,1,1};
+        EXCEPINFO ei;
+
+        V_VT(&var) = VT_EMPTY;
+        memset(&ei, 0, sizeof(ei));
+        hres = invoke_builtin_prop(This, id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, 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;
+    }
+
+    VariantClear(&prop->var);
+    prop->flags |= DYNPROP_DELETED;
+    *success = VARIANT_TRUE;
+    return S_OK;
+}
+
 #define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface)
 
 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
@@ -926,12 +977,12 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
 
     if(is_dynamic_dispid(id)) {
         DWORD idx = id - DISPID_DYNPROP_0;
-        VARIANT *var;
+        dynamic_prop_t *prop;
 
         if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx)
             return DISP_E_UNKNOWNNAME;
 
-        var = &This->dynamic_data->props[idx].var;
+        prop = This->dynamic_data->props+idx;
 
         switch(wFlags) {
         case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
@@ -942,8 +993,8 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
             DISPPARAMS dp = {NULL, &named_arg, 0, 1};
             IDispatchEx *dispex;
 
-            if(V_VT(var) != VT_DISPATCH) {
-                FIXME("invoke vt %d\n", V_VT(var));
+            if(V_VT(&prop->var) != VT_DISPATCH) {
+                FIXME("invoke %s\n", debugstr_variant(&prop->var));
                 return E_NOTIMPL;
             }
 
@@ -962,14 +1013,14 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
             V_VT(dp.rgvarg) = VT_DISPATCH;
             V_DISPATCH(dp.rgvarg) = (IDispatch*)DISPATCHEX(This);
 
-            hres = IDispatch_QueryInterface(V_DISPATCH(var), &IID_IDispatchEx, (void**)&dispex);
+            hres = IDispatch_QueryInterface(V_DISPATCH(&prop->var), &IID_IDispatchEx, (void**)&dispex);
             TRACE("%s call\n", debugstr_w(This->dynamic_data->props[idx].name));
             if(SUCCEEDED(hres)) {
                 hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, lcid, wFlags, &dp, pvarRes, pei, pspCaller);
                 IDispatchEx_Release(dispex);
             }else {
                 ULONG err = 0;
-                hres = IDispatch_Invoke(V_DISPATCH(var), DISPID_VALUE, &IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &err);
+                hres = IDispatch_Invoke(V_DISPATCH(&prop->var), DISPID_VALUE, &IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &err);
             }
             TRACE("%s ret %08x\n", debugstr_w(This->dynamic_data->props[idx].name), hres);
 
@@ -977,7 +1028,9 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
             return hres;
         }
         case DISPATCH_PROPERTYGET:
-            return VariantCopy(pvarRes, var);
+            if(prop->flags & DYNPROP_DELETED)
+                return DISP_E_UNKNOWNNAME;
+            return VariantCopy(pvarRes, &prop->var);
         case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF:
         case DISPATCH_PROPERTYPUT:
             if(pdp->cArgs != 1 || (pdp->cNamedArgs == 1 && *pdp->rgdispidNamedArgs != DISPID_PROPERTYPUT)
@@ -987,8 +1040,13 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
             }
 
             TRACE("put %s\n", debugstr_variant(pdp->rgvarg));
-            VariantClear(var);
-            return VariantCopy(var, pdp->rgvarg);
+            VariantClear(&prop->var);
+            hres = VariantCopy(&prop->var, pdp->rgvarg);
+            if(FAILED(hres))
+                return hres;
+
+            prop->flags &= ~DYNPROP_DELETED;
+            return S_OK;
         default:
             FIXME("unhandled wFlags %x\n", wFlags);
             return E_NOTIMPL;
@@ -1073,12 +1131,14 @@ static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex,
         if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx)
             return DISP_E_UNKNOWNNAME;
 
-        if(idx+1 == This->dynamic_data->prop_cnt) {
+        while(++idx < This->dynamic_data->prop_cnt && This->dynamic_data->props[idx].flags & DYNPROP_DELETED);
+
+        if(idx == This->dynamic_data->prop_cnt) {
             *pid = DISPID_STARTENUM;
             return S_FALSE;
         }
 
-        *pid = id+1;
+        *pid = DISPID_DYNPROP_0+idx;
         return S_OK;
     }
 
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index e77c1dc..b0cb791 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -198,8 +198,10 @@ static HRESULT WINAPI HTMLElement_removeAttribute(IHTMLElement *iface, BSTR strA
                                                   LONG lFlags, VARIANT_BOOL *pfSuccess)
 {
     HTMLElement *This = HTMLELEM_THIS(iface);
-    FIXME("(%p)->()\n", This);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(strAttributeName), lFlags, pfSuccess);
+
+    return remove_prop(&This->node.dispex, strAttributeName, pfSuccess);
 }
 
 static HRESULT WINAPI HTMLElement_put_className(IHTMLElement *iface, BSTR v)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 228be35..374b6c0 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -171,6 +171,7 @@ void release_dispex(DispatchEx*);
 BOOL dispex_query_interface(DispatchEx*,REFIID,void**);
 HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**);
 HRESULT get_dispids(tid_t,DWORD*,DISPID**);
+HRESULT remove_prop(DispatchEx*,BSTR,VARIANT_BOOL*);
 
 typedef struct HTMLWindow HTMLWindow;
 typedef struct HTMLDocumentNode HTMLDocumentNode;




More information about the wine-cvs mailing list