diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 3cbfe8d694a..1d483d4f9d0 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -2046,8 +2046,6 @@ static void HTMLDocumentNode_destructor(HTMLDOMNode *iface) detach_events(This); if(This->body_event_target) release_event_target(This->body_event_target); - if(This->nsevent_listener) - release_nsevents(This); if(This->catmgr) ICatInformation_Release(This->catmgr); diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index cfba560c449..0950c5e4ae7 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -1191,15 +1191,16 @@ static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, event_target_t *eve void detach_events(HTMLDocumentNode *doc) { - int i; + if(doc->event_vector) { + 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); + for(i=0; i < EVENTID_LAST; i++) { + if(doc->event_vector[i]) + detach_nsevent(doc, event_info[i].name); + } } + + release_nsevents(doc); } diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c index d4cdc1036a2..542b8c735ca 100644 --- a/dlls/mshtml/nsevents.c +++ b/dlls/mshtml/nsevents.c @@ -37,6 +37,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +static const PRUnichar blurW[] = {'b','l','u','r',0}; +static const PRUnichar focusW[] = {'f','o','c','u','s',0}; +static const PRUnichar keypressW[] = {'k','e','y','p','r','e','s','s',0}; +static const PRUnichar loadW[] = {'l','o','a','d',0}; + typedef struct { nsIDOMEventListener nsIDOMEventListener_iface; nsDocumentEventListener *This; @@ -363,7 +368,7 @@ void add_nsevent_listener(HTMLDocumentNode *doc, nsIDOMNode *nsnode, LPCWSTR typ nsIDOMEventTarget_Release(target); } -void detach_nsevent(HTMLDocumentNode *doc, const WCHAR *type) +static void detach_nslistener(HTMLDocumentNode *doc, const WCHAR *type, nsEventListener *listener, cpp_bool is_capture) { nsIDOMEventTarget *target; nsAString type_str; @@ -380,22 +385,35 @@ void detach_nsevent(HTMLDocumentNode *doc, const WCHAR *type) nsAString_InitDepend(&type_str, type); nsres = nsIDOMEventTarget_RemoveEventListener(target, &type_str, - &doc->nsevent_listener->htmlevent_listener.nsIDOMEventListener_iface, TRUE); + &listener->nsIDOMEventListener_iface, is_capture); nsAString_Finish(&type_str); nsIDOMEventTarget_Release(target); if(NS_FAILED(nsres)) ERR("RemoveEventTarget failed: %08x\n", nsres); } +void detach_nsevent(HTMLDocumentNode *doc, const WCHAR *type) +{ + detach_nslistener(doc, type, &doc->nsevent_listener->htmlevent_listener, TRUE); +} + void release_nsevents(HTMLDocumentNode *doc) { + nsDocumentEventListener *listener = doc->nsevent_listener; + TRACE("%p %p\n", doc, doc->nsevent_listener); - if(doc->nsevent_listener) { - doc->nsevent_listener->doc = NULL; - release_listener(doc->nsevent_listener); - doc->nsevent_listener = NULL; - } + if(!listener) + return; + + detach_nslistener(doc, blurW, &listener->blur_listener, TRUE); + detach_nslistener(doc, focusW, &listener->focus_listener, TRUE); + detach_nslistener(doc, keypressW, &listener->keypress_listener, FALSE); + detach_nslistener(doc, loadW, &listener->load_listener, TRUE); + + listener->doc = NULL; + release_listener(listener); + doc->nsevent_listener = NULL; } void init_nsevents(HTMLDocumentNode *doc) @@ -404,11 +422,6 @@ void init_nsevents(HTMLDocumentNode *doc) nsIDOMEventTarget *target; nsresult nsres; - static const PRUnichar wsz_blur[] = {'b','l','u','r',0}; - static const PRUnichar wsz_focus[] = {'f','o','c','u','s',0}; - static const PRUnichar wsz_keypress[] = {'k','e','y','p','r','e','s','s',0}; - static const PRUnichar wsz_load[] = {'l','o','a','d',0}; - listener = heap_alloc(sizeof(nsDocumentEventListener)); if(!listener) return; @@ -432,10 +445,10 @@ void init_nsevents(HTMLDocumentNode *doc) return; } - init_event(target, wsz_blur, &listener->blur_listener.nsIDOMEventListener_iface, TRUE); - init_event(target, wsz_focus, &listener->focus_listener.nsIDOMEventListener_iface, TRUE); - init_event(target, wsz_keypress, &listener->keypress_listener.nsIDOMEventListener_iface, FALSE); - init_event(target, wsz_load, &listener->load_listener.nsIDOMEventListener_iface, TRUE); + init_event(target, blurW, &listener->blur_listener.nsIDOMEventListener_iface, TRUE); + init_event(target, focusW, &listener->focus_listener.nsIDOMEventListener_iface, TRUE); + init_event(target, keypressW, &listener->keypress_listener.nsIDOMEventListener_iface, FALSE); + init_event(target, loadW, &listener->load_listener.nsIDOMEventListener_iface, TRUE); nsIDOMEventTarget_Release(target); }