Jacek Caban : mshtml: Store MSHTML node reference in Gecko node object and get rid of all node list in document object .

Alexandre Julliard julliard at winehq.org
Thu Jul 19 13:23:44 CDT 2012


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Jul 19 11:29:34 2012 +0200

mshtml: Store MSHTML node reference in Gecko node object and get rid of all node list in document object.

---

 dlls/mshtml/htmldoc.c        |    1 -
 dlls/mshtml/htmlnode.c       |   65 ++++++++++++++++++++---------------------
 dlls/mshtml/mshtml_private.h |    4 --
 3 files changed, 32 insertions(+), 38 deletions(-)

diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index d78767c..f9e11ce 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -2080,7 +2080,6 @@ static void HTMLDocumentNode_destructor(HTMLDOMNode *iface)
 
     detach_selection(This);
     detach_ranges(This);
-    release_nodes(This);
 
     while(!list_empty(&This->plugin_hosts))
         detach_plugin_host(LIST_ENTRY(list_head(&This->plugin_hosts), PluginHost, entry));
diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c
index a9e5d3f..7fcff17 100644
--- a/dlls/mshtml/htmlnode.c
+++ b/dlls/mshtml/htmlnode.c
@@ -17,6 +17,7 @@
  */
 
 #include <stdarg.h>
+#include <assert.h>
 
 #define COBJMACROS
 
@@ -1028,6 +1029,8 @@ void HTMLDOMNode_destructor(HTMLDOMNode *This)
 {
     if(This->nsnode)
         nsIDOMNode_Release(This->nsnode);
+    if(This->doc && &This->doc->node != This)
+        htmldoc_release(&This->doc->basedoc);
     if(This->event_target)
         release_event_target(This->event_target);
 }
@@ -1045,17 +1048,23 @@ static const NodeImplVtbl HTMLDOMNodeImplVtbl = {
 
 void HTMLDOMNode_Init(HTMLDocumentNode *doc, HTMLDOMNode *node, nsIDOMNode *nsnode)
 {
+    nsresult nsres;
+
     node->IHTMLDOMNode_iface.lpVtbl = &HTMLDOMNodeVtbl;
     node->IHTMLDOMNode2_iface.lpVtbl = &HTMLDOMNode2Vtbl;
-    ccref_init(&node->ccref, &doc->node != node ? 2 : 1);
+
+    ccref_init(&node->ccref, 1);
+
+    if(&doc->node != node)
+        htmldoc_addref(&doc->basedoc);
     node->doc = doc;
 
     if(nsnode)
         nsIDOMNode_AddRef(nsnode);
     node->nsnode = nsnode;
 
-    node->next = doc->nodes;
-    doc->nodes = node;
+    nsres = nsIDOMNode_SetMshtmlNode(nsnode, (nsISupports*)&node->IHTMLDOMNode_iface);
+    assert(nsres == NS_OK);
 }
 
 static HRESULT create_node(HTMLDocumentNode *doc, nsIDOMNode *nsnode, HTMLDOMNode **ret)
@@ -1123,6 +1132,8 @@ static nsresult NSAPI HTMLDOMNode_traverse(void *ccp, void *p, nsCycleCollection
 
     if(This->nsnode)
         note_cc_edge((nsISupports*)This->nsnode, "This->nsnode", cb);
+    if(This->doc && &This->doc->node != This)
+        note_cc_edge((nsISupports*)&This->doc->node.IHTMLDOMNode_iface, "This->doc", cb);
     dispex_traverse(&This->dispex, cb);
 
     if(This->vtbl->traverse)
@@ -1148,6 +1159,14 @@ static nsresult NSAPI HTMLDOMNode_unlink(void *p)
         nsIDOMNode_Release(nsnode);
     }
 
+    if(This->doc && &This->doc->node != This) {
+        HTMLDocument *doc = &This->doc->basedoc;
+        This->doc = NULL;
+        htmldoc_release(doc);
+    }else {
+        This->doc = NULL;
+    }
+
     return NS_OK;
 }
 
@@ -1162,43 +1181,23 @@ void init_node_cc(void)
     ccp_init(&node_ccp, &node_ccp_callback);
 }
 
-/*
- * FIXME
- * List looks really ugly here. We should use a better data structure or
- * (better) find a way to store HTMLDOMelement pointer in nsIDOMNode.
- */
-
 HRESULT get_node(HTMLDocumentNode *This, nsIDOMNode *nsnode, BOOL create, HTMLDOMNode **ret)
 {
-    HTMLDOMNode *iter = This->nodes;
+    nsISupports *unk = NULL;
+    nsresult nsres;
 
-    while(iter) {
-        if(iter->nsnode == nsnode)
-            break;
-        iter = iter->next;
+    nsres = nsIDOMNode_GetMshtmlNode(nsnode, &unk);
+    assert(nsres == NS_OK);
+
+    if(unk) {
+        *ret = get_node_obj(This, (IUnknown*)unk);
+        return NS_OK;
     }
 
-    if(iter || !create) {
-        if(iter)
-            IHTMLDOMNode_AddRef(&iter->IHTMLDOMNode_iface);
-        *ret = iter;
+    if(!create) {
+        *ret = NULL;
         return S_OK;
     }
 
     return create_node(This, nsnode, ret);
 }
-
-void release_nodes(HTMLDocumentNode *This)
-{
-    HTMLDOMNode *iter, *next;
-
-    if(!This->nodes)
-        return;
-
-    for(iter = This->nodes; iter; iter = next) {
-        next = iter->next;
-        iter->doc = NULL;
-        if(&This->node != iter)
-            IHTMLDOMNode_Release(&iter->IHTMLDOMNode_iface);
-    }
-}
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index af165bf..f006176 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -603,8 +603,6 @@ struct HTMLDOMNode {
     HTMLDocumentNode *doc;
     event_target_t *event_target;
     ConnectionPointContainer *cp_container;
-
-    HTMLDOMNode *next;
 };
 
 static inline void node_addref(HTMLDOMNode *node)
@@ -673,7 +671,6 @@ struct HTMLDocumentNode {
     LONG ref;
 
     nsIDOMHTMLDocument *nsdoc;
-    HTMLDOMNode *nodes;
     BOOL content_ready;
     event_target_t *body_event_target;
 
@@ -881,7 +878,6 @@ HRESULT HTMLFrameBase_QI(HTMLFrameBase*,REFIID,void**) DECLSPEC_HIDDEN;
 void HTMLFrameBase_destructor(HTMLFrameBase*) DECLSPEC_HIDDEN;
 
 HRESULT get_node(HTMLDocumentNode*,nsIDOMNode*,BOOL,HTMLDOMNode**) DECLSPEC_HIDDEN;
-void release_nodes(HTMLDocumentNode*) DECLSPEC_HIDDEN;
 
 HTMLElement *unsafe_impl_from_IHTMLElement(IHTMLElement*) DECLSPEC_HIDDEN;
 




More information about the wine-cvs mailing list