Jacek Caban : mshtml: Added support to accessing child nodes by index in IHTMLDOMChildrenCollection .

Alexandre Julliard julliard at winehq.org
Tue Jun 24 06:45:09 CDT 2008


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Jun 23 20:02:42 2008 -0500

mshtml: Added support to accessing child nodes by index in IHTMLDOMChildrenCollection.

---

 dlls/mshtml/htmlnode.c  |   79 ++++++++++++++++++++++++++++++++++++++++++++---
 dlls/mshtml/tests/dom.c |   46 +++++++++++++++++++++++++++
 2 files changed, 120 insertions(+), 5 deletions(-)

diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c
index 6886508..bfa999f 100644
--- a/dlls/mshtml/htmlnode.c
+++ b/dlls/mshtml/htmlnode.c
@@ -180,6 +180,58 @@ static HRESULT WINAPI HTMLDOMChildrenCollection_item(IHTMLDOMChildrenCollection
     return S_OK;
 }
 
+#define DISPID_CHILDCOL_0 MSHTML_DISPID_CUSTOM_MIN
+
+static HRESULT HTMLDOMChildrenCollection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid)
+{
+    HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface);
+    WCHAR *ptr;
+    DWORD idx=0;
+    PRUint32 len = 0;
+
+    for(ptr = name; *ptr && isdigitW(*ptr); ptr++)
+        idx = idx*10 + (*ptr-'0');
+    if(*ptr)
+        return DISP_E_UNKNOWNNAME;
+
+    nsIDOMNodeList_GetLength(This->nslist, &len);
+    if(idx >= len)
+        return DISP_E_UNKNOWNNAME;
+
+    *dispid = DISPID_CHILDCOL_0 + idx;
+    TRACE("ret %x\n", *dispid);
+    return S_OK;
+}
+
+static HRESULT HTMLDOMChildrenCollection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
+        VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
+{
+    HTMLDOMChildrenCollection *This = HTMLCHILDCOL_THIS(iface);
+
+    TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller);
+
+    switch(flags) {
+    case INVOKE_PROPERTYGET: {
+        IDispatch *disp = NULL;
+        HRESULT hres;
+
+        hres = IHTMLDOMChildrenCollection_item(HTMLCHILDCOL(This), id - DISPID_CHILDCOL_0, &disp);
+        if(0&&FAILED(hres))
+            return hres;
+
+        V_VT(res) = VT_DISPATCH;
+        V_DISPATCH(res) = disp;
+        break;
+    }
+
+    default:
+        FIXME("unimplemented flags %x\n", flags);
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
 #undef HTMLCHILDCOL_THIS
 
 static const IHTMLDOMChildrenCollectionVtbl HTMLDOMChildrenCollectionVtbl = {
@@ -199,8 +251,14 @@ static const tid_t HTMLDOMChildrenCollection_iface_tids[] = {
     IHTMLDOMChildrenCollection_tid,
     0
 };
+
+static const dispex_static_data_vtbl_t HTMLDOMChildrenCollection_dispex_vtbl = {
+    HTMLDOMChildrenCollection_get_dispid,
+    HTMLDOMChildrenCollection_invoke
+};
+
 static dispex_static_data_t HTMLDOMChildrenCollection_dispex = {
-    NULL,
+    &HTMLDOMChildrenCollection_dispex_vtbl,
     DispDOMChildrenCollection_tid,
     NULL,
     HTMLDOMChildrenCollection_iface_tids
@@ -374,11 +432,11 @@ static HRESULT WINAPI HTMLDOMNode_insertBefore(IHTMLDOMNode *iface, IHTMLDOMNode
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI HTMLDOMNode_removeChild(IHTMLDOMNode *iface, IHTMLDOMNode *newChild,
+static HRESULT WINAPI HTMLDOMNode_removeChild(IHTMLDOMNode *iface, IHTMLDOMNode *oldChild,
                                               IHTMLDOMNode **node)
 {
     HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
-    FIXME("(%p)->(%p %p)\n", This, newChild, node);
+    FIXME("(%p)->(%p %p)\n", This, oldChild, node);
     return E_NOTIMPL;
 }
 
@@ -548,8 +606,19 @@ static HRESULT WINAPI HTMLDOMNode_get_firstChild(IHTMLDOMNode *iface, IHTMLDOMNo
 static HRESULT WINAPI HTMLDOMNode_get_lastChild(IHTMLDOMNode *iface, IHTMLDOMNode **p)
 {
     HTMLDOMNode *This = HTMLDOMNODE_THIS(iface);
-    FIXME("(%p)->(%p)\n", This, p);
-    return E_NOTIMPL;
+    nsIDOMNode *nschild = NULL;
+
+    TRACE("(%p)->(%p)\n", This, p);
+
+    nsIDOMNode_GetLastChild(This->nsnode, &nschild);
+    if(nschild) {
+        *p = HTMLDOMNODE(get_node(This->doc, nschild, TRUE));
+        IHTMLDOMNode_AddRef(*p);
+    }else {
+        *p = NULL;
+    }
+
+    return S_OK;
 }
 
 static HRESULT WINAPI HTMLDOMNode_get_previousSibling(IHTMLDOMNode *iface, IHTMLDOMNode **p)
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index ae8f6de..7d57b24 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -1792,6 +1792,50 @@ static void test_stylesheets(IHTMLDocument2 *doc)
     IHTMLStyleSheetsCollection_Release(col);
 }
 
+static void test_child_col_disp(IHTMLDOMChildrenCollection *col)
+{
+    IDispatchEx *dispex;
+    IHTMLDOMNode *node;
+    DISPPARAMS dp = {NULL, NULL, 0, 0};
+    VARIANT var;
+    EXCEPINFO ei;
+    long type;
+    DISPID id;
+    BSTR bstr;
+    HRESULT hres;
+
+    static const WCHAR w0[] = {'0',0};
+    static const WCHAR w100[] = {'1','0','0',0};
+
+    hres = IHTMLDOMChildrenCollection_QueryInterface(col, &IID_IDispatchEx, (void**)&dispex);
+    ok(hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
+
+    bstr = SysAllocString(w0);
+    hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
+    ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
+    SysFreeString(bstr);
+
+    VariantInit(&var);
+    hres = IDispatchEx_InvokeEx(dispex, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_DISPATCH, "V_VT(var)=%d\n", V_VT(&var));
+    ok(V_DISPATCH(&var) != NULL, "V_DISPATCH(var) == NULL\n");
+    node = get_node_iface((IUnknown*)V_DISPATCH(&var));
+    type = get_node_type((IUnknown*)node);
+    ok(type == 3, "type=%ld\n", type);
+    IHTMLDOMNode_Release(node);
+    VariantClear(&var);
+
+    bstr = SysAllocString(w100);
+    hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameCaseSensitive, &id);
+    ok(hres == DISP_E_UNKNOWNNAME, "GetDispID failed: %08x, expected DISP_E_UNKNOWNNAME\n", hres);
+    SysFreeString(bstr);
+
+    IDispatchEx_Release(dispex);
+}
+
+
+
 static void test_elems(IHTMLDocument2 *doc)
 {
     IHTMLElementCollection *col;
@@ -1998,6 +2042,8 @@ static void test_elems(IHTMLDocument2 *doc)
         ok(hres == E_INVALIDARG, "item failed: %08x, expected E_INVALIDARG\n", hres);
         ok(disp == (void*)0xdeadbeef, "disp=%p\n", disp);
 
+        test_child_col_disp(child_col);
+
         IHTMLDOMChildrenCollection_Release(child_col);
     }
 




More information about the wine-cvs mailing list