Jacek Caban : mshtml: Added IHTMLElementCollection implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Mar 6 12:54:55 CST 2006


Module: wine
Branch: refs/heads/master
Commit: d6d76870cb1ccb83f6feb8736dfca6d9dc1d984d
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=d6d76870cb1ccb83f6feb8736dfca6d9dc1d984d

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Sun Mar  5 21:56:04 2006 +0100

mshtml: Added IHTMLElementCollection implementation.

- Added IHTMLElementCollection implementation.
- Added get_all implementation.

---

 dlls/mshtml/htmlelem.c |  267 ++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/mshtml/htmlnode.c |    1 
 2 files changed, 266 insertions(+), 2 deletions(-)

diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index 9502b7a..818a3a3 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -36,6 +36,8 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
 
+static HRESULT HTMLElementCollection_Create(IUnknown*,HTMLElement**,DWORD,IDispatch**);
+
 #define HTMLELEM_THIS(iface) DEFINE_THIS(HTMLElement, HTMLElement, iface)
 
 static HRESULT WINAPI HTMLElement_QueryInterface(IHTMLElement *iface,
@@ -738,11 +740,67 @@ static HRESULT WINAPI HTMLElement_get_ch
     return E_NOTIMPL;
 }
 
+static void create_all_list(HTMLDocument *doc, HTMLElement *elem, HTMLElement ***list, DWORD *size,
+                        DWORD *len)
+{
+    nsIDOMNodeList *nsnode_list;
+    nsIDOMNode *iter;
+    PRUint32 list_len = 0, i;
+    HTMLDOMNode *node;
+    nsresult nsres;
+
+    nsres = nsIDOMNode_GetChildNodes(elem->node->nsnode, &nsnode_list);
+    if(NS_FAILED(nsres)) {
+        ERR("GetChildNodes failed: %08lx\n", nsres);
+        return;
+    }
+
+    nsIDOMNodeList_GetLength(nsnode_list, &list_len);
+    if(!list_len)
+        return;
+
+    for(i=0; i<list_len; i++) {
+        nsres = nsIDOMNodeList_Item(nsnode_list, i, &iter);
+        if(NS_FAILED(nsres)) {
+            ERR("Item failed: %08lx\n", nsres);
+            continue;
+        }
+
+        node = get_node(doc, iter);
+        if(node->node_type != NT_HTMLELEM)
+            continue;
+
+        if(*len == *size) {
+            *size <<= 1;
+            *list = HeapReAlloc(GetProcessHeap(), 0, *list, *size * sizeof(HTMLElement**));
+        }
+
+        (*list)[(*len)++] = (HTMLElement*)node->impl.elem;
+
+        create_all_list(doc, (HTMLElement*)node->impl.elem, list, size, len);
+    }
+}
+
 static HRESULT WINAPI HTMLElement_get_all(IHTMLElement *iface, IDispatch **p)
 {
     HTMLElement *This = HTMLELEM_THIS(iface);
-    FIXME("(%p)->(%p)\n", This, p);
-    return E_NOTIMPL;
+    HTMLElement **elem_list;
+    DWORD list_size = 8, len = 0;
+
+    TRACE("(%p)->(%p)\n", This, p);
+
+    elem_list = HeapAlloc(GetProcessHeap(), 0, list_size*sizeof(HTMLElement**));
+
+    create_all_list(This->node->doc, This, &elem_list, &list_size, &len);
+
+    if(!len) {
+        HeapFree(GetProcessHeap(), 0, elem_list);
+        elem_list = NULL;
+    }else if(list_size > len) {
+        elem_list = HeapReAlloc(GetProcessHeap(), 0, elem_list, len*sizeof(HTMLElement**));
+    }
+
+    return HTMLElementCollection_Create((IUnknown*)HTMLELEM(This), elem_list, len, p);
 }
 
 static void HTMLElement_destructor(IUnknown *iface)
@@ -873,3 +931,208 @@ void HTMLElement_Create(HTMLDOMNode *nod
 
     nsIDOMNode_QueryInterface(node->nsnode, &IID_nsIDOMHTMLElement, (void**)&ret->nselem);
 }
