Piotr Caban : mshtml: Store attributes list in HTMLAttributeCollection.

Alexandre Julliard julliard at winehq.org
Fri Sep 2 13:13:38 CDT 2011


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Fri Sep  2 14:17:10 2011 +0200

mshtml: Store attributes list in HTMLAttributeCollection.

---

 dlls/mshtml/htmlattr.c       |   11 +++++-
 dlls/mshtml/htmlelem.c       |   78 ++++++++++++++++++++++++++---------------
 dlls/mshtml/htmlelem3.c      |   30 +++-------------
 dlls/mshtml/mshtml_private.h |    2 +-
 4 files changed, 66 insertions(+), 55 deletions(-)

diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c
index 40b2de6..d8203fe 100644
--- a/dlls/mshtml/htmlattr.c
+++ b/dlls/mshtml/htmlattr.c
@@ -186,18 +186,27 @@ static dispex_static_data_t HTMLDOMAttribute_dispex = {
 
 HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, DISPID dispid, HTMLDOMAttribute **attr)
 {
+    HTMLAttributeCollection *col;
     HTMLDOMAttribute *ret;
+    HRESULT hres;
 
     ret = heap_alloc_zero(sizeof(*ret));
     if(!ret)
         return E_OUTOFMEMORY;
 
+    hres = HTMLElement_get_attr_col(&elem->node, &col);
+    if(FAILED(hres)) {
+        heap_free(ret);
+        return hres;
+    }
+    IHTMLAttributeCollection_Release(&col->IHTMLAttributeCollection_iface);
+
     ret->IHTMLDOMAttribute_iface.lpVtbl = &HTMLDOMAttributeVtbl;
     ret->ref = 1;
 
     ret->dispid = dispid;
     ret->elem = elem;
-    list_add_tail(&elem->attrs, &ret->entry);
+    list_add_tail(&elem->attrs->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 b9840b1..ff8d022 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -1693,15 +1693,6 @@ HRESULT HTMLElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
 void HTMLElement_destructor(HTMLDOMNode *iface)
 {
     HTMLElement *This = impl_from_HTMLDOMNode(iface);
-    HTMLDOMAttribute *attr;
-
-    while(!list_empty(&This->attrs)) {
-        attr = LIST_ENTRY(list_head(&This->attrs), HTMLDOMAttribute, entry);
-
-        list_remove(&attr->entry);
-        attr->elem = NULL;
-        IHTMLDOMAttribute_Release(&attr->IHTMLDOMAttribute_iface);
-    }
 
     ConnectionPointContainer_Destroy(&This->cp_container);
 
@@ -1709,6 +1700,15 @@ void HTMLElement_destructor(HTMLDOMNode *iface)
         nsIDOMHTMLElement_Release(This->nselem);
     if(This->style)
         IHTMLStyle_Release(&This->style->IHTMLStyle_iface);
+    if(This->attrs) {
+        HTMLDOMAttribute *attr;
+
+        LIST_FOR_EACH_ENTRY(attr, &This->attrs->attrs, HTMLDOMAttribute, entry)
+            attr->elem = NULL;
+
+        This->attrs->elem = NULL;
+        IHTMLAttributeCollection_Release(&This->attrs->IHTMLAttributeCollection_iface);
+    }
 
     HTMLDOMNode_destructor(&This->node);
 }
@@ -1881,7 +1881,6 @@ 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);
 
@@ -2170,7 +2169,14 @@ static ULONG WINAPI HTMLAttributeCollection_Release(IHTMLAttributeCollection *if
     TRACE("(%p) ref=%d\n", This, ref);
 
     if(!ref) {
-        IHTMLElement_Release(&This->elem->IHTMLElement_iface);
+        while(!list_empty(&This->attrs)) {
+            HTMLDOMAttribute *attr = LIST_ENTRY(list_head(&This->attrs), HTMLDOMAttribute, entry);
+
+            list_remove(&attr->entry);
+            attr->elem = NULL;
+            IHTMLDOMAttribute_Release(&attr->IHTMLDOMAttribute_iface);
+        }
+
         heap_free(This);
     }
 
@@ -2253,18 +2259,23 @@ static inline HRESULT get_attr_dispid_by_name(HTMLAttributeCollection *This, BST
         }
     }
 
+    if(!This->elem) {
+        WARN("NULL elem\n");
+        return E_UNEXPECTED;
+    }
+
     hres = IDispatchEx_GetDispID(&This->elem->node.dispex.IDispatchEx_iface,
             name, fdexNameCaseInsensitive, id);
     return hres;
 }
 
