From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 28 +++- dlls/mshtml/htmlattr.c | 18 ++- dlls/mshtml/htmldoc.c | 20 +++ dlls/mshtml/htmlelem.c | 108 ++++++++++++++- dlls/mshtml/htmlelemcol.c | 27 +++- dlls/mshtml/htmlevent.c | 201 +++++++++++++++++++++++----- dlls/mshtml/htmlimg.c | 12 ++ dlls/mshtml/htmllocation.c | 22 +++- dlls/mshtml/htmlnode.c | 32 ++++- dlls/mshtml/htmlselect.c | 12 ++ dlls/mshtml/htmlstorage.c | 12 ++ dlls/mshtml/htmlstyle.c | 23 +++- dlls/mshtml/htmlstylesheet.c | 92 +++++++++++-- dlls/mshtml/htmltextnode.c | 10 ++ dlls/mshtml/htmlwindow.c | 123 ++++++++++++----- dlls/mshtml/mshtml_private.h | 6 +- dlls/mshtml/omnavigator.c | 247 ++++++++++++++++++++++++++++++++--- dlls/mshtml/range.c | 50 ++++++- dlls/mshtml/selection.c | 27 +++- dlls/mshtml/xmlhttprequest.c | 59 ++++++++- 20 files changed, 1003 insertions(+), 126 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index d23c37650c1..833dcac504d 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -842,6 +842,16 @@ static inline func_disp_t *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, func_disp_t, dispex); }
+static void function_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + func_disp_t *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "func_disp", cb); +} + +static void function_unlink(DispatchEx *dispex) +{ +} + static void function_destructor(DispatchEx *dispex) { func_disp_t *This = impl_from_DispatchEx(dispex); @@ -906,6 +916,8 @@ static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
static const dispex_static_data_vtbl_t function_dispex_vtbl = { function_destructor, + function_traverse, + function_unlink, function_value, NULL, NULL, @@ -2006,6 +2018,8 @@ nsresult NSAPI dispex_traverse(void *ccp, void *p, nsCycleCollectionTraversalCal DispatchEx *This = impl_from_IDispatchEx(p); dynamic_prop_t *prop;
+ This->info->desc->vtbl->traverse(This, cb); + if(!This->dynamic_data) return NS_OK;
@@ -2029,13 +2043,12 @@ nsresult NSAPI dispex_traverse(void *ccp, void *p, nsCycleCollectionTraversalCal return NS_OK; }
-nsresult NSAPI dispex_unlink(void *p) +void dispex_props_unlink(DispatchEx *This) { - DispatchEx *This = impl_from_IDispatchEx(p); dynamic_prop_t *prop;
if(!This->dynamic_data) - return NS_OK; + return;
for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) { VariantClear(&prop->var); @@ -2056,7 +2069,14 @@ nsresult NSAPI dispex_unlink(void *p) free(This->dynamic_data->func_disps); This->dynamic_data->func_disps = NULL; } +}
+nsresult NSAPI dispex_unlink(void *p) +{ + DispatchEx *This = impl_from_IDispatchEx(p); + + This->info->desc->vtbl->unlink(This); + dispex_props_unlink(This); return NS_OK; }
@@ -2065,6 +2085,8 @@ void NSAPI dispex_delete_cycle_collectable(void *p) DispatchEx *This = impl_from_IDispatchEx(p); dynamic_prop_t *prop;
+ This->info->desc->vtbl->unlink(This); + if(!This->dynamic_data) goto destructor;
diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c index 000e178046e..5fff115a551 100644 --- a/dlls/mshtml/htmlattr.c +++ b/dlls/mshtml/htmlattr.c @@ -477,17 +477,33 @@ static inline HTMLDOMAttribute *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDOMAttribute, dispex); }
+static void HTMLDOMAttribute_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDOMAttribute *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMAttribute", cb); + + if(V_VT(&This->value) == VT_DISPATCH) + note_cc_edge((nsISupports*)V_DISPATCH(&This->value), "value", cb); +} + +static void HTMLDOMAttribute_unlink(DispatchEx *dispex) +{ + HTMLDOMAttribute *This = impl_from_DispatchEx(dispex); + VariantClear(&This->value); +} + static void HTMLDOMAttribute_destructor(DispatchEx *dispex) { HTMLDOMAttribute *This = impl_from_DispatchEx(dispex); assert(!This->elem); - VariantClear(&This->value); free(This->name); free(This); }
static const dispex_static_data_vtbl_t HTMLDOMAttribute_dispex_vtbl = { HTMLDOMAttribute_destructor, + HTMLDOMAttribute_traverse, + HTMLDOMAttribute_unlink };
static const tid_t HTMLDOMAttribute_iface_tids[] = { diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index d40d3c4e799..79ad9752a1a 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -295,6 +295,14 @@ static inline DocumentType *DocumentType_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, DocumentType, node.event_target.dispex); }
+static void DocumentType_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void DocumentType_unlink(DispatchEx *dispex) +{ +} + static void DocumentType_dispex_destructor(DispatchEx *dispex) { } @@ -372,6 +380,8 @@ static IHTMLEventObj *DocumentType_set_current_event(DispatchEx *dispex, IHTMLEv static event_target_vtbl_t DocumentType_event_target_vtbl = { { DocumentType_dispex_destructor, + DocumentType_traverse, + DocumentType_unlink }, DocumentType_get_gecko_target, NULL, @@ -5929,6 +5939,14 @@ static inline HTMLDocumentNode *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDocumentNode, node.event_target.dispex); }
+static void HTMLDocumentNode_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLDocumentNode_dispex_unlink(DispatchEx *dispex) +{ +} + static void HTMLDocumentNode_dispex_destructor(DispatchEx *dispex) { } @@ -6105,6 +6123,8 @@ static HRESULT HTMLDocumentNode_location_hook(DispatchEx *dispex, WORD flags, DI static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = { { HTMLDocumentNode_dispex_destructor, + HTMLDocumentNode_traverse, + HTMLDocumentNode_dispex_unlink, NULL, NULL, HTMLDocumentNode_get_name, diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 5545d8b91a5..76781cc1e35 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -839,11 +839,28 @@ static inline HTMLRect *HTMLRect_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLRect, dispex); }
-static void HTMLRect_destructor(DispatchEx *dispex) +static void HTMLRect_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLRect *This = HTMLRect_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "ClientRect", cb); + if(This->nsrect) - nsIDOMClientRect_Release(This->nsrect); + note_cc_edge((nsISupports*)This->nsrect, "nsrect", cb); +} + +static void HTMLRect_unlink(DispatchEx *dispex) +{ + HTMLRect *This = HTMLRect_from_DispatchEx(dispex); + if(This->nsrect) { + nsIDOMClientRect *nsrect = This->nsrect; + This->nsrect = NULL; + nsIDOMClientRect_Release(nsrect); + } +} + +static void HTMLRect_destructor(DispatchEx *dispex) +{ + HTMLRect *This = HTMLRect_from_DispatchEx(dispex); free(This); }
@@ -855,6 +872,8 @@ void HTMLRect_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
static const dispex_static_data_vtbl_t HTMLRect_dispex_vtbl = { HTMLRect_destructor, + HTMLRect_traverse, + HTMLRect_unlink };
static const tid_t HTMLRect_iface_tids[] = { @@ -1197,11 +1216,28 @@ static inline HTMLRectCollection *HTMLRectCollection_from_DispatchEx(DispatchEx return CONTAINING_RECORD(iface, HTMLRectCollection, dispex); }
-static void HTMLRectCollection_destructor(DispatchEx *dispex) +static void HTMLRectCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "ClientRectCollection", cb); + if(This->rect_list) - nsIDOMClientRectList_Release(This->rect_list); + note_cc_edge((nsISupports*)This->rect_list, "rect_list", cb); +} + +static void HTMLRectCollection_unlink(DispatchEx *dispex) +{ + HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex); + if(This->rect_list) { + nsIDOMClientRectList *rect_list = This->rect_list; + This->rect_list = NULL; + nsIDOMClientRectList_Release(rect_list); + } +} + +static void HTMLRectCollection_destructor(DispatchEx *dispex) +{ + HTMLRectCollection *This = HTMLRectCollection_from_DispatchEx(dispex); free(This); }
@@ -1281,6 +1317,8 @@ static HRESULT HTMLRectCollection_invoke(DispatchEx *dispex, DISPID id, LCID lci
static const dispex_static_data_vtbl_t HTMLRectCollection_dispex_vtbl = { HTMLRectCollection_destructor, + HTMLRectCollection_traverse, + HTMLRectCollection_unlink, NULL, HTMLRectCollection_get_dispid, HTMLRectCollection_get_name, @@ -6945,6 +6983,14 @@ static inline HTMLElement *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLElement, node.event_target.dispex); }
+static void HTMLElement_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLElement_unlink(DispatchEx *dispex) +{ +} + static void HTMLElement_dispex_destructor(DispatchEx *dispex) { } @@ -7345,6 +7391,8 @@ static const tid_t HTMLElement_iface_tids[] = { const event_target_vtbl_t HTMLElement_event_target_vtbl = { { HTMLElement_dispex_destructor, + HTMLElement_traverse, + HTMLElement_unlink, NULL, HTMLElement_get_dispid, HTMLElement_get_name, @@ -7731,10 +7779,28 @@ static inline struct token_list *token_list_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, struct token_list, dispex); }
+static void token_list_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct token_list *token_list = token_list_from_DispatchEx(dispex); + describe_cc_node(&token_list->ccref, "DOMTokenList", cb); + + if(token_list->element) + note_cc_edge((nsISupports*)token_list->element, "element", cb); +} + +static void token_list_unlink(DispatchEx *dispex) +{ + struct token_list *token_list = token_list_from_DispatchEx(dispex); + if(token_list->element) { + IHTMLElement *element = token_list->element; + token_list->element = NULL; + IHTMLElement_Release(element); + } +} + static void token_list_destructor(DispatchEx *dispex) { struct token_list *token_list = token_list_from_DispatchEx(dispex); - IHTMLElement_Release(token_list->element); free(token_list); }
@@ -7814,6 +7880,8 @@ static HRESULT token_list_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD
static const dispex_static_data_vtbl_t token_list_dispex_vtbl = { token_list_destructor, + token_list_traverse, + token_list_unlink, token_list_value, token_list_get_dispid, token_list_get_name, @@ -8191,6 +8259,16 @@ static inline HTMLFiltersCollection *HTMLFiltersCollection_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLFiltersCollection, dispex); }
+static void HTMLFiltersCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLFiltersCollection *This = HTMLFiltersCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "FiltersCollection", cb); +} + +static void HTMLFiltersCollection_unlink(DispatchEx *dispex) +{ +} + static void HTMLFiltersCollection_destructor(DispatchEx *dispex) { HTMLFiltersCollection *This = HTMLFiltersCollection_from_DispatchEx(dispex); @@ -8237,6 +8315,8 @@ static HRESULT HTMLFiltersCollection_invoke(DispatchEx *dispex, DISPID id, LCID
static const dispex_static_data_vtbl_t HTMLFiltersCollection_dispex_vtbl = { HTMLFiltersCollection_destructor, + HTMLFiltersCollection_traverse, + HTMLFiltersCollection_unlink, NULL, HTMLFiltersCollection_get_dispid, HTMLFiltersCollection_get_name, @@ -8915,10 +8995,20 @@ static inline HTMLAttributeCollection *HTMLAttributeCollection_from_DispatchEx(D return CONTAINING_RECORD(iface, HTMLAttributeCollection, dispex); }
-static void HTMLAttributeCollection_destructor(DispatchEx *dispex) +static void HTMLAttributeCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); + HTMLDOMAttribute *attr; + + describe_cc_node(&This->ccref, "AttributeCollection", cb); + + LIST_FOR_EACH_ENTRY(attr, &This->attrs, HTMLDOMAttribute, entry) + note_cc_edge((nsISupports*)&attr->IHTMLDOMAttribute_iface, "attr", cb); +}
+static void HTMLAttributeCollection_unlink(DispatchEx *dispex) +{ + HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); while(!list_empty(&This->attrs)) { HTMLDOMAttribute *attr = LIST_ENTRY(list_head(&This->attrs), HTMLDOMAttribute, entry);
@@ -8926,7 +9016,11 @@ static void HTMLAttributeCollection_destructor(DispatchEx *dispex) attr->elem = NULL; IHTMLDOMAttribute_Release(&attr->IHTMLDOMAttribute_iface); } +}
+static void HTMLAttributeCollection_destructor(DispatchEx *dispex) +{ + HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex); free(This); }
@@ -8997,6 +9091,8 @@ static HRESULT HTMLAttributeCollection_invoke(DispatchEx *dispex, DISPID id, LCI
static const dispex_static_data_vtbl_t HTMLAttributeCollection_dispex_vtbl = { HTMLAttributeCollection_destructor, + HTMLAttributeCollection_traverse, + HTMLAttributeCollection_unlink, NULL, HTMLAttributeCollection_get_dispid, HTMLAttributeCollection_get_name, diff --git a/dlls/mshtml/htmlelemcol.c b/dlls/mshtml/htmlelemcol.c index ef610536536..e598a9cc211 100644 --- a/dlls/mshtml/htmlelemcol.c +++ b/dlls/mshtml/htmlelemcol.c @@ -539,14 +539,33 @@ static inline HTMLElementCollection *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLElementCollection, dispex); }
-static void HTMLElementCollection_destructor(DispatchEx *dispex) +static void HTMLElementCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLElementCollection *This = impl_from_DispatchEx(dispex); unsigned i;
+ describe_cc_node(&This->ccref, "ElementCollection", cb); + for(i = 0; i < This->len; i++) - node_release(&This->elems[i]->node); - free(This->elems); + note_cc_edge((nsISupports*)&This->elems[i]->node.IHTMLDOMNode_iface, "elem", cb); +} + +static void HTMLElementCollection_unlink(DispatchEx *dispex) +{ + HTMLElementCollection *This = impl_from_DispatchEx(dispex); + unsigned i, len = This->len; + + if(len) { + This->len = 0; + for(i = 0; i < len; i++) + node_release(&This->elems[i]->node); + free(This->elems); + } +} + +static void HTMLElementCollection_destructor(DispatchEx *dispex) +{ + HTMLElementCollection *This = impl_from_DispatchEx(dispex); free(This); }
@@ -623,6 +642,8 @@ static HRESULT HTMLElementCollection_invoke(DispatchEx *dispex, DISPID id, LCID
static const dispex_static_data_vtbl_t HTMLElementColection_dispex_vtbl = { HTMLElementCollection_destructor, + HTMLElementCollection_traverse, + HTMLElementCollection_unlink, NULL, HTMLElementCollection_get_dispid, HTMLElementCollection_get_name, diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index f36bcc977cc..2f4b22acc9c 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -870,16 +870,35 @@ static inline HTMLEventObj *HTMLEventObj_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLEventObj, dispex); }
-static void HTMLEventObj_destructor(DispatchEx *dispex) +static void HTMLEventObj_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "EventObj", cb); + if(This->event) - IDOMEvent_Release(&This->event->IDOMEvent_iface); + note_cc_edge((nsISupports*)&This->event->IDOMEvent_iface, "event", cb); +} + +static void HTMLEventObj_unlink(DispatchEx *dispex) +{ + HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex); + if(This->event) { + DOMEvent *event = This->event; + This->event = NULL; + IDOMEvent_Release(&event->IDOMEvent_iface); + } +} + +static void HTMLEventObj_destructor(DispatchEx *dispex) +{ + HTMLEventObj *This = HTMLEventObj_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLEventObj_dispex_vtbl = { HTMLEventObj_destructor, + HTMLEventObj_traverse, + HTMLEventObj_unlink };
static const tid_t HTMLEventObj_iface_tids[] = { @@ -1238,12 +1257,39 @@ static inline DOMEvent *DOMEvent_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, DOMEvent, dispex); }
+static void event_traverse(DOMEvent *This, nsCycleCollectionTraversalCallback *cb) +{ + if(This->target) + note_cc_edge((nsISupports*)&This->target->IEventTarget_iface, "target", cb); + if(This->nsevent) + note_cc_edge((nsISupports*)This->nsevent, "nsevent", cb); +} + +static void DOMEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMEvent *This = DOMEvent_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMEvent", cb); + event_traverse(This, cb); +} + +static void DOMEvent_unlink(DispatchEx *dispex) +{ + DOMEvent *This = DOMEvent_from_DispatchEx(dispex); + if(This->target) { + EventTarget *target = This->target; + This->target = NULL; + IEventTarget_Release(&target->IEventTarget_iface); + } + if(This->nsevent) { + nsIDOMEvent *nsevent = This->nsevent; + This->nsevent = NULL; + nsIDOMEvent_Release(nsevent); + } +} + static void DOMEvent_destructor(DispatchEx *dispex) { DOMEvent *This = DOMEvent_from_DispatchEx(dispex); - if(This->target) - IEventTarget_Release(&This->target->IEventTarget_iface); - nsIDOMEvent_Release(This->nsevent); free(This->type); free(This); } @@ -1396,9 +1442,24 @@ static void *DOMUIEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
+static void ui_event_traverse(DOMUIEvent *This, nsCycleCollectionTraversalCallback *cb) +{ + event_traverse(&This->event, cb); + if(This->nsevent) + note_cc_edge((nsISupports*)This->nsevent, "UIEvent.nsevent", cb); +} + +static void DOMUIEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&This->event.ccref, "DOMUIEvent", cb); + ui_event_traverse(This, cb); +} + static void DOMUIEvent_unlink(DispatchEx *dispex) { DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMEvent_unlink(&This->event.dispex); if(This->nsevent) { nsIDOMUIEvent *nsevent = This->nsevent; This->nsevent = NULL; @@ -1406,13 +1467,6 @@ static void DOMUIEvent_unlink(DispatchEx *dispex) } }
-static void DOMUIEvent_destructor(DispatchEx *dispex) -{ - DOMUIEvent *This = DOMUIEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); - DOMUIEvent_unlink(&This->event.dispex); - DOMEvent_destructor(dispex); -} - typedef struct { DOMUIEvent ui_event; IDOMMouseEvent IDOMMouseEvent_iface; @@ -1938,12 +1992,25 @@ static void *DOMMouseEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMMouseEvent_destructor(DispatchEx *dispex) +static void DOMMouseEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&This->ui_event.event.ccref, "DOMMouseEvent", cb); + + ui_event_traverse(&This->ui_event, cb); + if(This->nsevent) + note_cc_edge((nsISupports*)This->nsevent, "MouseEvent.nsevent", cb); +} + +static void DOMMouseEvent_unlink(DispatchEx *dispex) { DOMMouseEvent *This = DOMMouseEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); DOMUIEvent_unlink(&This->ui_event.event.dispex); - nsIDOMMouseEvent_Release(This->nsevent); - DOMEvent_destructor(dispex); + if(This->nsevent) { + nsIDOMMouseEvent *nsevent = This->nsevent; + This->nsevent = NULL; + nsIDOMMouseEvent_Release(nsevent); + } }
typedef struct { @@ -2238,12 +2305,25 @@ static void *DOMKeyboardEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMKeyboardEvent_destructor(DispatchEx *dispex) +static void DOMKeyboardEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&This->ui_event.event.ccref, "DOMKeyboardEvent", cb); + + ui_event_traverse(&This->ui_event, cb); + if(This->nsevent) + note_cc_edge((nsISupports*)This->nsevent, "KeyboardEvent.nsevent", cb); +} + +static void DOMKeyboardEvent_unlink(DispatchEx *dispex) { DOMKeyboardEvent *This = DOMKeyboardEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); DOMUIEvent_unlink(&This->ui_event.event.dispex); - nsIDOMKeyEvent_Release(This->nsevent); - DOMEvent_destructor(dispex); + if(This->nsevent) { + nsIDOMKeyEvent *nsevent = This->nsevent; + This->nsevent = NULL; + nsIDOMKeyEvent_Release(nsevent); + } }
typedef struct { @@ -2447,11 +2527,21 @@ static void *DOMCustomEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMCustomEvent_destructor(DispatchEx *dispex) +static void DOMCustomEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&custom_event->event.ccref, "DOMCustomEvent", cb); + + event_traverse(&custom_event->event, cb); + if(V_VT(&custom_event->detail) == VT_DISPATCH) + note_cc_edge((nsISupports*)V_DISPATCH(&custom_event->detail), "detail", cb); +} + +static void DOMCustomEvent_unlink(DispatchEx *dispex) { DOMCustomEvent *custom_event = DOMCustomEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMEvent_unlink(&custom_event->event.dispex); VariantClear(&custom_event->detail); - DOMEvent_destructor(dispex); }
typedef struct { @@ -2592,11 +2682,21 @@ static void *DOMMessageEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMMessageEvent_destructor(DispatchEx *dispex) +static void DOMMessageEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&message_event->event.ccref, "DOMMessageEvent", cb); + + event_traverse(&message_event->event, cb); + if(V_VT(&message_event->data) == VT_DISPATCH) + note_cc_edge((nsISupports*)V_DISPATCH(&message_event->data), "data", cb); +} + +static void DOMMessageEvent_unlink(DispatchEx *dispex) +{ + DOMMessageEvent *message_event = DOMMessageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMEvent_unlink(&message_event->event.dispex); VariantClear(&message_event->data); - DOMEvent_destructor(dispex); }
static void DOMMessageEvent_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode) @@ -2766,11 +2866,25 @@ static void *DOMProgressEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
-static void DOMProgressEvent_destructor(DispatchEx *dispex) +static void DOMProgressEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); - nsIDOMProgressEvent_Release(This->nsevent); - DOMEvent_destructor(dispex); + describe_cc_node(&This->event.ccref, "DOMProgressEvent", cb); + + event_traverse(&This->event, cb); + if(This->nsevent) + note_cc_edge((nsISupports*)This->nsevent, "ProgressEvent.nsevent", cb); +} + +static void DOMProgressEvent_unlink(DispatchEx *dispex) +{ + DOMProgressEvent *This = DOMProgressEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + DOMEvent_unlink(&This->event.dispex); + if(This->nsevent) { + nsIDOMProgressEvent *nsevent = This->nsevent; + This->nsevent = NULL; + nsIDOMProgressEvent_Release(nsevent); + } }
typedef struct { @@ -2929,6 +3043,12 @@ static void *DOMStorageEvent_query_interface(DOMEvent *event, REFIID riid) return NULL; }
+static void DOMStorageEvent_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + DOMStorageEvent *storage_event = DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); + describe_cc_node(&storage_event->event.ccref, "DOMStorageEvent", cb); +} + static void DOMStorageEvent_destructor(DispatchEx *dispex) { DOMStorageEvent *storage_event = DOMStorageEvent_from_DOMEvent(DOMEvent_from_DispatchEx(dispex)); @@ -2941,6 +3061,8 @@ static void DOMStorageEvent_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t DOMEvent_dispex_vtbl = { DOMEvent_destructor, + DOMEvent_traverse, + DOMEvent_unlink };
static const tid_t DOMEvent_iface_tids[] = { @@ -2956,7 +3078,9 @@ static dispex_static_data_t DOMEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMUIEvent_dispex_vtbl = { - DOMUIEvent_destructor, + DOMEvent_destructor, + DOMUIEvent_traverse, + DOMUIEvent_unlink };
static const tid_t DOMUIEvent_iface_tids[] = { @@ -2973,7 +3097,9 @@ static dispex_static_data_t DOMUIEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMMouseEvent_dispex_vtbl = { - DOMMouseEvent_destructor, + DOMEvent_destructor, + DOMMouseEvent_traverse, + DOMMouseEvent_unlink };
static const tid_t DOMMouseEvent_iface_tids[] = { @@ -2991,7 +3117,9 @@ static dispex_static_data_t DOMMouseEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMKeyboardEvent_dispex_vtbl = { - DOMKeyboardEvent_destructor, + DOMEvent_destructor, + DOMKeyboardEvent_traverse, + DOMKeyboardEvent_unlink };
static const tid_t DOMKeyboardEvent_iface_tids[] = { @@ -3023,7 +3151,9 @@ static dispex_static_data_t DOMPageTransitionEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMCustomEvent_dispex_vtbl = { - DOMCustomEvent_destructor, + DOMEvent_destructor, + DOMCustomEvent_traverse, + DOMCustomEvent_unlink };
static const tid_t DOMCustomEvent_iface_tids[] = { @@ -3040,7 +3170,9 @@ static dispex_static_data_t DOMCustomEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMMessageEvent_dispex_vtbl = { - DOMMessageEvent_destructor, + DOMEvent_destructor, + DOMMessageEvent_traverse, + DOMMessageEvent_unlink };
static const tid_t DOMMessageEvent_iface_tids[] = { @@ -3057,7 +3189,9 @@ static dispex_static_data_t DOMMessageEvent_dispex = { };
static const dispex_static_data_vtbl_t DOMProgressEvent_dispex_vtbl = { - DOMProgressEvent_destructor, + DOMEvent_destructor, + DOMProgressEvent_traverse, + DOMProgressEvent_unlink };
static const tid_t DOMProgressEvent_iface_tids[] = { @@ -3075,6 +3209,8 @@ static dispex_static_data_t DOMProgressEvent_dispex = {
static const dispex_static_data_vtbl_t DOMStorageEvent_dispex_vtbl = { DOMStorageEvent_destructor, + DOMStorageEvent_traverse, + DOMEvent_unlink };
static const tid_t DOMStorageEvent_iface_tids[] = { @@ -4498,11 +4634,12 @@ void release_event_target(EventTarget *event_target) WINE_RB_FOR_EACH_ENTRY_DESTRUCTOR(iter, iter2, &event_target->handler_map, listener_container_t, entry) { while(!list_empty(&iter->listeners)) { event_listener_t *listener = LIST_ENTRY(list_head(&iter->listeners), event_listener_t, entry); + list_remove(&listener->entry); if(listener->function) IDispatch_Release(listener->function); - list_remove(&listener->entry); free(listener); } free(iter); } + rb_destroy(&event_target->handler_map, NULL, NULL); } diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index 00859733286..d09c828d763 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -942,6 +942,16 @@ static inline HTMLImageElementFactory *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLImageElementFactory, dispex); }
+static void HTMLImageElementFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "ImageElementFactory", cb); +} + +static void HTMLImageElementFactory_unlink(DispatchEx *dispex) +{ +} + static void HTMLImageElementFactory_destructor(DispatchEx *dispex) { HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); @@ -983,6 +993,8 @@ static const tid_t HTMLImageElementFactory_iface_tids[] = {
static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = { HTMLImageElementFactory_destructor, + HTMLImageElementFactory_traverse, + HTMLImageElementFactory_unlink, HTMLImageElementFactory_value, NULL, NULL, diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index 9149251f62d..54fdde96ff5 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -615,15 +615,35 @@ static inline HTMLLocation *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLLocation, dispex); }
+static void HTMLLocation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLLocation *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Location", cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLLocation_unlink(DispatchEx *dispex) +{ + HTMLLocation *This = impl_from_DispatchEx(dispex); + if(This->window) { + HTMLOuterWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void HTMLLocation_destructor(DispatchEx *dispex) { HTMLLocation *This = impl_from_DispatchEx(dispex); - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); free(This); }
static const dispex_static_data_vtbl_t HTMLLocation_dispex_vtbl = { HTMLLocation_destructor, + HTMLLocation_traverse, + HTMLLocation_unlink };
static const tid_t HTMLLocation_iface_tids[] = { diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 354a4719601..f6b4ab4cdb8 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -359,10 +359,28 @@ static inline HTMLDOMChildrenCollection *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDOMChildrenCollection, dispex); }
+static void HTMLDOMChildrenCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMChildrenCollection", cb); + + if(This->nslist) + note_cc_edge((nsISupports*)This->nslist, "nslist", cb); +} + +static void HTMLDOMChildrenCollection_unlink(DispatchEx *dispex) +{ + HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex); + if(This->nslist) { + nsIDOMNodeList *nslist = This->nslist; + This->nslist = NULL; + nsIDOMNodeList_Release(nslist); + } +} + static void HTMLDOMChildrenCollection_destructor(DispatchEx *dispex) { HTMLDOMChildrenCollection *This = impl_from_DispatchEx(dispex); - nsIDOMNodeList_Release(This->nslist); free(This); }
@@ -436,6 +454,8 @@ static HRESULT HTMLDOMChildrenCollection_invoke(DispatchEx *dispex, DISPID id, L
static const dispex_static_data_vtbl_t HTMLDOMChildrenCollection_dispex_vtbl = { HTMLDOMChildrenCollection_destructor, + HTMLDOMChildrenCollection_traverse, + HTMLDOMChildrenCollection_unlink, NULL, HTMLDOMChildrenCollection_get_dispid, HTMLDOMChildrenCollection_get_name, @@ -1416,6 +1436,14 @@ static const IHTMLDOMNode3Vtbl HTMLDOMNode3Vtbl = { HTMLDOMNode3_isSupported };
+static void HTMLDOMNode_dispex_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLDOMNode_dispex_unlink(DispatchEx *dispex) +{ +} + static void HTMLDOMNode_dispex_destructor(DispatchEx *dispex) { } @@ -1504,6 +1532,8 @@ void HTMLDOMNode_Init(HTMLDocumentNode *doc, HTMLDOMNode *node, nsIDOMNode *nsno
static const dispex_static_data_vtbl_t HTMLDOMNode_dispex_vtbl = { HTMLDOMNode_dispex_destructor, + HTMLDOMNode_dispex_traverse, + HTMLDOMNode_dispex_unlink };
static const tid_t HTMLDOMNode_iface_tids[] = { diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index 4fc46f5d09b..f0086e0802c 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -592,6 +592,16 @@ static inline HTMLOptionElementFactory *HTMLOptionElementFactory_from_DispatchEx return CONTAINING_RECORD(iface, HTMLOptionElementFactory, dispex); }
+static void HTMLOptionElementFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "OptionElementFactory", cb); +} + +static void HTMLOptionElementFactory_unlink(DispatchEx *dispex) +{ +} + static void HTMLOptionElementFactory_destructor(DispatchEx *dispex) { HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); @@ -637,6 +647,8 @@ static const tid_t HTMLOptionElementFactory_iface_tids[] = {
static const dispex_static_data_vtbl_t HTMLOptionElementFactory_dispex_vtbl = { HTMLOptionElementFactory_destructor, + HTMLOptionElementFactory_traverse, + HTMLOptionElementFactory_unlink, HTMLOptionElementFactory_value, NULL, NULL, diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index 5d7f2603ac8..3e1d76e491e 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -1054,6 +1054,16 @@ static inline HTMLStorage *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLStorage, dispex); }
+static void HTMLStorage_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLStorage *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Storage", cb); +} + +static void HTMLStorage_unlink(DispatchEx *dispex) +{ +} + static void HTMLStorage_destructor(DispatchEx *dispex) { HTMLStorage *This = impl_from_DispatchEx(dispex); @@ -1310,6 +1320,8 @@ static HRESULT HTMLStorage_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pi
static const dispex_static_data_vtbl_t HTMLStorage_dispex_vtbl = { HTMLStorage_destructor, + HTMLStorage_traverse, + HTMLStorage_unlink, NULL, HTMLStorage_get_dispid, HTMLStorage_get_name, diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index f653f3c38b2..56558adcd9a 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -9962,11 +9962,28 @@ static inline CSSStyle *impl_from_DispatchEx(DispatchEx *dispex) return CONTAINING_RECORD(dispex, CSSStyle, dispex); }
-static void CSSStyle_destructor(DispatchEx *dispex) +static void CSSStyle_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { CSSStyle *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "CSSStyle", cb); + if(This->nsstyle) - nsIDOMCSSStyleDeclaration_Release(This->nsstyle); + note_cc_edge((nsISupports*)This->nsstyle, "nsstyle", cb); +} + +static void CSSStyle_unlink(DispatchEx *dispex) +{ + CSSStyle *This = impl_from_DispatchEx(dispex); + if(This->nsstyle) { + nsIDOMCSSStyleDeclaration *nsstyle = This->nsstyle; + This->nsstyle = NULL; + nsIDOMCSSStyleDeclaration_Release(nsstyle); + } +} + +static void CSSStyle_destructor(DispatchEx *dispex) +{ + CSSStyle *This = impl_from_DispatchEx(dispex); free(This); }
@@ -9999,6 +10016,8 @@ void CSSStyle_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
const dispex_static_data_vtbl_t CSSStyle_dispex_vtbl = { CSSStyle_destructor, + CSSStyle_traverse, + CSSStyle_unlink, NULL, CSSStyle_get_dispid, NULL, diff --git a/dlls/mshtml/htmlstylesheet.c b/dlls/mshtml/htmlstylesheet.c index e78ebe6592d..26b3c933bad 100644 --- a/dlls/mshtml/htmlstylesheet.c +++ b/dlls/mshtml/htmlstylesheet.c @@ -204,16 +204,35 @@ static inline HTMLStyleSheetRule *HTMLStyleSheetRule_from_DispatchEx(DispatchEx return CONTAINING_RECORD(iface, HTMLStyleSheetRule, dispex); }
-static void HTMLStyleSheetRule_destructor(DispatchEx *dispex) +static void HTMLStyleSheetRule_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLStyleSheetRule *This = HTMLStyleSheetRule_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheetRule", cb); + if(This->nsstylesheetrule) - nsIDOMCSSRule_Release(This->nsstylesheetrule); + note_cc_edge((nsISupports*)This->nsstylesheetrule, "nsstylesheetrule", cb); +} + +static void HTMLStyleSheetRule_unlink(DispatchEx *dispex) +{ + HTMLStyleSheetRule *This = HTMLStyleSheetRule_from_DispatchEx(dispex); + if(This->nsstylesheetrule) { + nsIDOMCSSRule *nsstylesheetrule = This->nsstylesheetrule; + This->nsstylesheetrule = NULL; + nsIDOMCSSRule_Release(nsstylesheetrule); + } +} + +static void HTMLStyleSheetRule_destructor(DispatchEx *dispex) +{ + HTMLStyleSheetRule *This = HTMLStyleSheetRule_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLStyleSheetRule_dispex_vtbl = { HTMLStyleSheetRule_destructor, + HTMLStyleSheetRule_traverse, + HTMLStyleSheetRule_unlink };
static const tid_t HTMLStyleSheetRule_iface_tids[] = { @@ -392,11 +411,28 @@ static inline HTMLStyleSheetRulesCollection *HTMLStyleSheetRulesCollection_from_ return CONTAINING_RECORD(iface, HTMLStyleSheetRulesCollection, dispex); }
-static void HTMLStyleSheetRulesCollection_destructor(DispatchEx *dispex) +static void HTMLStyleSheetRulesCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLStyleSheetRulesCollection *This = HTMLStyleSheetRulesCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheetRulesCollection", cb); + if(This->nslist) - nsIDOMCSSRuleList_Release(This->nslist); + note_cc_edge((nsISupports*)This->nslist, "nslist", cb); +} + +static void HTMLStyleSheetRulesCollection_unlink(DispatchEx *dispex) +{ + HTMLStyleSheetRulesCollection *This = HTMLStyleSheetRulesCollection_from_DispatchEx(dispex); + if(This->nslist) { + nsIDOMCSSRuleList *nslist = This->nslist; + This->nslist = NULL; + nsIDOMCSSRuleList_Release(nslist); + } +} + +static void HTMLStyleSheetRulesCollection_destructor(DispatchEx *dispex) +{ + HTMLStyleSheetRulesCollection *This = HTMLStyleSheetRulesCollection_from_DispatchEx(dispex); free(This); }
@@ -478,6 +514,8 @@ static HRESULT HTMLStyleSheetRulesCollection_invoke(DispatchEx *dispex, DISPID i
static const dispex_static_data_vtbl_t HTMLStyleSheetRulesCollection_dispex_vtbl = { HTMLStyleSheetRulesCollection_destructor, + HTMLStyleSheetRulesCollection_traverse, + HTMLStyleSheetRulesCollection_unlink, NULL, HTMLStyleSheetRulesCollection_get_dispid, HTMLStyleSheetRulesCollection_get_name, @@ -821,11 +859,28 @@ static inline HTMLStyleSheetsCollection *HTMLStyleSheetsCollection_from_Dispatch return CONTAINING_RECORD(iface, HTMLStyleSheetsCollection, dispex); }
-static void HTMLStyleSheetsCollection_destructor(DispatchEx *dispex) +static void HTMLStyleSheetsCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheetsCollection", cb); + if(This->nslist) - nsIDOMStyleSheetList_Release(This->nslist); + note_cc_edge((nsISupports*)This->nslist, "nslist", cb); +} + +static void HTMLStyleSheetsCollection_unlink(DispatchEx *dispex) +{ + HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex); + if(This->nslist) { + nsIDOMStyleSheetList *nslist = This->nslist; + This->nslist = NULL; + nsIDOMStyleSheetList_Release(nslist); + } +} + +static void HTMLStyleSheetsCollection_destructor(DispatchEx *dispex) +{ + HTMLStyleSheetsCollection *This = HTMLStyleSheetsCollection_from_DispatchEx(dispex); free(This); }
@@ -907,6 +962,8 @@ static HRESULT HTMLStyleSheetsCollection_invoke(DispatchEx *dispex, DISPID id, L
static const dispex_static_data_vtbl_t HTMLStyleSheetsCollection_dispex_vtbl = { HTMLStyleSheetsCollection_destructor, + HTMLStyleSheetsCollection_traverse, + HTMLStyleSheetsCollection_unlink, NULL, HTMLStyleSheetsCollection_get_dispid, HTMLStyleSheetsCollection_get_name, @@ -1474,11 +1531,28 @@ static inline HTMLStyleSheet *HTMLStyleSheet_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLStyleSheet, dispex); }
-static void HTMLStyleSheet_destructor(DispatchEx *dispex) +static void HTMLStyleSheet_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLStyleSheet *This = HTMLStyleSheet_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "StyleSheet", cb); + if(This->nsstylesheet) - nsIDOMCSSStyleSheet_Release(This->nsstylesheet); + note_cc_edge((nsISupports*)This->nsstylesheet, "nsstylesheet", cb); +} + +static void HTMLStyleSheet_unlink(DispatchEx *dispex) +{ + HTMLStyleSheet *This = HTMLStyleSheet_from_DispatchEx(dispex); + if(This->nsstylesheet) { + nsIDOMCSSStyleSheet *nsstylesheet = This->nsstylesheet; + This->nsstylesheet = NULL; + nsIDOMCSSStyleSheet_Release(nsstylesheet); + } +} + +static void HTMLStyleSheet_destructor(DispatchEx *dispex) +{ + HTMLStyleSheet *This = HTMLStyleSheet_from_DispatchEx(dispex); free(This); }
@@ -1490,6 +1564,8 @@ static void HTMLStyleSheet_init_dispex_info(dispex_data_t *info, compat_mode_t m
static const dispex_static_data_vtbl_t HTMLStyleSheet_dispex_vtbl = { HTMLStyleSheet_destructor, + HTMLStyleSheet_traverse, + HTMLStyleSheet_unlink };
static const tid_t HTMLStyleSheet_iface_tids[] = { diff --git a/dlls/mshtml/htmltextnode.c b/dlls/mshtml/htmltextnode.c index 76515aa6d95..c24d59086ff 100644 --- a/dlls/mshtml/htmltextnode.c +++ b/dlls/mshtml/htmltextnode.c @@ -319,6 +319,14 @@ static const IHTMLDOMTextNode2Vtbl HTMLDOMTextNode2Vtbl = { HTMLDOMTextNode2_replaceData };
+static void HTMLDOMTextNode_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ +} + +static void HTMLDOMTextNode_unlink(DispatchEx *dispex) +{ +} + static void HTMLDOMTextNode_destructor(DispatchEx *dispex) { } @@ -364,6 +372,8 @@ static const NodeImplVtbl HTMLDOMTextNodeImplVtbl = {
static const dispex_static_data_vtbl_t HTMLDOMTextNode_dispex_vtbl = { HTMLDOMTextNode_destructor, + HTMLDOMTextNode_traverse, + HTMLDOMTextNode_unlink };
static const tid_t HTMLDOMTextNode_iface_tids[] = { diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 6a0607700bf..0bdd8a6c68b 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -134,7 +134,7 @@ static void detach_inner_window(HTMLInnerWindow *window) detach_document_node(doc);
if(outer_window && outer_window->location) - dispex_unlink(&outer_window->location->dispex.IDispatchEx_iface); + dispex_props_unlink(&outer_window->location->dispex);
abort_window_bindings(window); remove_target_tasks(window->task_magic); @@ -3667,64 +3667,119 @@ static inline HTMLInnerWindow *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLInnerWindow, event_target.dispex); }
-static void HTMLWindow_destructor(DispatchEx *dispex) +static void HTMLWindow_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLInnerWindow *This = impl_from_DispatchEx(dispex); - unsigned i; + HTMLOuterWindow *child;
- TRACE("%p\n", This); + describe_cc_node(&This->base.ccref, "InnerWindow", cb);
if(This->base.console) - IWineMSHTMLConsole_Release(This->base.console); + note_cc_edge((nsISupports*)This->base.console, "console", cb); + LIST_FOR_EACH_ENTRY(child, &This->children, HTMLOuterWindow, sibling_entry) + note_cc_edge((nsISupports*)&child->base.IHTMLWindow2_iface, "child", cb); + if(This->doc) + note_cc_edge((nsISupports*)&This->doc->node.IHTMLDOMNode_iface, "doc", cb); + if(This->image_factory) + note_cc_edge((nsISupports*)&This->image_factory->IHTMLImageElementFactory_iface, "image_factory", cb); + if(This->option_factory) + note_cc_edge((nsISupports*)&This->option_factory->IHTMLOptionElementFactory_iface, "option_factory", cb); + if(This->xhr_factory) + note_cc_edge((nsISupports*)&This->xhr_factory->IHTMLXMLHttpRequestFactory_iface, "xhr_factory", cb); + if(This->screen) + note_cc_edge((nsISupports*)This->screen, "screen", cb); + if(This->history) + note_cc_edge((nsISupports*)&This->history->IOmHistory_iface, "history", cb); + if(This->navigator) + note_cc_edge((nsISupports*)This->navigator, "navigator", cb); + if(This->session_storage) + note_cc_edge((nsISupports*)This->session_storage, "session_storage", cb); + if(This->local_storage) + note_cc_edge((nsISupports*)This->local_storage, "local_storage", cb); + if(V_VT(&This->performance) == VT_DISPATCH) + note_cc_edge((nsISupports*)V_DISPATCH(&This->performance), "performance", cb); +} + +static void HTMLWindow_unlink(DispatchEx *dispex) +{ + HTMLInnerWindow *This = impl_from_DispatchEx(dispex); + + TRACE("%p\n", This); + + if(This->base.console) { + IWineMSHTMLConsole *console = This->base.console; + This->base.console = NULL; + IWineMSHTMLConsole_Release(console); + }
detach_inner_window(This);
if(This->doc) { + HTMLDocumentNode *doc = This->doc; This->doc->window = NULL; - IHTMLDOMNode_Release(&This->doc->node.IHTMLDOMNode_iface); + This->doc = NULL; + IHTMLDOMNode_Release(&doc->node.IHTMLDOMNode_iface); }
release_event_target(&This->event_target);
- for(i=0; i < This->global_prop_cnt; i++) - free(This->global_props[i].name); - free(This->global_props); - if(This->image_factory) { + HTMLImageElementFactory *image_factory = This->image_factory; This->image_factory->window = NULL; - IHTMLImageElementFactory_Release(&This->image_factory->IHTMLImageElementFactory_iface); + This->image_factory = NULL; + IHTMLImageElementFactory_Release(&image_factory->IHTMLImageElementFactory_iface); } - if(This->option_factory) { + HTMLOptionElementFactory *option_factory = This->option_factory; This->option_factory->window = NULL; - IHTMLOptionElementFactory_Release(&This->option_factory->IHTMLOptionElementFactory_iface); + This->option_factory = NULL; + IHTMLOptionElementFactory_Release(&option_factory->IHTMLOptionElementFactory_iface); } - if(This->xhr_factory) { + HTMLXMLHttpRequestFactory *xhr_factory = This->xhr_factory; This->xhr_factory->window = NULL; - IHTMLXMLHttpRequestFactory_Release(&This->xhr_factory->IHTMLXMLHttpRequestFactory_iface); + This->xhr_factory = NULL; + IHTMLXMLHttpRequestFactory_Release(&xhr_factory->IHTMLXMLHttpRequestFactory_iface); + } + if(This->screen) { + IHTMLScreen *screen = This->screen; + This->screen = NULL; + IHTMLScreen_Release(screen); } - - if(This->screen) - IHTMLScreen_Release(This->screen); - if(This->history) { + OmHistory *history = This->history; This->history->window = NULL; - IOmHistory_Release(&This->history->IOmHistory_iface); + This->history = NULL; + IOmHistory_Release(&history->IOmHistory_iface); + } + if(This->navigator) { + IOmNavigator *navigator = This->navigator; + This->navigator = NULL; + IOmNavigator_Release(navigator); } - - if(This->navigator) - IOmNavigator_Release(This->navigator); if(This->session_storage) { + IHTMLStorage *session_storage = This->session_storage; detach_html_storage(This->session_storage); - IHTMLStorage_Release(This->session_storage); + This->session_storage = NULL; + IHTMLStorage_Release(session_storage); } if(This->local_storage) { + IHTMLStorage *local_storage = This->local_storage; detach_html_storage(This->local_storage); - IHTMLStorage_Release(This->local_storage); + This->local_storage = NULL; + IHTMLStorage_Release(local_storage); } - VariantClear(&This->performance); +} + +static void HTMLWindow_destructor(DispatchEx *dispex) +{ + HTMLInnerWindow *This = impl_from_DispatchEx(dispex); + unsigned i; + + for(i = 0; i < This->global_prop_cnt; i++) + free(This->global_props[i].name); + free(This->global_props);
if(This->mon) IMoniker_Release(This->mon); @@ -3971,6 +4026,8 @@ static IHTMLEventObj *HTMLWindow_set_current_event(DispatchEx *dispex, IHTMLEven static const event_target_vtbl_t HTMLWindow_event_target_vtbl = { { HTMLWindow_destructor, + HTMLWindow_traverse, + HTMLWindow_unlink, NULL, NULL, HTMLWindow_get_name, @@ -4006,10 +4063,9 @@ static nsresult NSAPI window_traverse(void *ccp, void *p, nsCycleCollectionTrave HTMLWindow *This = impl_from_IHTMLWindow2(p); HTMLOuterWindow *window;
- if(!is_outer_window(This)) { - /* FIXME: Traverse inner window and its dispex */ - return NS_OK; - } + if(!is_outer_window(This)) + return dispex_traverse(&window_ccp, &This->inner_window->event_target.dispex.IDispatchEx_iface, cb); + window = This->outer_window;
describe_cc_node(&window->base.ccref, "OuterWindow", cb); @@ -4040,10 +4096,9 @@ static nsresult NSAPI window_unlink(void *p) IWineMSHTMLConsole_Release(console); }
- if(!is_outer_window(This)) { - /* FIXME: Unlink inner window and its dispex */ - return NS_OK; - } + if(!is_outer_window(This)) + return dispex_unlink(&This->inner_window->event_target.dispex.IDispatchEx_iface); + window = This->outer_window;
remove_target_tasks(window->task_magic); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 119568386fd..c1656dc11be 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -336,9 +336,12 @@ typedef struct dispex_dynamic_data_t dispex_dynamic_data_t; #define MSHTML_CUSTOM_DISPID_CNT (MSHTML_DISPID_CUSTOM_MAX-MSHTML_DISPID_CUSTOM_MIN)
typedef struct DispatchEx DispatchEx; +typedef struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback;
typedef struct { void (*destructor)(DispatchEx*); + void (*traverse)(DispatchEx*,nsCycleCollectionTraversalCallback*); + void (*unlink)(DispatchEx*); HRESULT (*value)(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*); HRESULT (*get_dispid)(DispatchEx*,BSTR,DWORD,DISPID*); HRESULT (*get_name)(DispatchEx*,DISPID,BSTR*); @@ -387,8 +390,6 @@ typedef struct { void *callbacks; } ExternalCycleCollectionParticipant;
-typedef struct nsCycleCollectionTraversalCallback nsCycleCollectionTraversalCallback; - typedef struct { nsresult (NSAPI *traverse)(void*,void*,nsCycleCollectionTraversalCallback*); nsresult (NSAPI *unlink)(void*); @@ -418,6 +419,7 @@ static inline LONG dispex_ccref_decr(nsCycleCollectingAutoRefCnt *ccref, Dispatc
void init_dispatch(DispatchEx*,IUnknown*,dispex_static_data_t*,compat_mode_t); BOOL dispex_query_interface(DispatchEx*,REFIID,void**); +void dispex_props_unlink(DispatchEx*); nsresult NSAPI dispex_traverse(void*,void*,nsCycleCollectionTraversalCallback*); nsresult NSAPI dispex_unlink(void*); void NSAPI dispex_delete_cycle_collectable(void*); diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 9b0cf027dd5..7c1e19fc711 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -291,17 +291,36 @@ static inline HTMLDOMImplementation *HTMLDOMImplementation_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLDOMImplementation, dispex); }
+static void HTMLDOMImplementation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDOMImplementation *This = HTMLDOMImplementation_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMImplementation", cb); + + if(This->implementation) + note_cc_edge((nsISupports*)This->implementation, "implementation", cb); +} + +static void HTMLDOMImplementation_unlink(DispatchEx *dispex) +{ + HTMLDOMImplementation *This = HTMLDOMImplementation_from_DispatchEx(dispex); + if(This->implementation) { + nsIDOMDOMImplementation *implementation = This->implementation; + This->implementation = NULL; + nsIDOMDOMImplementation_Release(implementation); + } +} + static void HTMLDOMImplementation_destructor(DispatchEx *dispex) { HTMLDOMImplementation *This = HTMLDOMImplementation_from_DispatchEx(dispex); assert(!This->browser); - if(This->implementation) - nsIDOMDOMImplementation_Release(This->implementation); free(This); }
static const dispex_static_data_vtbl_t HTMLDOMImplementation_dispex_vtbl = { HTMLDOMImplementation_destructor, + HTMLDOMImplementation_traverse, + HTMLDOMImplementation_unlink };
static void HTMLDOMImplementation_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode) @@ -563,6 +582,16 @@ static inline HTMLScreen *HTMLScreen_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLScreen, dispex); }
+static void HTMLScreen_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLScreen *This = HTMLScreen_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Screen", cb); +} + +static void HTMLScreen_unlink(DispatchEx *dispex) +{ +} + static void HTMLScreen_destructor(DispatchEx *dispex) { HTMLScreen *This = HTMLScreen_from_DispatchEx(dispex); @@ -571,6 +600,8 @@ static void HTMLScreen_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t HTMLScreen_dispex_vtbl = { HTMLScreen_destructor, + HTMLScreen_traverse, + HTMLScreen_unlink };
static const tid_t HTMLScreen_iface_tids[] = { @@ -737,6 +768,16 @@ static inline OmHistory *OmHistory_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, OmHistory, dispex); }
+static void OmHistory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + OmHistory *This = OmHistory_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "History", cb); +} + +static void OmHistory_unlink(DispatchEx *dispex) +{ +} + static void OmHistory_destructor(DispatchEx *dispex) { OmHistory *This = OmHistory_from_DispatchEx(dispex); @@ -745,6 +786,8 @@ static void OmHistory_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t OmHistory_dispex_vtbl = { OmHistory_destructor, + OmHistory_traverse, + OmHistory_unlink };
static const tid_t OmHistory_iface_tids[] = { @@ -902,16 +945,31 @@ static inline HTMLPluginsCollection *HTMLPluginsCollection_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLPluginsCollection, dispex); }
-static void HTMLPluginsCollection_destructor(DispatchEx *dispex) +static void HTMLPluginsCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPluginsCollection *This = HTMLPluginsCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "PluginsCollection", cb); +} + +static void HTMLPluginsCollection_unlink(DispatchEx *dispex) { HTMLPluginsCollection *This = HTMLPluginsCollection_from_DispatchEx(dispex); - if(This->navigator) + if(This->navigator) { This->navigator->plugins = NULL; + This->navigator = NULL; + } +} + +static void HTMLPluginsCollection_destructor(DispatchEx *dispex) +{ + HTMLPluginsCollection *This = HTMLPluginsCollection_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLPluginsCollection_dispex_vtbl = { HTMLPluginsCollection_destructor, + HTMLPluginsCollection_traverse, + HTMLPluginsCollection_unlink };
static const tid_t HTMLPluginsCollection_iface_tids[] = { @@ -1057,16 +1115,31 @@ static inline HTMLMimeTypesCollection *HTMLMimeTypesCollection_from_DispatchEx(D return CONTAINING_RECORD(iface, HTMLMimeTypesCollection, dispex); }
-static void HTMLMimeTypesCollection_destructor(DispatchEx *dispex) +static void HTMLMimeTypesCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLMimeTypesCollection *This = HTMLMimeTypesCollection_from_DispatchEx(dispex); - if(This->navigator) + describe_cc_node(&This->ccref, "MimeTypesCollection", cb); +} + +static void HTMLMimeTypesCollection_unlink(DispatchEx *dispex) +{ + HTMLMimeTypesCollection *This = HTMLMimeTypesCollection_from_DispatchEx(dispex); + if(This->navigator) { This->navigator->mime_types = NULL; + This->navigator = NULL; + } +} + +static void HTMLMimeTypesCollection_destructor(DispatchEx *dispex) +{ + HTMLMimeTypesCollection *This = HTMLMimeTypesCollection_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLMimeTypesCollection_dispex_vtbl = { HTMLMimeTypesCollection_destructor, + HTMLMimeTypesCollection_traverse, + HTMLMimeTypesCollection_unlink };
static const tid_t HTMLMimeTypesCollection_iface_tids[] = { @@ -1493,18 +1566,35 @@ static inline OmNavigator *OmNavigator_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, OmNavigator, dispex); }
-static void OmNavigator_destructor(DispatchEx *dispex) +static void OmNavigator_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + OmNavigator *This = OmNavigator_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "Navigator", cb); +} + +static void OmNavigator_unlink(DispatchEx *dispex) { OmNavigator *This = OmNavigator_from_DispatchEx(dispex); - if(This->plugins) + if(This->plugins) { This->plugins->navigator = NULL; - if(This->mime_types) + This->plugins = NULL; + } + if(This->mime_types) { This->mime_types->navigator = NULL; + This->mime_types = NULL; + } +} + +static void OmNavigator_destructor(DispatchEx *dispex) +{ + OmNavigator *This = OmNavigator_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t OmNavigator_dispex_vtbl = { OmNavigator_destructor, + OmNavigator_traverse, + OmNavigator_unlink };
static const tid_t OmNavigator_iface_tids[] = { @@ -1916,15 +2006,35 @@ static inline HTMLPerformanceTiming *HTMLPerformanceTiming_from_DispatchEx(Dispa return CONTAINING_RECORD(iface, HTMLPerformanceTiming, dispex); }
+static void HTMLPerformanceTiming_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "PerformanceTiming", cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLPerformanceTiming_unlink(DispatchEx *dispex) +{ + HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void HTMLPerformanceTiming_destructor(DispatchEx *dispex) { HTMLPerformanceTiming *This = HTMLPerformanceTiming_from_DispatchEx(dispex); - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); free(This); }
static const dispex_static_data_vtbl_t HTMLPerformanceTiming_dispex_vtbl = { HTMLPerformanceTiming_destructor, + HTMLPerformanceTiming_traverse, + HTMLPerformanceTiming_unlink };
static const tid_t HTMLPerformanceTiming_iface_tids[] = { @@ -2083,15 +2193,35 @@ static inline HTMLPerformanceNavigation *HTMLPerformanceNavigation_from_Dispatch return CONTAINING_RECORD(iface, HTMLPerformanceNavigation, dispex); }
+static void HTMLPerformanceNavigation_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLPerformanceNavigation *This = HTMLPerformanceNavigation_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "PerformanceNavigation", cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLPerformanceNavigation_unlink(DispatchEx *dispex) +{ + HTMLPerformanceNavigation *This = HTMLPerformanceNavigation_from_DispatchEx(dispex); + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void HTMLPerformanceNavigation_destructor(DispatchEx *dispex) { HTMLPerformanceNavigation *This = HTMLPerformanceNavigation_from_DispatchEx(dispex); - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); free(This); }
static const dispex_static_data_vtbl_t HTMLPerformanceNavigation_dispex_vtbl = { HTMLPerformanceNavigation_destructor, + HTMLPerformanceNavigation_traverse, + HTMLPerformanceNavigation_unlink };
static const tid_t HTMLPerformanceNavigation_iface_tids[] = { @@ -2290,19 +2420,49 @@ static inline HTMLPerformance *HTMLPerformance_from_DispatchEx(DispatchEx *iface return CONTAINING_RECORD(iface, HTMLPerformance, dispex); }
-static void HTMLPerformance_destructor(DispatchEx *dispex) +static void HTMLPerformance_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + describe_cc_node(&This->ccref, "Performance", cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); if(This->navigation) - IHTMLPerformanceNavigation_Release(This->navigation); + note_cc_edge((nsISupports*)This->navigation, "navigation", cb); if(This->timing) - IHTMLPerformanceTiming_Release(This->timing); + note_cc_edge((nsISupports*)This->timing, "timing", cb); +} + +static void HTMLPerformance_unlink(DispatchEx *dispex) +{ + HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } + if(This->navigation) { + IHTMLPerformanceNavigation *navigation = This->navigation; + This->navigation = NULL; + IHTMLPerformanceNavigation_Release(navigation); + } + if(This->timing) { + IHTMLPerformanceTiming *timing = This->timing; + This->timing = NULL; + IHTMLPerformanceTiming_Release(timing); + } +} + +static void HTMLPerformance_destructor(DispatchEx *dispex) +{ + HTMLPerformance *This = HTMLPerformance_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLPerformance_dispex_vtbl = { HTMLPerformance_destructor, + HTMLPerformance_traverse, + HTMLPerformance_unlink };
static const tid_t HTMLPerformance_iface_tids[] = { @@ -2467,6 +2627,16 @@ static inline HTMLNamespaceCollection *HTMLNamespaceCollection_from_DispatchEx(D return CONTAINING_RECORD(iface, HTMLNamespaceCollection, dispex); }
+static void HTMLNamespaceCollection_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLNamespaceCollection *This = HTMLNamespaceCollection_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "NamespaceCollection", cb); +} + +static void HTMLNamespaceCollection_unlink(DispatchEx *dispex) +{ +} + static void HTMLNamespaceCollection_destructor(DispatchEx *dispex) { HTMLNamespaceCollection *This = HTMLNamespaceCollection_from_DispatchEx(dispex); @@ -2475,6 +2645,8 @@ static void HTMLNamespaceCollection_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t HTMLNamespaceCollection_dispex_vtbl = { HTMLNamespaceCollection_destructor, + HTMLNamespaceCollection_traverse, + HTMLNamespaceCollection_unlink };
static const tid_t HTMLNamespaceCollection_iface_tids[] = { @@ -2733,6 +2905,16 @@ static inline struct console *console_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, struct console, dispex); }
+static void console_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct console *console = console_from_DispatchEx(dispex); + describe_cc_node(&console->ccref, "Console", cb); +} + +static void console_unlink(DispatchEx *dispex) +{ +} + static void console_destructor(DispatchEx *dispex) { struct console *console = console_from_DispatchEx(dispex); @@ -2741,6 +2923,8 @@ static void console_destructor(DispatchEx *dispex)
static const dispex_static_data_vtbl_t console_dispex_vtbl = { console_destructor, + console_traverse, + console_unlink };
static const tid_t console_iface_tids[] = { @@ -3058,23 +3242,48 @@ static inline struct media_query_list *media_query_list_from_DispatchEx(Dispatch return CONTAINING_RECORD(iface, struct media_query_list, dispex); }
-static void media_query_list_destructor(DispatchEx *dispex) +static void media_query_list_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct media_query_list *media_query_list = media_query_list_from_DispatchEx(dispex); + struct media_query_list_listener *listener; + + describe_cc_node(&media_query_list->ccref, "MediaQueryList", cb); + + LIST_FOR_EACH_ENTRY(listener, &media_query_list->listeners, struct media_query_list_listener, entry) + note_cc_edge((nsISupports*)listener->function, "function", cb); + if(media_query_list->nsquerylist) + note_cc_edge((nsISupports*)media_query_list->nsquerylist, "nsquerylist", cb); +} + +static void media_query_list_unlink(DispatchEx *dispex) { struct media_query_list *media_query_list = media_query_list_from_DispatchEx(dispex); - struct media_query_list_listener *listener, *listener2;
media_query_list->callback->media_query_list = NULL; - LIST_FOR_EACH_ENTRY_SAFE(listener, listener2, &media_query_list->listeners, struct media_query_list_listener, entry) { + while(!list_empty(&media_query_list->listeners)) { + struct media_query_list_listener *listener = LIST_ENTRY(list_head(&media_query_list->listeners), struct media_query_list_listener, entry); + list_remove(&listener->entry); IDispatch_Release(listener->function); free(listener); } + if(media_query_list->nsquerylist) { + nsIDOMMediaQueryList *nsquerylist = media_query_list->nsquerylist; + media_query_list->nsquerylist = NULL; + nsIDOMMediaQueryList_Release(nsquerylist); + } +} + +static void media_query_list_destructor(DispatchEx *dispex) +{ + struct media_query_list *media_query_list = media_query_list_from_DispatchEx(dispex); nsIDOMMediaQueryListListener_Release(&media_query_list->callback->nsIDOMMediaQueryListListener_iface); - nsIDOMMediaQueryList_Release(media_query_list->nsquerylist); free(media_query_list); }
static const dispex_static_data_vtbl_t media_query_list_dispex_vtbl = { media_query_list_destructor, + media_query_list_traverse, + media_query_list_unlink };
static const tid_t media_query_list_iface_tids[] = { diff --git a/dlls/mshtml/range.c b/dlls/mshtml/range.c index 20730b5e0f2..599c9ea4b7a 100644 --- a/dlls/mshtml/range.c +++ b/dlls/mshtml/range.c @@ -1714,18 +1714,39 @@ static inline HTMLTxtRange *HTMLTxtRange_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLTxtRange, dispex); }
-static void HTMLTxtRange_destructor(DispatchEx *dispex) +static void HTMLTxtRange_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLTxtRange *This = HTMLTxtRange_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "TextRange", cb); + if(This->nsrange) - nsIDOMRange_Release(This->nsrange); - if(This->doc) + note_cc_edge((nsISupports*)This->nsrange, "nsrange", cb); +} + +static void HTMLTxtRange_unlink(DispatchEx *dispex) +{ + HTMLTxtRange *This = HTMLTxtRange_from_DispatchEx(dispex); + if(This->nsrange) { + nsIDOMRange *nsrange = This->nsrange; + This->nsrange = NULL; + nsIDOMRange_Release(nsrange); + } + if(This->doc) { + This->doc = NULL; list_remove(&This->entry); + } +} + +static void HTMLTxtRange_destructor(DispatchEx *dispex) +{ + HTMLTxtRange *This = HTMLTxtRange_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLTxtRange_dispex_vtbl = { HTMLTxtRange_destructor, + HTMLTxtRange_traverse, + HTMLTxtRange_unlink };
static const tid_t HTMLTxtRange_iface_tids[] = { @@ -2071,16 +2092,35 @@ static inline HTMLDOMRange *HTMLDOMRange_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLDOMRange, dispex); }
-static void HTMLDOMRange_destructor(DispatchEx *dispex) +static void HTMLDOMRange_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLDOMRange *This = HTMLDOMRange_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "DOMRange", cb); + if(This->nsrange) - nsIDOMRange_Release(This->nsrange); + note_cc_edge((nsISupports*)This->nsrange, "nsrange", cb); +} + +static void HTMLDOMRange_unlink(DispatchEx *dispex) +{ + HTMLDOMRange *This = HTMLDOMRange_from_DispatchEx(dispex); + if(This->nsrange) { + nsIDOMRange *nsrange = This->nsrange; + This->nsrange = NULL; + nsIDOMRange_Release(nsrange); + } +} + +static void HTMLDOMRange_destructor(DispatchEx *dispex) +{ + HTMLDOMRange *This = HTMLDOMRange_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLDOMRange_dispex_vtbl = { HTMLDOMRange_destructor, + HTMLDOMRange_traverse, + HTMLDOMRange_unlink };
static const tid_t HTMLDOMRange_iface_tids[] = { diff --git a/dlls/mshtml/selection.c b/dlls/mshtml/selection.c index 639ab0ce391..91be8bbc8ba 100644 --- a/dlls/mshtml/selection.c +++ b/dlls/mshtml/selection.c @@ -325,18 +325,39 @@ static inline HTMLSelectionObject *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLSelectionObject, dispex); }
-static void HTMLSelectionObject_destructor(DispatchEx *dispex) +static void HTMLSelectionObject_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLSelectionObject *This = impl_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "SelectionObject", cb); + if(This->nsselection) - nsISelection_Release(This->nsselection); - if(This->doc) + note_cc_edge((nsISupports*)This->nsselection, "nsselection", cb); +} + +static void HTMLSelectionObject_unlink(DispatchEx *dispex) +{ + HTMLSelectionObject *This = impl_from_DispatchEx(dispex); + if(This->nsselection) { + nsISelection *nsselection = This->nsselection; + This->nsselection = NULL; + nsISelection_Release(nsselection); + } + if(This->doc) { + This->doc = NULL; list_remove(&This->entry); + } +} + +static void HTMLSelectionObject_destructor(DispatchEx *dispex) +{ + HTMLSelectionObject *This = impl_from_DispatchEx(dispex); free(This); }
static const dispex_static_data_vtbl_t HTMLSelectionObject_dispex_vtbl = { HTMLSelectionObject_destructor, + HTMLSelectionObject_traverse, + HTMLSelectionObject_unlink };
static const tid_t HTMLSelectionObject_iface_tids[] = { diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 2f7544ae191..1afb5131f0d 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -1523,16 +1523,49 @@ static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface) return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, event_target.dispex); }
-static void HTMLXMLHttpRequest_destructor(DispatchEx *dispex) +static void HTMLXMLHttpRequest_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); - remove_target_tasks(This->task_magic); - detach_xhr_event_listener(This->event_listener); + describe_cc_node(&This->ccref, "XMLHttpRequest", cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); if(This->pending_progress_event) - IDOMEvent_Release(&This->pending_progress_event->IDOMEvent_iface); - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); + note_cc_edge((nsISupports*)&This->pending_progress_event->IDOMEvent_iface, "pending_progress_event", cb); + if(This->nsxhr) + note_cc_edge((nsISupports*)This->nsxhr, "nsxhr", cb); +} + +static void HTMLXMLHttpRequest_unlink(DispatchEx *dispex) +{ + HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); + remove_target_tasks(This->task_magic); + if(This->event_listener) { + XMLHttpReqEventListener *event_listener = This->event_listener; + This->event_listener = NULL; + detach_xhr_event_listener(event_listener); + } + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } + if(This->pending_progress_event) { + DOMEvent *pending_progress_event = This->pending_progress_event; + This->pending_progress_event = NULL; + IDOMEvent_Release(&pending_progress_event->IDOMEvent_iface); + } + if(This->nsxhr) { + nsIXMLHttpRequest *nsxhr = This->nsxhr; + This->nsxhr = NULL; + nsIXMLHttpRequest_Release(nsxhr); + } release_event_target(&This->event_target); - nsIXMLHttpRequest_Release(This->nsxhr); +} + +static void HTMLXMLHttpRequest_destructor(DispatchEx *dispex) +{ + HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); free(This); }
@@ -1581,6 +1614,8 @@ static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = { { HTMLXMLHttpRequest_destructor, + HTMLXMLHttpRequest_traverse, + HTMLXMLHttpRequest_unlink }, HTMLXMLHttpRequest_get_gecko_target, HTMLXMLHttpRequest_bind_event @@ -1767,6 +1802,16 @@ static inline HTMLXMLHttpRequestFactory *factory_from_DispatchEx(DispatchEx *ifa return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, dispex); }
+static void HTMLXMLHttpRequestFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); + describe_cc_node(&This->ccref, "XMLHttpRequestFactory", cb); +} + +static void HTMLXMLHttpRequestFactory_unlink(DispatchEx *dispex) +{ +} + static void HTMLXMLHttpRequestFactory_destructor(DispatchEx *dispex) { HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); @@ -1798,6 +1843,8 @@ static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WOR
static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl = { HTMLXMLHttpRequestFactory_destructor, + HTMLXMLHttpRequestFactory_traverse, + HTMLXMLHttpRequestFactory_unlink, HTMLXMLHttpRequestFactory_value };