mshtml: Store DOMEvent instead of nsIDOMEvent in HTMLEventObj.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2017-10-19 17:02:21 +02:00 committed by Alexandre Julliard
parent 8c74926bf9
commit 3077358aa1
2 changed files with 114 additions and 100 deletions

View File

@ -223,15 +223,6 @@ static eventid_t attr_to_eid(const WCHAR *str)
return EVENTID_LAST; return EVENTID_LAST;
} }
typedef struct {
DispatchEx dispex;
IDOMEvent IDOMEvent_iface;
LONG ref;
nsIDOMEvent *nsevent;
} DOMEvent;
struct HTMLEventObj { struct HTMLEventObj {
DispatchEx dispex; DispatchEx dispex;
IHTMLEventObj IHTMLEventObj_iface; IHTMLEventObj IHTMLEventObj_iface;
@ -240,7 +231,7 @@ struct HTMLEventObj {
EventTarget *target; EventTarget *target;
const event_info_t *type; const event_info_t *type;
nsIDOMEvent *nsevent; DOMEvent *event;
VARIANT return_value; VARIANT return_value;
BOOL prevent_default; BOOL prevent_default;
BOOL cancel_bubble; BOOL cancel_bubble;
@ -293,8 +284,8 @@ static ULONG WINAPI HTMLEventObj_Release(IHTMLEventObj *iface)
if(!ref) { if(!ref) {
if(This->target) if(This->target)
IDispatchEx_Release(&This->target->dispex.IDispatchEx_iface); IDispatchEx_Release(&This->target->dispex.IDispatchEx_iface);
if(This->nsevent) if(This->event)
nsIDOMEvent_Release(This->nsevent); IDOMEvent_Release(&This->event->IDOMEvent_iface);
release_dispex(&This->dispex); release_dispex(&This->dispex);
heap_free(This); heap_free(This);
} }
@ -352,18 +343,18 @@ static HRESULT WINAPI HTMLEventObj_get_altKey(IHTMLEventObj *iface, VARIANT_BOOL
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMKeyEvent *key_event; nsIDOMKeyEvent *key_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMKeyEvent_GetAltKey(key_event, &ret); nsIDOMKeyEvent_GetAltKey(key_event, &ret);
nsIDOMKeyEvent_Release(key_event); nsIDOMKeyEvent_Release(key_event);
}else { }else {
nsIDOMMouseEvent *mouse_event; nsIDOMMouseEvent *mouse_event;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMMouseEvent_GetAltKey(mouse_event, &ret); nsIDOMMouseEvent_GetAltKey(mouse_event, &ret);
nsIDOMMouseEvent_Release(mouse_event); nsIDOMMouseEvent_Release(mouse_event);
@ -382,18 +373,18 @@ static HRESULT WINAPI HTMLEventObj_get_ctrlKey(IHTMLEventObj *iface, VARIANT_BOO
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMKeyEvent *key_event; nsIDOMKeyEvent *key_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMKeyEvent_GetCtrlKey(key_event, &ret); nsIDOMKeyEvent_GetCtrlKey(key_event, &ret);
nsIDOMKeyEvent_Release(key_event); nsIDOMKeyEvent_Release(key_event);
}else { }else {
nsIDOMMouseEvent *mouse_event; nsIDOMMouseEvent *mouse_event;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMMouseEvent_GetCtrlKey(mouse_event, &ret); nsIDOMMouseEvent_GetCtrlKey(mouse_event, &ret);
nsIDOMMouseEvent_Release(mouse_event); nsIDOMMouseEvent_Release(mouse_event);
@ -412,18 +403,18 @@ static HRESULT WINAPI HTMLEventObj_get_shiftKey(IHTMLEventObj *iface, VARIANT_BO
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMKeyEvent *key_event; nsIDOMKeyEvent *key_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMKeyEvent_GetShiftKey(key_event, &ret); nsIDOMKeyEvent_GetShiftKey(key_event, &ret);
nsIDOMKeyEvent_Release(key_event); nsIDOMKeyEvent_Release(key_event);
}else { }else {
nsIDOMMouseEvent *mouse_event; nsIDOMMouseEvent *mouse_event;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMMouseEvent_GetShiftKey(mouse_event, &ret); nsIDOMMouseEvent_GetShiftKey(mouse_event, &ret);
nsIDOMMouseEvent_Release(mouse_event); nsIDOMMouseEvent_Release(mouse_event);
@ -516,11 +507,11 @@ static HRESULT WINAPI HTMLEventObj_get_keyCode(IHTMLEventObj *iface, LONG *p)
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMKeyEvent *key_event; nsIDOMKeyEvent *key_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMKeyEvent, (void**)&key_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMKeyEvent_GetKeyCode(key_event, &key_code); nsIDOMKeyEvent_GetKeyCode(key_event, &key_code);
nsIDOMKeyEvent_Release(key_event); nsIDOMKeyEvent_Release(key_event);
@ -538,11 +529,11 @@ static HRESULT WINAPI HTMLEventObj_get_button(IHTMLEventObj *iface, LONG *p)
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMMouseEvent *mouse_event; nsIDOMMouseEvent *mouse_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMMouseEvent_GetButton(mouse_event, &button); nsIDOMMouseEvent_GetButton(mouse_event, &button);
nsIDOMMouseEvent_Release(mouse_event); nsIDOMMouseEvent_Release(mouse_event);
@ -595,11 +586,11 @@ static HRESULT WINAPI HTMLEventObj_get_x(IHTMLEventObj *iface, LONG *p)
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMUIEvent *ui_event; nsIDOMUIEvent *ui_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
/* NOTE: pageX is not exactly right here. */ /* NOTE: pageX is not exactly right here. */
nsres = nsIDOMUIEvent_GetPageX(ui_event, &x); nsres = nsIDOMUIEvent_GetPageX(ui_event, &x);
@ -619,11 +610,11 @@ static HRESULT WINAPI HTMLEventObj_get_y(IHTMLEventObj *iface, LONG *p)
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMUIEvent *ui_event; nsIDOMUIEvent *ui_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
/* NOTE: pageY is not exactly right here. */ /* NOTE: pageY is not exactly right here. */
nsres = nsIDOMUIEvent_GetPageY(ui_event, &y); nsres = nsIDOMUIEvent_GetPageY(ui_event, &y);
@ -643,11 +634,11 @@ static HRESULT WINAPI HTMLEventObj_get_clientX(IHTMLEventObj *iface, LONG *p)
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMMouseEvent *mouse_event; nsIDOMMouseEvent *mouse_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMMouseEvent_GetClientX(mouse_event, &x); nsIDOMMouseEvent_GetClientX(mouse_event, &x);
nsIDOMMouseEvent_Release(mouse_event); nsIDOMMouseEvent_Release(mouse_event);
@ -665,11 +656,11 @@ static HRESULT WINAPI HTMLEventObj_get_clientY(IHTMLEventObj *iface, LONG *p)
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMMouseEvent *mouse_event; nsIDOMMouseEvent *mouse_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMMouseEvent_GetClientY(mouse_event, &y); nsIDOMMouseEvent_GetClientY(mouse_event, &y);
nsIDOMMouseEvent_Release(mouse_event); nsIDOMMouseEvent_Release(mouse_event);
@ -707,11 +698,11 @@ static HRESULT WINAPI HTMLEventObj_get_screenX(IHTMLEventObj *iface, LONG *p)
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMMouseEvent *mouse_event; nsIDOMMouseEvent *mouse_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMMouseEvent_GetScreenX(mouse_event, &x); nsIDOMMouseEvent_GetScreenX(mouse_event, &x);
nsIDOMMouseEvent_Release(mouse_event); nsIDOMMouseEvent_Release(mouse_event);
@ -729,11 +720,11 @@ static HRESULT WINAPI HTMLEventObj_get_screenY(IHTMLEventObj *iface, LONG *p)
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
if(This->nsevent) { if(This->event) {
nsIDOMMouseEvent *mouse_event; nsIDOMMouseEvent *mouse_event;
nsresult nsres; nsresult nsres;
nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event); nsres = nsIDOMEvent_QueryInterface(This->event->nsevent, &IID_nsIDOMMouseEvent, (void**)&mouse_event);
if(NS_SUCCEEDED(nsres)) { if(NS_SUCCEEDED(nsres)) {
nsIDOMMouseEvent_GetScreenY(mouse_event, &y); nsIDOMMouseEvent_GetScreenY(mouse_event, &y);
nsIDOMMouseEvent_Release(mouse_event); nsIDOMMouseEvent_Release(mouse_event);
@ -805,20 +796,34 @@ static dispex_static_data_t HTMLEventObj_dispex = {
HTMLEventObj_iface_tids HTMLEventObj_iface_tids
}; };
static HTMLEventObj *create_event(void) static HTMLEventObj *alloc_event_obj(DOMEvent *event)
{ {
HTMLEventObj *ret; HTMLEventObj *event_obj;
ret = heap_alloc_zero(sizeof(*ret)); event_obj = heap_alloc_zero(sizeof(*event_obj));
if(!ret) if(!event_obj)
return NULL; return NULL;
ret->IHTMLEventObj_iface.lpVtbl = &HTMLEventObjVtbl; event_obj->IHTMLEventObj_iface.lpVtbl = &HTMLEventObjVtbl;
ret->ref = 1; event_obj->ref = 1;
event_obj->event = event;
if(event)
IDOMEvent_AddRef(&event->IDOMEvent_iface);
init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLEventObj_iface, &HTMLEventObj_dispex); init_dispex(&event_obj->dispex, (IUnknown*)&event_obj->IHTMLEventObj_iface, &HTMLEventObj_dispex);
return event_obj;
}
return ret; HRESULT create_event_obj(IHTMLEventObj **ret)
{
HTMLEventObj *event_obj;
event_obj = alloc_event_obj(NULL);
if(!event_obj)
return E_OUTOFMEMORY;
*ret = &event_obj->IHTMLEventObj_iface;
return S_OK;
} }
static inline DOMEvent *impl_from_IDOMEvent(IDOMEvent *iface) static inline DOMEvent *impl_from_IDOMEvent(IDOMEvent *iface)
@ -1053,7 +1058,7 @@ static dispex_static_data_t DOMEvent_dispex = {
DOMEvent_iface_tids DOMEvent_iface_tids
}; };
static HRESULT create_event_from_nsevent(nsIDOMEvent *nsevent, IDOMEvent **ret_event) static HRESULT create_event_from_nsevent(nsIDOMEvent *nsevent, DOMEvent **ret_event)
{ {
DOMEvent *event; DOMEvent *event;
@ -1067,13 +1072,14 @@ static HRESULT create_event_from_nsevent(nsIDOMEvent *nsevent, IDOMEvent **ret_e
nsIDOMEvent_AddRef(event->nsevent = nsevent); nsIDOMEvent_AddRef(event->nsevent = nsevent);
*ret_event = &event->IDOMEvent_iface; *ret_event = event;
return S_OK; return S_OK;
} }
HRESULT create_document_event_str(HTMLDocumentNode *doc, const WCHAR *type, IDOMEvent **ret_event) HRESULT create_document_event_str(HTMLDocumentNode *doc, const WCHAR *type, IDOMEvent **ret_event)
{ {
nsIDOMEvent *nsevent; nsIDOMEvent *nsevent;
DOMEvent *event;
nsAString nsstr; nsAString nsstr;
nsresult nsres; nsresult nsres;
HRESULT hres; HRESULT hres;
@ -1082,48 +1088,34 @@ HRESULT create_document_event_str(HTMLDocumentNode *doc, const WCHAR *type, IDOM
nsres = nsIDOMHTMLDocument_CreateEvent(doc->nsdoc, &nsstr, &nsevent); nsres = nsIDOMHTMLDocument_CreateEvent(doc->nsdoc, &nsstr, &nsevent);
nsAString_Finish(&nsstr); nsAString_Finish(&nsstr);
if(NS_FAILED(nsres)) { if(NS_FAILED(nsres)) {
FIXME("CreateEvent failed: %08x\n", nsres); FIXME("CreateEvent(%s) failed: %08x\n", debugstr_w(type), nsres);
return E_FAIL; return E_FAIL;
} }
hres = create_event_from_nsevent(nsevent, ret_event); hres = create_event_from_nsevent(nsevent, &event);
nsIDOMEvent_Release(nsevent); nsIDOMEvent_Release(nsevent);
return hres; if(FAILED(hres))
return hres;
*ret_event = &event->IDOMEvent_iface;
return S_OK;
} }
static HRESULT set_event_info(HTMLEventObj *event, eventid_t eid, HTMLDocumentNode *doc, nsIDOMEvent *nsevent) static HRESULT create_document_event(HTMLDocumentNode *doc, eventid_t event_id, DOMEvent **ret_event)
{ {
event->type = event_info+eid; nsIDOMEvent *nsevent;
event->nsevent = nsevent; nsAString nsstr;
nsresult nsres;
if(nsevent) { nsAString_InitDepend(&nsstr, event_types[event_info[event_id].type]);
nsIDOMEvent_AddRef(nsevent); nsres = nsIDOMHTMLDocument_CreateEvent(doc->nsdoc, &nsstr, &nsevent);
}else if(event_types[event_info[eid].type]) { nsAString_Finish(&nsstr);
nsAString type_str; if(NS_FAILED(nsres)) {
nsresult nsres; FIXME("CreateEvent(%s) failed: %08x\n", debugstr_w(event_types[event_info[event_id].type]), nsres);
return E_FAIL;
nsAString_InitDepend(&type_str, event_types[event_info[eid].type]);
nsres = nsIDOMHTMLDocument_CreateEvent(doc->nsdoc, &type_str, &event->nsevent);
nsAString_Finish(&type_str);
if(NS_FAILED(nsres)) {
ERR("Could not create event: %08x\n", nsres);
return E_FAIL;
}
} }
return S_OK; return create_event_from_nsevent(nsevent, ret_event);
}
HRESULT create_event_obj(IHTMLEventObj **ret)
{
HTMLEventObj *event;
event = create_event();
if(!event)
return E_OUTOFMEMORY;
*ret = &event->IHTMLEventObj_iface;
return S_OK;
} }
static handler_vector_t *get_handler_vector(EventTarget *event_target, eventid_t eid, BOOL alloc) static handler_vector_t *get_handler_vector(EventTarget *event_target, eventid_t eid, BOOL alloc)
@ -1410,7 +1402,8 @@ static void fire_event_obj(EventTarget *event_target, eventid_t eid, HTMLEventOb
vtbl = dispex_get_vtbl(&target_chain[i]->dispex); vtbl = dispex_get_vtbl(&target_chain[i]->dispex);
if(!vtbl || !vtbl->handle_event_default) if(!vtbl || !vtbl->handle_event_default)
continue; continue;
hres = vtbl->handle_event_default(&event_target->dispex, eid, event_obj ? event_obj->nsevent : NULL, &prevent_default); hres = vtbl->handle_event_default(&event_target->dispex, eid,
event_obj && event_obj->event ? event_obj->event->nsevent : NULL, &prevent_default);
if(FAILED(hres) || (event_obj && event_obj->cancel_bubble)) if(FAILED(hres) || (event_obj && event_obj->cancel_bubble))
break; break;
} }
@ -1421,40 +1414,46 @@ static void fire_event_obj(EventTarget *event_target, eventid_t eid, HTMLEventOb
if(target_chain != target_chain_buf) if(target_chain != target_chain_buf)
heap_free(target_chain); heap_free(target_chain);
if(prevent_default && event_obj && event_obj->nsevent) { if(prevent_default && event_obj && event_obj->event && event_obj->event->nsevent) {
TRACE("calling PreventDefault\n"); TRACE("calling PreventDefault\n");
nsIDOMEvent_PreventDefault(event_obj->nsevent); nsIDOMEvent_PreventDefault(event_obj->event->nsevent);
} }
} }
void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, EventTarget *target, nsIDOMEvent *nsevent) void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, EventTarget *target, nsIDOMEvent *nsevent)
{ {
HTMLEventObj *event_obj = NULL; HTMLEventObj *event_obj = NULL;
DOMEvent *event;
HRESULT hres; HRESULT hres;
if(set_event) { if(nsevent)
event_obj = create_event(); hres = create_event_from_nsevent(nsevent, &event);
if(!event_obj) else
return; hres = create_document_event(doc, eid, &event);
if(FAILED(hres))
return;
hres = set_event_info(event_obj, eid, doc, nsevent); if(set_event) {
if(FAILED(hres)) { event_obj = alloc_event_obj(event);
IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface); if(!event_obj) {
IDOMEvent_Release(&event->IDOMEvent_iface);
return; return;
} }
event_obj->type = event_info + eid;
} }
fire_event_obj(target, eid, event_obj); fire_event_obj(target, eid, event_obj);
if(event_obj) if(event_obj)
IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface); IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
IDOMEvent_Release(&event->IDOMEvent_iface);
} }
HRESULT dispatch_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *event_var, VARIANT_BOOL *cancelled) HRESULT dispatch_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *event_var, VARIANT_BOOL *cancelled)
{ {
HTMLEventObj *event_obj = NULL; HTMLEventObj *event_obj = NULL;
eventid_t eid; eventid_t eid;
HRESULT hres; HRESULT hres = S_OK;
eid = attr_to_eid(event_name); eid = attr_to_eid(event_name);
if(eid == EVENTID_LAST) { if(eid == EVENTID_LAST) {
@ -1486,18 +1485,24 @@ HRESULT dispatch_event(HTMLDOMNode *node, const WCHAR *event_name, VARIANT *even
} }
} }
if(event_obj) { if(!event_obj) {
hres = set_event_info(event_obj, eid, node->doc, NULL); event_obj = alloc_event_obj(NULL);
if(SUCCEEDED(hres)) if(!event_obj)
fire_event_obj(&node->event_target, eid, event_obj); return E_OUTOFMEMORY;
IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
if(FAILED(hres))
return hres;
}else {
fire_event(node->doc, eid, TRUE, &node->event_target, NULL);
} }
event_obj->type = event_info + eid;
if(!event_obj->event)
hres = create_document_event(node->doc, eid, &event_obj->event);
if(SUCCEEDED(hres))
fire_event_obj(&node->event_target, eid, event_obj);
if(event_obj)
IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
if(FAILED(hres))
return hres;
*cancelled = VARIANT_TRUE; /* FIXME */ *cancelled = VARIANT_TRUE; /* FIXME */
return S_OK; return S_OK;
} }

View File

@ -55,6 +55,15 @@ typedef enum {
EVENTID_LAST EVENTID_LAST
} eventid_t; } eventid_t;
typedef struct {
DispatchEx dispex;
IDOMEvent IDOMEvent_iface;
LONG ref;
nsIDOMEvent *nsevent;
} DOMEvent;
eventid_t str_to_eid(LPCWSTR) DECLSPEC_HIDDEN; eventid_t str_to_eid(LPCWSTR) DECLSPEC_HIDDEN;
void check_event_attr(HTMLDocumentNode*,nsIDOMHTMLElement*) DECLSPEC_HIDDEN; void check_event_attr(HTMLDocumentNode*,nsIDOMHTMLElement*) DECLSPEC_HIDDEN;
void release_event_target(EventTarget*) DECLSPEC_HIDDEN; void release_event_target(EventTarget*) DECLSPEC_HIDDEN;