Module: wine Branch: master Commit: 570d05ec7c68d9f3e95e737638f28b11a9d43862 URL: http://source.winehq.org/git/wine.git/?a=commit;h=570d05ec7c68d9f3e95e737638...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Apr 22 16:23:22 2014 +0200
mshtml: Added IHTMLDOMChildrenCollection::get__newEnum implementation.
---
dlls/mshtml/htmlnode.c | 172 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 168 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 00468d0..518448b 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -48,6 +48,155 @@ typedef struct { nsIDOMNodeList *nslist; } HTMLDOMChildrenCollection;
+typedef struct { + IEnumVARIANT IEnumVARIANT_iface; + + LONG ref; + + ULONG iter; + HTMLDOMChildrenCollection *col; +} HTMLDOMChildrenCollectionEnum; + +static inline HTMLDOMChildrenCollectionEnum *impl_from_IEnumVARIANT(IEnumVARIANT *iface) +{ + return CONTAINING_RECORD(iface, HTMLDOMChildrenCollectionEnum, IEnumVARIANT_iface); +} + +static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) +{ + HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); + + if(IsEqualGUID(riid, &IID_IUnknown)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = &This->IEnumVARIANT_iface; + }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) { + TRACE("(%p)->(IID_IEnumVARIANT %p)\n", This, ppv); + *ppv = &This->IEnumVARIANT_iface; + }else { + FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI HTMLDOMChildrenCollectionEnum_AddRef(IEnumVARIANT *iface) +{ + HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI HTMLDOMChildrenCollectionEnum_Release(IEnumVARIANT *iface) +{ + HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + IHTMLDOMChildrenCollection_Release(&This->col->IHTMLDOMChildrenCollection_iface); + heap_free(This); + } + + return ref; +} + +static ULONG get_enum_len(HTMLDOMChildrenCollectionEnum *This) +{ + ULONG len; + nsresult nsres; + + nsres = nsIDOMNodeList_GetLength(This->col->nslist, &len); + assert(nsres == NS_OK); + return len; +} + +static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +{ + HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); + ULONG fetched = 0, len; + nsIDOMNode *nsnode; + HTMLDOMNode *node; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%d %p %p)\n", This, celt, rgVar, pCeltFetched); + + len = get_enum_len(This); + + while(This->iter+fetched < len && fetched < celt) { + nsres = nsIDOMNodeList_Item(This->col->nslist, This->iter+fetched, &nsnode); + assert(nsres == NS_OK); + + hres = get_node(This->col->doc, nsnode, TRUE, &node); + nsIDOMNode_Release(nsnode); + if(FAILED(hres)) { + ERR("get_node failed: %08x\n", hres); + break; + } + + V_VT(rgVar+fetched) = VT_DISPATCH; + IHTMLDOMNode_AddRef(&node->IHTMLDOMNode_iface); + V_DISPATCH(rgVar+fetched) = (IDispatch*)&node->IHTMLDOMNode_iface; + fetched++; + } + + This->iter += fetched; + if(pCeltFetched) + *pCeltFetched = fetched; + return fetched == celt ? S_OK : S_FALSE; +} + +static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) +{ + HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); + ULONG len; + + TRACE("(%p)->(%d)\n", This, celt); + + len = get_enum_len(This); + if(This->iter + celt > len) { + This->iter = len; + return S_FALSE; + } + + This->iter += celt; + return S_OK; +} + +static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Reset(IEnumVARIANT *iface) +{ + HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); + + TRACE("(%p)->()\n", This); + + This->iter = 0; + return S_OK; +} + +static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) +{ + HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); + FIXME("(%p)->(%p)\n", This, ppEnum); + return E_NOTIMPL; +} + +static const IEnumVARIANTVtbl HTMLDOMChildrenCollectionEnumVtbl = { + HTMLDOMChildrenCollectionEnum_QueryInterface, + HTMLDOMChildrenCollectionEnum_AddRef, + HTMLDOMChildrenCollectionEnum_Release, + HTMLDOMChildrenCollectionEnum_Next, + HTMLDOMChildrenCollectionEnum_Skip, + HTMLDOMChildrenCollectionEnum_Reset, + HTMLDOMChildrenCollectionEnum_Clone +}; + static inline HTMLDOMChildrenCollection *impl_from_IHTMLDOMChildrenCollection(IHTMLDOMChildrenCollection *iface) { return CONTAINING_RECORD(iface, HTMLDOMChildrenCollection, IHTMLDOMChildrenCollection_iface); @@ -146,11 +295,26 @@ static HRESULT WINAPI HTMLDOMChildrenCollection_get_length(IHTMLDOMChildrenColle return S_OK; }
-static HRESULT WINAPI HTMLDOMChildrenCollection__newEnum(IHTMLDOMChildrenCollection *iface, IUnknown **p) +static HRESULT WINAPI HTMLDOMChildrenCollection_get__newEnum(IHTMLDOMChildrenCollection *iface, IUnknown **p) { HTMLDOMChildrenCollection *This = impl_from_IHTMLDOMChildrenCollection(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + HTMLDOMChildrenCollectionEnum *ret; + + TRACE("(%p)->(%p)\n", This, p); + + ret = heap_alloc(sizeof(*ret)); + if(!ret) + return E_OUTOFMEMORY; + + ret->IEnumVARIANT_iface.lpVtbl = &HTMLDOMChildrenCollectionEnumVtbl; + ret->ref = 1; + ret->iter = 0; + + IHTMLDOMChildrenCollection_AddRef(&This->IHTMLDOMChildrenCollection_iface); + ret->col = This; + + *p = (IUnknown*)&ret->IEnumVARIANT_iface; + return S_OK; }
static HRESULT WINAPI HTMLDOMChildrenCollection_item(IHTMLDOMChildrenCollection *iface, LONG index, IDispatch **ppItem) @@ -196,7 +360,7 @@ static const IHTMLDOMChildrenCollectionVtbl HTMLDOMChildrenCollectionVtbl = { HTMLDOMChildrenCollection_GetIDsOfNames, HTMLDOMChildrenCollection_Invoke, HTMLDOMChildrenCollection_get_length, - HTMLDOMChildrenCollection__newEnum, + HTMLDOMChildrenCollection_get__newEnum, HTMLDOMChildrenCollection_item };