From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 141 +++++++++++++++++++++++++++++++++++ dlls/mshtml/htmlelemcol.c | 139 ++++------------------------------ dlls/mshtml/mshtml_private.h | 17 +++++ 3 files changed, 171 insertions(+), 126 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index cd256dba677..88d2e3e37ba 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -2901,6 +2901,147 @@ static IWineJSDispatchHostVtbl JSDispatchHostVtbl = { JSDispatchHost_ToString, };
+static inline CollectionEnum *CollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface) +{ + return CONTAINING_RECORD(iface, CollectionEnum, IEnumVARIANT_iface); +} + +static HRESULT WINAPI CollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); + + if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumVARIANT)) + *ppv = &This->IEnumVARIANT_iface; + else { + FIXME("Unsupported iface %s\n", debugstr_mshtml_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI CollectionEnum_AddRef(IEnumVARIANT *iface) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + return ref; +} + +static ULONG WINAPI CollectionEnum_Release(IEnumVARIANT *iface) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%ld\n", This, ref); + + if(!ref) { + DispatchEx_Release(&This->collection->IWineJSDispatchHost_iface); + free(This); + } + + return ref; +} + +static HRESULT WINAPI CollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + ULONG iter = This->iter, len, fetched = 0; + DispatchEx *col = This->collection; + HRESULT hres; + + TRACE("(%p)->(%ld %p %p)\n", This, celt, rgVar, pCeltFetched); + + len = This->vtbl->get_length(col); + + while(iter + fetched < len && fetched < celt) { + hres = This->vtbl->get_item(col, iter + fetched, &V_DISPATCH(rgVar + fetched)); + if(FAILED(hres)) { + while(fetched--) + VariantClear(rgVar + fetched); + return hres; + } + V_VT(rgVar + fetched) = V_DISPATCH(rgVar + fetched) ? VT_DISPATCH : VT_NULL; + fetched++; + } + + This->iter = iter + fetched; + if(pCeltFetched) + *pCeltFetched = fetched; + return fetched == celt ? S_OK : S_FALSE; +} + +static HRESULT WINAPI CollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + ULONG len; + + TRACE("(%p)->(%ld)\n", This, celt); + + len = This->vtbl->get_length(This->collection); + + if(This->iter + celt > len) { + This->iter = len; + return S_FALSE; + } + + This->iter += celt; + return S_OK; +} + +static HRESULT WINAPI CollectionEnum_Reset(IEnumVARIANT *iface) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + + TRACE("(%p)->()\n", This); + + This->iter = 0; + return S_OK; +} + +static HRESULT WINAPI CollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); + + FIXME("(%p)->(%p)\n", This, ppEnum); + + return E_NOTIMPL; +} + +static const IEnumVARIANTVtbl CollectionEnumVtbl = { + CollectionEnum_QueryInterface, + CollectionEnum_AddRef, + CollectionEnum_Release, + CollectionEnum_Next, + CollectionEnum_Skip, + CollectionEnum_Reset, + CollectionEnum_Clone +}; + +HRESULT CollectionEnum_create(DispatchEx *collection, const CollectionEnum_vtbl *vtbl, IUnknown **ret) +{ + CollectionEnum *colenum = malloc(sizeof(*colenum)); + + if(!colenum) + return E_OUTOFMEMORY; + + colenum->vtbl = vtbl; + colenum->IEnumVARIANT_iface.lpVtbl = &CollectionEnumVtbl; + colenum->ref = 1; + colenum->iter = 0; + colenum->collection = collection; + DispatchEx_AddRef(&collection->IWineJSDispatchHost_iface); + + *ret = (IUnknown*)&colenum->IEnumVARIANT_iface; + return S_OK; +} + HRESULT dispex_builtin_props_to_json(DispatchEx *dispex, HTMLInnerWindow *window, VARIANT *ret) { func_info_t *func, *end; diff --git a/dlls/mshtml/htmlelemcol.c b/dlls/mshtml/htmlelemcol.c index 5b3d9b56310..937628e7b4f 100644 --- a/dlls/mshtml/htmlelemcol.c +++ b/dlls/mshtml/htmlelemcol.c @@ -39,15 +39,6 @@ typedef struct { DWORD len; } HTMLElementCollection;
-typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - - ULONG iter; - HTMLElementCollection *col; -} HTMLElementCollectionEnum; - typedef struct { HTMLElement **buf; DWORD len; @@ -93,116 +84,30 @@ static inline BOOL is_elem_node(nsIDOMNode *node) return type == ELEMENT_NODE || type == COMMENT_NODE; }
-static inline HTMLElementCollectionEnum *impl_from_IEnumVARIANT(IEnumVARIANT *iface) -{ - return CONTAINING_RECORD(iface, HTMLElementCollectionEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLElementCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - - if(IsEqualGUID(riid, &IID_IUnknown)) { - *ppv = &This->IEnumVARIANT_iface; - }else if(IsEqualGUID(riid, &IID_IEnumVARIANT)) { - *ppv = &This->IEnumVARIANT_iface; - }else { - FIXME("Unsupported iface %s\n", debugstr_mshtml_guid(riid)); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLElementCollectionEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLElementCollectionEnum_Release(IEnumVARIANT *iface) -{ - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLElementCollection_Release(&This->col->IHTMLElementCollection_iface); - free(This); - } - - return ref; -} - -static HRESULT WINAPI HTMLElementCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) +static inline HTMLElementCollection *impl_from_DispatchEx(DispatchEx *iface) { - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - ULONG fetched = 0; - - TRACE("(%p)->(%ld %p %p)\n", This, celt, rgVar, pCeltFetched); - - while(This->iter+fetched < This->col->len && fetched < celt) { - V_VT(rgVar+fetched) = VT_DISPATCH; - V_DISPATCH(rgVar+fetched) = (IDispatch*)&This->col->elems[This->iter+fetched]->IHTMLElement_iface; - IDispatch_AddRef(V_DISPATCH(rgVar+fetched)); - fetched++; - } - - This->iter += fetched; - if(pCeltFetched) - *pCeltFetched = fetched; - return fetched == celt ? S_OK : S_FALSE; + return CONTAINING_RECORD(iface, HTMLElementCollection, dispex); }
-static HRESULT WINAPI HTMLElementCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) +static ULONG HTMLElementCollectionEnum_get_length(DispatchEx *dispex) { - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); + HTMLElementCollection *col = impl_from_DispatchEx(dispex);
- TRACE("(%p)->(%ld)\n", This, celt); - - if(This->iter + celt > This->col->len) { - This->iter = This->col->len; - return S_FALSE; - } - - This->iter += celt; - return S_OK; + return col->len; }
-static HRESULT WINAPI HTMLElementCollectionEnum_Reset(IEnumVARIANT *iface) +static HRESULT HTMLElementCollectionEnum_get_item(DispatchEx *dispex, ULONG index, IDispatch **p) { - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - - TRACE("(%p)->()\n", This); + HTMLElementCollection *col = impl_from_DispatchEx(dispex);
- This->iter = 0; + *p = (IDispatch*)&col->elems[index]->IHTMLElement_iface; + IDispatch_AddRef(*p); return S_OK; }
-static HRESULT WINAPI HTMLElementCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum) -{ - HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); - FIXME("(%p)->(%p)\n", This, ppEnum); - return E_NOTIMPL; -} - -static const IEnumVARIANTVtbl HTMLElementCollectionEnumVtbl = { - HTMLElementCollectionEnum_QueryInterface, - HTMLElementCollectionEnum_AddRef, - HTMLElementCollectionEnum_Release, - HTMLElementCollectionEnum_Next, - HTMLElementCollectionEnum_Skip, - HTMLElementCollectionEnum_Reset, - HTMLElementCollectionEnum_Clone +static const CollectionEnum_vtbl HTMLElementCollectionEnum_vtbl = { + HTMLElementCollectionEnum_get_length, + HTMLElementCollectionEnum_get_item, };
static inline HTMLElementCollection *impl_from_IHTMLElementCollection(IHTMLElementCollection *iface) @@ -246,23 +151,10 @@ static HRESULT WINAPI HTMLElementCollection_get__newEnum(IHTMLElementCollection IUnknown **p) { HTMLElementCollection *This = impl_from_IHTMLElementCollection(iface); - HTMLElementCollectionEnum *ret;
TRACE("(%p)->(%p)\n", This, p);
- ret = malloc(sizeof(*ret)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IEnumVARIANT_iface.lpVtbl = &HTMLElementCollectionEnumVtbl; - ret->ref = 1; - ret->iter = 0; - - IHTMLElementCollection_AddRef(&This->IHTMLElementCollection_iface); - ret->col = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; - return S_OK; + return CollectionEnum_create(&This->dispex, &HTMLElementCollectionEnum_vtbl, p); }
static BOOL is_elem_id(HTMLElement *elem, LPCWSTR name) @@ -459,11 +351,6 @@ static const IHTMLElementCollectionVtbl HTMLElementCollectionVtbl = { HTMLElementCollection_tags };
-static inline HTMLElementCollection *impl_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLElementCollection, dispex); -} - static void *HTMLElementCollection_query_interface(DispatchEx *dispex, REFIID riid) { HTMLElementCollection *This = impl_from_DispatchEx(dispex); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 6e4a58aee55..0966b294e46 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -360,6 +360,7 @@ typedef struct dispex_dynamic_data_t dispex_dynamic_data_t; #define MSHTML_CUSTOM_DISPID_CNT (MSHTML_DISPID_CUSTOM_MAX-MSHTML_DISPID_CUSTOM_MIN)
typedef struct DispatchEx DispatchEx; +typedef struct CollectionEnum CollectionEnum; typedef struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback; typedef struct dispex_static_data_t dispex_static_data_t;
@@ -609,6 +610,22 @@ struct DispatchEx { } \ DISPEX_IDISPATCH_NOUNK_IMPL(prefix, iface_name, dispex)
+typedef struct { + ULONG (*get_length)(DispatchEx*); + HRESULT (*get_item)(DispatchEx*,ULONG,IDispatch**); +} CollectionEnum_vtbl; + +struct CollectionEnum { + const CollectionEnum_vtbl *vtbl; + IEnumVARIANT IEnumVARIANT_iface; + LONG ref; + + DispatchEx *collection; + ULONG iter; +}; + +HRESULT CollectionEnum_create(DispatchEx*,const CollectionEnum_vtbl*,IUnknown**); + typedef struct { void *vtbl; int ref_flags;