From 8c74926bf925919caa6402e45d262a95979fcc0d Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 19 Oct 2017 17:02:08 +0200 Subject: [PATCH] mshtml: Added IDocumentEvent::createEvent implementation. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/mshtml/htmldoc.c | 6 +- dlls/mshtml/htmlevent.c | 279 +++++++++++++++++++++++++++++++++++++++++++ dlls/mshtml/htmlevent.h | 2 + dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/tests/events.c | 9 ++ 5 files changed, 295 insertions(+), 2 deletions(-) diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 622ceea497b..734f649fc0b 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -4355,8 +4355,10 @@ static HRESULT WINAPI DocumentEvent_Invoke(IDocumentEvent *iface, DISPID dispIdM static HRESULT WINAPI DocumentEvent_createEvent(IDocumentEvent *iface, BSTR eventType, IDOMEvent **p) { HTMLDocument *This = impl_from_IDocumentEvent(iface); - FIXME("(%p)->(%s %p)\n", This, debugstr_w(eventType), p); - return E_NOTIMPL; + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(eventType), p); + + return create_document_event_str(This->doc_node, eventType, p); } static const IDocumentEventVtbl DocumentEventVtbl = { diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index cffd6c8e2a4..aee9d39026c 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -223,6 +223,15 @@ static eventid_t attr_to_eid(const WCHAR *str) return EVENTID_LAST; } +typedef struct { + DispatchEx dispex; + IDOMEvent IDOMEvent_iface; + + LONG ref; + + nsIDOMEvent *nsevent; +} DOMEvent; + struct HTMLEventObj { DispatchEx dispex; IHTMLEventObj IHTMLEventObj_iface; @@ -812,6 +821,276 @@ static HTMLEventObj *create_event(void) return ret; } +static inline DOMEvent *impl_from_IDOMEvent(IDOMEvent *iface) +{ + return CONTAINING_RECORD(iface, DOMEvent, IDOMEvent_iface); +} + +static HRESULT WINAPI DOMEvent_QueryInterface(IDOMEvent *iface, REFIID riid, void **ppv) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); + + if(IsEqualGUID(&IID_IUnknown, riid)) + *ppv = &This->IDOMEvent_iface; + else if(IsEqualGUID(&IID_IDOMEvent, riid)) + *ppv = &This->IDOMEvent_iface; + else if(dispex_query_interface(&This->dispex, riid, ppv)) + return *ppv ? S_OK : E_NOINTERFACE; + else { + *ppv = NULL; + WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI DOMEvent_AddRef(IDOMEvent *iface) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%u\n", This, ref); + + return ref; +} + +static ULONG WINAPI DOMEvent_Release(IDOMEvent *iface) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%u\n", This, ref); + + if(!ref) { + nsIDOMEvent_Release(This->nsevent); + release_dispex(&This->dispex); + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI DOMEvent_GetTypeInfoCount(IDOMEvent *iface, UINT *pctinfo) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI DOMEvent_GetTypeInfo(IDOMEvent *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI DOMEvent_GetIDsOfNames(IDOMEvent *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI DOMEvent_Invoke(IDOMEvent *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI DOMEvent_get_bubbles(IDOMEvent *iface, VARIANT_BOOL *p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_get_cancelable(IDOMEvent *iface, VARIANT_BOOL *p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_get_currentTarget(IDOMEvent *iface, IEventTarget **p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_get_defaultPrevented(IDOMEvent *iface, VARIANT_BOOL *p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_get_eventPhase(IDOMEvent *iface, USHORT *p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_get_target(IDOMEvent *iface, IEventTarget **p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_get_timeStamp(IDOMEvent *iface, ULONGLONG *p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_get_type(IDOMEvent *iface, BSTR *p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_initEvent(IDOMEvent *iface, BSTR type, VARIANT_BOOL can_bubble, VARIANT_BOOL cancelable) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_preventDefault(IDOMEvent *iface) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_stopPropagation(IDOMEvent *iface) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_stopImmediatePropagation(IDOMEvent *iface) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_get_isTrusted(IDOMEvent *iface, VARIANT_BOOL *p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_put_cancelBubble(IDOMEvent *iface, VARIANT_BOOL v) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%x)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_get_cancelBubble(IDOMEvent *iface, VARIANT_BOOL *p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI DOMEvent_get_srcElement(IDOMEvent *iface, IHTMLElement **p) +{ + DOMEvent *This = impl_from_IDOMEvent(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static const IDOMEventVtbl DOMEventVtbl = { + DOMEvent_QueryInterface, + DOMEvent_AddRef, + DOMEvent_Release, + DOMEvent_GetTypeInfoCount, + DOMEvent_GetTypeInfo, + DOMEvent_GetIDsOfNames, + DOMEvent_Invoke, + DOMEvent_get_bubbles, + DOMEvent_get_cancelable, + DOMEvent_get_currentTarget, + DOMEvent_get_defaultPrevented, + DOMEvent_get_eventPhase, + DOMEvent_get_target, + DOMEvent_get_timeStamp, + DOMEvent_get_type, + DOMEvent_initEvent, + DOMEvent_preventDefault, + DOMEvent_stopPropagation, + DOMEvent_stopImmediatePropagation, + DOMEvent_get_isTrusted, + DOMEvent_put_cancelBubble, + DOMEvent_get_cancelBubble, + DOMEvent_get_srcElement +}; + +static const tid_t DOMEvent_iface_tids[] = { + IDOMEvent_tid, + 0 +}; + +static dispex_static_data_t DOMEvent_dispex = { + NULL, + IDOMEvent_tid, + DOMEvent_iface_tids +}; + +static HRESULT create_event_from_nsevent(nsIDOMEvent *nsevent, IDOMEvent **ret_event) +{ + DOMEvent *event; + + event = heap_alloc_zero(sizeof(*event)); + if(!event) + return E_OUTOFMEMORY; + + init_dispex(&event->dispex, (IUnknown*)&event->IDOMEvent_iface, &DOMEvent_dispex); + event->IDOMEvent_iface.lpVtbl = &DOMEventVtbl; + event->ref = 1; + + nsIDOMEvent_AddRef(event->nsevent = nsevent); + + *ret_event = &event->IDOMEvent_iface; + return S_OK; +} + +HRESULT create_document_event_str(HTMLDocumentNode *doc, const WCHAR *type, IDOMEvent **ret_event) +{ + nsIDOMEvent *nsevent; + nsAString nsstr; + nsresult nsres; + HRESULT hres; + + nsAString_InitDepend(&nsstr, type); + nsres = nsIDOMHTMLDocument_CreateEvent(doc->nsdoc, &nsstr, &nsevent); + nsAString_Finish(&nsstr); + if(NS_FAILED(nsres)) { + FIXME("CreateEvent failed: %08x\n", nsres); + return E_FAIL; + } + + hres = create_event_from_nsevent(nsevent, ret_event); + nsIDOMEvent_Release(nsevent); + return hres; +} + static HRESULT set_event_info(HTMLEventObj *event, eventid_t eid, HTMLDocumentNode *doc, nsIDOMEvent *nsevent) { event->type = event_info+eid; diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index d3ddded1f5d..f604003c9b1 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -74,6 +74,8 @@ HRESULT ensure_doc_nsevent_handler(HTMLDocumentNode*,eventid_t) DECLSPEC_HIDDEN; typedef struct HTMLEventObj HTMLEventObj; void call_event_handlers(HTMLEventObj*,EventTarget*,eventid_t); +HRESULT create_document_event_str(HTMLDocumentNode*,const WCHAR*,IDOMEvent**) DECLSPEC_HIDDEN; + void init_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN; void release_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN; void add_nsevent_listener(HTMLDocumentNode*,nsIDOMNode*,LPCWSTR) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 5d64151d477..2098b78f5e3 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -125,6 +125,7 @@ typedef struct EventTarget EventTarget; XDIID(DispHTMLXMLHttpRequest) \ XDIID(HTMLDocumentEvents) \ XDIID(HTMLElementEvents2) \ + XIID(IDOMEvent) \ XIID(IDocumentSelector) \ XIID(IElementSelector) \ XIID(IElementTraversal) \ diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index f8a8d44ceb3..228aa047926 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -2533,6 +2533,8 @@ static void test_iframe_connections(IHTMLDocument2 *doc) static void test_create_event(IHTMLDocument2 *doc) { IDocumentEvent *doc_event; + IDOMEvent *event; + BSTR str; HRESULT hres; trace("createEvent tests...\n"); @@ -2540,6 +2542,13 @@ static void test_create_event(IHTMLDocument2 *doc) hres = IHTMLDocument2_QueryInterface(doc, &IID_IDocumentEvent, (void**)&doc_event); ok(hres == S_OK, "Could not get IDocumentEvent iface: %08x\n", hres); + str = a2bstr("Event"); + hres = IDocumentEvent_createEvent(doc_event, str, &event); + SysFreeString(str); + ok(hres == S_OK, "createEvent failed: %08x\n", hres); + + IDOMEvent_Release(event); + IDocumentEvent_Release(doc_event); } -- 2.11.4.GIT