[PATCH 6/7] mshtml: Allocate DISPIDs only for actual attributes in HTMLAttributeCollection.
Gabriel Ivăncescu
gabrielopcode at gmail.com
Fri Oct 1 08:12:47 CDT 2021
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at 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.");
});
--
2.31.1
More information about the wine-devel
mailing list