Module: wine Branch: master Commit: 7f85937158f82bc508aad60d4a27cf3780bb22a5 URL: https://gitlab.winehq.org/wine/wine/-/commit/7f85937158f82bc508aad60d4a27cf3...
Author: Gabriel Ivăncescu gabrielopcode@gmail.com Date: Wed Nov 1 17:00:40 2023 +0200
mshtml: Keep ref from the OptionElementFactory to the inner window.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
---
dlls/mshtml/htmlselect.c | 27 ++++++++++++++++++++++----- dlls/mshtml/htmlwindow.c | 1 - dlls/mshtml/tests/events.c | 10 ++++++++++ 3 files changed, 32 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 3e08a90d5fc..85794b7fe85 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3982,7 +3982,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); } diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 515a2cf443c..0ccb892603a 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -3236,8 +3236,10 @@ static void test_iframe_connections(IHTMLDocument2 *doc)
static void test_window_refs(IHTMLDocument2 *doc) { + IHTMLOptionElementFactory *option_factory; IHTMLImageElementFactory *image_factory; IHTMLWindow2 *self, *parent, *child; + IHTMLOptionElement *option_elem; IHTMLImgElement *img_elem; IHTMLFrameBase2 *iframe; IHTMLDocument6 *doc6; @@ -3265,6 +3267,8 @@ static void test_window_refs(IHTMLDocument2 *doc)
hres = IHTMLWindow2_get_Image(window, &image_factory); ok(hres == S_OK, "get_Image failed: %08lx\n", hres); + hres = IHTMLWindow2_get_Option(window, &option_factory); + ok(hres == S_OK, "get_Option failed: %08lx\n", hres);
hres = IHTMLWindow2_get_self(window, &self); ok(hres == S_OK, "get_self failed: %08lx\n", hres); @@ -3287,6 +3291,12 @@ static void test_window_refs(IHTMLDocument2 *doc) ok(img_elem != NULL, "img_elem == NULL\n"); IHTMLImageElementFactory_Release(image_factory); IHTMLImgElement_Release(img_elem); + + hres = IHTMLOptionElementFactory_create(option_factory, vempty, vempty, vempty, vempty, &option_elem); + ok(hres == S_OK, "create failed: %08lx\n", hres); + ok(option_elem != NULL, "option_elem == NULL\n"); + IHTMLOptionElementFactory_Release(option_factory); + IHTMLOptionElement_Release(option_elem); }
static void test_doc_obj(IHTMLDocument2 *doc)