Module: wine Branch: master Commit: 57cf4a38acf09613465d4ed3568fd95483da4d89 URL: https://source.winehq.org/git/wine.git/?a=commit;h=57cf4a38acf09613465d4ed35...
Author: Jacek Caban jacek@codeweavers.com Date: Thu Jan 24 13:49:51 2019 +0100
mshtml: Add IDOMCustomEvent interface stub implementation.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/mshtml/htmlevent.c | 144 +++++++++++++++++++++++++++++++++++++++++-- dlls/mshtml/htmlevent.h | 4 +- dlls/mshtml/mshtml_private.h | 2 + dlls/mshtml/nsiface.idl | 12 ++++ dlls/mshtml/tests/events.c | 12 ++++ 5 files changed, 168 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index f2c24a4..62ae8d3 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -851,7 +851,7 @@ static HRESULT WINAPI DOMEvent_QueryInterface(IDOMEvent *iface, REFIID riid, voi *ppv = &This->IDOMKeyboardEvent_iface; else if(dispex_query_interface(&This->dispex, riid, ppv)) return *ppv ? S_OK : E_NOINTERFACE; - else { + else if(!This->query_interface || !(*ppv = This->query_interface(This, riid))) { *ppv = NULL; WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); return E_NOINTERFACE; @@ -879,10 +879,14 @@ static ULONG WINAPI DOMEvent_Release(IDOMEvent *iface) TRACE("(%p) ref=%u\n", This, ref);
if(!ref) { + if(This->destroy) + This->destroy(This); if(This->ui_event) nsIDOMUIEvent_Release(This->ui_event); if(This->mouse_event) nsIDOMMouseEvent_Release(This->mouse_event); + if(This->keyboard_event) + nsIDOMKeyEvent_Release(This->keyboard_event); if(This->target) IEventTarget_Release(&This->target->IEventTarget_iface); nsIDOMEvent_Release(This->nsevent); @@ -2042,6 +2046,112 @@ static const IDOMKeyboardEventVtbl DOMKeyboardEventVtbl = { DOMKeyboardEvent_get_locale };
+typedef struct { + DOMEvent event; + IDOMCustomEvent IDOMCustomEvent_iface; + VARIANT detail; +} DOMCustomEvent; + +static inline DOMCustomEvent *impl_from_IDOMCustomEvent(IDOMCustomEvent *iface) +{ + return CONTAINING_RECORD(iface, DOMCustomEvent, IDOMCustomEvent_iface); +} + +static HRESULT WINAPI DOMCustomEvent_QueryInterface(IDOMCustomEvent *iface, REFIID riid, void **ppv) +{ + DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface); + return IDOMEvent_QueryInterface(&This->event.IDOMEvent_iface, riid, ppv); +} + +static ULONG WINAPI DOMCustomEvent_AddRef(IDOMCustomEvent *iface) +{ + DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface); + return IDOMEvent_AddRef(&This->event.IDOMEvent_iface); +} + +static ULONG WINAPI DOMCustomEvent_Release(IDOMCustomEvent *iface) +{ + DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface); + return IDOMEvent_Release(&This->event.IDOMEvent_iface); +} + +static HRESULT WINAPI DOMCustomEvent_GetTypeInfoCount(IDOMCustomEvent *iface, UINT *pctinfo) +{ + DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface); + return IDispatchEx_GetTypeInfoCount(&This->event.dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI DOMCustomEvent_GetTypeInfo(IDOMCustomEvent *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface); + return IDispatchEx_GetTypeInfo(&This->event.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI DOMCustomEvent_GetIDsOfNames(IDOMCustomEvent *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface); + return IDispatchEx_GetIDsOfNames(&This->event.dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI DOMCustomEvent_Invoke(IDOMCustomEvent *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface); + return IDispatchEx_Invoke(&This->event.dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI DOMCustomEvent_get_detail(IDOMCustomEvent *iface, VARIANT *p) +{ + DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMCustomEvent_initCustomEvent(IDOMCustomEvent *iface, BSTR type, VARIANT_BOOL can_bubble, + VARIANT_BOOL cancelable, VARIANT *detail) +{ + DOMCustomEvent *This = impl_from_IDOMCustomEvent(iface); + FIXME("(%p)->(%s %x %x %p)\n", This, debugstr_w(type), can_bubble, cancelable, debugstr_variant(detail)); + return E_NOTIMPL; +} + +static const IDOMCustomEventVtbl DOMCustomEventVtbl = { + DOMCustomEvent_QueryInterface, + DOMCustomEvent_AddRef, + DOMCustomEvent_Release, + DOMCustomEvent_GetTypeInfoCount, + DOMCustomEvent_GetTypeInfo, + DOMCustomEvent_GetIDsOfNames, + DOMCustomEvent_Invoke, + DOMCustomEvent_get_detail, + DOMCustomEvent_initCustomEvent +}; + +static DOMCustomEvent *DOMCustomEvent_from_DOMEvent(DOMEvent *event) +{ + return CONTAINING_RECORD(event, DOMCustomEvent, event); +} + +static void *DOMCustomEvent_query_interface(DOMEvent *event, REFIID riid) +{ + DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(event); + if(IsEqualGUID(&IID_IDOMCustomEvent, riid)) + return &custom_event->IDOMCustomEvent_iface; + return NULL; +} + +static void DOMCustomEvent_destroy(DOMEvent *event) +{ + DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(event); + VariantClear(&custom_event->detail); +} + + static const tid_t DOMEvent_iface_tids[] = { IDOMEvent_tid, 0 @@ -2091,19 +2201,43 @@ static dispex_static_data_t DOMKeyboardEvent_dispex = { DOMKeyboardEvent_iface_tids };
+static BOOL check_event_iface(nsIDOMEvent *event, REFIID riid) +{ + nsISupports *iface; + nsresult nsres; + + nsres = nsIDOMEvent_QueryInterface(event, riid, (void**)&iface); + if(NS_FAILED(nsres)) + return FALSE; + + nsISupports_Release(iface); + return TRUE; +} + static DOMEvent *alloc_event(nsIDOMEvent *nsevent, eventid_t event_id) { dispex_static_data_t *dispex_data = &DOMEvent_dispex; - DOMEvent *event; + DOMEvent *event = NULL; FILETIME time; nsresult nsres;
/* 1601 to 1970 is 369 years plus 89 leap days */ const ULONGLONG time_epoch = (ULONGLONG)(369 * 365 + 89) * 86400 * 1000;
- event = heap_alloc_zero(sizeof(*event)); - if(!event) - return NULL; + if(check_event_iface(nsevent, &IID_nsIDOMCustomEvent)) { + DOMCustomEvent *custom_event = heap_alloc_zero(sizeof(*custom_event)); + if(!custom_event) + return NULL; + + custom_event->IDOMCustomEvent_iface.lpVtbl = &DOMCustomEventVtbl; + custom_event->event.query_interface = DOMCustomEvent_query_interface; + custom_event->event.destroy = DOMCustomEvent_destroy; + event = &custom_event->event; + }else if(!event) { + event = heap_alloc_zero(sizeof(*event)); + if(!event) + return NULL; + }
event->IDOMEvent_iface.lpVtbl = &DOMEventVtbl; event->IDOMUIEvent_iface.lpVtbl = &DOMUIEventVtbl; diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 1a7afb5..e2f45dc 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -57,7 +57,7 @@ typedef enum { EVENTID_LAST } eventid_t;
-typedef struct { +typedef struct DOMEvent { DispatchEx dispex; IDOMEvent IDOMEvent_iface; IDOMUIEvent IDOMUIEvent_iface; @@ -65,6 +65,8 @@ typedef struct { IDOMKeyboardEvent IDOMKeyboardEvent_iface;
LONG ref; + void *(*query_interface)(struct DOMEvent*,REFIID); + void (*destroy)(struct DOMEvent*);
nsIDOMEvent *nsevent; nsIDOMUIEvent *ui_event; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 89a56bd..bc3c5a6e 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -80,6 +80,7 @@ typedef struct EventTarget EventTarget; XDIID(DispCEventObj) \ XDIID(DispCPlugins) \ XDIID(DispDOMChildrenCollection) \ + XDIID(DispDOMCustomEvent) \ XDIID(DispDOMEvent) \ XDIID(DispDOMKeyboardEvent) \ XDIID(DispDOMMouseEvent) \ @@ -130,6 +131,7 @@ typedef struct EventTarget EventTarget; XDIID(DispHTMLXMLHttpRequest) \ XDIID(HTMLDocumentEvents) \ XDIID(HTMLElementEvents2) \ + XIID(IDOMCustomEvent) \ XIID(IDOMEvent) \ XIID(IDOMKeyboardEvent) \ XIID(IDOMMouseEvent) \ diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index 34f83ab..b3335ba 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -3243,6 +3243,18 @@ interface nsIDOMKeyEvent : nsIDOMUIEvent
[ object, + uuid(5be16b03-36f9-4ca8-b2c5-0daadf3cd1b3), + local +] +interface nsIDOMCustomEvent : nsISupports +{ + nsresult GetDetail(nsIVariant **aDetail); + nsresult InitCustomEvent(const nsAString *typeArg, bool canBubbleArg, bool cancelableArg, + nsIVariant *detailArg); +} + +[ + object, uuid(0b976267-4aaa-4f36-a2d4-27b5ca8d73bb), local ] diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index a219987..f9bf88e 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -2667,6 +2667,7 @@ static void test_iframe_connections(IHTMLDocument2 *doc) static void test_create_event(IHTMLDocument2 *doc) { IDOMKeyboardEvent *keyboard_event; + IDOMCustomEvent *custom_event; IDOMMouseEvent *mouse_event; IDocumentEvent *doc_event; IEventTarget *event_target; @@ -2771,6 +2772,17 @@ static void test_create_event(IHTMLDocument2 *doc)
IDOMEvent_Release(event);
+ str = a2bstr("CustomEvent"); + hres = IDocumentEvent_createEvent(doc_event, str, &event); + SysFreeString(str); + ok(hres == S_OK, "createEvent failed: %08x\n", hres); + + hres = IDOMEvent_QueryInterface(event, &IID_IDOMCustomEvent, (void**)&custom_event); + ok(hres == S_OK, "QueryInterface(IID_IDOMCustomEvent returned %08x\n", hres); + IDOMCustomEvent_Release(custom_event); + + IDOMEvent_Release(event); + IDocumentEvent_Release(doc_event); }