mshtml: Implement enumerator for HTMLStyleSheetsCollection.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Gabriel Ivăncescu 2022-04-13 17:34:53 +03:00 committed by Alexandre Julliard
parent 2bdce91e8f
commit 7c311fbcc1
2 changed files with 177 additions and 2 deletions

View File

@ -50,6 +50,15 @@ struct HTMLStyleSheetsCollection {
nsIDOMStyleSheetList *nslist;
};
typedef struct {
IEnumVARIANT IEnumVARIANT_iface;
LONG ref;
ULONG iter;
HTMLStyleSheetsCollection *col;
} HTMLStyleSheetsCollectionEnum;
struct HTMLStyleSheetRulesCollection {
DispatchEx dispex;
IHTMLStyleSheetRulesCollection IHTMLStyleSheetRulesCollection_iface;
@ -479,6 +488,130 @@ static HRESULT create_style_sheet_rules_collection(nsIDOMCSSRuleList *nslist, co
return S_OK;
}
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;
}
static ULONG WINAPI HTMLStyleSheetsCollectionEnum_Release(IEnumVARIANT *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);
heap_free(This);
}
return ref;
}
static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Next(IEnumVARIANT *iface, ULONG celt, VARIANT *rgVar, ULONG *pCeltFetched)
{
HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface);
VARIANT index;
HRESULT hres;
ULONG num, i;
UINT32 len;
TRACE("(%p)->(%lu %p %p)\n", This, celt, rgVar, pCeltFetched);
nsIDOMStyleSheetList_GetLength(This->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]);
if(FAILED(hres)) {
while(i--)
VariantClear(&rgVar[i]);
return hres;
}
}
This->iter += num;
if(pCeltFetched)
*pCeltFetched = num;
return num == celt ? S_OK : S_FALSE;
}
static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Skip(IEnumVARIANT *iface, ULONG celt)
{
HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface);
UINT32 len;
TRACE("(%p)->(%lu)\n", This, celt);
nsIDOMStyleSheetList_GetLength(This->col->nslist, &len);
if(This->iter + celt > len) {
This->iter = len;
return S_FALSE;
}
This->iter += celt;
return S_OK;
}
static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Reset(IEnumVARIANT *iface)
{
HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface);
TRACE("(%p)->()\n", This);
This->iter = 0;
return S_OK;
}
static HRESULT WINAPI HTMLStyleSheetsCollectionEnum_Clone(IEnumVARIANT *iface, IEnumVARIANT **ppEnum)
{
HTMLStyleSheetsCollectionEnum *This = HTMLStyleSheetsCollectionEnum_from_IEnumVARIANT(iface);
FIXME("(%p)->(%p)\n", This, ppEnum);
return E_NOTIMPL;
}
static const IEnumVARIANTVtbl HTMLStyleSheetsCollectionEnumVtbl = {
HTMLStyleSheetsCollectionEnum_QueryInterface,
HTMLStyleSheetsCollectionEnum_AddRef,
HTMLStyleSheetsCollectionEnum_Release,
HTMLStyleSheetsCollectionEnum_Next,
HTMLStyleSheetsCollectionEnum_Skip,
HTMLStyleSheetsCollectionEnum_Reset,
HTMLStyleSheetsCollectionEnum_Clone
};
static inline HTMLStyleSheetsCollection *impl_from_IHTMLStyleSheetsCollection(IHTMLStyleSheetsCollection *iface)
{
return CONTAINING_RECORD(iface, HTMLStyleSheetsCollection, IHTMLStyleSheetsCollection_iface);
@ -586,8 +719,23 @@ static HRESULT WINAPI HTMLStyleSheetsCollection_get__newEnum(IHTMLStyleSheetsCol
IUnknown **p)
{
HTMLStyleSheetsCollection *This = impl_from_IHTMLStyleSheetsCollection(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
HTMLStyleSheetsCollectionEnum *ret;
TRACE("(%p)->(%p)\n", This, p);
ret = heap_alloc(sizeof(*ret));
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;
return S_OK;
}
static HRESULT WINAPI HTMLStyleSheetsCollection_item(IHTMLStyleSheetsCollection *iface,

View File

@ -8577,7 +8577,10 @@ static void test_stylesheet(IDispatch *disp)
static void test_stylesheets(IHTMLDocument2 *doc)
{
IHTMLStyleSheetsCollection *col = NULL;
IEnumVARIANT *enum_var;
IUnknown *enum_unk;
VARIANT idx, res;
ULONG fetched;
LONG len = 0;
HRESULT hres;
@ -8611,6 +8614,30 @@ static void test_stylesheets(IHTMLDocument2 *doc)
ok(V_VT(&res) == VT_EMPTY, "V_VT(res) = %d\n", V_VT(&res));
VariantClear(&res);
hres = IHTMLStyleSheetsCollection_get__newEnum(col, &enum_unk);
ok(hres == S_OK, "_newEnum failed: %08lx\n", hres);
hres = IUnknown_QueryInterface(enum_unk, &IID_IEnumVARIANT, (void**)&enum_var);
IUnknown_Release(enum_unk);
ok(hres == S_OK, "Could not get IEnumVARIANT iface: %08lx\n", hres);
fetched = 0;
V_VT(&res) = VT_ERROR;
hres = IEnumVARIANT_Next(enum_var, 1, &res, &fetched);
ok(hres == S_OK, "Next failed: %08lx\n", hres);
ok(fetched == 1, "fetched = %lu\n", fetched);
ok(V_VT(&res) == VT_DISPATCH, "V_VT(res) = %d\n", V_VT(&res));
ok(V_DISPATCH(&res) != NULL, "V_DISPATCH(&res) == NULL\n");
test_disp2((IUnknown*)V_DISPATCH(&res), &DIID_DispHTMLStyleSheet, &IID_IHTMLStyleSheet, NULL, L"[object]");
VariantClear(&res);
fetched = 0;
V_VT(&res) = VT_ERROR;
hres = IEnumVARIANT_Next(enum_var, 1, &res, &fetched);
ok(hres == S_FALSE, "Next failed: %08lx\n", hres);
ok(fetched == 0, "fetched = %lu\n", fetched);
IEnumVARIANT_Release(enum_var);
IHTMLStyleSheetsCollection_Release(col);
}