Jacek Caban : mshtml: Added support for IHTMLEventObj:: cancelBubble property.

Alexandre Julliard julliard at winehq.org
Mon Apr 16 13:35:46 CDT 2012


Module: wine
Branch: master
Commit: cea8bc5237268be68185c1bb2081915f5c6fc6bb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=cea8bc5237268be68185c1bb2081915f5c6fc6bb

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Apr 16 13:48:46 2012 +0200

mshtml: Added support for IHTMLEventObj::cancelBubble property.

---

 dlls/mshtml/htmlevent.c    |   18 +++++++----
 dlls/mshtml/tests/events.c |   68 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 7 deletions(-)

diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c
index 2d8dc83..b9c9aad 100644
--- a/dlls/mshtml/htmlevent.c
+++ b/dlls/mshtml/htmlevent.c
@@ -250,6 +250,7 @@ typedef struct {
     const event_info_t *type;
     nsIDOMEvent *nsevent;
     BOOL prevent_default;
+    BOOL cancel_bubble;
 } HTMLEventObj;
 
 static inline HTMLEventObj *impl_from_IHTMLEventObj(IHTMLEventObj *iface)
@@ -471,17 +472,20 @@ static HRESULT WINAPI HTMLEventObj_get_returnValue(IHTMLEventObj *iface, VARIANT
 static HRESULT WINAPI HTMLEventObj_put_cancelBubble(IHTMLEventObj *iface, VARIANT_BOOL v)
 {
     HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
-    FIXME("(%p)->(%x)\n", This, v);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%x)\n", This, v);
+
+    This->cancel_bubble = !!v;
+    return S_OK;
 }
 
 static HRESULT WINAPI HTMLEventObj_get_cancelBubble(IHTMLEventObj *iface, VARIANT_BOOL *p)
 {
     HTMLEventObj *This = impl_from_IHTMLEventObj(iface);
 
-    FIXME("(%p)->(%p)\n", This, p);
+    TRACE("(%p)->(%p)\n", This, p);
 
-    *p = VARIANT_FALSE;
+    *p = This->cancel_bubble ? VARIANT_TRUE : VARIANT_FALSE;
     return S_OK;
 }
 
@@ -1016,7 +1020,7 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode
                 call_event_handlers(doc, event_obj, *get_node_event_target(node),
                         node->cp_container, eid, (IDispatch*)&node->IHTMLDOMNode_iface);
 
-            if(!(event_info[eid].flags & EVENT_BUBBLE))
+            if(!(event_info[eid].flags & EVENT_BUBBLE) || (event_obj && event_obj->cancel_bubble))
                 break;
 
             nsIDOMNode_GetParentNode(nsnode, &parent);
@@ -1028,7 +1032,7 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode
             nsIDOMNode_GetNodeType(nsnode, &node_type);
         }while(node_type == ELEMENT_NODE);
 
-        if(!(event_info[eid].flags & EVENT_BUBBLE))
+        if(!(event_info[eid].flags & EVENT_BUBBLE) || (event_obj && event_obj->cancel_bubble))
             break;
 
     case DOCUMENT_NODE:
@@ -1076,7 +1080,7 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode
 
             if(node && node->vtbl->handle_event) {
                 hres = node->vtbl->handle_event(node, eid, nsevent, &prevent_default);
-                if(FAILED(hres) || prevent_default)
+                if(FAILED(hres) || prevent_default || (event_obj && event_obj->cancel_bubble))
                     break;
             }
 
diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c
index d1f4e9b..6d74f40 100644
--- a/dlls/mshtml/tests/events.c
+++ b/dlls/mshtml/tests/events.c
@@ -78,7 +78,9 @@ DEFINE_EXPECT(input_onblur);
 DEFINE_EXPECT(form_onsubmit);
 DEFINE_EXPECT(form_onclick);
 DEFINE_EXPECT(submit_onclick);
+DEFINE_EXPECT(submit_onclick_cancel);
 DEFINE_EXPECT(submit_onclick_attached);
+DEFINE_EXPECT(submit_onclick_attached_check_cancel);
 DEFINE_EXPECT(submit_onclick_setret);
 
 static HWND container_hwnd = NULL;
