diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 49349b0fd66..85e2b4b2fdd 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -980,8 +980,10 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode HTMLEventObj *event_obj = NULL; IHTMLEventObj *prev_event; nsIDOMNode *parent, *nsnode; + BOOL prevent_default = FALSE; HTMLDOMNode *node; PRUint16 node_type; + nsresult nsres; HRESULT hres; TRACE("(%p) %s\n", doc, debugstr_w(event_info[eid].name)); @@ -1053,14 +1055,42 @@ void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode if(nsnode) nsIDOMNode_Release(nsnode); + if(event_obj && event_obj->prevent_default) + prevent_default = TRUE; doc->basedoc.window->event = prev_event; - - if(event_obj) { - if(event_obj->prevent_default && nsevent) { - TRACE("calling PreventDefault\n"); - nsIDOMEvent_PreventDefault(nsevent); - } + if(event_obj) IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface); + + if(!prevent_default) { + nsIDOMNode_AddRef(target); + nsnode = target; + + do { + hres = get_node(doc, nsnode, TRUE, &node); + if(FAILED(hres)) + break; + + if(node && node->vtbl->handle_event) { + hres = node->vtbl->handle_event(node, eid, &prevent_default); + if(FAILED(hres) || prevent_default) + break; + } + + nsres = nsIDOMNode_GetParentNode(nsnode, &parent); + if(NS_FAILED(nsres)) + break; + + nsIDOMNode_Release(nsnode); + nsnode = parent; + } while(nsnode); + + if(nsnode) + nsIDOMNode_Release(nsnode); + } + + if(prevent_default && nsevent) { + TRACE("calling PreventDefault\n"); + nsIDOMEvent_PreventDefault(nsevent); } } diff --git a/dlls/mshtml/htmlform.c b/dlls/mshtml/htmlform.c index ac6d39ca31e..ae84ac3a4c9 100644 --- a/dlls/mshtml/htmlform.c +++ b/dlls/mshtml/htmlform.c @@ -639,6 +639,7 @@ static const NodeImplVtbl HTMLFormElementImplVtbl = { NULL, NULL, NULL, + NULL, HTMLFormElement_get_dispid, HTMLFormElement_invoke }; diff --git a/dlls/mshtml/htmlframe.c b/dlls/mshtml/htmlframe.c index 7c0cfb1854a..3b4126b664b 100644 --- a/dlls/mshtml/htmlframe.c +++ b/dlls/mshtml/htmlframe.c @@ -274,6 +274,7 @@ static const NodeImplVtbl HTMLFrameElementImplVtbl = { NULL, NULL, NULL, + NULL, HTMLFrameElement_get_document, HTMLFrameElement_get_readystate, HTMLFrameElement_get_dispid, diff --git a/dlls/mshtml/htmliframe.c b/dlls/mshtml/htmliframe.c index 7aba57021a8..8a293464b5c 100644 --- a/dlls/mshtml/htmliframe.c +++ b/dlls/mshtml/htmliframe.c @@ -252,6 +252,7 @@ static const NodeImplVtbl HTMLIFrameImplVtbl = { NULL, NULL, NULL, + NULL, HTMLIFrame_get_document, HTMLIFrame_get_readystate, HTMLIFrame_get_dispid, diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index 1fb0e83e021..2f72484f98f 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -663,6 +663,7 @@ static const NodeImplVtbl HTMLImgElementImplVtbl = { NULL, NULL, NULL, + NULL, HTMLImgElement_get_readystate }; diff --git a/dlls/mshtml/htmlinput.c b/dlls/mshtml/htmlinput.c index 242812021bb..9d197618695 100644 --- a/dlls/mshtml/htmlinput.c +++ b/dlls/mshtml/htmlinput.c @@ -1187,6 +1187,7 @@ static const NodeImplVtbl HTMLInputElementImplVtbl = { HTMLElement_clone, NULL, HTMLInputElementImpl_fire_event, + NULL, HTMLInputElementImpl_put_disabled, HTMLInputElementImpl_get_disabled, }; diff --git a/dlls/mshtml/htmlobject.c b/dlls/mshtml/htmlobject.c index dce6c8c53ff..50e04a916d9 100644 --- a/dlls/mshtml/htmlobject.c +++ b/dlls/mshtml/htmlobject.c @@ -475,6 +475,7 @@ static const NodeImplVtbl HTMLObjectElementImplVtbl = { NULL, NULL, NULL, + NULL, HTMLObjectElement_get_readystate, HTMLObjectElement_get_dispid, HTMLObjectElement_invoke diff --git a/dlls/mshtml/htmlscript.c b/dlls/mshtml/htmlscript.c index 7b4cbc98d04..ca0524fecdc 100644 --- a/dlls/mshtml/htmlscript.c +++ b/dlls/mshtml/htmlscript.c @@ -335,6 +335,7 @@ static const NodeImplVtbl HTMLScriptElementImplVtbl = { NULL, NULL, NULL, + NULL, HTMLScriptElement_get_readystate }; diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index 3208bbc193b..6d2e3935a6e 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -617,6 +617,7 @@ static const NodeImplVtbl HTMLSelectElementImplVtbl = { HTMLElement_clone, NULL, NULL, + NULL, HTMLSelectElementImpl_put_disabled, HTMLSelectElementImpl_get_disabled, NULL, diff --git a/dlls/mshtml/htmltextarea.c b/dlls/mshtml/htmltextarea.c index 3b7651da3bd..ae2fd6a8aa8 100644 --- a/dlls/mshtml/htmltextarea.c +++ b/dlls/mshtml/htmltextarea.c @@ -449,6 +449,7 @@ static const NodeImplVtbl HTMLTextAreaElementImplVtbl = { HTMLElement_clone, NULL, NULL, + NULL, HTMLTextAreaElementImpl_put_disabled, HTMLTextAreaElementImpl_get_disabled }; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c3d648d5337..1a0755238af 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -499,6 +499,7 @@ typedef struct { HRESULT (*clone)(HTMLDOMNode*,nsIDOMNode*,HTMLDOMNode**); event_target_t **(*get_event_target)(HTMLDOMNode*); HRESULT (*fire_event)(HTMLDOMNode*,DWORD,BOOL*); + HRESULT (*handle_event)(HTMLDOMNode*,DWORD,BOOL*); HRESULT (*put_disabled)(HTMLDOMNode*,VARIANT_BOOL); HRESULT (*get_disabled)(HTMLDOMNode*,VARIANT_BOOL*); HRESULT (*get_document)(HTMLDOMNode*,IDispatch**);