Module: wine Branch: master Commit: cea8bc5237268be68185c1bb2081915f5c6fc6bb URL: http://source.winehq.org/git/wine.git/?a=commit;h=cea8bc5237268be68185c1bb20...
Author: Jacek Caban jacek@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); }