Jacek Caban : mshtml: Reuse attribute objects.

Alexandre Julliard julliard at winehq.org
Wed Mar 2 12:23:49 CST 2011


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Mar  2 13:34:04 2011 +0100

mshtml: Reuse attribute objects.

---

 dlls/mshtml/htmlattr.c       |    7 ++++++-
 dlls/mshtml/htmlelem.c       |    7 +++++++
 dlls/mshtml/htmlelem3.c      |   30 +++++++++++++++++++++---------
 dlls/mshtml/mshtml_private.h |    6 +++++-
 dlls/mshtml/tests/dom.c      |    1 -
 5 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c
index 9fef7d8..bd0f6a2 100644
--- a/dlls/mshtml/htmlattr.c
+++ b/dlls/mshtml/htmlattr.c
@@ -18,6 +18,7 @@
 
 
 #include <stdarg.h>
+#include <assert.h>
 
 #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 897a7c5..c4d5607 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 7841346..02015e5 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 0adb344..b39ad75 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 85bac69..88d8790 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);
 




More information about the wine-cvs mailing list