mshtml: Reuse attribute objects.

This commit is contained in:
Jacek Caban 2011-03-02 13:34:04 +01:00 committed by Alexandre Julliard
parent b9975bf88e
commit 110155099b
5 changed files with 39 additions and 12 deletions

View File

@ -18,6 +18,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <assert.h>
#define COBJMACROS #define COBJMACROS
@ -78,6 +79,7 @@ static ULONG WINAPI HTMLDOMAttribute_Release(IHTMLDOMAttribute *iface)
TRACE("(%p) ref=%d\n", This, ref); TRACE("(%p) ref=%d\n", This, ref);
if(!ref) { if(!ref) {
assert(!This->elem);
nsIDOMAttr_Release(This->nsattr); nsIDOMAttr_Release(This->nsattr);
release_dispex(&This->dispex); release_dispex(&This->dispex);
heap_free(This); heap_free(This);
@ -189,7 +191,7 @@ static dispex_static_data_t HTMLDOMAttribute_dispex = {
HTMLDOMAttribute_iface_tids HTMLDOMAttribute_iface_tids
}; };
HRESULT HTMLDOMAttribute_Create(HTMLDocumentNode *doc, nsIDOMAttr *nsattr, HTMLDOMAttribute **attr) HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, nsIDOMAttr *nsattr, HTMLDOMAttribute **attr)
{ {
HTMLDOMAttribute *ret; HTMLDOMAttribute *ret;
@ -203,6 +205,9 @@ HRESULT HTMLDOMAttribute_Create(HTMLDocumentNode *doc, nsIDOMAttr *nsattr, HTMLD
nsIDOMAttr_AddRef(nsattr); nsIDOMAttr_AddRef(nsattr);
ret->nsattr = nsattr; ret->nsattr = nsattr;
ret->elem = elem;
list_add_tail(&elem->attrs, &ret->entry);
init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLDOMAttribute_iface, init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLDOMAttribute_iface,
&HTMLDOMAttribute_dispex); &HTMLDOMAttribute_dispex);

View File

@ -1647,6 +1647,12 @@ HRESULT HTMLElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
void HTMLElement_destructor(HTMLDOMNode *iface) void HTMLElement_destructor(HTMLDOMNode *iface)
{ {
HTMLElement *This = impl_from_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); ConnectionPointContainer_Destroy(&This->cp_container);
@ -1742,6 +1748,7 @@ void HTMLElement_Init(HTMLElement *This, HTMLDocumentNode *doc, nsIDOMHTMLElemen
if(nselem) if(nselem)
nsIDOMHTMLElement_AddRef(nselem); nsIDOMHTMLElement_AddRef(nselem);
This->nselem = nselem; This->nselem = nselem;
list_init(&This->attrs);
HTMLDOMNode_Init(doc, &This->node, (nsIDOMNode*)nselem); HTMLDOMNode_Init(doc, &This->node, (nsIDOMNode*)nselem);

View File

@ -560,7 +560,7 @@ static HRESULT WINAPI HTMLElement4_normalize(IHTMLElement4 *iface)
static HRESULT WINAPI HTMLElement4_getAttributeNode(IHTMLElement4 *iface, BSTR bstrname, IHTMLDOMAttribute **ppAttribute) static HRESULT WINAPI HTMLElement4_getAttributeNode(IHTMLElement4 *iface, BSTR bstrname, IHTMLDOMAttribute **ppAttribute)
{ {
HTMLElement *This = impl_from_IHTMLElement4(iface); HTMLElement *This = impl_from_IHTMLElement4(iface);
HTMLDOMAttribute *attr; HTMLDOMAttribute *attr = NULL, *iter;
nsAString name_str; nsAString name_str;
nsIDOMAttr *nsattr; nsIDOMAttr *nsattr;
nsresult nsres; nsresult nsres;
@ -576,16 +576,28 @@ static HRESULT WINAPI HTMLElement4_getAttributeNode(IHTMLElement4 *iface, BSTR b
return E_FAIL; return E_FAIL;
} }
if(nsattr) { if(!nsattr) {
hres = HTMLDOMAttribute_Create(This->node.doc, nsattr, &attr);
nsIDOMAttr_Release(nsattr);
if(FAILED(hres))
return hres;
*ppAttribute = &attr->IHTMLDOMAttribute_iface;
}else {
*ppAttribute = NULL; *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; return S_OK;
} }

View File

@ -561,6 +561,7 @@ typedef struct {
nsIDOMHTMLElement *nselem; nsIDOMHTMLElement *nselem;
HTMLStyle *style; HTMLStyle *style;
struct list attrs;
} HTMLElement; } HTMLElement;
#define HTMLELEMENT_TIDS \ #define HTMLELEMENT_TIDS \
@ -749,9 +750,12 @@ typedef struct {
LONG ref; LONG ref;
nsIDOMAttr *nsattr; nsIDOMAttr *nsattr;
HTMLElement *elem;
struct list entry;
} HTMLDOMAttribute; } HTMLDOMAttribute;
HRESULT HTMLDOMAttribute_Create(HTMLDocumentNode*,nsIDOMAttr*,HTMLDOMAttribute**); HRESULT HTMLDOMAttribute_Create(HTMLElement*,nsIDOMAttr*,HTMLDOMAttribute**);
HRESULT HTMLElement_Create(HTMLDocumentNode*,nsIDOMNode*,BOOL,HTMLElement**); HRESULT HTMLElement_Create(HTMLDocumentNode*,nsIDOMNode*,BOOL,HTMLElement**);
HRESULT HTMLCommentElement_Create(HTMLDocumentNode*,nsIDOMNode*,HTMLElement**); HRESULT HTMLCommentElement_Create(HTMLDocumentNode*,nsIDOMNode*,HTMLElement**);

View File

@ -6812,7 +6812,6 @@ static void test_attr(IHTMLElement *elem)
test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode); test_no_iface((IUnknown*)attr, &IID_IHTMLDOMNode);
attr2 = get_elem_attr_node((IUnknown*)elem, "id", TRUE); attr2 = get_elem_attr_node((IUnknown*)elem, "id", TRUE);
todo_wine
ok(iface_cmp((IUnknown*)attr, (IUnknown*)attr2), "attr != attr2\n"); ok(iface_cmp((IUnknown*)attr, (IUnknown*)attr2), "attr != attr2\n");
IHTMLDOMAttribute_Release(attr2); IHTMLDOMAttribute_Release(attr2);