Jacek Caban : mshtml: Use event target vtbl to set current window event in fire_event_obj.
Alexandre Julliard
julliard at winehq.org
Thu Oct 19 14:31:35 CDT 2017
Module: wine
Branch: master
Commit: 6dc67c4234a93f49a64ea05a7acca4dc31323947
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6dc67c4234a93f49a64ea05a7acca4dc31323947
Author: Jacek Caban <jacek at codeweavers.com>
Date: Thu Oct 19 17:01:43 2017 +0200
mshtml: Use event target vtbl to set current window event in fire_event_obj.
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mshtml/htmldoc.c | 9 ++++++++-
dlls/mshtml/htmlelem.c | 9 ++++++++-
dlls/mshtml/htmlevent.c | 37 ++++++++++++++++---------------------
dlls/mshtml/htmlevent.h | 3 +++
dlls/mshtml/htmlwindow.c | 26 +++++++++++++++++++++++++-
5 files changed, 60 insertions(+), 24 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index 6624257..622ceea 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -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 = {
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index f7cdcf4..8aab4c4 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -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 = {
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c
index 7769932..6f81a89 100644
--- a/dlls/mshtml/htmlevent.c
+++ b/dlls/mshtml/htmlevent.c
@@ -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))
diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h
index efe707f..d3ddded 100644
--- a/dlls/mshtml/htmlevent.h
+++ b/dlls/mshtml/htmlevent.h
@@ -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;
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c
index f9fd047..df181d6 100644
--- a/dlls/mshtml/htmlwindow.c
+++ b/dlls/mshtml/htmlwindow.c
@@ -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[] = {
More information about the wine-cvs
mailing list