Jacek Caban : mshtml: Properly remove event listeners.
Alexandre Julliard
julliard at winehq.org
Thu Nov 24 15:04:39 CST 2011
Module: wine
Branch: master
Commit: ea0ebbfeb2c513e41d0ebf1812ff3f40bd728dbd
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ea0ebbfeb2c513e41d0ebf1812ff3f40bd728dbd
Author: Jacek Caban <jacek at codeweavers.com>
Date: Thu Nov 24 12:48:31 2011 +0100
mshtml: Properly remove event listeners.
---
dlls/mshtml/htmldoc.c | 1 +
dlls/mshtml/htmlevent.c | 14 ++++++++++++++
dlls/mshtml/htmlevent.h | 2 ++
dlls/mshtml/htmlwindow.c | 1 +
dlls/mshtml/nsevents.c | 30 +++++++++++++++++++++++++++++-
5 files changed, 47 insertions(+), 1 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index 32cbde4..45a7986 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -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)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c
index 2b9e62e..74e8069 100644
--- a/dlls/mshtml/htmlevent.c
+++ b/dlls/mshtml/htmlevent.c
@@ -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) {
diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h
index 9072482..b3ff251 100644
--- a/dlls/mshtml/htmlevent.h
+++ b/dlls/mshtml/htmlevent.h
@@ -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)
{
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c
index e9bb8eb..f907776 100644
--- a/dlls/mshtml/htmlwindow.c
+++ b/dlls/mshtml/htmlwindow.c
@@ -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);
diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c
index 89684fe..d4cdc10 100644
--- a/dlls/mshtml/nsevents.c
+++ b/dlls/mshtml/nsevents.c
@@ -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;
More information about the wine-cvs
mailing list