diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 8216c8b2975..c77ebb92218 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -128,6 +128,7 @@ static REFIID tid_ids[] = { &IID_IHTMLElement4, &IID_IHTMLElementCollection, &IID_IHTMLEventObj, + &IID_IHTMLFiltersCollection, &IID_IHTMLFormElement, &IID_IHTMLFrameBase, &IID_IHTMLFrameBase2, diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index b3703f3d0b5..a65ed20065e 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -34,6 +34,22 @@ #include "mshtml_private.h" #include "htmlevent.h" +typedef struct +{ + DispatchEx dispex; + const IHTMLFiltersCollectionVtbl *lpHTMLFiltersCollectionVtbl; + + LONG ref; +} HTMLFiltersCollection; + +#define HTMLFILTERSCOLLECTION(x) ((IHTMLFiltersCollection*) &(x)->lpHTMLFiltersCollectionVtbl) + +#define HTMLFILTERSCOLLECTION_THIS(iface) \ + DEFINE_THIS(HTMLFiltersCollection, HTMLFiltersCollection, iface) + +IHTMLFiltersCollection *HTMLFiltersCollection_Create(void); + + WINE_DEFAULT_DEBUG_CHANNEL(mshtml); #define HTMLELEM_THIS(iface) DEFINE_THIS(HTMLElement, HTMLElement, iface) @@ -1193,8 +1209,14 @@ static HRESULT WINAPI HTMLElement_get_filters(IHTMLElement *iface, IHTMLFiltersCollection **p) { HTMLElement *This = HTMLELEM_THIS(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + + if(!p) + return E_POINTER; + + *p = HTMLFiltersCollection_Create(); + + return S_OK; } static HRESULT WINAPI HTMLElement_put_ondragstart(IHTMLElement *iface, VARIANT v) @@ -1664,3 +1686,185 @@ HTMLElement *HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL return ret; } + +/* interaface IHTMLFiltersCollection */ +static HRESULT WINAPI HTMLFiltersCollection_QueryInterface(IHTMLFiltersCollection *iface, REFIID riid, void **ppv) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + + TRACE("%p %s %p\n", This, debugstr_guid( riid ), ppv ); + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = HTMLFILTERSCOLLECTION(This); + }else if(IsEqualGUID(&IID_IHTMLFiltersCollection, riid)) { + TRACE("(%p)->(IID_IHTMLFiltersCollection %p)\n", This, ppv); + *ppv = HTMLFILTERSCOLLECTION(This); + }else if(dispex_query_interface(&This->dispex, riid, ppv)) { + return *ppv ? S_OK : E_NOINTERFACE; + } + + if(*ppv) { + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + } + + FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + return E_NOINTERFACE; +} + +static ULONG WINAPI HTMLFiltersCollection_AddRef(IHTMLFiltersCollection *iface) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI HTMLFiltersCollection_Release(IHTMLFiltersCollection *iface) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) + { + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI HTMLFiltersCollection_GetTypeInfoCount(IHTMLFiltersCollection *iface, UINT *pctinfo) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + return IDispatchEx_GetTypeInfoCount(DISPATCHEX(&This->dispex), pctinfo); +} + +static HRESULT WINAPI HTMLFiltersCollection_GetTypeInfo(IHTMLFiltersCollection *iface, + UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + return IDispatchEx_GetTypeInfo(DISPATCHEX(&This->dispex), iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLFiltersCollection_GetIDsOfNames(IHTMLFiltersCollection *iface, + REFIID riid, LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + return IDispatchEx_GetIDsOfNames(DISPATCHEX(&This->dispex), riid, rgszNames, cNames, lcid, rgDispId); +} + +static HRESULT WINAPI HTMLFiltersCollection_Invoke(IHTMLFiltersCollection *iface, DISPID dispIdMember, REFIID riid, + LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + return IDispatchEx_Invoke(DISPATCHEX(&This->dispex), dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLFiltersCollection_get_length(IHTMLFiltersCollection *iface, LONG *p) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + + FIXME("(%p)->(%p) Always returning 0\n", This, p); + + if(!p) + return E_POINTER; + + if(p) + *p = 0; + + return S_OK; +} + +static HRESULT WINAPI HTMLFiltersCollection_get__newEnum(IHTMLFiltersCollection *iface, IUnknown **p) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLFiltersCollection_item(IHTMLFiltersCollection *iface, VARIANT *pvarIndex, VARIANT *pvarResult) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + FIXME("(%p)->(%p, %p)\n", This, pvarIndex, pvarResult); + return E_NOTIMPL; +} + +static const IHTMLFiltersCollectionVtbl HTMLFiltersCollectionVtbl = { + HTMLFiltersCollection_QueryInterface, + HTMLFiltersCollection_AddRef, + HTMLFiltersCollection_Release, + HTMLFiltersCollection_GetTypeInfoCount, + HTMLFiltersCollection_GetTypeInfo, + HTMLFiltersCollection_GetIDsOfNames, + HTMLFiltersCollection_Invoke, + HTMLFiltersCollection_get_length, + HTMLFiltersCollection_get__newEnum, + HTMLFiltersCollection_item +}; + +static HRESULT HTMLFiltersCollection_get_dispid(IUnknown *iface, BSTR name, DWORD flags, DISPID *dispid) +{ + WCHAR *ptr; + int idx = 0; + + for(ptr = name; *ptr && isdigitW(*ptr); ptr++) + idx = idx*10 + (*ptr-'0'); + if(*ptr) + return DISP_E_UNKNOWNNAME; + + *dispid = MSHTML_DISPID_CUSTOM_MIN + idx; + TRACE("ret %x\n", *dispid); + return S_OK; +} + +static HRESULT HTMLFiltersCollection_invoke(IUnknown *iface, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + HTMLFiltersCollection *This = HTMLFILTERSCOLLECTION_THIS(iface); + + TRACE("(%p)->(%x %x %x %p %p %p)\n", This, id, lcid, flags, params, res, ei); + + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = NULL; + + FIXME("always returning NULL\n"); + + return S_OK; +} + +static const dispex_static_data_vtbl_t HTMLFiltersCollection_dispex_vtbl = { + NULL, + HTMLFiltersCollection_get_dispid, + HTMLFiltersCollection_invoke +}; + +static const tid_t HTMLFiltersCollection_iface_tids[] = { + IHTMLFiltersCollection_tid, + 0 +}; +static dispex_static_data_t HTMLFiltersCollection_dispex = { + &HTMLFiltersCollection_dispex_vtbl, + IHTMLFiltersCollection_tid, + NULL, + HTMLFiltersCollection_iface_tids +}; + +IHTMLFiltersCollection *HTMLFiltersCollection_Create() +{ + HTMLFiltersCollection *ret = heap_alloc(sizeof(HTMLFiltersCollection)); + + ret->lpHTMLFiltersCollectionVtbl = &HTMLFiltersCollectionVtbl; + ret->ref = 1; + + init_dispex(&ret->dispex, (IUnknown*)HTMLFILTERSCOLLECTION(ret), &HTMLFiltersCollection_dispex); + + return HTMLFILTERSCOLLECTION(ret); +} diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 04ae71925d4..2ef7611bf6d 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -105,6 +105,7 @@ typedef enum { IHTMLElement4_tid, IHTMLElementCollection_tid, IHTMLEventObj_tid, + IHTMLFiltersCollection_tid, IHTMLFormElement_tid, IHTMLFrameBase_tid, IHTMLFrameBase2_tid, diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 10d802ae36e..cf140e5ed5c 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -2122,6 +2122,37 @@ static void _test_elem_set_tabindex(unsigned line, IUnknown *unk, short index) _test_elem_tabindex(line, unk, index); } +#define test_elem_filters(u) _test_elem_filters(__LINE__,u) +static void _test_elem_filters(unsigned line, IUnknown *unk) +{ + IHTMLElement *elem = _get_elem_iface(line, unk); + HRESULT hres; + IHTMLFiltersCollection *filters; + + hres = IHTMLElement_get_filters(elem, &filters); + ok_(__FILE__,line) (hres == S_OK, "get_filters failed: %08x\n", hres); + if(hres == S_OK) + { + LONG len; + IDispatchEx *dispex; + + hres = IHTMLFiltersCollection_get_length(filters, &len); + ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres); + ok_(__FILE__,line) (len == 0, "expect 0 got %d\n", len); + + hres = IHTMLFiltersCollection_QueryInterface(filters, &IID_IDispatchEx, (void**)&dispex); + ok(hres == S_OK || broken(hres == E_NOINTERFACE), "Could not get IDispatchEx interface: %08x\n", hres); + if(SUCCEEDED(hres)) { + test_disp((IUnknown*)filters, &IID_IHTMLFiltersCollection, "[object]"); + IDispatchEx_Release(dispex); + } + + IHTMLFiltersCollection_Release(filters); + } + + IHTMLElement_Release(elem); +} + #define test_elem_set_class(u,c) _test_elem_set_class(__LINE__,u,c) static void _test_elem_set_class(unsigned line, IUnknown *unk, const char *class) { @@ -5018,6 +5049,9 @@ static void test_defaults(IHTMLDocument2 *doc) IHTMLStyleSheetsCollection_Release(stylesheetcol); + hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFiltersCollection, (void**)&body); + ok(hres == E_NOINTERFACE, "got interface IHTMLFiltersCollection\n"); + test_default_selection(doc); test_doc_title(doc, ""); } @@ -5380,6 +5414,7 @@ static void test_elems(IHTMLDocument2 *doc) test_elem_set_class((IUnknown*)elem, NULL); test_elem_tabindex((IUnknown*)elem, 0); test_elem_set_tabindex((IUnknown*)elem, 1); + test_elem_filters((IUnknown*)elem); node = test_node_get_parent((IUnknown*)elem); ok(node != NULL, "node == NULL\n");