+
+typedef struct {
+    const IHTMLElementCollectionVtbl *lpHTMLElementCollectionVtbl;
+
+    IUnknown *ref_unk;
+    HTMLElement **elems;
+    DWORD len;
+
+    LONG ref;
+} HTMLElementCollection;
+
+#define HTMLELEMCOL(x)  ((IHTMLElementCollection*) &(x)->lpHTMLElementCollectionVtbl)
+
+#define ELEMCOL_THIS(iface) DEFINE_THIS(HTMLElementCollection, HTMLElementCollection, iface)
+
+static HRESULT WINAPI HTMLElementCollection_QueryInterface(IHTMLElementCollection *iface,
+                                                           REFIID riid, void **ppv)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+
+    *ppv = NULL;
+
+    if(IsEqualGUID(&IID_IUnknown, riid)) {
+        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+        *ppv = HTMLELEMCOL(This);
+    }else if(IsEqualGUID(&IID_IDispatch, riid)) {
+        TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
+        *ppv = HTMLELEMCOL(This);
+    }else if(IsEqualGUID(&IID_IHTMLElementCollection, riid)) {
+        TRACE("(%p)->(IID_IHTMLElementCollection %p)\n", This, ppv);
+        *ppv = HTMLELEMCOL(This);
+    }
+
+    if(*ppv) {
+        IHTMLElementCollection_AddRef(HTMLELEMCOL(This));
+        return S_OK;
+    }
+
+    FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI HTMLElementCollection_AddRef(IHTMLElementCollection *iface)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%ld\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI HTMLElementCollection_Release(IHTMLElementCollection *iface)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%ld\n", This, ref);
+
+    if(!ref) {
+        IUnknown_Release(This->ref_unk);
+        HeapFree(GetProcessHeap(), 0, This->elems);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI HTMLElementCollection_GetTypeInfoCount(IHTMLElementCollection *iface,
+                                                             UINT *pctinfo)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+    FIXME("(%p)->(%p)\n", This, pctinfo);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLElementCollection_GetTypeInfo(IHTMLElementCollection *iface,
+        UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+    FIXME("(%p)->(%u %lu %p)\n", This, iTInfo, lcid, ppTInfo);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLElementCollection_GetIDsOfNames(IHTMLElementCollection *iface,
+        REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+    FIXME("(%p)->(%s %p %u %lu %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
+                                        lcid, rgDispId);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLElementCollection_Invoke(IHTMLElementCollection *iface,
+        DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
+        VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+    FIXME("(%p)->(%ld %s %ld %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
+            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLElementCollection_toString(IHTMLElementCollection *iface,
+                                                     BSTR *String)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+    FIXME("(%p)->(%p)\n", This, String);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLElementCollection_put_length(IHTMLElementCollection *iface,
+                                                       long v)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+    FIXME("(%p)->(%ld)\n", This, v);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLElementCollection_get_length(IHTMLElementCollection *iface,
+                                                       long *p)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+
+    TRACE("(%p)->(%p)\n", This, p);
+
+    *p = This->len;
+    return S_OK;
+}
+
+static HRESULT WINAPI HTMLElementCollection_get__newEnum(IHTMLElementCollection *iface,
+                                                         IUnknown **p)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+    FIXME("(%p)->(%p)\n", This, p);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLElementCollection_item(IHTMLElementCollection *iface,
+        VARIANT name, VARIANT index, IDispatch **pdisp)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+
+    if(V_VT(&index) != VT_I4) {
+        WARN("Invalid index vt=%d\n", V_VT(&index));
+        return E_INVALIDARG;
+    }
+
+    if(V_VT(&name) != VT_I4 || V_I4(&name) != V_I4(&index))
+        FIXME("Unsupproted name vt=%d\n", V_VT(&name));
+
+    TRACE("(%p)->(%ld %ld %p)\n", This, V_I4(&name), V_I4(&index), pdisp);
+
+    if(V_I4(&index) < 0 || V_I4(&index) >= This->len)
+        return E_INVALIDARG;
+
+    *pdisp = (IDispatch*)This->elems[V_I4(&index)];
+    IDispatch_AddRef(*pdisp);
+    return S_OK;
+}
+
+static HRESULT WINAPI HTMLElementCollection_tags(IHTMLElementCollection *iface,
+                                                 VARIANT tagName, IDispatch **pdisp)
+{
+    HTMLElementCollection *This = ELEMCOL_THIS(iface);
+    FIXME("(%p)->(%s %p)\n", This, debugstr_w(V_BSTR(&tagName)), pdisp);
+    return E_NOTIMPL;
+}
+
+#undef ELEMCOL_THIS
+
+static const IHTMLElementCollectionVtbl HTMLElementCollectionVtbl = {
+    HTMLElementCollection_QueryInterface,
+    HTMLElementCollection_AddRef,
+    HTMLElementCollection_Release,
+    HTMLElementCollection_GetTypeInfoCount,
+    HTMLElementCollection_GetTypeInfo,
+    HTMLElementCollection_GetIDsOfNames,
+    HTMLElementCollection_Invoke,
+    HTMLElementCollection_toString,
+    HTMLElementCollection_put_length,
+    HTMLElementCollection_get_length,
+    HTMLElementCollection_get__newEnum,
+    HTMLElementCollection_item,
+    HTMLElementCollection_tags
+};
+
+static HRESULT HTMLElementCollection_Create(IUnknown *ref_unk, HTMLElement **elems, DWORD len,
+                                            IDispatch **p)
+{
+    HTMLElementCollection *ret = HeapAlloc(GetProcessHeap(), 0, sizeof(HTMLElementCollection));
+
+    ret->lpHTMLElementCollectionVtbl = &HTMLElementCollectionVtbl;
+    ret->ref = 1;
+    ret->elems = elems;
+    ret->len = len;
+
+    IUnknown_AddRef(ref_unk);
+    ret->ref_unk = ref_unk;
+
+    TRACE("ret=%p len=%ld\n", ret, len);
+
+    *p = (IDispatch*)ret;
+    return S_OK;
+}
diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c
index cb4e8e6..ef8f5fa 100644
--- a/dlls/mshtml/htmlnode.c
+++ b/dlls/mshtml/htmlnode.c
@@ -328,6 +328,7 @@ HTMLDOMNode *get_node(HTMLDocument *This
     ret->lpHTMLDOMNodeVtbl = &HTMLDOMNodeVtbl;
     ret->node_type = NT_UNKNOWN;
     ret->impl.unk = NULL;
+    ret->destructor = NULL;
     ret->doc = This;
 
     nsIDOMNode_AddRef(nsnode);




More information about the wine-cvs mailing list