Jacek Caban : mshtml: Added IHTMLDOMAttribute::get_specified implementation .

Alexandre Julliard julliard at winehq.org
Tue Jul 24 14:39:43 CDT 2012


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Jul 24 15:55:54 2012 +0200

mshtml: Added IHTMLDOMAttribute::get_specified implementation.

---

 dlls/mshtml/dispex.c         |    9 +++++++++
 dlls/mshtml/htmlattr.c       |   41 +++++++++++++++++++++++++++++++++++++++--
 dlls/mshtml/mshtml_private.h |    8 ++++++++
 dlls/mshtml/tests/dom.c      |   18 ++++++++++++++++++
 4 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
index b2024d4..614c9d5 100644
--- a/dlls/mshtml/dispex.c
+++ b/dlls/mshtml/dispex.c
@@ -385,6 +385,15 @@ static inline BOOL is_dynamic_dispid(DISPID id)
     return DISPID_DYNPROP_0 <= id && id <= DISPID_DYNPROP_MAX;
 }
 
+dispex_prop_type_t get_dispid_type(DISPID id)
+{
+    if(is_dynamic_dispid(id))
+        return DISPEXPROP_DYNAMIC;
+    if(is_custom_dispid(id))
+        return DISPEXPROP_CUSTOM;
+    return DISPEXPROP_BUILTIN;
+}
+
 static HRESULT variant_copy(VARIANT *dest, VARIANT *src)
 {
     if(V_VT(src) == VT_BSTR && !V_BSTR(src)) {
diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c
index d8203fe..5d4c2b4 100644
--- a/dlls/mshtml/htmlattr.c
+++ b/dlls/mshtml/htmlattr.c
@@ -155,8 +155,45 @@ static HRESULT WINAPI HTMLDOMAttribute_get_nodeValue(IHTMLDOMAttribute *iface, V
 static HRESULT WINAPI HTMLDOMAttribute_get_specified(IHTMLDOMAttribute *iface, VARIANT_BOOL *p)
 {
     HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
-    FIXME("(%p)->(%p)\n", This, p);
-    return E_NOTIMPL;
+    nsIDOMAttr *nsattr;
+    nsAString nsname;
+    BSTR name;
+    nsresult nsres;
+    HRESULT hres;
+
+    TRACE("(%p)->(%p)\n", This, p);
+
+    if(get_dispid_type(This->dispid) != DISPEXPROP_BUILTIN) {
+        *p = VARIANT_TRUE;
+        return S_OK;
+    }
+
+    if(!This->elem || !This->elem->nselem) {
+        FIXME("NULL This->elem\n");
+        return E_UNEXPECTED;
+    }
+
+    hres = IDispatchEx_GetMemberName(&This->elem->node.dispex.IDispatchEx_iface, This->dispid, &name);
+    if(FAILED(hres))
+        return hres;
+
+    /* FIXME: This is not exactly right, we have some attributes that don't map directly to Gecko attributes. */
+    nsAString_InitDepend(&nsname, name);
+    nsres = nsIDOMHTMLElement_GetAttributeNode(This->elem->nselem, &nsname, &nsattr);
+    nsAString_Finish(&nsname);
+    SysFreeString(name);
+    if(NS_FAILED(nsres))
+        return E_FAIL;
+
+    /* If the Gecko attribute node can be found, we know that the attribute is specified.
+       There is no point in calling GetSpecified */
+    if(nsattr) {
+        nsIDOMAttr_Release(nsattr);
+        *p = VARIANT_TRUE;
+    }else {
+        *p = VARIANT_FALSE;
+    }
+    return S_OK;
 }
 
 static const IHTMLDOMAttributeVtbl HTMLDOMAttributeVtbl = {
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 04b5b1e..1f51804 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -263,6 +263,14 @@ void dispex_unlink(DispatchEx*) DECLSPEC_HIDDEN;
 void release_typelib(void) DECLSPEC_HIDDEN;
 HRESULT get_htmldoc_classinfo(ITypeInfo **typeinfo) DECLSPEC_HIDDEN;
 
+typedef enum {
+    DISPEXPROP_CUSTOM,
+    DISPEXPROP_DYNAMIC,
+    DISPEXPROP_BUILTIN
+} dispex_prop_type_t;
+
+dispex_prop_type_t get_dispid_type(DISPID) DECLSPEC_HIDDEN;
+
 typedef struct HTMLWindow HTMLWindow;
 typedef struct HTMLInnerWindow HTMLInnerWindow;
 typedef struct HTMLOuterWindow HTMLOuterWindow;
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index 1a1732f..b0c5335 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -2632,6 +2632,17 @@ static void test_attr_collection(IHTMLElement *elem)
     IHTMLAttributeCollection_Release(attr_col);
 }
 
+#define test_attr_specified(a,b) _test_attr_specified(__LINE__,a,b)
+static void _test_attr_specified(unsigned line, IHTMLDOMAttribute *attr, VARIANT_BOOL expected)
+{
+    VARIANT_BOOL specified;
+    HRESULT hres;
+
+    hres = IHTMLDOMAttribute_get_specified(attr, &specified);
+    ok_(__FILE__,line)(hres == S_OK, "get_specified failed: %08x\n", hres);
+    ok_(__FILE__,line)(specified == expected, "specified = %x, expected %x\n", specified, expected);
+}
+
 #define test_input_type(i,t) _test_input_type(__LINE__,i,t)
 static void _test_input_type(unsigned line, IHTMLInputElement *input, const char *extype)
 {
@@ -5721,6 +5732,7 @@ static void test_attr(IHTMLElement *elem)
     test_disp((IUnknown*)attr, &DIID_DispHTMLDOMAttribute, "[object]");
     test_ifaces((IUnknown*)attr, attr_iids);
     test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode);
+    test_attr_specified(attr, VARIANT_TRUE);
 
     attr2 = get_elem_attr_node((IUnknown*)elem, "id", TRUE);
     ok(iface_cmp((IUnknown*)attr, (IUnknown*)attr2), "attr != attr2\n");
@@ -5736,6 +5748,7 @@ static void test_attr(IHTMLElement *elem)
     get_attr_node_value(attr, &v, VT_BSTR);
     ok(!V_BSTR(&v), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
     VariantClear(&v);
+    test_attr_specified(attr, VARIANT_TRUE);
     IHTMLDOMAttribute_Release(attr);
 
     V_VT(&v) = VT_I4;
@@ -5744,6 +5757,11 @@ static void test_attr(IHTMLElement *elem)
     attr = get_elem_attr_node((IUnknown*)elem, "dispprop", TRUE);
     get_attr_node_value(attr, &v, VT_I4);
     ok(V_I4(&v) == 100, "V_I4(v) = %d\n", V_I4(&v));
+    test_attr_specified(attr, VARIANT_TRUE);
+    IHTMLDOMAttribute_Release(attr);
+
+    attr = get_elem_attr_node((IUnknown*)elem, "tabIndex", TRUE);
+    test_attr_specified(attr, VARIANT_FALSE);
     IHTMLDOMAttribute_Release(attr);
 }
 




More information about the wine-cvs mailing list