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