From af4967186a5547965cfc0ae8034038ad1472cd96 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Tue, 24 Jul 2012 15:55:54 +0200 Subject: [PATCH] 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 b2024d4b3d1..614c9d54b83 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 d8203fef48b..5d4c2b46dea 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 04b5b1ef848..1f51804cc58 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 1a1732f549e..b0c5335cb5b 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); } -- 2.11.4.GIT