Jacek Caban : mshtml: Inherit HTMLDocumentNode from HTMLDOMNode.

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


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

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

mshtml: Inherit HTMLDocumentNode from HTMLDOMNode.

---

 dlls/mshtml/htmldoc.c        |   79 +++++++++++++++++++++++++++---------------
 dlls/mshtml/htmlnode.c       |    3 +-
 dlls/mshtml/mshtml_private.h |   23 ++++++------
 dlls/mshtml/tests/dom.c      |   28 +++++++++++++++
 4 files changed, 93 insertions(+), 40 deletions(-)

diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index 9c9bed2..3bd6ddf 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -1597,7 +1597,7 @@ static const IDispatchExVtbl DocDispatchExVtbl = {
     DocDispatchEx_GetNameSpaceParent
 };
 
-static HRESULT htmldoc_qi(HTMLDocument *This, REFIID riid, void **ppv)
+static BOOL htmldoc_qi(HTMLDocument *This, REFIID riid, void **ppv)
 {
     *ppv = NULL;
 
@@ -1696,25 +1696,25 @@ static HRESULT htmldoc_qi(HTMLDocument *This, REFIID riid, void **ppv)
         *ppv = PERSISTHIST(This);
     }else if(IsEqualGUID(&CLSID_CMarkup, riid)) {
         FIXME("(%p)->(CLSID_CMarkup %p)\n", This, ppv);
-        return E_NOINTERFACE;
+        *ppv = NULL;
     }else if(IsEqualGUID(&IID_IRunnableObject, riid)) {
         TRACE("(%p)->(IID_IRunnableObject %p) returning NULL\n", This, ppv);
-        return E_NOINTERFACE;
+        *ppv = NULL;
     }else if(IsEqualGUID(&IID_IPersistPropertyBag, riid)) {
         TRACE("(%p)->(IID_IPersistPropertyBag %p) returning NULL\n", This, ppv);
-        return E_NOINTERFACE;
+        *ppv = NULL;
     }else if(IsEqualGUID(&IID_IMarshal, riid)) {
         TRACE("(%p)->(IID_IMarshal %p) returning NULL\n", This, ppv);
-        return E_NOINTERFACE;
+        *ppv = NULL;
     }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
-        return *ppv ? S_OK : E_NOINTERFACE;
+        return TRUE;
     }else {
-        FIXME("(%p)->(%s %p) interface not supported\n", This, debugstr_guid(riid), ppv);
-        return E_NOINTERFACE;
+        return FALSE;
     }
 
-    IUnknown_AddRef((IUnknown*)*ppv);
-    return S_OK;
+    if(*ppv)
+        IUnknown_AddRef((IUnknown*)*ppv);
+    return TRUE;
 }
 
 static const tid_t HTMLDocument_iface_tids[] = {
@@ -1777,35 +1777,21 @@ static HRESULT HTMLDocumentNode_QueryInterface(HTMLDocument *base, REFIID riid,
 {
     HTMLDocumentNode *This = HTMLDOCNODE_THIS(base);
 
-    return htmldoc_qi(&This->basedoc, riid, ppv);
+    return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(&This->node), riid, ppv);
 }
 
 static ULONG HTMLDocumentNode_AddRef(HTMLDocument *base)
 {
     HTMLDocumentNode *This = HTMLDOCNODE_THIS(base);
-    ULONG ref = InterlockedIncrement(&This->ref);
-
-    TRACE("(%p) ref = %u\n", This, ref);
 
-    return ref;
+    return IHTMLDOMNode_AddRef(HTMLDOMNODE(&This->node));
 }
 
 static ULONG HTMLDocumentNode_Release(HTMLDocument *base)
 {
     HTMLDocumentNode *This = HTMLDOCNODE_THIS(base);
-    ULONG ref = InterlockedDecrement(&This->ref);
-
-    TRACE("(%p) ref = %u\n", This, ref);
 
-    if(!ref) {
-        detach_selection(This);
-        detach_ranges(This);
-        release_nodes(This);
-        destroy_htmldoc(&This->basedoc);
-        heap_free(This);
-    }
-
-    return ref;
+    return IHTMLDOMNode_Release(HTMLDOMNODE(&This->node));
 }
 
 #undef HTMLDOCNODE_THIS
@@ -1816,6 +1802,35 @@ static const htmldoc_vtbl_t HTMLDocumentNodeVtbl = {
     HTMLDocumentNode_Release
 };
 
+#define HTMLDOCNODE_NODE_THIS(iface) DEFINE_THIS2(HTMLDocumentNode, node, iface)
+
+static HRESULT HTMLDocumentNode_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
+{
+    HTMLDocumentNode *This = HTMLDOCNODE_NODE_THIS(iface);
+
+    if(htmldoc_qi(&This->basedoc, riid, ppv))
+        return *ppv ? S_OK : E_NOINTERFACE;
+
+    return HTMLDOMNode_QI(&This->node, riid, ppv);
+}
+
+void HTMLDocumentNode_destructor(HTMLDOMNode *iface)
+{
+    HTMLDocumentNode *This = HTMLDOCNODE_NODE_THIS(iface);
+
+    detach_selection(This);
+    detach_ranges(This);
+    release_nodes(This);
+    destroy_htmldoc(&This->basedoc);
+}
+
+#undef HTMLDOCNODE_NODE_THIS
+
+static const NodeImplVtbl HTMLDocumentNodeImplVtbl = {
+    HTMLDocumentNode_QI,
+    HTMLDocumentNode_destructor
+};
+
 HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocumentObj *doc_obj, HTMLWindow *window, HTMLDocumentNode **ret)
 {
     HTMLDocumentNode *doc;
@@ -1838,6 +1853,9 @@ HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocumentObj *doc_ob
     list_init(&doc->selection_list);
     list_init(&doc->range_list);
 
+    HTMLDOMNode_Init(doc, &doc->node, (nsIDOMNode*)nsdoc);
+    doc->node.vtbl = &HTMLDocumentNodeImplVtbl;
+
     *ret = doc;
     return S_OK;
 }
