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