mshtml: Added IDOMMouseEvent::relatedTarget implementation.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Jacek Caban 2018-02-20 13:48:44 +01:00 committed by Alexandre Julliard
parent ad1599f276
commit 832b90d4a5
7 changed files with 110 additions and 16 deletions

View File

@ -5039,6 +5039,12 @@ static compat_mode_t HTMLDocumentNode_get_compat_mode(DispatchEx *dispex)
return This->document_mode;
}
static nsISupports *HTMLDocumentNode_get_gecko_target(DispatchEx *dispex)
{
HTMLDocumentNode *This = impl_from_DispatchEx(dispex);
return (nsISupports*)This->node.nsnode;
}
static void HTMLDocumentNode_bind_event(DispatchEx *dispex, eventid_t eid)
{
HTMLDocumentNode *This = impl_from_DispatchEx(dispex);
@ -5077,6 +5083,7 @@ static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = {
HTMLDocumentNode_get_compat_mode,
NULL
},
HTMLDocumentNode_get_gecko_target,
HTMLDocumentNode_bind_event,
HTMLDocumentNode_get_parent_event_target,
NULL,

View File

@ -5430,6 +5430,12 @@ static HRESULT HTMLElement_populate_props(DispatchEx *dispex)
return S_OK;
}
static nsISupports *HTMLElement_get_gecko_target(DispatchEx *dispex)
{
HTMLElement *This = impl_from_DispatchEx(dispex);
return (nsISupports*)This->node.nsnode;
}
static void HTMLElement_bind_event(DispatchEx *dispex, eventid_t eid)
{
HTMLElement *This = impl_from_DispatchEx(dispex);
@ -5521,6 +5527,7 @@ static event_target_vtbl_t HTMLElement_event_target_vtbl = {
NULL,
HTMLElement_populate_props
},
HTMLElement_get_gecko_target,
HTMLElement_bind_event,
HTMLElement_get_parent_event_target,
HTMLElement_handle_event_default,

View File

@ -293,6 +293,8 @@ static void remove_event_listener(EventTarget *event_target, const WCHAR *type_n
}
}
static HRESULT get_gecko_target(IEventTarget*,nsIDOMEventTarget**);
typedef struct {
DispatchEx dispex;
IHTMLEventObj IHTMLEventObj_iface;
@ -1459,8 +1461,37 @@ static HRESULT WINAPI DOMMouseEvent_get_button(IDOMMouseEvent *iface, USHORT *p)
static HRESULT WINAPI DOMMouseEvent_get_relatedTarget(IDOMMouseEvent *iface, IEventTarget **p)
{
DOMEvent *This = impl_from_IDOMMouseEvent(iface);
FIXME("(%p)->(%p)\n", This, p);
return E_NOTIMPL;
nsIDOMEventTarget *related_target;
nsIDOMNode *target_node;
HTMLDOMNode *node;
HRESULT hres;
nsresult nsres;
TRACE("(%p)->(%p)\n", This, p);
nsres = nsIDOMMouseEvent_GetRelatedTarget(This->mouse_event, &related_target);
if(NS_FAILED(nsres))
return E_FAIL;
if(!related_target) {
*p = NULL;
return S_OK;
}
nsres = nsIDOMEventTarget_QueryInterface(related_target, &IID_nsIDOMNode, (void**)&target_node);
nsIDOMEventTarget_Release(related_target);
if(NS_FAILED(nsres)) {
FIXME("Only node targets supported\n");
return E_NOTIMPL;
}
hres = get_node(target_node, TRUE, &node);
nsIDOMNode_Release(target_node);
if(FAILED(hres))
return hres;
*p = &node->event_target.IEventTarget_iface;
return S_OK;
}
static HRESULT WINAPI DOMMouseEvent_initMouseEvent(IDOMMouseEvent *iface, BSTR type,
@ -1470,6 +1501,7 @@ static HRESULT WINAPI DOMMouseEvent_initMouseEvent(IDOMMouseEvent *iface, BSTR t
IEventTarget *related_target)
{
DOMEvent *This = impl_from_IDOMMouseEvent(iface);
nsIDOMEventTarget *nstarget = NULL;
nsAString type_str;
nsresult nsres;
HRESULT hres;
@ -1486,21 +1518,28 @@ static HRESULT WINAPI DOMMouseEvent_initMouseEvent(IDOMMouseEvent *iface, BSTR t
if(view)
FIXME("view argument is not supported\n");
hres = IDOMEvent_initEvent(&This->IDOMEvent_iface, type, can_bubble, cancelable);
if(FAILED(hres))
return hres;
nsAString_InitDepend(&type_str, type);
nsres = nsIDOMMouseEvent_InitMouseEvent(This->mouse_event, &type_str, can_bubble, cancelable,
NULL /* FIXME */, detail, screen_x, screen_y,
client_x, client_y, ctrl_key, alt_key, shift_key,
meta_key, button, NULL /* FIXME */);
nsAString_Finish(&type_str);
if(NS_FAILED(nsres)) {
FIXME("InitMouseEvent failed: %08x\n", nsres);
return E_FAIL;
if(related_target) {
hres = get_gecko_target(related_target, &nstarget);
if(FAILED(hres))
return hres;
}
hres = IDOMEvent_initEvent(&This->IDOMEvent_iface, type, can_bubble, cancelable);
if(SUCCEEDED(hres)) {
nsAString_InitDepend(&type_str, type);
nsres = nsIDOMMouseEvent_InitMouseEvent(This->mouse_event, &type_str, can_bubble, cancelable,
NULL /* FIXME */, detail, screen_x, screen_y,
client_x, client_y, ctrl_key, alt_key, shift_key,
meta_key, button, nstarget);
nsAString_Finish(&type_str);
if(NS_FAILED(nsres)) {
FIXME("InitMouseEvent failed: %08x\n", nsres);
return E_FAIL;
}
}
if(nstarget)
nsIDOMEventTarget_Release(nstarget);
return S_OK;
}
@ -3120,6 +3159,29 @@ static const IEventTargetVtbl EventTargetVtbl = {
EventTarget_dispatchEvent
};
static EventTarget *unsafe_impl_from_IEventTarget(IEventTarget *iface)
{
return iface && iface->lpVtbl == &EventTargetVtbl ? impl_from_IEventTarget(iface) : NULL;
}
static HRESULT get_gecko_target(IEventTarget *target, nsIDOMEventTarget **ret)
{
EventTarget *event_target = unsafe_impl_from_IEventTarget(target);
const event_target_vtbl_t *vtbl;
nsresult nsres;
if(!event_target) {
WARN("Not our IEventTarget implementation\n");
return E_INVALIDARG;
}
vtbl = (const event_target_vtbl_t*)dispex_get_vtbl(&event_target->dispex);
nsres = nsISupports_QueryInterface(vtbl->get_gecko_target(&event_target->dispex),
&IID_nsIDOMEventTarget, (void**)ret);
assert(nsres == NS_OK);
return S_OK;
}
HRESULT EventTarget_QI(EventTarget *event_target, REFIID riid, void **ppv)
{
if(IsEqualGUID(riid, &IID_IEventTarget)) {

View File

@ -114,6 +114,7 @@ void detach_nsevent(HTMLDocumentNode*,const WCHAR*) DECLSPEC_HIDDEN;
/* We extend dispex vtbl for EventTarget functions to avoid separated vtbl. */
typedef struct {
dispex_static_data_vtbl_t dispex_vtbl;
nsISupports *(*get_gecko_target)(DispatchEx*);
void (*bind_event)(DispatchEx*,eventid_t);
EventTarget *(*get_parent_event_target)(DispatchEx*);
HRESULT (*handle_event_default)(DispatchEx*,eventid_t,nsIDOMEvent*,BOOL*);

View File

@ -3024,6 +3024,12 @@ static compat_mode_t HTMLWindow_get_compat_mode(DispatchEx *dispex)
return This->doc->document_mode;
}
static nsISupports *HTMLWindow_get_gecko_target(DispatchEx *dispex)
{
HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
return (nsISupports*)This->base.outer_window->nswindow;
}
static void HTMLWindow_bind_event(DispatchEx *dispex, eventid_t eid)
{
HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
@ -3050,6 +3056,7 @@ static const event_target_vtbl_t HTMLWindow_event_target_vtbl = {
HTMLWindow_get_compat_mode,
NULL
},
HTMLWindow_get_gecko_target,
HTMLWindow_bind_event,
NULL,
NULL,

View File

@ -629,6 +629,7 @@ function test_mouse_event() {
ok(e.pageX === 0, "pageX = " + e.pageX);
ok(e.pageY === 0, "pageY = " + e.pageY);
ok(e.which === 1, "which = " + e.which);
ok(e.relatedTarget === null, "relatedTarget = " + e.relatedTarget);
e.initMouseEvent("test", true, true, window, 1, 2, 3, 4, 5, false, false, false, false, 1, document);
ok(e.type === "test", "type = " + e.type);
@ -648,8 +649,9 @@ function test_mouse_event() {
ok(e.button === 1, "button = " + e.button);
ok(e.buttons === 0, "buttons = " + e.buttons);
ok(e.which === 2, "which = " + e.which);
ok(e.relatedTarget === document, "relatedTarget = " + e.relatedTarget);
e.initMouseEvent("test", false, false, window, 9, 8, 7, 6, 5, true, true, true, true, 127, document);
e.initMouseEvent("test", false, false, window, 9, 8, 7, 6, 5, true, true, true, true, 127, document.body);
ok(e.type === "test", "type = " + e.type);
ok(e.cancelable === false, "cancelable = " + e.cancelable);
ok(e.bubbles === false, "bubbles = " + e.bubbles);
@ -664,6 +666,7 @@ function test_mouse_event() {
ok(e.metaKey === true, "metaKey = " + e.metaKey);
ok(e.button === 127, "button = " + e.button);
ok(e.which === 128, "which = " + e.which);
ok(e.relatedTarget === document.body, "relatedTarget = " + e.relatedTarget);
e.initEvent("testevent", true, true);
ok(e.type === "testevent", "type = " + e.type);

View File

@ -738,6 +738,12 @@ static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface)
return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex);
}
static nsISupports *HTMLXMLHttpRequest_get_gecko_target(DispatchEx *dispex)
{
HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
return (nsISupports*)This->nsxhr;
}
static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, eventid_t eid)
{
HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
@ -775,6 +781,7 @@ static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, eventid_t eid)
static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = {
{NULL},
HTMLXMLHttpRequest_get_gecko_target,
HTMLXMLHttpRequest_bind_event
};