mshtml: Use event target vtbl to set current window event in fire_event_obj.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
57b830526b
commit
6dc67c4234
|
@ -5048,6 +5048,12 @@ static ConnectionPointContainer *HTMLDocumentNode_get_cp_container(DispatchEx *d
|
|||
return container;
|
||||
}
|
||||
|
||||
static IHTMLEventObj *HTMLDocumentNode_set_current_event(DispatchEx *dispex, IHTMLEventObj *event)
|
||||
{
|
||||
HTMLDocumentNode *This = impl_from_DispatchEx(dispex);
|
||||
return default_set_current_event(This->window, event);
|
||||
}
|
||||
|
||||
static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = {
|
||||
{
|
||||
NULL,
|
||||
|
@ -5059,7 +5065,8 @@ static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = {
|
|||
HTMLDocumentNode_bind_event,
|
||||
HTMLDocumentNode_get_parent_event_target,
|
||||
NULL,
|
||||
HTMLDocumentNode_get_cp_container
|
||||
HTMLDocumentNode_get_cp_container,
|
||||
HTMLDocumentNode_set_current_event
|
||||
};
|
||||
|
||||
static const NodeImplVtbl HTMLDocumentFragmentImplVtbl = {
|
||||
|
|
|
@ -5384,6 +5384,12 @@ static ConnectionPointContainer *HTMLElement_get_cp_container(DispatchEx *dispex
|
|||
return &This->cp_container;
|
||||
}
|
||||
|
||||
static IHTMLEventObj *HTMLElement_set_current_event(DispatchEx *dispex, IHTMLEventObj *event)
|
||||
{
|
||||
HTMLElement *This = impl_from_DispatchEx(dispex);
|
||||
return default_set_current_event(This->node.doc->window, event);
|
||||
}
|
||||
|
||||
void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
|
||||
{
|
||||
static const DISPID elem2_ie11_blacklist[] = {DISPID_IHTMLELEMENT2_DOSCROLL, DISPID_UNKNOWN};
|
||||
|
@ -5417,7 +5423,8 @@ static event_target_vtbl_t HTMLElement_event_target_vtbl = {
|
|||
HTMLElement_bind_event,
|
||||
HTMLElement_get_parent_event_target,
|
||||
HTMLElement_handle_event_default,
|
||||
HTMLElement_get_cp_container
|
||||
HTMLElement_get_cp_container,
|
||||
HTMLElement_set_current_event
|
||||
};
|
||||
|
||||
static dispex_static_data_t HTMLElement_dispex = {
|
||||
|
|
|
@ -1063,29 +1063,17 @@ void call_event_handlers(HTMLEventObj *event_obj, EventTarget *event_target, eve
|
|||
}
|
||||
}
|
||||
|
||||
static void fire_event_obj(HTMLDocumentNode *doc, eventid_t eid, HTMLEventObj *event_obj, EventTarget *event_target)
|
||||
static void fire_event_obj(EventTarget *event_target, eventid_t eid, HTMLEventObj *event_obj)
|
||||
{
|
||||
EventTarget *target_chain_buf[8], **target_chain = target_chain_buf;
|
||||
unsigned chain_cnt, chain_buf_size, i;
|
||||
IHTMLEventObj *prev_event;
|
||||
const event_target_vtbl_t *vtbl;
|
||||
const event_target_vtbl_t *vtbl, *target_vtbl;
|
||||
IHTMLEventObj *prev_event = NULL;
|
||||
BOOL prevent_default = FALSE;
|
||||
HTMLInnerWindow *window;
|
||||
EventTarget *iter;
|
||||
HRESULT hres;
|
||||
|
||||
TRACE("(%p) %s\n", doc, debugstr_w(event_info[eid].name));
|
||||
|
||||
window = doc->window;
|
||||
if(!window) {
|
||||
WARN("NULL window\n");
|
||||
return;
|
||||
}
|
||||
|
||||
htmldoc_addref(&doc->basedoc);
|
||||
|
||||
prev_event = window->event;
|
||||
window->event = event_obj ? &event_obj->IHTMLEventObj_iface : NULL;
|
||||
TRACE("(%p) %s\n", event_target, debugstr_w(event_info[eid].name));
|
||||
|
||||
iter = event_target;
|
||||
IDispatchEx_AddRef(&event_target->dispex.IDispatchEx_iface);
|
||||
|
@ -1117,15 +1105,24 @@ static void fire_event_obj(HTMLDocumentNode *doc, eventid_t eid, HTMLEventObj *e
|
|||
iter = vtbl->get_parent_event_target(&iter->dispex);
|
||||
} while(iter);
|
||||
|
||||
target_vtbl = dispex_get_vtbl(&event_target->dispex);
|
||||
if(target_vtbl && target_vtbl->set_current_event)
|
||||
prev_event = target_vtbl->set_current_event(&event_target->dispex, event_obj ? &event_obj->IHTMLEventObj_iface : NULL);
|
||||
|
||||
for(i = 0; i < chain_cnt; i++) {
|
||||
call_event_handlers(event_obj, target_chain[i], eid);
|
||||
if(!(event_info[eid].flags & EVENT_BUBBLES) || (event_obj && event_obj->cancel_bubble))
|
||||
break;
|
||||
}
|
||||
|
||||
if(target_vtbl && target_vtbl->set_current_event) {
|
||||
prev_event = target_vtbl->set_current_event(&event_target->dispex, prev_event);
|
||||
if(prev_event)
|
||||
IHTMLEventObj_Release(prev_event);
|
||||
}
|
||||
|
||||
if(event_obj && event_obj->prevent_default)
|
||||
prevent_default = TRUE;
|
||||
window->event = prev_event;
|
||||
|
||||
if(event_info[eid].flags & EVENT_HASDEFAULTHANDLERS) {
|
||||
for(i = 0; !prevent_default && i < chain_cnt; i++) {
|
||||
|
@ -1147,8 +1144,6 @@ static void fire_event_obj(HTMLDocumentNode *doc, eventid_t eid, HTMLEventObj *e
|
|||
TRACE("calling PreventDefault\n");
|
||||
nsIDOMEvent_PreventDefault(event_obj->nsevent);
|
||||
}
|
||||
|
||||
htmldoc_release(&doc->basedoc);
|
||||
}
|
||||
|
||||
void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, EventTarget *target, nsIDOMEvent *nsevent)
|
||||
|
@ -1168,7 +1163,7 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, EventTarge
|
|||
}
|
||||
}
|
||||
|
||||
fire_event_obj(doc, eid, event_obj, target);
|
||||
fire_event_obj(target, eid, event_obj);
|
||||
|
||||
if(event_obj)
|
||||
IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
|
||||
|
@ -1213,7 +1208,7 @@ HRESULT dispatch_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *even
|
|||
if(event_obj) {
|
||||
hres = set_event_info(event_obj, &node->event_target, eid, node->doc, NULL);
|
||||
if(SUCCEEDED(hres))
|
||||
fire_event_obj(node->doc, eid, event_obj, &node->event_target);
|
||||
fire_event_obj(&node->event_target, eid, event_obj);
|
||||
|
||||
IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
|
||||
if(FAILED(hres))
|
||||
|
|
|
@ -86,8 +86,11 @@ typedef struct {
|
|||
EventTarget *(*get_parent_event_target)(DispatchEx*);
|
||||
HRESULT (*handle_event_default)(DispatchEx*,eventid_t,nsIDOMEvent*,BOOL*);
|
||||
ConnectionPointContainer *(*get_cp_container)(DispatchEx*);
|
||||
IHTMLEventObj *(*set_current_event)(DispatchEx*,IHTMLEventObj*);
|
||||
} event_target_vtbl_t;
|
||||
|
||||
IHTMLEventObj *default_set_current_event(HTMLInnerWindow*,IHTMLEventObj*) DECLSPEC_HIDDEN;
|
||||
|
||||
static inline EventTarget *get_node_event_prop_target(HTMLDOMNode *node, eventid_t eid)
|
||||
{
|
||||
return node->vtbl->get_event_prop_target ? node->vtbl->get_event_prop_target(node, eid) : &node->event_target;
|
||||
|
|
|
@ -1241,6 +1241,20 @@ static HRESULT WINAPI HTMLWindow2_get_document(IHTMLWindow2 *iface, IHTMLDocumen
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
IHTMLEventObj *default_set_current_event(HTMLInnerWindow *window, IHTMLEventObj *event_obj)
|
||||
{
|
||||
IHTMLEventObj *prev_event = NULL;
|
||||
|
||||
if(window) {
|
||||
if(event_obj)
|
||||
IHTMLEventObj_AddRef(event_obj);
|
||||
prev_event = window->event;
|
||||
window->event = event_obj;
|
||||
}
|
||||
|
||||
return prev_event;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLWindow2_get_event(IHTMLWindow2 *iface, IHTMLEventObj **p)
|
||||
{
|
||||
HTMLWindow *This = impl_from_IHTMLWindow2(iface);
|
||||
|
@ -3006,6 +3020,12 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa
|
|||
dispex_info_add_interface(info, IHTMLWindow5_tid, NULL);
|
||||
}
|
||||
|
||||
static IHTMLEventObj *HTMLWindow_set_current_event(DispatchEx *dispex, IHTMLEventObj *event)
|
||||
{
|
||||
HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
|
||||
return default_set_current_event(This, event);
|
||||
}
|
||||
|
||||
static const event_target_vtbl_t HTMLWindow_event_target_vtbl = {
|
||||
{
|
||||
NULL,
|
||||
|
@ -3014,7 +3034,11 @@ static const event_target_vtbl_t HTMLWindow_event_target_vtbl = {
|
|||
NULL,
|
||||
NULL
|
||||
},
|
||||
HTMLWindow_bind_event
|
||||
HTMLWindow_bind_event,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
HTMLWindow_set_current_event
|
||||
};
|
||||
|
||||
static const tid_t HTMLWindow_iface_tids[] = {
|
||||
|
|
Loading…
Reference in New Issue