@@ -429,6 +431,7 @@ static void _test_event_shiftkey(unsigned line, IHTMLEventObj *event, VARIANT_BO
     ok_(__FILE__,line)(b == exval, "shiftKey = %x, expected %x\n", b, exval);
 }
 
+#define test_event_cancelbubble(a,b) _test_event_cancelbubble(__LINE__,a,b)
 static void _test_event_cancelbubble(unsigned line, IHTMLEventObj *event, VARIANT_BOOL exval)
 {
     VARIANT_BOOL b;
@@ -1015,6 +1018,27 @@ static HRESULT WINAPI submit_onclick_attached(IDispatchEx *iface, DISPID id, LCI
 
 EVENT_HANDLER_FUNC_OBJ(submit_onclick_attached);
 
+static HRESULT WINAPI submit_onclick_attached_check_cancel(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+    IHTMLEventObj *event;
+    HRESULT hres;
+
+    CHECK_EXPECT(submit_onclick_attached_check_cancel);
+    test_attached_event_args(id, wFlags, pdp, pvarRes, pei);
+    test_event_src("INPUT");
+
+    event = NULL;
+    hres = IHTMLWindow2_get_event(window, &event);
+    ok(hres == S_OK, "get_event failed: %08x\n", hres);
+    ok(event != NULL, "event == NULL\n");
+
+    test_event_cancelbubble(event, VARIANT_TRUE);
+    return S_OK;
+}
+
+EVENT_HANDLER_FUNC_OBJ(submit_onclick_attached_check_cancel);
+
 static VARIANT onclick_retval, onclick_event_retval;
 
 static HRESULT WINAPI submit_onclick_setret(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
@@ -1042,6 +1066,33 @@ static HRESULT WINAPI submit_onclick_setret(IDispatchEx *iface, DISPID id, LCID
 
 EVENT_HANDLER_FUNC_OBJ(submit_onclick_setret);
 
+static HRESULT WINAPI submit_onclick_cancel(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+    IHTMLEventObj *event;
+    HRESULT hres;
+
+    CHECK_EXPECT(submit_onclick_cancel);
+    test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
+    test_event_src("INPUT");
+
+    event = NULL;
+    hres = IHTMLWindow2_get_event(window, &event);
+    ok(hres == S_OK, "get_event failed: %08x\n", hres);
+    ok(event != NULL, "event == NULL\n");
+
+    test_event_cancelbubble(event, VARIANT_FALSE);
+
+    hres = IHTMLEventObj_put_cancelBubble(event, VARIANT_TRUE);
+    ok(hres == S_OK, "put_returnValue failed: %08x\n", hres);
+    IHTMLEventObj_Release(event);
+
+    test_event_cancelbubble(event, VARIANT_TRUE);
+    return S_OK;
+}
+
+EVENT_HANDLER_FUNC_OBJ(submit_onclick_cancel);
+
 static HRESULT WINAPI iframedoc_onreadystatechange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
 {
@@ -1930,6 +1981,23 @@ static void test_submit(IHTMLDocument2 *doc)
     CHECK_CALLED(submit_onclick_setret);
     CHECK_CALLED(form_onclick);
 
+    elem_attach_event((IUnknown*)submit, "onclick", (IDispatch*)&submit_onclick_attached_obj);
+    elem_attach_event((IUnknown*)submit, "onclick", (IDispatch*)&submit_onclick_attached_check_cancel_obj);
+
+    V_VT(&v) = VT_DISPATCH;
+    V_DISPATCH(&v) = (IDispatch*)&submit_onclick_cancel_obj;
+    hres = IHTMLElement_put_onclick(submit, v);
+    ok(hres == S_OK, "put_onclick failed: %08x\n", hres);
+
+    SET_EXPECT(submit_onclick_cancel);
+    SET_EXPECT(submit_onclick_attached_check_cancel);
+    SET_EXPECT(submit_onclick_attached);
+    hres = IHTMLElement_click(submit);
+    ok(hres == S_OK, "click failed: %08x\n", hres);
+    CHECK_CALLED(submit_onclick_cancel);
+    CHECK_CALLED(submit_onclick_attached_check_cancel);
+    CHECK_CALLED(submit_onclick_attached);
+
     IHTMLElement_Release(submit);
 }
 




More information about the wine-cvs mailing list