diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c
index 9fef7d835cf..bd0f6a29d23 100644
--- a/dlls/mshtml/htmlattr.c
+++ b/dlls/mshtml/htmlattr.c
@@ -18,6 +18,7 @@
#include
+#include
#define COBJMACROS
@@ -78,6 +79,7 @@ static ULONG WINAPI HTMLDOMAttribute_Release(IHTMLDOMAttribute *iface)
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
+ assert(!This->elem);
nsIDOMAttr_Release(This->nsattr);
release_dispex(&This->dispex);
heap_free(This);
@@ -189,7 +191,7 @@ static dispex_static_data_t HTMLDOMAttribute_dispex = {
HTMLDOMAttribute_iface_tids
};
-HRESULT HTMLDOMAttribute_Create(HTMLDocumentNode *doc, nsIDOMAttr *nsattr, HTMLDOMAttribute **attr)
+HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, nsIDOMAttr *nsattr, HTMLDOMAttribute **attr)
{
HTMLDOMAttribute *ret;
@@ -203,6 +205,9 @@ HRESULT HTMLDOMAttribute_Create(HTMLDocumentNode *doc, nsIDOMAttr *nsattr, HTMLD
nsIDOMAttr_AddRef(nsattr);
ret->nsattr = nsattr;
+ ret->elem = elem;
+ list_add_tail(&elem->attrs, &ret->entry);
+
init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLDOMAttribute_iface,
&HTMLDOMAttribute_dispex);
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index 897a7c53ab7..c4d56078fea 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -1647,6 +1647,12 @@ HRESULT HTMLElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
void HTMLElement_destructor(HTMLDOMNode *iface)
{
HTMLElement *This = impl_from_HTMLDOMNode(iface);
+ HTMLDOMAttribute *attr;
+
+ LIST_FOR_EACH_ENTRY(attr, &This->attrs, HTMLDOMAttribute, entry) {
+ attr->elem = NULL;
+ IHTMLDOMAttribute_Release(&attr->IHTMLDOMAttribute_iface);
+ }
ConnectionPointContainer_Destroy(&This->cp_container);
@@ -1742,6 +1748,7 @@ void HTMLElement_Init(HTMLElement *This, HTMLDocumentNode *doc, nsIDOMHTMLElemen
if(nselem)
nsIDOMHTMLElement_AddRef(nselem);
This->nselem = nselem;
+ list_init(&This->attrs);
HTMLDOMNode_Init(doc, &This->node, (nsIDOMNode*)nselem);
diff --git a/dlls/mshtml/htmlelem3.c b/dlls/mshtml/htmlelem3.c
index 78413460d1a..02015e57a28 100644
--- a/dlls/mshtml/htmlelem3.c
+++ b/dlls/mshtml/htmlelem3.c
@@ -560,7 +560,7 @@ static HRESULT WINAPI HTMLElement4_normalize(IHTMLElement4 *iface)
static HRESULT WINAPI HTMLElement4_getAttributeNode(IHTMLElement4 *iface, BSTR bstrname, IHTMLDOMAttribute **ppAttribute)
{
HTMLElement *This = impl_from_IHTMLElement4(iface);
- HTMLDOMAttribute *attr;
+ HTMLDOMAttribute *attr = NULL, *iter;
nsAString name_str;
nsIDOMAttr *nsattr;
nsresult nsres;
@@ -576,16 +576,28 @@ static HRESULT WINAPI HTMLElement4_getAttributeNode(IHTMLElement4 *iface, BSTR b
return E_FAIL;
}
- if(nsattr) {
- hres = HTMLDOMAttribute_Create(This->node.doc, nsattr, &attr);
- nsIDOMAttr_Release(nsattr);
- if(FAILED(hres))
- return hres;
-
- *ppAttribute = &attr->IHTMLDOMAttribute_iface;
- }else {
+ if(!nsattr) {
*ppAttribute = NULL;
+ return S_OK;
}
+
+ LIST_FOR_EACH_ENTRY(iter, &This->attrs, HTMLDOMAttribute, entry) {
+ if(iter->nsattr == nsattr) {
+ attr = iter;
+ break;
+ }
+ }
+
+ if(!attr) {
+ hres = HTMLDOMAttribute_Create(This, nsattr, &attr);
+ if(FAILED(hres)) {
+ nsIDOMAttr_Release(nsattr);
+ return hres;
+ }
+ }
+
+ IHTMLDOMAttribute_AddRef(&attr->IHTMLDOMAttribute_iface);
+ *ppAttribute = &attr->IHTMLDOMAttribute_iface;
return S_OK;
}
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 0adb34425b9..b39ad75ad26 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -561,6 +561,7 @@ typedef struct {
nsIDOMHTMLElement *nselem;
HTMLStyle *style;
+ struct list attrs;
} HTMLElement;
#define HTMLELEMENT_TIDS \
@@ -749,9 +750,12 @@ typedef struct {
LONG ref;
nsIDOMAttr *nsattr;
+
+ HTMLElement *elem;
+ struct list entry;
} HTMLDOMAttribute;
-HRESULT HTMLDOMAttribute_Create(HTMLDocumentNode*,nsIDOMAttr*,HTMLDOMAttribute**);
+HRESULT HTMLDOMAttribute_Create(HTMLElement*,nsIDOMAttr*,HTMLDOMAttribute**);
HRESULT HTMLElement_Create(HTMLDocumentNode*,nsIDOMNode*,BOOL,HTMLElement**);
HRESULT HTMLCommentElement_Create(HTMLDocumentNode*,nsIDOMNode*,HTMLElement**);
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index 85bac69ed4d..88d87907a17 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -6812,7 +6812,6 @@ static void test_attr(IHTMLElement *elem)
test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode);
attr2 = get_elem_attr_node((IUnknown*)elem, "id", TRUE);
- todo_wine
ok(iface_cmp((IUnknown*)attr, (IUnknown*)attr2), "attr != attr2\n");
IHTMLDOMAttribute_Release(attr2);