@@ -1848,7 +1866,12 @@ static HRESULT HTMLDocumentObj_QueryInterface(HTMLDocument *base, REFIID riid, v
 {
     HTMLDocumentObj *This = HTMLDOCOBJ_THIS(base);
 
-    return htmldoc_qi(&This->basedoc, riid, ppv);
+    if(htmldoc_qi(&This->basedoc, riid, ppv))
+        return *ppv ? S_OK : E_NOINTERFACE;
+
+    FIXME("Unimplemented interface %s\n", debugstr_guid(riid));
+    *ppv = NULL;
+    return E_NOINTERFACE;
 }
 
 static ULONG HTMLDocumentObj_AddRef(HTMLDocument *base)
diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c
index cdfa6fa..399355b 100644
--- a/dlls/mshtml/htmlnode.c
+++ b/dlls/mshtml/htmlnode.c
@@ -972,6 +972,7 @@ void release_nodes(HTMLDocumentNode *This)
     for(iter = This->nodes; iter; iter = next) {
         next = iter->next;
         iter->doc = NULL;
-        IHTMLDOMNode_Release(HTMLDOMNODE(iter));
+        if(&This->node != iter)
+            IHTMLDOMNode_Release(HTMLDOMNODE(iter));
     }
 }
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index b823093..828aebb 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -306,17 +306,6 @@ static inline ULONG htmldoc_release(HTMLDocument *This)
     return This->vtbl->release(This);
 }
 
-struct HTMLDocumentNode {
-    HTMLDocument basedoc;
-
-    LONG ref;
-
-    HTMLDOMNode *nodes;
-
-    struct list selection_list;
-    struct list range_list;
-};
-
 struct HTMLDocumentObj {
     HTMLDocument basedoc;
 
@@ -477,6 +466,18 @@ typedef struct {
     ConnectionPoint cp;
 } HTMLTextContainer;
 
+struct HTMLDocumentNode {
+    HTMLDOMNode node;
+    HTMLDocument basedoc;
+
+    LONG ref;
+
+    HTMLDOMNode *nodes;
+
+    struct list selection_list;
+    struct list range_list;
+};
+
 #define HTMLWINDOW2(x)   ((IHTMLWindow2*)                 &(x)->lpHTMLWindow2Vtbl)
 #define HTMLWINDOW3(x)   ((IHTMLWindow3*)                 &(x)->lpHTMLWindow3Vtbl)
 
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index b69705d..bc6f699 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -94,6 +94,31 @@ static const IID * const none_iids[] = {
     NULL
 };
 
+static const IID * const doc_node_iids[] = {
+    &IID_IHTMLDOMNode,
+    &IID_IHTMLDOMNode2,
+    &IID_IHTMLDocument,
+    &IID_IHTMLDocument2,
+    &IID_IHTMLDocument3,
+    &IID_IHTMLDocument4,
+    &IID_IHTMLDocument5,
+    &IID_IDispatchEx,
+    &IID_IConnectionPointContainer,
+    NULL
+};
+
+static const IID * const doc_obj_iids[] = {
+    &IID_IHTMLDocument,
+    &IID_IHTMLDocument2,
+    &IID_IHTMLDocument3,
+    &IID_IHTMLDocument4,
+    &IID_IHTMLDocument5,
+    &IID_IDispatchEx,
+    &IID_IConnectionPointContainer,
+    &IID_ICustomDoc,
+    NULL
+};
+
 static const IID * const elem_iids[] = {
     &IID_IHTMLDOMNode,
     &IID_IHTMLDOMNode2,
@@ -4082,6 +4107,9 @@ static void test_window(IHTMLDocument2 *doc)
     ok(hres == S_OK, "get_document failed: %08x\n", hres);
     ok(doc2 != NULL, "doc2 == NULL\n");
 
+    test_ifaces((IUnknown*)doc2, doc_node_iids);
+    test_ifaces((IUnknown*)doc, doc_obj_iids);
+
     IHTMLDocument_Release(doc2);
 
     hres = IHTMLWindow2_get_window(window, &window2);




More information about the wine-cvs mailing list