From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 9750ad19765..f1da5eaad07 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -5700,6 +5700,12 @@ void detach_document_node(HTMLDocumentNode *doc) { unsigned i;
+ if(doc->window) { + HTMLInnerWindow *window = doc->window; + doc->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } + while(!list_empty(&doc->plugin_hosts)) detach_plugin_host(LIST_ENTRY(list_head(&doc->plugin_hosts), PluginHost, entry));
@@ -5855,6 +5861,15 @@ static void *HTMLDocumentNode_query_interface(DispatchEx *dispex, REFIID riid) return HTMLDOMNode_query_interface(&This->node.event_target.dispex, riid); }
+static void HTMLDocumentNode_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLDocumentNode *This = impl_from_DispatchEx(dispex); + HTMLDOMNode_traverse(dispex, cb); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + static void HTMLDocumentNode_unlink(DispatchEx *dispex) { HTMLDocumentNode *This = impl_from_DispatchEx(dispex); @@ -5865,13 +5880,8 @@ static void HTMLDocumentNode_unlink(DispatchEx *dispex) detach_document_node(This); This->dom_document = NULL; This->html_document = NULL; - This->window = NULL; }else if(This->window) { detach_document_node(This); - - /* document fragments own reference to inner window */ - IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); - This->window = NULL; } }
@@ -6057,7 +6067,7 @@ static const event_target_vtbl_t HTMLDocumentNode_event_target_vtbl = { { .query_interface = HTMLDocumentNode_query_interface, .destructor = HTMLDocumentNode_destructor, - .traverse = HTMLDOMNode_traverse, + .traverse = HTMLDocumentNode_traverse, .unlink = HTMLDocumentNode_unlink, .get_name = HTMLDocumentNode_get_name, .invoke = HTMLDocumentNode_invoke, @@ -6166,6 +6176,9 @@ static HTMLDocumentNode *alloc_doc_node(HTMLDocumentObj *doc_obj, HTMLInnerWindo doc->outer_window = window ? window->base.outer_window : NULL; doc->window = window;
+ if(window) + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); + ConnectionPointContainer_Init(&doc->cp_container, (IUnknown*)&doc->IHTMLDocument2_iface, HTMLDocumentNode_cpc); HTMLDocumentNode_Persist_Init(doc); HTMLDocumentNode_Service_Init(doc); @@ -6241,8 +6254,6 @@ static HRESULT create_document_fragment(nsIDOMNode *nsnode, HTMLDocumentNode *do if(!doc_frag) return E_OUTOFMEMORY;
- IHTMLWindow2_AddRef(&doc_frag->window->base.IHTMLWindow2_iface); - HTMLDOMNode_Init(doc_node, &doc_frag->node, nsnode, &HTMLDocumentNode_dispex); doc_frag->node.vtbl = &HTMLDocumentFragmentImplVtbl; doc_frag->document_mode = lock_document_mode(doc_node);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index f1da5eaad07..4daf5ccc58d 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -5868,6 +5868,10 @@ static void HTMLDocumentNode_traverse(DispatchEx *dispex, nsCycleCollectionTrave
if(This->window) note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); + if(This->dom_implementation) + note_cc_edge((nsISupports*)This->dom_implementation, "dom_implementation", cb); + if(This->namespaces) + note_cc_edge((nsISupports*)This->namespaces, "namespaces", cb); }
static void HTMLDocumentNode_unlink(DispatchEx *dispex)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 47e65472c01..4afa434ad27 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -112,9 +112,11 @@ static void detach_inner_window(HTMLInnerWindow *window)
while(!list_empty(&window->children)) { HTMLOuterWindow *child = LIST_ENTRY(list_tail(&window->children), HTMLOuterWindow, sibling_entry); + HTMLOuterWindow *parent = child->parent;
list_remove(&child->sibling_entry); child->parent = NULL; + IHTMLWindow2_Release(&parent->base.IHTMLWindow2_iface);
if(child->base.inner_window) detach_inner_window(child->base.inner_window); @@ -4330,6 +4332,8 @@ static nsresult NSAPI outer_window_traverse(void *ccp, void *p, nsCycleCollectio note_cc_edge((nsISupports*)&window->pending_window->base.IHTMLWindow2_iface, "pending_window", cb); if(window->base.inner_window) note_cc_edge((nsISupports*)&window->base.inner_window->base.IHTMLWindow2_iface, "inner_window", cb); + if(window->parent) + note_cc_edge((nsISupports*)&window->parent->base.IHTMLWindow2_iface, "parent", cb); if(window->location) note_cc_edge((nsISupports*)&window->location->IHTMLLocation_iface, "location", cb); if(window->nswindow) @@ -4359,6 +4363,11 @@ static nsresult NSAPI outer_window_unlink(void *p) set_current_uri(window, NULL); if(window->base.inner_window) detach_inner_window(window->base.inner_window); + if(window->parent) { + HTMLOuterWindow *parent = window->parent; + window->parent = NULL; + IHTMLWindow2_Release(&parent->base.IHTMLWindow2_iface); + } if(window->location) { HTMLLocation *location = window->location; window->location = NULL; @@ -4490,6 +4499,7 @@ HRESULT create_outer_window(GeckoBrowser *browser, mozIDOMWindowProxy *mozwindow
if(parent) { IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); + IHTMLWindow2_AddRef(&parent->base.IHTMLWindow2_iface);
window->parent = parent; list_add_tail(&parent->base.inner_window->children, &window->sibling_entry);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlframe.c | 52 +++++++++++++++++++--------------------- dlls/mshtml/htmlwindow.c | 5 +++- 2 files changed, 28 insertions(+), 29 deletions(-)
diff --git a/dlls/mshtml/htmlframe.c b/dlls/mshtml/htmlframe.c index 5dab4e44bc5..94b737126be 100644 --- a/dlls/mshtml/htmlframe.c +++ b/dlls/mshtml/htmlframe.c @@ -48,20 +48,19 @@ static HRESULT set_frame_doc(HTMLFrameBase *frame, nsIDOMDocument *nsdoc) return E_FAIL;
window = mozwindow_to_window(mozwindow); - if(!window && frame->element.node.doc->browser) { + if(window) + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); + else if(frame->element.node.doc->browser) hres = create_outer_window(frame->element.node.doc->browser, mozwindow, frame->element.node.doc->outer_window, &window);
- /* Don't hold ref to the created window; the parent keeps ref to it */ - if(SUCCEEDED(hres)) - IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); - } mozIDOMWindowProxy_Release(mozwindow); if(FAILED(hres)) return hres;
frame->content_window = window; window->frame_element = frame; + IHTMLDOMNode_AddRef(&frame->element.node.IHTMLDOMNode_iface); return S_OK; }
@@ -710,12 +709,23 @@ static void *HTMLFrameBase_QI(HTMLFrameBase *This, REFIID riid) return HTMLElement_query_interface(&This->element.node.event_target.dispex, riid); }
-static void HTMLFrameBase_destructor(HTMLFrameBase *This) +static void HTMLFrameBase_traverse(HTMLFrameBase *This, nsCycleCollectionTraversalCallback *cb) { + HTMLDOMNode_traverse(&This->element.node.event_target.dispex, cb); + if(This->content_window) - This->content_window->frame_element = NULL; + note_cc_edge((nsISupports*)&This->content_window->base.IHTMLWindow2_iface, "content_window", cb); +} + +static void HTMLFrameBase_unlink(HTMLFrameBase *This) +{ + HTMLDOMNode_unlink(&This->element.node.event_target.dispex);
- HTMLElement_destructor(&This->element.node.event_target.dispex); + if(This->content_window) { + HTMLOuterWindow *content_window = This->content_window; + This->content_window = NULL; + IHTMLWindow2_Release(&content_window->base.IHTMLWindow2_iface); + } }
static void HTMLFrameBase_Init(HTMLFrameBase *This, HTMLDocumentNode *doc, nsIDOMElement *nselem, @@ -944,7 +954,7 @@ static void *HTMLFrameElement_query_interface(DispatchEx *dispex, REFIID riid) static void HTMLFrameElement_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLFrameElement *This = frame_from_DispatchEx(dispex); - HTMLDOMNode_traverse(dispex, cb); + HTMLFrameBase_traverse(&This->framebase, cb);
if(This->framebase.nsframe) note_cc_edge((nsISupports*)This->framebase.nsframe, "nsframe", cb); @@ -953,17 +963,10 @@ static void HTMLFrameElement_traverse(DispatchEx *dispex, nsCycleCollectionTrave static void HTMLFrameElement_unlink(DispatchEx *dispex) { HTMLFrameElement *This = frame_from_DispatchEx(dispex); - HTMLDOMNode_unlink(dispex); + HTMLFrameBase_unlink(&This->framebase); unlink_ref(&This->framebase.nsframe); }
-static void HTMLFrameElement_destructor(DispatchEx *dispex) -{ - HTMLFrameElement *This = frame_from_DispatchEx(dispex); - - HTMLFrameBase_destructor(&This->framebase); -} - static HRESULT HTMLFrameElement_get_dispid(DispatchEx *dispex, BSTR name, DWORD grfdex, DISPID *dispid) { HTMLFrameElement *This = frame_from_DispatchEx(dispex); @@ -1015,7 +1018,7 @@ static const event_target_vtbl_t HTMLFrameElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, .query_interface= HTMLFrameElement_query_interface, - .destructor = HTMLFrameElement_destructor, + .destructor = HTMLElement_destructor, .traverse = HTMLFrameElement_traverse, .unlink = HTMLFrameElement_unlink, .get_dispid = HTMLFrameElement_get_dispid, @@ -1534,7 +1537,7 @@ static void *HTMLIFrame_query_interface(DispatchEx *dispex, REFIID riid) static void HTMLIFrame_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) { HTMLIFrame *This = iframe_from_DispatchEx(dispex); - HTMLDOMNode_traverse(dispex, cb); + HTMLFrameBase_traverse(&This->framebase, cb);
if(This->framebase.nsiframe) note_cc_edge((nsISupports*)This->framebase.nsiframe, "nsiframe", cb); @@ -1543,17 +1546,10 @@ static void HTMLIFrame_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCa static void HTMLIFrame_unlink(DispatchEx *dispex) { HTMLIFrame *This = iframe_from_DispatchEx(dispex); - HTMLDOMNode_unlink(dispex); + HTMLFrameBase_unlink(&This->framebase); unlink_ref(&This->framebase.nsiframe); }
-static void HTMLIFrame_destructor(DispatchEx *dispex) -{ - HTMLIFrame *This = iframe_from_DispatchEx(dispex); - - HTMLFrameBase_destructor(&This->framebase); -} - static HRESULT HTMLIFrame_get_dispid(DispatchEx *dispex, BSTR name, DWORD grfdex, DISPID *dispid) { HTMLIFrame *This = iframe_from_DispatchEx(dispex); @@ -1605,7 +1601,7 @@ static const event_target_vtbl_t HTMLIFrame_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES, .query_interface= HTMLIFrame_query_interface, - .destructor = HTMLIFrame_destructor, + .destructor = HTMLElement_destructor, .traverse = HTMLIFrame_traverse, .unlink = HTMLIFrame_unlink, .get_dispid = HTMLIFrame_get_dispid, diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 4afa434ad27..9222a349749 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -4336,6 +4336,8 @@ static nsresult NSAPI outer_window_traverse(void *ccp, void *p, nsCycleCollectio note_cc_edge((nsISupports*)&window->parent->base.IHTMLWindow2_iface, "parent", cb); if(window->location) note_cc_edge((nsISupports*)&window->location->IHTMLLocation_iface, "location", cb); + if(window->frame_element) + note_cc_edge((nsISupports*)&window->frame_element->element.node.IHTMLDOMNode_iface, "frame_element", cb); if(window->nswindow) note_cc_edge((nsISupports*)window->nswindow, "nswindow", cb); if(window->window_proxy) @@ -4374,8 +4376,9 @@ static nsresult NSAPI outer_window_unlink(void *p) IHTMLLocation_Release(&location->IHTMLLocation_iface); } if(window->frame_element) { - window->frame_element->content_window = NULL; + HTMLFrameBase *frame_element = window->frame_element; window->frame_element = NULL; + IHTMLDOMNode_Release(&frame_element->element.node.IHTMLDOMNode_iface); } unlink_ref(&window->nswindow); if(window->window_proxy) {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlimg.c | 31 +++++++++++++++++++++++-------- dlls/mshtml/htmlwindow.c | 1 - 2 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index cf69b62e744..07ce5643ad1 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -846,7 +846,7 @@ static HRESULT WINAPI HTMLImageElementFactory_create(IHTMLImageElementFactory *i VARIANT width, VARIANT height, IHTMLImgElement **img_elem) { HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface); - HTMLDocumentNode *doc; + HTMLDocumentNode *doc = This->window->doc; IHTMLImgElement *img; HTMLElement *elem; nsIDOMElement *nselem; @@ -856,13 +856,6 @@ static HRESULT WINAPI HTMLImageElementFactory_create(IHTMLImageElementFactory *i TRACE("(%p)->(%s %s %p)\n", This, debugstr_variant(&width), debugstr_variant(&height), img_elem);
- if(!This->window || !This->window->doc) { - WARN("NULL doc\n"); - return E_UNEXPECTED; - } - - doc = This->window->doc; - *img_elem = NULL;
hres = create_nselem(doc, L"IMG", &nselem); @@ -921,6 +914,25 @@ static void *HTMLImageElementFactory_query_interface(DispatchEx *dispex, REFIID return NULL; }
+static void HTMLImageElementFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLImageElementFactory_unlink(DispatchEx *dispex) +{ + HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); + + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void HTMLImageElementFactory_destructor(DispatchEx *dispex) { HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); @@ -963,6 +975,8 @@ static const tid_t HTMLImageElementFactory_iface_tids[] = { static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = { .query_interface = HTMLImageElementFactory_query_interface, .destructor = HTMLImageElementFactory_destructor, + .traverse = HTMLImageElementFactory_traverse, + .unlink = HTMLImageElementFactory_unlink, .value = HTMLImageElementFactory_value, };
@@ -983,6 +997,7 @@ HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow *window, HTMLImageElement
ret->IHTMLImageElementFactory_iface.lpVtbl = &HTMLImageElementFactoryVtbl; ret->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
init_dispatch(&ret->dispex, &HTMLImageElementFactory_dispex, dispex_compat_mode(&window->event_target.dispex));
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 9222a349749..a0512557918 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3979,7 +3979,6 @@ static void HTMLWindow_unlink(DispatchEx *dispex)
if(This->image_factory) { HTMLImageElementFactory *image_factory = This->image_factory; - This->image_factory->window = NULL; This->image_factory = NULL; IHTMLImageElementFactory_Release(&image_factory->IHTMLImageElementFactory_iface); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlselect.c | 27 ++++++++++++++++++++++----- dlls/mshtml/htmlwindow.c | 1 - 2 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index 2daed7e8b2c..1b867195595 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -491,11 +491,6 @@ static HRESULT WINAPI HTMLOptionElementFactory_create(IHTMLOptionElementFactory TRACE("(%p)->(%s %s %s %s %p)\n", This, debugstr_variant(&text), debugstr_variant(&value), debugstr_variant(&defaultselected), debugstr_variant(&selected), optelem);
- if(!This->window || !This->window->doc) { - WARN("NULL doc\n"); - return E_UNEXPECTED; - } - *optelem = NULL;
hres = create_nselem(This->window->doc, L"OPTION", &nselem); @@ -555,6 +550,25 @@ static void *HTMLOptionElementFactory_query_interface(DispatchEx *dispex, REFIID return NULL; }
+static void HTMLOptionElementFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLOptionElementFactory_unlink(DispatchEx *dispex) +{ + HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); + + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void HTMLOptionElementFactory_destructor(DispatchEx *dispex) { HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); @@ -601,6 +615,8 @@ static const tid_t HTMLOptionElementFactory_iface_tids[] = { static const dispex_static_data_vtbl_t HTMLOptionElementFactory_dispex_vtbl = { .query_interface = HTMLOptionElementFactory_query_interface, .destructor = HTMLOptionElementFactory_destructor, + .traverse = HTMLOptionElementFactory_traverse, + .unlink = HTMLOptionElementFactory_unlink, .value = HTMLOptionElementFactory_value, };
@@ -621,6 +637,7 @@ HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow *window, HTMLOptionEleme
ret->IHTMLOptionElementFactory_iface.lpVtbl = &HTMLOptionElementFactoryVtbl; ret->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
init_dispatch(&ret->dispex, &HTMLOptionElementFactory_dispex, dispex_compat_mode(&window->event_target.dispex));
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index a0512557918..91941439ecd 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3984,7 +3984,6 @@ static void HTMLWindow_unlink(DispatchEx *dispex) } if(This->option_factory) { HTMLOptionElementFactory *option_factory = This->option_factory; - This->option_factory->window = NULL; This->option_factory = NULL; IHTMLOptionElementFactory_Release(&option_factory->IHTMLOptionElementFactory_iface); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 1 - dlls/mshtml/xmlhttprequest.c | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 91941439ecd..90a5ca9560e 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3989,7 +3989,6 @@ static void HTMLWindow_unlink(DispatchEx *dispex) } if(This->xhr_factory) { HTMLXMLHttpRequestFactory *xhr_factory = This->xhr_factory; - This->xhr_factory->window = NULL; This->xhr_factory = NULL; IHTMLXMLHttpRequestFactory_Release(&xhr_factory->IHTMLXMLHttpRequestFactory_iface); } diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 44f83dd8809..8fd0d9e1325 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -1768,6 +1768,25 @@ static void *HTMLXMLHttpRequestFactory_query_interface(DispatchEx *dispex, REFII return NULL; }
+static void HTMLXMLHttpRequestFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLXMLHttpRequestFactory_unlink(DispatchEx *dispex) +{ + HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); + + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void HTMLXMLHttpRequestFactory_destructor(DispatchEx *dispex) { HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); @@ -1800,6 +1819,8 @@ static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WOR static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl = { .query_interface = HTMLXMLHttpRequestFactory_query_interface, .destructor = HTMLXMLHttpRequestFactory_destructor, + .traverse = HTMLXMLHttpRequestFactory_traverse, + .unlink = HTMLXMLHttpRequestFactory_unlink, .value = HTMLXMLHttpRequestFactory_value };
@@ -1824,6 +1845,7 @@ HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpReq
ret->IHTMLXMLHttpRequestFactory_iface.lpVtbl = &HTMLXMLHttpRequestFactoryVtbl; ret->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
init_dispatch(&ret->dispex, &HTMLXMLHttpRequestFactory_dispex, dispex_compat_mode(&window->event_target.dispex));
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstorage.c | 30 ++++++++++++++++++++++-------- dlls/mshtml/htmlwindow.c | 2 -- dlls/mshtml/mshtml_private.h | 2 -- 3 files changed, 22 insertions(+), 12 deletions(-)
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index d3bbb30580e..efd4b2d88ae 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -322,8 +322,6 @@ static HRESULT send_storage_event(HTMLStorage *storage, BSTR key, BSTR old_value HRESULT hres = S_OK;
ctx.url = NULL; - if(!window) - goto done; if(window->base.outer_window->uri_nofrag) { hres = IUri_GetDisplayUri(window->base.outer_window->uri_nofrag, &ctx.url); if(hres != S_OK) @@ -1041,6 +1039,25 @@ static void *HTMLStorage_query_interface(DispatchEx *dispex, REFIID riid) return NULL; }
+static void HTMLStorage_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + HTMLStorage *This = impl_from_DispatchEx(dispex); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void HTMLStorage_unlink(DispatchEx *dispex) +{ + HTMLStorage *This = impl_from_DispatchEx(dispex); + + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void HTMLStorage_destructor(DispatchEx *dispex) { HTMLStorage *This = impl_from_DispatchEx(dispex); @@ -1298,6 +1315,8 @@ static HRESULT HTMLStorage_next_dispid(DispatchEx *dispex, DISPID id, DISPID *pi static const dispex_static_data_vtbl_t HTMLStorage_dispex_vtbl = { .query_interface = HTMLStorage_query_interface, .destructor = HTMLStorage_destructor, + .traverse = HTMLStorage_traverse, + .unlink = HTMLStorage_unlink, .get_dispid = HTMLStorage_get_dispid, .get_name = HTMLStorage_get_name, .invoke = HTMLStorage_invoke, @@ -1464,15 +1483,10 @@ HRESULT create_html_storage(HTMLInnerWindow *window, BOOL local, IHTMLStorage **
storage->IHTMLStorage_iface.lpVtbl = &HTMLStorageVtbl; storage->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
init_dispatch(&storage->dispex, &HTMLStorage_dispex, dispex_compat_mode(&window->event_target.dispex));
*p = &storage->IHTMLStorage_iface; return S_OK; } - -void detach_html_storage(IHTMLStorage *iface) -{ - HTMLStorage *storage = impl_from_IHTMLStorage(iface); - storage->window = NULL; -} diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 90a5ca9560e..afb16f36027 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -4003,13 +4003,11 @@ static void HTMLWindow_unlink(DispatchEx *dispex) unlink_ref(&This->navigator); if(This->session_storage) { IHTMLStorage *session_storage = This->session_storage; - detach_html_storage(session_storage); This->session_storage = NULL; IHTMLStorage_Release(session_storage); } if(This->local_storage) { IHTMLStorage *local_storage = This->local_storage; - detach_html_storage(local_storage); This->local_storage = NULL; IHTMLStorage_Release(local_storage); } diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 7515fbfd2cd..504504dd1d4 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -998,9 +998,7 @@ HRESULT create_history(HTMLInnerWindow*,OmHistory**); HRESULT create_namespace_collection(compat_mode_t,IHTMLNamespaceCollection**); HRESULT create_dom_implementation(HTMLDocumentNode*,IHTMLDOMImplementation**); void detach_dom_implementation(IHTMLDOMImplementation*); - HRESULT create_html_storage(HTMLInnerWindow*,BOOL,IHTMLStorage**); -void detach_html_storage(IHTMLStorage*);
void HTMLDocument_View_Init(HTMLDocumentObj*); void HTMLDocumentObj_Persist_Init(HTMLDocumentObj*);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlwindow.c | 1 - dlls/mshtml/omnavigator.c | 24 +++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index afb16f36027..a6d10184459 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3996,7 +3996,6 @@ static void HTMLWindow_unlink(DispatchEx *dispex) unlink_ref(&This->screen); if(This->history) { OmHistory *history = This->history; - This->history->window = NULL; This->history = NULL; IOmHistory_Release(&history->IOmHistory_iface); } diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 58cd0c78fb2..db7da8276ef 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -644,7 +644,7 @@ static HRESULT WINAPI OmHistory_get_length(IOmHistory *iface, short *p)
TRACE("(%p)->(%p)\n", This, p);
- if(This->window && This->window->base.outer_window) + if(This->window->base.outer_window) browser = This->window->base.outer_window->browser;
*p = browser && browser->doc->travel_log @@ -703,6 +703,25 @@ static void *OmHistory_query_interface(DispatchEx *dispex, REFIID riid) return NULL; }
+static void OmHistory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + OmHistory *This = OmHistory_from_DispatchEx(dispex); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +static void OmHistory_unlink(DispatchEx *dispex) +{ + OmHistory *This = OmHistory_from_DispatchEx(dispex); + + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + static void OmHistory_destructor(DispatchEx *dispex) { OmHistory *This = OmHistory_from_DispatchEx(dispex); @@ -712,6 +731,8 @@ static void OmHistory_destructor(DispatchEx *dispex) static const dispex_static_data_vtbl_t OmHistory_dispex_vtbl = { .query_interface = OmHistory_query_interface, .destructor = OmHistory_destructor, + .traverse = OmHistory_traverse, + .unlink = OmHistory_unlink, };
static const tid_t OmHistory_iface_tids[] = { @@ -738,6 +759,7 @@ HRESULT create_history(HTMLInnerWindow *window, OmHistory **ret) history->IOmHistory_iface.lpVtbl = &OmHistoryVtbl;
history->window = window; + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
*ret = history; return S_OK;
Removing weak references is questionable in some of those cases. We're not in an environment fully controlled by cycle collector, those objects are exposed as regular COM objects. Even making cycle collector aware of JS objects will not change that. I think it's fine for some simple cases like constructors, for which it's unlikely to matter. But things like parent window reference would need a strong argument to change, IMHO.
On Tue Oct 31 13:42:24 2023 +0000, Jacek Caban wrote:
Removing weak references is questionable in some of those cases. We're not in an environment fully controlled by cycle collector, those objects are exposed as regular COM objects. Even making cycle collector aware of JS objects will not change that. I think it's fine for some simple cases like constructors, for which it's unlikely to matter. But things like parent window reference would need a strong argument to change, IMHO.
I see. I wanted to keep it consistent with the rest, and also to get rid of semi hacks like in `set_frame_doc`. That said I'm also a bit worried it feels somewhat arbitrary, although it doesn't matter if it's an implementation detail only, so I'll see if I can find a way to test these and see what happens… otherwise I'll get rid of it.
Note that some things are actually tested to work by being detached, like the navigator's `mimeTypes` or `plugins`, so who knows.