Jacek Caban : mshtml: Store reference to document node in window object.

Alexandre Julliard julliard at winehq.org
Thu Sep 17 13:52:20 CDT 2009


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Sep 16 22:08:41 2009 +0200

mshtml: Store reference to document node in window object.

---

 dlls/mshtml/htmldoc.c        |    9 +++++----
 dlls/mshtml/htmliframe.c     |   25 ++++++++++++++++---------
 dlls/mshtml/htmlwindow.c     |   13 +++++++++++++
 dlls/mshtml/mshtml_private.h |    1 +
 dlls/mshtml/nsembed.c        |    8 ++++----
 5 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index 37b1d51..d083f6b 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -1783,9 +1783,6 @@ static void destroy_htmldoc(HTMLDocument *This)
     if(This->hwnd)
         DestroyWindow(This->hwnd);
 
-    if(This->window)
-        IHTMLWindow2_Release(HTMLWINDOW2(This->window));
-
     if(This->event_target)
         release_event_target(This->event_target);
 
@@ -1864,7 +1861,6 @@ HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocumentObj *doc_ob
     nsIDOMHTMLDocument_AddRef(nsdoc);
     doc->basedoc.nsdoc = nsdoc;
 
-    IHTMLWindow2_AddRef(HTMLWINDOW2(window));
     doc->basedoc.window = window;
 
     *ret = doc;
@@ -1902,6 +1898,11 @@ static ULONG HTMLDocumentObj_Release(HTMLDocument *base)
             This->basedoc.doc_node->basedoc.doc_obj = NULL;
             IHTMLDocument2_Release(HTMLDOC(&This->basedoc.doc_node->basedoc));
         }
+        if(This->basedoc.window) {
+            This->basedoc.window->doc_obj = NULL;
+            IHTMLWindow2_Release(HTMLWINDOW2(This->basedoc.window));
+        }
+
         destroy_htmldoc(&This->basedoc);
         heap_free(This);
     }
diff --git a/dlls/mshtml/htmliframe.c b/dlls/mshtml/htmliframe.c
index 45673dd..9124a0a 100644
--- a/dlls/mshtml/htmliframe.c
+++ b/dlls/mshtml/htmliframe.c
@@ -38,7 +38,7 @@ typedef struct {
     LONG ref;
 
     nsIDOMHTMLIFrameElement *nsiframe;
-    HTMLDocumentNode *content_doc;
+    HTMLWindow *content_window;
 } HTMLIFrame;
 
 #define HTMLFRAMEBASE2(x)  (&(x)->lpIHTMLFrameBase2Vtbl)
