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**);