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;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlnode.c | 76 +++++++----------------------------------- 1 file changed, 12 insertions(+), 64 deletions(-)
diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 0d9a5259935..1a4f7cda40e 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -44,70 +44,27 @@ typedef struct { } HTMLDOMChildrenCollection;
typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - + CollectionEnum colenum; 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); - - 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("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; + return CONTAINING_RECORD(iface, HTMLDOMChildrenCollectionEnum, colenum.IEnumVARIANT_iface); }
-static ULONG WINAPI HTMLDOMChildrenCollectionEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLDOMChildrenCollectionEnum_Release(IEnumVARIANT *iface) +static inline HTMLDOMChildrenCollection *impl_from_DispatchEx(DispatchEx *iface) { - HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLDOMChildrenCollection_Release(&This->col->IHTMLDOMChildrenCollection_iface); - free(This); - } - - return ref; + return CONTAINING_RECORD(iface, HTMLDOMChildrenCollection, dispex); }
static ULONG get_enum_len(HTMLDOMChildrenCollectionEnum *This) { + HTMLDOMChildrenCollection *col = impl_from_DispatchEx(This->colenum.disp); UINT32 len; nsresult nsres;
- nsres = nsIDOMNodeList_GetLength(This->col->nslist, &len); + nsres = nsIDOMNodeList_GetLength(col->nslist, &len); assert(nsres == NS_OK); return len; } @@ -115,6 +72,7 @@ static ULONG get_enum_len(HTMLDOMChildrenCollectionEnum *This) static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) { HTMLDOMChildrenCollectionEnum *This = impl_from_IEnumVARIANT(iface); + HTMLDOMChildrenCollection *col = impl_from_DispatchEx(This->colenum.disp); ULONG fetched = 0, len; nsIDOMNode *nsnode; HTMLDOMNode *node; @@ -126,7 +84,7 @@ static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Next(IEnumVARIANT *iface, UL len = get_enum_len(This);
while(This->iter+fetched < len && fetched < celt) { - nsres = nsIDOMNodeList_Item(This->col->nslist, This->iter+fetched, &nsnode); + nsres = nsIDOMNodeList_Item(col->nslist, This->iter+fetched, &nsnode); assert(nsres == NS_OK);
hres = get_node(nsnode, TRUE, &node); @@ -183,9 +141,9 @@ static HRESULT WINAPI HTMLDOMChildrenCollectionEnum_Clone(IEnumVARIANT *iface, I }
static const IEnumVARIANTVtbl HTMLDOMChildrenCollectionEnumVtbl = { - HTMLDOMChildrenCollectionEnum_QueryInterface, - HTMLDOMChildrenCollectionEnum_AddRef, - HTMLDOMChildrenCollectionEnum_Release, + CollectionEnum_QueryInterface, + CollectionEnum_AddRef, + CollectionEnum_Release, HTMLDOMChildrenCollectionEnum_Next, HTMLDOMChildrenCollectionEnum_Skip, HTMLDOMChildrenCollectionEnum_Reset, @@ -223,14 +181,9 @@ static HRESULT WINAPI HTMLDOMChildrenCollection_get__newEnum(IHTMLDOMChildrenCol 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; + *p = CollectionEnum_init(&ret->colenum, &This->dispex, &HTMLDOMChildrenCollectionEnumVtbl); return S_OK; }
@@ -282,11 +235,6 @@ static const IHTMLDOMChildrenCollectionVtbl HTMLDOMChildrenCollectionVtbl = { HTMLDOMChildrenCollection_item };
-static inline HTMLDOMChildrenCollection *impl_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLDOMChildrenCollection, dispex); -} - static void *HTMLDOMChildrenCollection_query_interface(DispatchEx *dispex, REFIID riid) { HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlform.c | 78 +++++++----------------------------------- 1 file changed, 13 insertions(+), 65 deletions(-)
diff --git a/dlls/mshtml/htmlform.c b/dlls/mshtml/htmlform.c index 29986158ca7..8e2a570a839 100644 --- a/dlls/mshtml/htmlform.c +++ b/dlls/mshtml/htmlform.c @@ -43,12 +43,8 @@ struct HTMLFormElement { };
typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - + CollectionEnum colenum; ULONG iter; - HTMLFormElement *elem; } HTMLFormElementEnum;
HRESULT return_nsform(nsresult nsres, nsIDOMHTMLFormElement *form, IHTMLFormElement **p) @@ -120,57 +116,18 @@ static HRESULT htmlform_item(HTMLFormElement *This, int i, IDispatch **ret)
static inline HTMLFormElementEnum *impl_from_IEnumVARIANT(IEnumVARIANT *iface) { - return CONTAINING_RECORD(iface, HTMLFormElementEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLFormElementEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLFormElementEnum *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("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; + return CONTAINING_RECORD(iface, HTMLFormElementEnum, colenum.IEnumVARIANT_iface); }
-static ULONG WINAPI HTMLFormElementEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLFormElementEnum_Release(IEnumVARIANT *iface) +static inline HTMLFormElement *impl_from_DispatchEx(DispatchEx *iface) { - HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLFormElement_Release(&This->elem->IHTMLFormElement_iface); - free(This); - } - - return ref; + return CONTAINING_RECORD(iface, HTMLFormElement, element.node.event_target.dispex); }
static HRESULT WINAPI HTMLFormElementEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) { HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); + HTMLFormElement *elem = impl_from_DispatchEx(This->colenum.disp); nsresult nsres; HRESULT hres; ULONG num, i; @@ -178,13 +135,13 @@ static HRESULT WINAPI HTMLFormElementEnum_Next(IEnumVARIANT *iface, ULONG celt,
TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
- nsres = nsIDOMHTMLFormElement_GetLength(This->elem->nsform, &len); + nsres = nsIDOMHTMLFormElement_GetLength(elem->nsform, &len); if(NS_FAILED(nsres)) return E_FAIL; num = min(len - This->iter, celt);
for(i = 0; i < num; i++) { - hres = htmlform_item(This->elem, This->iter + i, &V_DISPATCH(&rgVar[i])); + hres = htmlform_item(elem, This->iter + i, &V_DISPATCH(&rgVar[i])); if(FAILED(hres)) { while(i--) VariantClear(&rgVar[i]); @@ -202,12 +159,13 @@ static HRESULT WINAPI HTMLFormElementEnum_Next(IEnumVARIANT *iface, ULONG celt, static HRESULT WINAPI HTMLFormElementEnum_Skip(IEnumVARIANT *iface, ULONG celt) { HTMLFormElementEnum *This = impl_from_IEnumVARIANT(iface); + HTMLFormElement *elem = impl_from_DispatchEx(This->colenum.disp); nsresult nsres; LONG len;
TRACE("(%p)->(%lu)\n", This, celt);
- nsres = nsIDOMHTMLFormElement_GetLength(This->elem->nsform, &len); + nsres = nsIDOMHTMLFormElement_GetLength(elem->nsform, &len); if(NS_FAILED(nsres)) return E_FAIL;
@@ -238,9 +196,9 @@ static HRESULT WINAPI HTMLFormElementEnum_Clone(IEnumVARIANT *iface, IEnumVARIAN }
static const IEnumVARIANTVtbl HTMLFormElementEnumVtbl = { - HTMLFormElementEnum_QueryInterface, - HTMLFormElementEnum_AddRef, - HTMLFormElementEnum_Release, + CollectionEnum_QueryInterface, + CollectionEnum_AddRef, + CollectionEnum_Release, HTMLFormElementEnum_Next, HTMLFormElementEnum_Skip, HTMLFormElementEnum_Reset, @@ -641,14 +599,9 @@ static HRESULT WINAPI HTMLFormElement__newEnum(IHTMLFormElement *iface, IUnknown if(!ret) return E_OUTOFMEMORY;
- ret->IEnumVARIANT_iface.lpVtbl = &HTMLFormElementEnumVtbl; - ret->ref = 1; ret->iter = 0;
- HTMLFormElement_AddRef(&This->IHTMLFormElement_iface); - ret->elem = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; + *p = CollectionEnum_init(&ret->colenum, &This->element.node.event_target.dispex, &HTMLFormElementEnumVtbl); return S_OK; }
@@ -718,11 +671,6 @@ static const IHTMLFormElementVtbl HTMLFormElementVtbl = { HTMLFormElement_tags };
-static inline HTMLFormElement *impl_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLFormElement, element.node.event_target.dispex); -} - static void *HTMLFormElement_query_interface(DispatchEx *dispex, REFIID riid) { HTMLFormElement *This = impl_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlselect.c | 84 ++++++++-------------------------------- 1 file changed, 16 insertions(+), 68 deletions(-)
diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index 97a47e38762..5e28b573930 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -530,12 +530,8 @@ struct HTMLSelectElement { };
typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - + CollectionEnum colenum; ULONG iter; - HTMLSelectElement *elem; } HTMLSelectElementEnum;
static inline HTMLSelectElement *impl_from_IHTMLSelectElement(IHTMLSelectElement *iface) @@ -543,6 +539,11 @@ static inline HTMLSelectElement *impl_from_IHTMLSelectElement(IHTMLSelectElement return CONTAINING_RECORD(iface, HTMLSelectElement, IHTMLSelectElement_iface); }
+static inline HTMLSelectElement *impl_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, HTMLSelectElement, element.node.event_target.dispex); +} + static HRESULT htmlselect_item(HTMLSelectElement *This, int i, IDispatch **ret) { nsIDOMHTMLOptionsCollection *nscol; @@ -580,57 +581,13 @@ static HRESULT htmlselect_item(HTMLSelectElement *This, int i, IDispatch **ret)
static inline HTMLSelectElementEnum *impl_from_IEnumVARIANT(IEnumVARIANT *iface) { - return CONTAINING_RECORD(iface, HTMLSelectElementEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLSelectElementEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLSelectElementEnum *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("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLSelectElementEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLSelectElementEnum_Release(IEnumVARIANT *iface) -{ - HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLSelectElement_Release(&This->elem->IHTMLSelectElement_iface); - free(This); - } - - return ref; + return CONTAINING_RECORD(iface, HTMLSelectElementEnum, colenum.IEnumVARIANT_iface); }
static HRESULT WINAPI HTMLSelectElementEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) { HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); + HTMLSelectElement *elem = impl_from_DispatchEx(This->colenum.disp); nsresult nsres; HRESULT hres; ULONG num, i; @@ -638,13 +595,13 @@ static HRESULT WINAPI HTMLSelectElementEnum_Next(IEnumVARIANT *iface, ULONG celt
TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
- nsres = nsIDOMHTMLSelectElement_GetLength(This->elem->nsselect, &len); + nsres = nsIDOMHTMLSelectElement_GetLength(elem->nsselect, &len); if(NS_FAILED(nsres)) return E_FAIL; num = min(len - This->iter, celt);
for(i = 0; i < num; i++) { - hres = htmlselect_item(This->elem, This->iter + i, &V_DISPATCH(&rgVar[i])); + hres = htmlselect_item(elem, This->iter + i, &V_DISPATCH(&rgVar[i])); if(FAILED(hres)) { while(i--) VariantClear(&rgVar[i]); @@ -662,12 +619,13 @@ static HRESULT WINAPI HTMLSelectElementEnum_Next(IEnumVARIANT *iface, ULONG celt static HRESULT WINAPI HTMLSelectElementEnum_Skip(IEnumVARIANT *iface, ULONG celt) { HTMLSelectElementEnum *This = impl_from_IEnumVARIANT(iface); + HTMLSelectElement *elem = impl_from_DispatchEx(This->colenum.disp); nsresult nsres; UINT32 len;
TRACE("(%p)->(%lu)\n", This, celt);
- nsres = nsIDOMHTMLSelectElement_GetLength(This->elem->nsselect, &len); + nsres = nsIDOMHTMLSelectElement_GetLength(elem->nsselect, &len); if(NS_FAILED(nsres)) return E_FAIL;
@@ -698,9 +656,9 @@ static HRESULT WINAPI HTMLSelectElementEnum_Clone(IEnumVARIANT *iface, IEnumVARI }
static const IEnumVARIANTVtbl HTMLSelectElementEnumVtbl = { - HTMLSelectElementEnum_QueryInterface, - HTMLSelectElementEnum_AddRef, - HTMLSelectElementEnum_Release, + CollectionEnum_QueryInterface, + CollectionEnum_AddRef, + CollectionEnum_Release, HTMLSelectElementEnum_Next, HTMLSelectElementEnum_Skip, HTMLSelectElementEnum_Reset, @@ -1063,14 +1021,9 @@ static HRESULT WINAPI HTMLSelectElement_get__newEnum(IHTMLSelectElement *iface, if(!ret) return E_OUTOFMEMORY;
- ret->IEnumVARIANT_iface.lpVtbl = &HTMLSelectElementEnumVtbl; - ret->ref = 1; ret->iter = 0;
- HTMLSelectElement_AddRef(&This->IHTMLSelectElement_iface); - ret->elem = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; + *p = CollectionEnum_init(&ret->colenum, &This->element.node.event_target.dispex, &HTMLSelectElementEnumVtbl); return S_OK; }
@@ -1154,11 +1107,6 @@ static HRESULT HTMLSelectElementImpl_get_disabled(HTMLDOMNode *iface, VARIANT_BO return IHTMLSelectElement_get_disabled(&This->IHTMLSelectElement_iface, p); }
-static inline HTMLSelectElement *impl_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLSelectElement, element.node.event_target.dispex); -} - static void *HTMLSelectElement_query_interface(DispatchEx *dispex, REFIID riid) { HTMLSelectElement *This = impl_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlelem.c | 78 +++++++----------------------------------- 1 file changed, 13 insertions(+), 65 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 354f521697c..7925d762aef 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -816,67 +816,24 @@ typedef struct { } HTMLRectCollection;
typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - + CollectionEnum colenum; ULONG iter; - HTMLRectCollection *col; } HTMLRectCollectionEnum;
static inline HTMLRectCollectionEnum *HTMLRectCollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface) { - return CONTAINING_RECORD(iface, HTMLRectCollectionEnum, IEnumVARIANT_iface); + return CONTAINING_RECORD(iface, HTMLRectCollectionEnum, colenum.IEnumVARIANT_iface); }
-static HRESULT WINAPI HTMLRectCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_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("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLRectCollectionEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLRectCollectionEnum_Release(IEnumVARIANT *iface) +static inline HTMLRectCollection *HTMLRectCollection_from_DispatchEx(DispatchEx *iface) { - HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLRectCollection_Release(&This->col->IHTMLRectCollection_iface); - free(This); - } - - return ref; + return CONTAINING_RECORD(iface, HTMLRectCollection, dispex); }
static HRESULT WINAPI HTMLRectCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) { HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); + HTMLRectCollection *col = HTMLRectCollection_from_DispatchEx(This->colenum.disp); VARIANT index; HRESULT hres; ULONG num, i; @@ -884,13 +841,13 @@ static HRESULT WINAPI HTMLRectCollectionEnum_Next(IEnumVARIANT *iface, ULONG cel
TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
- nsIDOMClientRectList_GetLength(This->col->rect_list, &len); + nsIDOMClientRectList_GetLength(col->rect_list, &len); num = min(len - This->iter, celt); V_VT(&index) = VT_I4;
for(i = 0; i < num; i++) { V_I4(&index) = This->iter + i; - hres = IHTMLRectCollection_item(&This->col->IHTMLRectCollection_iface, &index, &rgVar[i]); + hres = IHTMLRectCollection_item(&col->IHTMLRectCollection_iface, &index, &rgVar[i]); if(FAILED(hres)) { while(i--) VariantClear(&rgVar[i]); @@ -907,11 +864,12 @@ static HRESULT WINAPI HTMLRectCollectionEnum_Next(IEnumVARIANT *iface, ULONG cel static HRESULT WINAPI HTMLRectCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) { HTMLRectCollectionEnum *This = HTMLRectCollectionEnum_from_IEnumVARIANT(iface); + HTMLRectCollection *col = HTMLRectCollection_from_DispatchEx(This->colenum.disp); UINT32 len;
TRACE("(%p)->(%lu)\n", This, celt);
- nsIDOMClientRectList_GetLength(This->col->rect_list, &len); + nsIDOMClientRectList_GetLength(col->rect_list, &len); if(This->iter + celt > len) { This->iter = len; return S_FALSE; @@ -939,9 +897,9 @@ static HRESULT WINAPI HTMLRectCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVAR }
static const IEnumVARIANTVtbl HTMLRectCollectionEnumVtbl = { - HTMLRectCollectionEnum_QueryInterface, - HTMLRectCollectionEnum_AddRef, - HTMLRectCollectionEnum_Release, + CollectionEnum_QueryInterface, + CollectionEnum_AddRef, + CollectionEnum_Release, HTMLRectCollectionEnum_Next, HTMLRectCollectionEnum_Skip, HTMLRectCollectionEnum_Reset, @@ -980,14 +938,9 @@ static HRESULT WINAPI HTMLRectCollection_get__newEnum(IHTMLRectCollection *iface if(!ret) return E_OUTOFMEMORY;
- ret->IEnumVARIANT_iface.lpVtbl = &HTMLRectCollectionEnumVtbl; - ret->ref = 1; ret->iter = 0;
- HTMLRectCollection_AddRef(&This->IHTMLRectCollection_iface); - ret->col = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; + *p = CollectionEnum_init(&ret->colenum, &This->dispex, &HTMLRectCollectionEnumVtbl); return S_OK; }
@@ -1037,11 +990,6 @@ static const IHTMLRectCollectionVtbl HTMLRectCollectionVtbl = { HTMLRectCollection_item };
-static inline HTMLRectCollection *HTMLRectCollection_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLRectCollection, dispex); -} - static void *HTMLRectCollection_query_interface(DispatchEx *dispex, REFIID riid) { HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlelem.c | 80 ++++++++---------------------------------- 1 file changed, 14 insertions(+), 66 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 7925d762aef..60e864c7dc0 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -7857,67 +7857,24 @@ static inline HRESULT get_domattr(HTMLAttributeCollection *This, DISPID id, LONG }
typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - + CollectionEnum colenum; DISPID iter_dispid; - HTMLAttributeCollection *col; } HTMLAttributeCollectionEnum;
static inline HTMLAttributeCollectionEnum *HTMLAttributeCollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface) { - return CONTAINING_RECORD(iface, HTMLAttributeCollectionEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLAttributeCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_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("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; + return CONTAINING_RECORD(iface, HTMLAttributeCollectionEnum, colenum.IEnumVARIANT_iface); }
-static ULONG WINAPI HTMLAttributeCollectionEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; -} - -static ULONG WINAPI HTMLAttributeCollectionEnum_Release(IEnumVARIANT *iface) +static inline HTMLAttributeCollection *HTMLAttributeCollection_from_DispatchEx(DispatchEx *iface) { - HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLAttributeCollection_Release(&This->col->IHTMLAttributeCollection_iface); - free(This); - } - - return ref; + return CONTAINING_RECORD(iface, HTMLAttributeCollection, dispex); }
static HRESULT WINAPI HTMLAttributeCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) { HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); + HTMLAttributeCollection *col = HTMLAttributeCollection_from_DispatchEx(This->colenum.disp); DISPID tmp, dispid = This->iter_dispid; HTMLDOMAttribute *attr; LONG rel_index = 0; @@ -7927,10 +7884,10 @@ static HRESULT WINAPI HTMLAttributeCollectionEnum_Next(IEnumVARIANT *iface, ULON TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
for(i = 0; i < celt; i++) { - hres = get_attr_dispid_by_relative_idx(This->col, &rel_index, dispid, &tmp); + hres = get_attr_dispid_by_relative_idx(col, &rel_index, dispid, &tmp); if(SUCCEEDED(hres)) { dispid = tmp; - hres = get_domattr(This->col, dispid, NULL, &attr); + hres = get_domattr(col, dispid, NULL, &attr); } else if(hres == DISP_E_UNKNOWNNAME) break; @@ -7954,6 +7911,7 @@ static HRESULT WINAPI HTMLAttributeCollectionEnum_Next(IEnumVARIANT *iface, ULON static HRESULT WINAPI HTMLAttributeCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) { HTMLAttributeCollectionEnum *This = HTMLAttributeCollectionEnum_from_IEnumVARIANT(iface); + HTMLAttributeCollection *col = HTMLAttributeCollection_from_DispatchEx(This->colenum.disp); LONG remaining, rel_index; DISPID dispid; HRESULT hres; @@ -7964,14 +7922,14 @@ static HRESULT WINAPI HTMLAttributeCollectionEnum_Skip(IEnumVARIANT *iface, ULON return S_OK;
rel_index = -1; - hres = get_attr_dispid_by_relative_idx(This->col, &rel_index, This->iter_dispid, NULL); + hres = get_attr_dispid_by_relative_idx(col, &rel_index, This->iter_dispid, NULL); if(FAILED(hres)) return hres; remaining = min(celt, rel_index);
if(remaining) { rel_index = remaining - 1; - hres = get_attr_dispid_by_relative_idx(This->col, &rel_index, This->iter_dispid, &dispid); + hres = get_attr_dispid_by_relative_idx(col, &rel_index, This->iter_dispid, &dispid); if(FAILED(hres)) return hres; This->iter_dispid = dispid; @@ -7997,9 +7955,9 @@ static HRESULT WINAPI HTMLAttributeCollectionEnum_Clone(IEnumVARIANT *iface, IEn }
static const IEnumVARIANTVtbl HTMLAttributeCollectionEnumVtbl = { - HTMLAttributeCollectionEnum_QueryInterface, - HTMLAttributeCollectionEnum_AddRef, - HTMLAttributeCollectionEnum_Release, + CollectionEnum_QueryInterface, + CollectionEnum_AddRef, + CollectionEnum_Release, HTMLAttributeCollectionEnum_Next, HTMLAttributeCollectionEnum_Skip, HTMLAttributeCollectionEnum_Reset, @@ -8038,14 +7996,9 @@ static HRESULT WINAPI HTMLAttributeCollection__newEnum(IHTMLAttributeCollection if(!ret) return E_OUTOFMEMORY;
- ret->IEnumVARIANT_iface.lpVtbl = &HTMLAttributeCollectionEnumVtbl; - ret->ref = 1; ret->iter_dispid = DISPID_STARTENUM;
- HTMLAttributeCollection_AddRef(&This->IHTMLAttributeCollection_iface); - ret->col = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; + *p = CollectionEnum_init(&ret->colenum, &This->dispex, &HTMLAttributeCollectionEnumVtbl); return S_OK; }
@@ -8368,11 +8321,6 @@ static const IHTMLAttributeCollection4Vtbl HTMLAttributeCollection4Vtbl = { HTMLAttributeCollection4_get_length };
-static inline HTMLAttributeCollection *HTMLAttributeCollection_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLAttributeCollection, dispex); -} - static void *HTMLAttributeCollection_query_interface(DispatchEx *dispex, REFIID riid) { HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstylesheet.c | 78 ++++++------------------------------ 1 file changed, 13 insertions(+), 65 deletions(-)
diff --git a/dlls/mshtml/htmlstylesheet.c b/dlls/mshtml/htmlstylesheet.c index fb9d71f894f..9210f80eab5 100644 --- a/dlls/mshtml/htmlstylesheet.c +++ b/dlls/mshtml/htmlstylesheet.c @@ -48,12 +48,8 @@ struct HTMLStyleSheetsCollection { };
typedef struct { - IEnumVARIANT IEnumVARIANT_iface; - - LONG ref; - + CollectionEnum colenum; ULONG iter; - HTMLStyleSheetsCollection *col; } HTMLStyleSheetsCollectionEnum;
struct HTMLStyleSheetRulesCollection { @@ -401,57 +397,18 @@ static HRESULT create_style_sheet_rules_collection(nsIDOMCSSRuleList *nslist, Di
static inline HTMLStyleSheetsCollectionEnum *HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface) { - return CONTAINING_RECORD(iface, HTMLStyleSheetsCollectionEnum, IEnumVARIANT_iface); -} - -static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, void **ppv) -{ - HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_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("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); - *ppv = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*ppv); - return S_OK; -} - -static ULONG WINAPI HTMLStyleSheetsCollectionEnum_AddRef(IEnumVARIANT *iface) -{ - HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - return ref; + return CONTAINING_RECORD(iface, HTMLStyleSheetsCollectionEnum, colenum.IEnumVARIANT_iface); }
-static ULONG WINAPI HTMLStyleSheetsCollectionEnum_Release(IEnumVARIANT *iface) +static inline HTMLStyleSheetsCollection *HTMLStyleSheetsCollection_from_DispatchEx(DispatchEx *iface) { - HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%ld\n", This, ref); - - if(!ref) { - IHTMLStyleSheetsCollection_Release(&This->col->IHTMLStyleSheetsCollection_iface); - free(This); - } - - return ref; + return CONTAINING_RECORD(iface, HTMLStyleSheetsCollection, dispex); }
static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched) { HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); + HTMLStyleSheetsCollection *col = HTMLStyleSheetsCollection_from_DispatchEx(This->colenum.disp); VARIANT index; HRESULT hres; ULONG num, i; @@ -459,13 +416,13 @@ static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Next(IEnumVARIANT *iface, UL
TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
- nsIDOMStyleSheetList_GetLength(This->col->nslist, &len); + nsIDOMStyleSheetList_GetLength(col->nslist, &len); num = min(len - This->iter, celt); V_VT(&index) = VT_I4;
for(i = 0; i < num; i++) { V_I4(&index) = This->iter + i; - hres = IHTMLStyleSheetsCollection_item(&This->col->IHTMLStyleSheetsCollection_iface, &index, &rgVar[i]); + hres = IHTMLStyleSheetsCollection_item(&col->IHTMLStyleSheetsCollection_iface, &index, &rgVar[i]); if(FAILED(hres)) { while(i--) VariantClear(&rgVar[i]); @@ -482,11 +439,12 @@ static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Next(IEnumVARIANT *iface, UL static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt) { HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface); + HTMLStyleSheetsCollection *col = HTMLStyleSheetsCollection_from_DispatchEx(This->colenum.disp); UINT32 len;
TRACE("(%p)->(%lu)\n", This, celt);
- nsIDOMStyleSheetList_GetLength(This->col->nslist, &len); + nsIDOMStyleSheetList_GetLength(col->nslist, &len); if(This->iter + celt > len) { This->iter = len; return S_FALSE; @@ -514,9 +472,9 @@ static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Clone(IEnumVARIANT *iface, I }
static const IEnumVARIANTVtbl HTMLStyleSheetsCollectionEnumVtbl = { - HTMLStyleSheetsCollectionEnum_QueryInterface, - HTMLStyleSheetsCollectionEnum_AddRef, - HTMLStyleSheetsCollectionEnum_Release, + CollectionEnum_QueryInterface, + CollectionEnum_AddRef, + CollectionEnum_Release, HTMLStyleSheetsCollectionEnum_Next, HTMLStyleSheetsCollectionEnum_Skip, HTMLStyleSheetsCollectionEnum_Reset, @@ -558,14 +516,9 @@ static HRESULT WINAPI HTMLStyleSheetsCollection_get__newEnum(IHTMLStyleSheetsCol if(!ret) return E_OUTOFMEMORY;
- ret->IEnumVARIANT_iface.lpVtbl = &HTMLStyleSheetsCollectionEnumVtbl; - ret->ref = 1; ret->iter = 0;
- HTMLStyleSheetsCollection_AddRef(&This->IHTMLStyleSheetsCollection_iface); - ret->col = This; - - *p = (IUnknown*)&ret->IEnumVARIANT_iface; + *p = CollectionEnum_init(&ret->colenum, &This->dispex, &HTMLStyleSheetsCollectionEnumVtbl); return S_OK; }
@@ -626,11 +579,6 @@ static const IHTMLStyleSheetsCollectionVtbl HTMLStyleSheetsCollectionVtbl = { HTMLStyleSheetsCollection_item };
-static inline HTMLStyleSheetsCollection *HTMLStyleSheetsCollection_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLStyleSheetsCollection, dispex); -} - static void *HTMLStyleSheetsCollection_query_interface(DispatchEx *dispex, REFIID riid) { HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Example of non-contrived cyclic ref:
document.body.foobar = function() {} var enumerator = new Enumerator(document.getElementsByTagName("body"));
body element (BODY) has a prop with a function (FUNC) which holds link to the enclosing scope (SCOPE). The scope holds link to "enumerator" (ENUM) which holds a link to the IEnumVARIANT of the element collection (ELEMCOL), which holds a link to body element. So: BODY->FUNC->SCOPE->ENUM->ELEMCOL->BODY.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 61 ++++++++++++++++++++++++++++++------ dlls/mshtml/mshtml_private.h | 3 +- dlls/mshtml/nsembed.c | 1 + 3 files changed, 55 insertions(+), 10 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index f5e6462bf54..8d414c3726b 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -2901,6 +2901,8 @@ static IWineJSDispatchHostVtbl JSDispatchHostVtbl = { JSDispatchHost_ToString, };
+static ExternalCycleCollectionParticipant enum_ccp; + static inline CollectionEnum *CollectionEnum_from_IEnumVARIANT(IEnumVARIANT *iface) { return CONTAINING_RECORD(iface, CollectionEnum, IEnumVARIANT_iface); @@ -2912,9 +2914,15 @@ HRESULT WINAPI CollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, v
TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
- if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumVARIANT)) + if(IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumVARIANT)) { *ppv = &This->IEnumVARIANT_iface; - else { + }else if(IsEqualGUID(&IID_nsXPCOMCycleCollectionParticipant, riid)) { + *ppv = &enum_ccp; + return S_OK; + }else if(IsEqualGUID(&IID_nsCycleCollectionISupports, riid)) { + *ppv = &This->IEnumVARIANT_iface; + return S_OK; + }else { FIXME("Unsupported iface %s\n", debugstr_mshtml_guid(riid)); *ppv = NULL; return E_NOINTERFACE; @@ -2927,7 +2935,7 @@ HRESULT WINAPI CollectionEnum_QueryInterface(IEnumVARIANT *iface, REFIID riid, v ULONG WINAPI CollectionEnum_AddRef(IEnumVARIANT *iface) { CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedIncrement(&This->ref); + LONG ref = ccref_incr(&This->ccref, (nsISupports*)&This->IEnumVARIANT_iface);
TRACE("(%p) ref=%ld\n", This, ref);
@@ -2937,27 +2945,62 @@ ULONG WINAPI CollectionEnum_AddRef(IEnumVARIANT *iface) ULONG WINAPI CollectionEnum_Release(IEnumVARIANT *iface) { CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(iface); - LONG ref = InterlockedDecrement(&This->ref); + LONG ref = ccref_decr(&This->ccref, (nsISupports*)&This->IEnumVARIANT_iface, &enum_ccp);
TRACE("(%p) ref=%ld\n", This, ref);
- if(!ref) { - DispatchEx_Release(&This->disp->IWineJSDispatchHost_iface); - free(This); + return ref; +} + +static nsresult NSAPI CollectionEnum_traverse(void *ccp, void *p, nsCycleCollectionTraversalCallback *cb) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(p); + + describe_cc_node(&This->ccref, "CollectionEnum", cb); + + if(This->disp) + note_cc_edge((nsISupports*)&This->disp->IWineJSDispatchHost_iface, "disp", cb); + return NS_OK; +} + +static nsresult NSAPI CollectionEnum_unlink(void *p) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(p); + + if(This->disp) { + DispatchEx *disp = This->disp; + This->disp = NULL; + DispatchEx_Release(&disp->IWineJSDispatchHost_iface); } + return NS_OK; +}
- return ref; +static void NSAPI CollectionEnum_delete_cycle_collectable(void *p) +{ + CollectionEnum *This = CollectionEnum_from_IEnumVARIANT(p); + CollectionEnum_unlink(p); + free(This); }
IUnknown *CollectionEnum_init(CollectionEnum *colenum, DispatchEx *disp, const IEnumVARIANTVtbl *vtbl) { colenum->IEnumVARIANT_iface.lpVtbl = vtbl; - colenum->ref = 1; colenum->disp = disp; + ccref_init(&colenum->ccref, 1); DispatchEx_AddRef(&disp->IWineJSDispatchHost_iface); return (IUnknown*)&colenum->IEnumVARIANT_iface; }
+void init_enum_cc(void) +{ + static const CCObjCallback ccp_callback = { + CollectionEnum_traverse, + CollectionEnum_unlink, + CollectionEnum_delete_cycle_collectable + }; + ccp_init(&enum_ccp, &ccp_callback); +} + HRESULT dispex_builtin_props_to_json(DispatchEx *dispex, HTMLInnerWindow *window, VARIANT *ret) { func_info_t *func, *end; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 9b24bfd9a6e..bd16e3e35bf 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -611,7 +611,7 @@ struct DispatchEx {
typedef struct { IEnumVARIANT IEnumVARIANT_iface; - LONG ref; + nsCycleCollectingAutoRefCnt ccref; DispatchEx *disp; } CollectionEnum;
@@ -1265,6 +1265,7 @@ float get_viewer_zoom(GeckoBrowser*);
void init_dispex_cc(void); void init_window_cc(void); +void init_enum_cc(void);
HRESULT nsuri_to_url(LPCWSTR,BOOL,BSTR*);
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 62e1922cf6c..d6dba02551a 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -599,6 +599,7 @@ static BOOL init_xpcom(const PRUnichar *gre_path)
init_dispex_cc(); init_window_cc(); + init_enum_cc();
return TRUE; }
This doesn't fix mentioned cycle on its own. We don't have JS/CC integration yet, so JS is not part of the CC graph anyway. Let's wait with the CC change until it makes sense.
As for sharing, it would perhaps be more interesting to have entire `IEnumVARIANT` interface shared instead of splitting it halfway. The caller could just pass a vtbl with `get_length(disp)` and `get_item(disp,index)` and remaining functions could be shared on top of that.
On Thu Oct 9 16:57:58 2025 +0000, Jacek Caban wrote:
This doesn't fix mentioned cycle on its own. We don't have JS/CC integration yet, so JS is not part of the CC graph anyway. Let's wait with the CC change until it makes sense. As for sharing, it would perhaps be more interesting to have entire `IEnumVARIANT` interface shared instead of splitting it halfway. The caller could just pass a vtbl with `get_length(disp)` and `get_item(disp,index)` and remaining functions could be shared on top of that.
Ah right. I had some problems with the attribute collection though, since it uses relative next/skip. I added optional next/skip methods in the vtbl for that but I'm not sure if it's the best way, I can use them for all the others too if you prefer.