From: Gabriel Ivăncescu gabrielopcode@gmail.com
Not just to avoid boilerplate for now, but needed when we have to convert them to be part of the Cycle Collection (it can form cyclic refs with the enumerator). That's why the collection pointer itself is part of the common impl, since it will have to be traversed.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 57 +++++++++++++++++++++++++ dlls/mshtml/htmlelemcol.c | 80 +++++++----------------------------- dlls/mshtml/mshtml_private.h | 11 +++++ 3 files changed, 82 insertions(+), 66 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index cd256dba677..f5e6462bf54 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -2901,6 +2901,63 @@ static IWineJSDispatchHostVtbl JSDispatchHostVtbl = { JSDispatchHost_ToString, };
+static inline CollectionEnum *CollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface) +{ + return CONTAINING_RECORD(iface, CollectionEnum, IEnumVARIANT_iface); +} + +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; +} + +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; +} + +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->disp->IWineJSDispatchHost_iface); + free(This); + } + + return ref; +} + +IUnknown *CollectionEnum_init(CollectionEnum *colenum, DispatchEx *disp, const IEnumVARIANTVtbl *vtbl) +{ + colenum->IEnumVARIANT_iface.lpVtbl = vtbl; + colenum->ref = 1; + colenum->disp = disp; + DispatchEx_AddRef(&disp->IWineJSDispatchHost_iface); + return (IUnknown*)&colenum->IEnumVARIANT_iface; +} + 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..39165088b91 100644 --- a/dlls/mshtml/htmlelemcol.c +++ b/dlls/mshtml/htmlelemcol.c @@ -40,12 +40,8 @@ typedef struct { } HTMLElementCollection;
typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - + CollectionEnum colenum; ULONG iter; - HTMLElementCollection *col; } HTMLElementCollectionEnum;
typedef struct { @@ -95,64 +91,25 @@ static inline BOOL is_elem_node(nsIDOMNode *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; + return CONTAINING_RECORD(iface, HTMLElementCollectionEnum, colenum.IEnumVARIANT_iface); }
-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) +static inline HTMLElementCollection *impl_from_DispatchEx(DispatchEx *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; + return CONTAINING_RECORD(iface, HTMLElementCollection, dispex); }
static HRESULT WINAPI HTMLElementCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) { HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); + HTMLElementCollection *col = impl_from_DispatchEx(This->colenum.disp); ULONG fetched = 0;
TRACE("(%p)->(%ld %p %p)\n", This, celt, rgVar, pCeltFetched);
- while(This->iter+fetched < This->col->len && fetched < celt) { + while(This->iter+fetched < col->len && fetched < celt) { V_VT(rgVar+fetched) = VT_DISPATCH; - V_DISPATCH(rgVar+fetched) = (IDispatch*)&This->col->elems[This->iter+fetched]->IHTMLElement_iface; + V_DISPATCH(rgVar+fetched) = (IDispatch*)&col->elems[This->iter+fetched]->IHTMLElement_iface; IDispatch_AddRef(V_DISPATCH(rgVar+fetched)); fetched++; } @@ -166,11 +123,12 @@ static HRESULT WINAPI HTMLElementCollectionEnum_Next(IEnumVARIANT *iface, ULONG static HRESULT WINAPI HTMLElementCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) { HTMLElementCollectionEnum *This = impl_from_IEnumVARIANT(iface); + HTMLElementCollection *col = impl_from_DispatchEx(This->colenum.disp);
TRACE("(%p)->(%ld)\n", This, celt);
- if(This->iter + celt > This->col->len) { - This->iter = This->col->len; + if(This->iter + celt > col->len) { + This->iter = col->len; return S_FALSE; }
@@ -196,9 +154,9 @@ static HRESULT WINAPI HTMLElementCollectionEnum_Clone(IEnumVARIANT *iface, IEnum }
static const IEnumVARIANTVtbl HTMLElementCollectionEnumVtbl = { - HTMLElementCollectionEnum_QueryInterface, - HTMLElementCollectionEnum_AddRef, - HTMLElementCollectionEnum_Release, + CollectionEnum_QueryInterface, + CollectionEnum_AddRef, + CollectionEnum_Release, HTMLElementCollectionEnum_Next, HTMLElementCollectionEnum_Skip, HTMLElementCollectionEnum_Reset, @@ -254,14 +212,9 @@ static HRESULT WINAPI HTMLElementCollection_get__newEnum(IHTMLElementCollection 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; + *p = CollectionEnum_init(&ret->colenum, &This->dispex, &HTMLElementCollectionEnumVtbl); return S_OK; }
@@ -459,11 +412,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..9b24bfd9a6e 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -609,6 +609,17 @@ struct DispatchEx { } \ DISPEX_IDISPATCH_NOUNK_IMPL(prefix, iface_name, dispex)
+typedef struct { + IEnumVARIANT IEnumVARIANT_iface; + LONG ref; + DispatchEx *disp; +} CollectionEnum; + +IUnknown *CollectionEnum_init(CollectionEnum*,DispatchEx*,const IEnumVARIANTVtbl*); +HRESULT WINAPI CollectionEnum_QueryInterface(IEnumVARIANT*,REFIID,void**); +ULONG WINAPI CollectionEnum_AddRef(IEnumVARIANT*); +ULONG WINAPI CollectionEnum_Release(IEnumVARIANT*); + typedef struct { void *vtbl; int ref_flags;