Module: wine Branch: master Commit: 6dc67c4234a93f49a64ea05a7acca4dc31323947 URL: http://source.winehq.org/git/wine.git/?a=commit;h=6dc67c4234a93f49a64ea05a7a...
Author: Jacek Caban jacek@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@codeweavers.com Signed-off-by: Alexandre Julliard julliard@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[] = {