Jacek Caban : mshtml: Added IHTMLElement3::[get|put]_implementation.

Alexandre Julliard julliard at winehq.org
Fri Oct 10 08:06:42 CDT 2008


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Oct  9 15:30:51 2008 -0500

mshtml: Added IHTMLElement3::[get|put]_implementation.

---

 dlls/mshtml/dispex.c         |  119 +++++++++++++++++++++++++-----------------
 dlls/mshtml/htmlelem3.c      |   33 ++++++++++--
 dlls/mshtml/mshtml_private.h |    1 +
 dlls/mshtml/tests/dom.c      |    4 ++
 4 files changed, 105 insertions(+), 52 deletions(-)

diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
index 9d77f97..551be8d 100644
--- a/dlls/mshtml/dispex.c
+++ b/dlls/mshtml/dispex.c
@@ -333,6 +333,70 @@ static inline BOOL is_dynamic_dispid(DISPID id)
     return DISPID_DYNPROP_0 <= id && id <= DISPID_DYNPROP_MAX;
 }
 
+static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, BOOL alloc, dynamic_prop_t **ret)
+{
+    dispex_dynamic_data_t *data = This->dynamic_data;
+
+    if(data) {
+        unsigned i;
+
+        for(i=0; i < data->prop_cnt; i++) {
+            if(!strcmpW(data->props[i].name, name)) {
+                *ret = data->props+i;
+                return S_OK;
+            }
+        }
+    }
+
+    if(alloc) {
+        TRACE("creating dynamic prop %s\n", debugstr_w(name));
+
+        if(!data) {
+            data = This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t));
+            if(!data)
+                return E_OUTOFMEMORY;
+        }
+
+        if(!data->buf_size) {
+            data->props = heap_alloc(sizeof(dynamic_prop_t)*4);
+            if(!data->props)
+                return E_OUTOFMEMORY;
+            data->buf_size = 4;
+        }else if(data->buf_size == data->prop_cnt) {
+            dynamic_prop_t *new_props;
+
+            new_props = heap_realloc(data->props, sizeof(dynamic_prop_t)*(data->buf_size<<1));
+            if(!new_props)
+                return E_OUTOFMEMORY;
+
+            data->props = new_props;
+            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++;
+
+        return S_OK;
+    }
+
+    TRACE("not found %s\n", debugstr_w(name));
+    return DISP_E_UNKNOWNNAME;
+}
+
+HRESULT dispex_get_dprop_ref(DispatchEx *This, const WCHAR *name, BOOL alloc, VARIANT **ret)
+{
+    dynamic_prop_t *prop;
+    HRESULT hres;
+
+    hres = get_dynamic_prop(This, name, alloc, &prop);
+    if(FAILED(hres))
+        return hres;
+
+    *ret = &prop->var;
+    return S_OK;
+}
+
 #define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface)
 
 static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
@@ -418,8 +482,10 @@ static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
 static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
 {
     DispatchEx *This = DISPATCHEX_THIS(iface);
+    dynamic_prop_t *dprop;
     dispex_data_t *data;
     int min, max, n, c;
+    HRESULT hres;
 
     TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
 
@@ -451,17 +517,6 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
             min = n+1;
     }
 
-    if(This->dynamic_data) {
-        unsigned i;
-
-        for(i=0; i < This->dynamic_data->prop_cnt; i++) {
-            if(!strcmpW(This->dynamic_data->props[i].name, bstrName)) {
-                *pid = DISPID_DYNPROP_0 + i;
-                return S_OK;
-            }
-        }
-    }
-
     if(This->data->vtbl && This->data->vtbl->get_dispid) {
         HRESULT hres;
 
@@ -470,44 +525,12 @@ static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DW
             return hres;
     }
 
-    if(grfdex & fdexNameEnsure) {
-        dispex_dynamic_data_t *dynamic_data;
-
-        TRACE("creating dynamic prop %s\n", debugstr_w(bstrName));
-
-        if(This->dynamic_data) {
-            dynamic_data = This->dynamic_data;
-        }else {
-            dynamic_data = This->dynamic_data = heap_alloc_zero(sizeof(dispex_dynamic_data_t));
-            if(!dynamic_data)
-                return E_OUTOFMEMORY;
-        }
-
-        if(!dynamic_data->buf_size) {
-            dynamic_data->props = heap_alloc(sizeof(dynamic_prop_t)*4);
-            if(!dynamic_data->props)
-                return E_OUTOFMEMORY;
-            dynamic_data->buf_size = 4;
-        }else if(dynamic_data->buf_size == dynamic_data->prop_cnt) {
-            dynamic_prop_t *new_props;
-
-            new_props = heap_realloc(dynamic_data->props, sizeof(dynamic_prop_t)*(dynamic_data->buf_size<<1));
-            if(!new_props)
-                return E_OUTOFMEMORY;
-
-            dynamic_data->props = new_props;
-            dynamic_data->buf_size <<= 1;
-        }
-
-        dynamic_data->props[dynamic_data->prop_cnt].name = heap_strdupW(bstrName);
-        VariantInit(&dynamic_data->props[dynamic_data->prop_cnt].var);
-        *pid = DISPID_DYNPROP_0 + dynamic_data->prop_cnt++;
-
-        return S_OK;
-    }
+    hres = get_dynamic_prop(This, bstrName, grfdex&fdexNameEnsure, &dprop);
+    if(FAILED(hres))
+        return hres;
 
