Jacek Caban : mshtml: Create HTMLDocumentNode for each HTMLDocumentObj.

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


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

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

mshtml: Create HTMLDocumentNode for each HTMLDocumentObj.

---

 dlls/mshtml/htmldoc.c        |   12 ++++++++++--
 dlls/mshtml/htmliframe.c     |    2 +-
 dlls/mshtml/mshtml_private.h |   18 ++++++++++++------
 dlls/mshtml/navigate.c       |    2 +-
 dlls/mshtml/nsembed.c        |   38 +++++++++++++++++++++++++++-----------
 dlls/mshtml/nsevents.c       |    2 +-
 6 files changed, 52 insertions(+), 22 deletions(-)

diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index 04ef042..d240ee3 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -1847,7 +1847,7 @@ static const htmldoc_vtbl_t HTMLDocumentNodeVtbl = {
     HTMLDocumentNode_Release
 };
 
-HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLWindow *window, HTMLDocumentNode **ret)
+HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocumentObj *doc_obj, HTMLWindow *window, HTMLDocumentNode **ret)
 {
     HTMLDocumentNode *doc;
 
@@ -1855,6 +1855,9 @@ HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLWindow *window, HTM
     if(!doc)
         return E_OUTOFMEMORY;
 
+    doc->basedoc.doc_node = doc;
+    doc->basedoc.doc_obj = doc_obj;
+
     init_doc(&doc->basedoc, &HTMLDocumentNodeVtbl);
     doc->ref = 1;
 
@@ -1895,6 +1898,10 @@ static ULONG HTMLDocumentObj_Release(HTMLDocument *base)
     TRACE("(%p) ref = %u\n", This, ref);
 
     if(!ref) {
+        if(This->basedoc.doc_node) {
+            This->basedoc.doc_node->basedoc.doc_obj = NULL;
+            IHTMLDocument2_Release(HTMLDOC(&This->basedoc.doc_node->basedoc));
+        }
         destroy_htmldoc(&This->basedoc);
         heap_free(This);
     }
@@ -1925,6 +1932,7 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
     init_doc(&doc->basedoc, &HTMLDocumentObjVtbl);
 
     doc->ref = 1;
+    doc->basedoc.doc_obj = doc;
 
     hres = htmldoc_query_interface(&doc->basedoc, riid, ppvObject);
     htmldoc_release(&doc->basedoc);
@@ -1932,7 +1940,6 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
         return hres;
 
     doc->basedoc.nscontainer = NSContainer_Create(&doc->basedoc, NULL);
-    update_nsdocument(&doc->basedoc);
 
     if(doc->basedoc.nscontainer) {
         nsresult nsres;
@@ -1950,6 +1957,7 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
         return hres;
     }
 
+    update_nsdocument(doc);
     doc->basedoc.window->doc = &doc->basedoc;
     get_thread_hwnd();
 
diff --git a/dlls/mshtml/htmliframe.c b/dlls/mshtml/htmliframe.c
index f0c8cdd..8540cac 100644
--- a/dlls/mshtml/htmliframe.c
+++ b/dlls/mshtml/htmliframe.c
@@ -135,7 +135,7 @@ static HRESULT WINAPI HTMLIFrameBase2_get_contentWindow(IHTMLFrameBase2 *iface,
             return hres;
         }
 
-        hres = create_doc_from_nsdoc(nshtmldoc, window, &This->content_doc);
+        hres = create_doc_from_nsdoc(nshtmldoc, This->element.node.doc->doc_obj, window, &This->content_doc);
         if(SUCCEEDED(hres))
             window->doc = &This->content_doc->basedoc;
         IHTMLWindow2_Release(HTMLWINDOW2(window));
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 21e6e2a..5085407 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -249,6 +249,9 @@ typedef struct {
     ULONG (*release)(HTMLDocument*);
 } htmldoc_vtbl_t;
 
+typedef struct HTMLDocumentNode HTMLDocumentNode;
+typedef struct HTMLDocumentObj HTMLDocumentObj;
+
 struct HTMLDocument {
     DispatchEx dispex;
     const htmldoc_vtbl_t                  *vtbl;
@@ -275,6 +278,9 @@ struct HTMLDocument {
     const IDispatchExVtbl                 *lpIDispatchExVtbl;
     const ISupportErrorInfoVtbl           *lpSupportErrorInfoVtbl;
 
+    HTMLDocumentObj *doc_obj;
+    HTMLDocumentNode *doc_node;
+
     NSContainer *nscontainer;
     HTMLWindow *window;
     nsIDOMHTMLDocument *nsdoc;
@@ -336,17 +342,17 @@ static inline ULONG htmldoc_release(HTMLDocument *This)
     return This->vtbl->release(This);
 }
 
-typedef struct {
+struct HTMLDocumentNode {
     HTMLDocument basedoc;
 
     LONG ref;
-} HTMLDocumentNode;
+};
 
-typedef struct {
+struct HTMLDocumentObj {
     HTMLDocument basedoc;
 
     LONG ref;
-} HTMLDocumentObj;
+};
 
 typedef struct {
     const nsIDOMEventListenerVtbl      *lpDOMEventListenerVtbl;
@@ -540,7 +546,7 @@ typedef struct {
 
 HRESULT HTMLDocument_Create(IUnknown*,REFIID,void**);
 HRESULT HTMLLoadOptions_Create(IUnknown*,REFIID,void**);
-HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument*,HTMLWindow*,HTMLDocumentNode**);
+HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument*,HTMLDocumentObj*,HTMLWindow*,HTMLDocumentNode**);
 
 HRESULT HTMLWindow_Create(nsIDOMWindow*,HTMLWindow**);
 HTMLWindow *nswindow_to_window(const nsIDOMWindow*);
@@ -614,7 +620,7 @@ void get_editor_controller(NSContainer*);
 void init_nsevents(NSContainer*);
 void add_nsevent_listener(HTMLWindow*,LPCWSTR);
 nsresult get_nsinterface(nsISupports*,REFIID,void**);
-void update_nsdocument(HTMLDocument*);
+void update_nsdocument(HTMLDocumentObj*);
 
 void set_document_bscallback(HTMLDocument*,nsChannelBSC*);
 void set_current_mon(HTMLDocument*,IMoniker*);
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c
index e8fa949..54f9aa9 100644
--- a/dlls/mshtml/navigate.c
+++ b/dlls/mshtml/navigate.c
@@ -950,7 +950,7 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream)
 
             /* events are reset when a new document URI is loaded, so re-initialise them here */
             if(This->bsc.doc && This->bsc.doc->bscallback == This && This->bsc.doc->nscontainer) {
-                update_nsdocument(This->bsc.doc);
+                update_nsdocument(This->bsc.doc->doc_obj);
                 init_nsevents(This->bsc.doc->nscontainer);
             }
         }
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c
index 0abb2b4..1a0471d 100644
--- a/dlls/mshtml/nsembed.c
+++ b/dlls/mshtml/nsembed.c
@@ -807,16 +807,18 @@ void set_ns_editmode(NSContainer *This)
     nsIWebBrowser_SetParentURIContentListener(This->webbrowser, NSURICL(This));
 }
 
