Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Presently, even toString() is exposed as an attribute, because it's a builtin of the element, which makes no sense.
dlls/mshtml/htmlattr.c | 21 ++++----------------- dlls/mshtml/htmlelem.c | 31 ++++++++++++++++++++++++++++++- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/tests/documentmode.js | 31 +++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 18 deletions(-)
diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c index dc8c45e..b293d91 100644 --- a/dlls/mshtml/htmlattr.c +++ b/dlls/mshtml/htmlattr.c @@ -174,10 +174,7 @@ 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); - nsIDOMAttr *nsattr; - nsAString nsname; BSTR name; - nsresult nsres; HRESULT hres;
TRACE("(%p)->(%p)\n", This, p); @@ -196,22 +193,12 @@ static HRESULT WINAPI HTMLDOMAttribute_get_specified(IHTMLDOMAttribute *iface, V 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 = nsIDOMElement_GetAttributeNode(This->elem->dom_element, &nsname, &nsattr); - nsAString_Finish(&nsname); + hres = is_elem_attr_specified(This->elem, name); SysFreeString(name); - if(NS_FAILED(nsres)) - return E_FAIL; + if(FAILED(hres)) + return hres;
- /* 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; - } + *p = (hres == S_OK) ? VARIANT_TRUE : VARIANT_FALSE; return S_OK; }
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index b07de03..c285a21 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -7169,6 +7169,28 @@ static HRESULT WINAPI HTMLAttributeCollection_Invoke(IHTMLAttributeCollection *i wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); }
+HRESULT is_elem_attr_specified(HTMLElement *elem, const WCHAR *name) +{ + nsIDOMAttr *nsattr; + nsAString nsname; + nsresult nsres; + + /* FIXME: This is not exactly right, we have some attributes that don't map directly to Gecko attributes. */ + nsAString_InitDepend(&nsname, name); + nsres = nsIDOMElement_GetAttributeNode(elem->dom_element, &nsname, &nsattr); + nsAString_Finish(&nsname); + 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); + return S_OK; + } + return S_FALSE; +} + static HRESULT get_attr_dispid_by_idx(HTMLAttributeCollection *This, LONG *idx, DISPID *dispid) { IDispatchEx *dispex = &This->elem->node.event_target.dispex.IDispatchEx_iface; @@ -7222,7 +7244,14 @@ static inline HRESULT get_attr_dispid_by_name(HTMLAttributeCollection *This, BST
hres = IDispatchEx_GetDispID(&This->elem->node.event_target.dispex.IDispatchEx_iface, name, fdexNameCaseInsensitive, id); - return hres; + if(FAILED(hres)) + return hres; + + if(get_dispid_type(*id) != DISPEXPROP_BUILTIN) + return S_OK; + + hres = is_elem_attr_specified(This->elem, name); + return (hres == S_FALSE) ? DISP_E_UNKNOWNNAME : hres; }
static inline HRESULT get_domattr(HTMLAttributeCollection *This, DISPID id, LONG *list_pos, HTMLDOMAttribute **attr) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c1e7e78..624963a 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -1161,6 +1161,7 @@ HRESULT create_child_collection(nsIDOMNodeList*,compat_mode_t,IHTMLDOMChildrenCo HRESULT attr_value_to_string(VARIANT*) DECLSPEC_HIDDEN; HRESULT get_elem_attr_value_by_dispid(HTMLElement*,DISPID,VARIANT*) DECLSPEC_HIDDEN; HRESULT get_elem_source_index(HTMLElement*,LONG*) DECLSPEC_HIDDEN; +HRESULT is_elem_attr_specified(HTMLElement*,const WCHAR*) DECLSPEC_HIDDEN;
nsresult get_elem_attr_value(nsIDOMElement*,const WCHAR*,nsAString*,const PRUnichar**) DECLSPEC_HIDDEN; HRESULT elem_string_attr_getter(HTMLElement*,const WCHAR*,BOOL,BSTR*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index c20f6ee..41d7a6b 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -785,4 +785,35 @@ sync_test("elem_attr", function() { ok(r === "cls2", "class attr = " + r); r = elem.getAttribute("className"); ok(r === "cls3", "className attr = " + r); + + function test_exposed(prop, expect) { + if(expect) + ok(prop in elem.attributes, prop + " not found in elem.attributes."); + else + ok(!(prop in elem.attributes), prop + " found in elem.attributes."); + } + + test_exposed("className", v >= 8); + test_exposed("doScroll", false); + test_exposed("readyState", false); + test_exposed("clientTop", false); + if (v >= 9 /* todo_wine */) test_exposed("title", v < 9); + test_exposed("querySelectorAll", false); + test_exposed("textContent", false); + test_exposed("prefix", false); + test_exposed("firstElementChild", false); + test_exposed("onsubmit", false); + test_exposed("getElementsByClassName", false); + test_exposed("removeAttributeNS", false); + test_exposed("addEventListener", false); + test_exposed("hasAttribute", false); + test_exposed("removeEventListener", false); + test_exposed("dispatchEvent", false); + test_exposed("msSetPointerCapture", false); + if (v >= 9 /* todo_wine */) test_exposed("spellcheck", v < 9); + + if(v < 9) + test_exposed("toString", false); + else if(false /* todo_wine */) + ok(!elem.attributes.hasOwnProperty("toString"), "toString found in elem.attributes."); });