-    TRACE("not found %s\n", debugstr_w(bstrName));
-    return DISP_E_UNKNOWNNAME;
+    *pid = DISPID_DYNPROP_0 + (dprop - This->dynamic_data->props);
+    return S_OK;
 }
 
 static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
diff --git a/dlls/mshtml/htmlelem3.c b/dlls/mshtml/htmlelem3.c
index 05805b9..22c93a9 100644
--- a/dlls/mshtml/htmlelem3.c
+++ b/dlls/mshtml/htmlelem3.c
@@ -202,30 +202,55 @@ static HRESULT WINAPI HTMLElement3_get_hideFocus(IHTMLElement3 *iface, VARIANT_B
     return E_NOTIMPL;
 }
 
+static const WCHAR disabledW[] = {'d','i','s','a','b','l','e','d',0};
+
 static HRESULT WINAPI HTMLElement3_put_disabled(IHTMLElement3 *iface, VARIANT_BOOL v)
 {
     HTMLElement *This = HTMLELEM3_THIS(iface);
+    VARIANT *var;
+    HRESULT hres;
 
     TRACE("(%p)->(%x)\n", This, v);
 
     if(This->node.vtbl->put_disabled)
         return This->node.vtbl->put_disabled(&This->node, v);
 
-    FIXME("No implementation for element\n");
-    return E_NOTIMPL;
+    hres = dispex_get_dprop_ref(&This->node.dispex, disabledW, TRUE, &var);
+    if(FAILED(hres))
+        return hres;
+
+    VariantClear(var);
+    V_VT(var) = VT_BOOL;
+    V_BOOL(var) = v;
+    return S_OK;
 }
 
 static HRESULT WINAPI HTMLElement3_get_disabled(IHTMLElement3 *iface, VARIANT_BOOL *p)
 {
     HTMLElement *This = HTMLELEM3_THIS(iface);
+    VARIANT *var;
+    HRESULT hres;
 
     TRACE("(%p)->(%p)\n", This, p);
 
     if(This->node.vtbl->get_disabled)
         return This->node.vtbl->get_disabled(&This->node, p);
 
-    FIXME("No implementation for element\n");
-    return E_NOTIMPL;
+    hres = dispex_get_dprop_ref(&This->node.dispex, disabledW, FALSE, &var);
+    if(hres == DISP_E_UNKNOWNNAME) {
+        *p = VARIANT_FALSE;
+        return S_OK;
+    }
+    if(FAILED(hres))
+        return hres;
+
+    if(V_VT(var) != VT_BOOL) {
+        FIXME("vt %d\n", V_VT(var));
+        return E_NOTIMPL;
+    }
+
+    *p = V_BOOL(var);
+    return S_OK;
 }
 
 static HRESULT WINAPI HTMLElement3_get_isDisabled(IHTMLElement3 *iface, VARIANT_BOOL *p)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 3ebd655..c86aa81 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -151,6 +151,7 @@ typedef struct {
 
 void init_dispex(DispatchEx*,IUnknown*,dispex_static_data_t*);
 BOOL dispex_query_interface(DispatchEx*,REFIID,void**);
+HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**);
 
 typedef struct {
     DispatchEx dispex;
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index 463bc5c..0a9de53 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -2986,6 +2986,10 @@ static void test_elems(IHTMLDocument2 *doc)
         IHTMLDOMChildrenCollection_Release(child_col);
     }
 
+    test_elem3_get_disabled((IUnknown*)elem, VARIANT_FALSE);
+    test_elem3_set_disabled((IUnknown*)elem, VARIANT_TRUE);
+    test_elem3_set_disabled((IUnknown*)elem, VARIANT_FALSE);
+
     IHTMLElement_Release(elem);
 
     test_stylesheets(doc);




More information about the wine-cvs mailing list