@@ -104,8 +104,9 @@ static HRESULT WINAPI HTMLIFrameBase2_get_contentWindow(IHTMLFrameBase2 *iface,
 
     TRACE("(%p)->(%p)\n", This, p);
 
-    if(!This->content_doc) {
+    if(!This->content_window) {
         nsIDOMHTMLDocument *nshtmldoc;
+        HTMLDocumentNode *content_doc;
         nsIDOMDocument *nsdoc;
         HTMLWindow *window;
         nsresult nsres;
@@ -135,16 +136,22 @@ static HRESULT WINAPI HTMLIFrameBase2_get_contentWindow(IHTMLFrameBase2 *iface,
             return hres;
         }
 
-        hres = create_doc_from_nsdoc(nshtmldoc, This->element.node.doc->doc_obj, window, &This->content_doc);
-        if(SUCCEEDED(hres))
-            window->doc = This->content_doc;
-        IHTMLWindow2_Release(HTMLWINDOW2(window));
+        hres = create_doc_from_nsdoc(nshtmldoc, This->element.node.doc->doc_obj, window, &content_doc);
         nsIDOMHTMLDocument_Release(nshtmldoc);
+        if(SUCCEEDED(hres))
+            window_set_docnode(window, content_doc);
+        else
+            IHTMLWindow2_Release(HTMLWINDOW2(window));
+        htmldoc_release(&content_doc->basedoc);
         if(FAILED(hres))
             return hres;
+
+        This->content_window = window;
     }
 
-    return IHTMLDocument2_get_parentWindow(HTMLDOC(&This->content_doc->basedoc), p);
+    IHTMLWindow2_AddRef(HTMLWINDOW2(This->content_window));
+    *p = HTMLWINDOW2(This->content_window);
+    return S_OK;
 }
 
 static HRESULT WINAPI HTMLIFrameBase2_put_onload(IHTMLFrameBase2 *iface, VARIANT v)
@@ -239,8 +246,8 @@ static void HTMLIFrame_destructor(HTMLDOMNode *iface)
 {
     HTMLIFrame *This = HTMLIFRAME_NODE_THIS(iface);
 
-    if(This->content_doc)
-        htmldoc_release(&This->content_doc->basedoc);
+    if(This->content_window)
+        IHTMLWindow2_Release(HTMLWINDOW2(This->content_window));
     if(This->nsiframe)
         nsIDOMHTMLIFrameElement_Release(This->nsiframe);
 
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c
index 5720fe8..970e327 100644
--- a/dlls/mshtml/htmlwindow.c
+++ b/dlls/mshtml/htmlwindow.c
@@ -36,6 +36,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
 
 static struct list window_list = LIST_INIT(window_list);
 
+void window_set_docnode(HTMLWindow *window, HTMLDocumentNode *doc_node)
+{
+    if(window->doc) {
+        window->doc->basedoc.window = NULL;
+        htmldoc_release(&window->doc->basedoc);
+    }
+    window->doc = doc_node;
+    if(doc_node)
+        htmldoc_addref(&doc_node->basedoc);
+}
+
 #define HTMLWINDOW2_THIS(iface) DEFINE_THIS(HTMLWindow, HTMLWindow2, iface)
 
 static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID riid, void **ppv)
@@ -95,6 +106,8 @@ static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
     if(!ref) {
         DWORD i;
 
+        window_set_docnode(This, NULL);
+
         if(This->option_factory) {
             This->option_factory->window = NULL;
             IHTMLOptionElementFactory_Release(HTMLOPTFACTORY(This->option_factory));
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 93cf7a6..71a8c8b 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -549,6 +549,7 @@ HRESULT HTMLLoadOptions_Create(IUnknown*,REFIID,void**);
 HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument*,HTMLDocumentObj*,HTMLWindow*,HTMLDocumentNode**);
 
 HRESULT HTMLWindow_Create(HTMLDocumentObj*,nsIDOMWindow*,HTMLWindow**);
+void window_set_docnode(HTMLWindow*,HTMLDocumentNode*);
 HTMLWindow *nswindow_to_window(const nsIDOMWindow*);
 HTMLOptionElementFactory *HTMLOptionElementFactory_Create(HTMLWindow*);
 HRESULT HTMLLocation_Create(HTMLWindow*,HTMLLocation**);
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c
index bf063dd..61759e9 100644
--- a/dlls/mshtml/nsembed.c
+++ b/dlls/mshtml/nsembed.c
@@ -844,13 +844,13 @@ void update_nsdocument(HTMLDocumentObj *doc)
         doc_node->basedoc.doc_obj = NULL;
         IHTMLDocument2_Release(HTMLDOC(&doc_node->basedoc));
         doc->basedoc.doc_node = NULL;
-
-        doc->basedoc.window->doc = NULL;
     }
 
     doc->basedoc.nsdoc = nsdoc;
-    if(!nsdoc)
+    if(!nsdoc) {
+        window_set_docnode(doc->basedoc.window, NULL);
         return;
+    }
 
     set_mutation_observer(doc->basedoc.nscontainer, nsdoc);
 
@@ -861,7 +861,7 @@ void update_nsdocument(HTMLDocumentObj *doc)
     }
 
     doc->basedoc.doc_node = doc_node;
-    doc->basedoc.window->doc = doc_node;
+    window_set_docnode(doc->basedoc.window, doc_node);
 }
 
 void close_gecko(void)




More information about the wine-cvs mailing list