mshtml: Properly remove event listeners.

This commit is contained in:
Jacek Caban 2011-11-24 12:48:31 +01:00 committed by Alexandre Julliard
parent 66520ea08a
commit ea0ebbfeb2
5 changed files with 47 additions and 1 deletions

View file

@ -2032,6 +2032,7 @@ static void HTMLDocumentNode_destructor(HTMLDOMNode *iface)
heap_free(This->elem_vars[i]);
heap_free(This->elem_vars);
detach_events(This);
if(This->body_event_target)
release_event_target(This->body_event_target);
if(This->nsevent_listener)

View file

@ -1184,6 +1184,20 @@ static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, event_target_t *eve
return S_OK;
}
void detach_events(HTMLDocumentNode *doc)
{
int i;
if(!doc->event_vector)
return;
for(i=0; i < EVENTID_LAST; i++) {
if(doc->event_vector[i])
detach_nsevent(doc, event_info[i].name);
}
}
static HRESULT remove_event_handler(event_target_t **event_target, eventid_t eid)
{
if(*event_target && (*event_target)->event_table[eid] && (*event_target)->event_table[eid]->handler_prop) {

View file

@ -54,10 +54,12 @@ HRESULT dispatch_event(HTMLDOMNode*,const WCHAR*,VARIANT*,VARIANT_BOOL*) DECLSPE
HRESULT call_fire_event(HTMLDOMNode*,eventid_t) DECLSPEC_HIDDEN;
void update_cp_events(HTMLWindow*,event_target_t**,cp_static_data_t*,nsIDOMNode*) DECLSPEC_HIDDEN;
HRESULT doc_init_events(HTMLDocumentNode*) DECLSPEC_HIDDEN;
void detach_events(HTMLDocumentNode *doc) DECLSPEC_HIDDEN;
void init_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN;
void release_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN;
void add_nsevent_listener(HTMLDocumentNode*,nsIDOMNode*,LPCWSTR) DECLSPEC_HIDDEN;
void detach_nsevent(HTMLDocumentNode*,const WCHAR*) DECLSPEC_HIDDEN;
static inline event_target_t **get_node_event_target(HTMLDOMNode *node)
{

View file

@ -46,6 +46,7 @@ static void window_set_docnode(HTMLWindow *window, HTMLDocumentNode *doc_node)
if(window->doc) {
if(window->doc_obj && window == window->doc_obj->basedoc.window)
window->doc->basedoc.cp_container.forward_container = NULL;
detach_events(window->doc);
abort_document_bindings(window->doc);
window->doc->basedoc.window = NULL;
htmldoc_release(&window->doc->basedoc);

View file

@ -281,7 +281,7 @@ static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent *
eventid_t eid;
nsresult nsres;
TRACE("\n");
TRACE("%p\n", This->This);
nsAString_Init(&type_str, NULL);
nsIDOMEvent_GetType(event, &type_str);
@ -363,8 +363,34 @@ void add_nsevent_listener(HTMLDocumentNode *doc, nsIDOMNode *nsnode, LPCWSTR typ
nsIDOMEventTarget_Release(target);
}
void detach_nsevent(HTMLDocumentNode *doc, const WCHAR *type)
{
nsIDOMEventTarget *target;
nsAString type_str;
nsresult nsres;
if(!doc->basedoc.window)
return;
nsres = nsIDOMWindow_QueryInterface(doc->basedoc.window->nswindow, &IID_nsIDOMEventTarget, (void**)&target);
if(NS_FAILED(nsres)) {
ERR("Could not get nsIDOMEventTarget interface: %08x\n", nsres);
return;
}
nsAString_InitDepend(&type_str, type);
nsres = nsIDOMEventTarget_RemoveEventListener(target, &type_str,
&doc->nsevent_listener->htmlevent_listener.nsIDOMEventListener_iface, TRUE);
nsAString_Finish(&type_str);
nsIDOMEventTarget_Release(target);
if(NS_FAILED(nsres))
ERR("RemoveEventTarget failed: %08x\n", nsres);
}
void release_nsevents(HTMLDocumentNode *doc)
{
TRACE("%p %p\n", doc, doc->nsevent_listener);
if(doc->nsevent_listener) {
doc->nsevent_listener->doc = NULL;
release_listener(doc->nsevent_listener);
@ -387,6 +413,8 @@ void init_nsevents(HTMLDocumentNode *doc)
if(!listener)
return;
TRACE("%p %p\n", doc, listener);
listener->ref = 1;
listener->doc = doc;