-static inline HRESULT get_domattr(HTMLElement *elem, DISPID id, HTMLDOMAttribute **attr)
+static inline HRESULT get_domattr(HTMLAttributeCollection *This, DISPID id, HTMLDOMAttribute **attr)
 {
     HTMLDOMAttribute *iter;
     HRESULT hres;
 
     *attr = NULL;
-    LIST_FOR_EACH_ENTRY(iter, &elem->attrs, HTMLDOMAttribute, entry) {
+    LIST_FOR_EACH_ENTRY(iter, &This->attrs, HTMLDOMAttribute, entry) {
         if(iter->dispid == id) {
             *attr = iter;
             break;
@@ -2272,7 +2283,12 @@ static inline HRESULT get_domattr(HTMLElement *elem, DISPID id, HTMLDOMAttribute
     }
 
     if(!*attr) {
-        hres = HTMLDOMAttribute_Create(elem, id, attr);
+        if(!This->elem) {
+            WARN("NULL elem\n");
+            return E_UNEXPECTED;
+        }
+
+        hres = HTMLDOMAttribute_Create(This->elem, id, attr);
         if(FAILED(hres))
             return hres;
     }
@@ -2325,7 +2341,7 @@ static HRESULT WINAPI HTMLAttributeCollection_item(IHTMLAttributeCollection *ifa
     if(FAILED(hres))
         return hres;
 
-    hres = get_domattr(This->elem, id, &attr);
+    hres = get_domattr(This, id, &attr);
     if(FAILED(hres))
         return hres;
 
@@ -2417,7 +2433,7 @@ static HRESULT WINAPI HTMLAttributeCollection2_getNamedItem(IHTMLAttributeCollec
         return hres;
     }
 
-    hres = get_domattr(This->elem, id, &attr);
+    hres = get_domattr(This, id, &attr);
     if(FAILED(hres))
         return hres;
 
@@ -2545,7 +2561,7 @@ static HRESULT WINAPI HTMLAttributeCollection3_item(IHTMLAttributeCollection3 *i
     if(FAILED(hres))
         return hres;
 
-    hres = get_domattr(This->elem, id, &attr);
+    hres = get_domattr(This, id, &attr);
     if(FAILED(hres))
         return hres;
 
@@ -2618,23 +2634,27 @@ static dispex_static_data_t HTMLAttributeCollection_dispex = {
 HRESULT HTMLElement_get_attr_col(HTMLDOMNode *iface, HTMLAttributeCollection **ac)
 {
     HTMLElement *This = impl_from_HTMLDOMNode(iface);
-    HTMLAttributeCollection *ret;
 
-    ret = heap_alloc_zero(sizeof(*ret));
-    if(!ret)
-        return E_OUTOFMEMORY;
+    if(This->attrs) {
+        IHTMLAttributeCollection_AddRef(&This->attrs->IHTMLAttributeCollection_iface);
+        *ac = This->attrs;
+        return S_OK;
+    }
 
-    ret->IHTMLAttributeCollection_iface.lpVtbl = &HTMLAttributeCollectionVtbl;
-    ret->IHTMLAttributeCollection2_iface.lpVtbl = &HTMLAttributeCollection2Vtbl;
-    ret->IHTMLAttributeCollection3_iface.lpVtbl = &HTMLAttributeCollection3Vtbl;
-    ret->ref = 1;
+    This->attrs = heap_alloc_zero(sizeof(HTMLAttributeCollection));
+    if(!This->attrs)
+        return E_OUTOFMEMORY;
 
-    IHTMLElement_AddRef(&This->IHTMLElement_iface);
-    ret->elem = This;
+    This->attrs->IHTMLAttributeCollection_iface.lpVtbl = &HTMLAttributeCollectionVtbl;
+    This->attrs->IHTMLAttributeCollection2_iface.lpVtbl = &HTMLAttributeCollection2Vtbl;
+    This->attrs->IHTMLAttributeCollection3_iface.lpVtbl = &HTMLAttributeCollection3Vtbl;
+    This->attrs->ref = 2;
 
-    init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLAttributeCollection_iface,
+    This->attrs->elem = This;
+    list_init(&This->attrs->attrs);
+    init_dispex(&This->attrs->dispex, (IUnknown*)&This->attrs->IHTMLAttributeCollection_iface,
             &HTMLAttributeCollection_dispex);
 
-    *ac = ret;
+    *ac = This->attrs;
     return S_OK;
 }
diff --git a/dlls/mshtml/htmlelem3.c b/dlls/mshtml/htmlelem3.c
index 73ca1ed..392b4e4 100644
--- a/dlls/mshtml/htmlelem3.c
+++ b/dlls/mshtml/htmlelem3.c
@@ -559,36 +559,18 @@ 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 = NULL, *iter;
-    DISPID dispid;
+    HTMLAttributeCollection *attrs;
     HRESULT hres;
 
     TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrname), ppAttribute);
 
-    hres = IDispatchEx_GetDispID(&This->node.dispex.IDispatchEx_iface, bstrname, fdexNameCaseInsensitive, &dispid);
-    if(hres == DISP_E_UNKNOWNNAME) {
-        *ppAttribute = NULL;
-        return S_OK;
-    }else if(FAILED(hres)) {
+    hres = HTMLElement_get_attr_col(&This->node, &attrs);
+    if(FAILED(hres))
         return hres;
-    }
 
-    LIST_FOR_EACH_ENTRY(iter, &This->attrs, HTMLDOMAttribute, entry) {
-        if(iter->dispid == dispid) {
-            attr = iter;
-            break;
-        }
-    }
-
-    if(!attr) {
-        hres = HTMLDOMAttribute_Create(This, dispid, &attr);
-        if(FAILED(hres))
-            return hres;
-    }
-
-    IHTMLDOMAttribute_AddRef(&attr->IHTMLDOMAttribute_iface);
-    *ppAttribute = &attr->IHTMLDOMAttribute_iface;
-    return S_OK;
+    hres = IHTMLAttributeCollection2_getNamedItem(&attrs->IHTMLAttributeCollection2_iface, bstrname, ppAttribute);
+    IHTMLAttributeCollection_Release(&attrs->IHTMLAttributeCollection_iface);
+    return hres;
 }
 
 static HRESULT WINAPI HTMLElement4_setAttributeNode(IHTMLElement4 *iface, IHTMLDOMAttribute *pattr,
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index aae8ffe..7b759e0 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -543,7 +543,7 @@ typedef struct {
 
     nsIDOMHTMLElement *nselem;
     HTMLStyle *style;
-    struct list attrs;
+    HTMLAttributeCollection *attrs;
 } HTMLElement;
 
 #define HTMLELEMENT_TIDS    \




More information about the wine-cvs mailing list