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");