-void update_nsdocument(HTMLDocument *doc)
+void update_nsdocument(HTMLDocumentObj *doc)
 {
+    HTMLDocumentNode *doc_node;
     nsIDOMHTMLDocument *nsdoc;
     nsIDOMDocument *nsdomdoc;
     nsresult nsres;
+    HRESULT hres;
 
-    if(!doc->nscontainer || !doc->nscontainer->navigation)
+    if(!doc->basedoc.nscontainer || !doc->basedoc.nscontainer->navigation)
         return;
 
-    nsres = nsIWebNavigation_GetDocument(doc->nscontainer->navigation, &nsdomdoc);
+    nsres = nsIWebNavigation_GetDocument(doc->basedoc.nscontainer->navigation, &nsdomdoc);
     if(NS_FAILED(nsres) || !nsdomdoc) {
         ERR("GetDocument failed: %08x\n", nsres);
         return;
@@ -829,20 +831,34 @@ void update_nsdocument(HTMLDocument *doc)
         return;
     }
 
-    if(nsdoc == doc->nsdoc) {
+    if(nsdoc == doc->basedoc.nsdoc) {
         nsIDOMHTMLDocument_Release(nsdoc);
         return;
     }
 
-    if(doc->nsdoc) {
-        remove_mutation_observer(doc->nscontainer, doc->nsdoc);
-        nsIDOMHTMLDocument_Release(doc->nsdoc);
+    if(doc->basedoc.nsdoc) {
+        remove_mutation_observer(doc->basedoc.nscontainer, doc->basedoc.nsdoc);
+        nsIDOMHTMLDocument_Release(doc->basedoc.nsdoc);
+
+        doc_node = doc->basedoc.doc_node;
+        doc_node->basedoc.doc_obj = NULL;
+        IHTMLDocument2_Release(HTMLDOC(&doc_node->basedoc));
+        doc->basedoc.doc_node = NULL;
     }
 
-    doc->nsdoc = nsdoc;
+    doc->basedoc.nsdoc = nsdoc;
+    if(!nsdoc)
+        return;
+
+    set_mutation_observer(doc->basedoc.nscontainer, nsdoc);
+
+    hres = create_doc_from_nsdoc(nsdoc, doc, doc->basedoc.window, &doc_node);
+    if(FAILED(hres)) {
+        ERR("Could not create document: %08x\n", hres);
+        return;
+    }
 
-    if(nsdoc)
-        set_mutation_observer(doc->nscontainer, nsdoc);
+    doc->basedoc.doc_node = doc_node;
 }
 
 void close_gecko(void)
@@ -949,7 +965,7 @@ static nsresult NSAPI nsWebBrowserChrome_SetStatus(nsIWebBrowserChrome *iface,
 
     /* FIXME: This hack should be removed when we'll load all pages by URLMoniker */
     if(This->doc)
-        update_nsdocument(This->doc);
+        update_nsdocument(This->doc->doc_obj);
 
     return NS_OK;
 }
diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c
index d131e8d..930a725 100644
--- a/dlls/mshtml/nsevents.c
+++ b/dlls/mshtml/nsevents.c
@@ -137,7 +137,7 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
     if(!This->doc)
         return NS_OK;
 
-    update_nsdocument(This->doc);
+    update_nsdocument(This->doc->doc_obj);
     connect_scripts(This->doc->window);
 
     if(This->editor_controller) {




More information about the wine-cvs mailing list