From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/htmlwindow.c | 12 +++++++++++- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/range.c | 7 ++++++- 3 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 11c7c6d892d..fc0a03e3bf8 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3955,6 +3955,8 @@ static void HTMLWindow_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCa 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(This->dom_window) + note_cc_edge((nsISupports*)This->dom_window, "dom_window", cb); traverse_variant(&This->performance, "performance", cb); }
@@ -4009,6 +4011,7 @@ static void HTMLWindow_unlink(DispatchEx *dispex) IHTMLStorage_Release(local_storage); } unlink_variant(&This->performance); + unlink_ref(&This->dom_window); }
static void HTMLWindow_destructor(DispatchEx *dispex) @@ -4523,11 +4526,12 @@ HRESULT update_window_doc(HTMLInnerWindow *window) { HTMLOuterWindow *outer_window = window->base.outer_window; compat_mode_t parent_mode = COMPAT_MODE_QUIRKS; + mozIDOMWindow *gecko_inner_window; nsIDOMDocument *nsdoc; nsresult nsres; HRESULT hres;
- assert(!window->doc); + assert(!window->doc && !window->dom_window);
if(!outer_window) return E_UNEXPECTED; @@ -4538,6 +4542,12 @@ HRESULT update_window_doc(HTMLInnerWindow *window) return E_FAIL; }
+ nsres = nsIDOMWindow_GetInnerWindow(outer_window->nswindow, &gecko_inner_window); + assert(nsres == NS_OK); + nsres = mozIDOMWindow_QueryInterface(gecko_inner_window, &IID_nsIDOMWindow, (void **)&window->dom_window); + assert(nsres == NS_OK); + mozIDOMWindow_Release(gecko_inner_window); + if(outer_window->parent) parent_mode = outer_window->parent->base.inner_window->doc->document_mode;
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 23e1decc68b..40dcb0ebfab 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -580,6 +580,7 @@ struct HTMLInnerWindow { EventTarget event_target;
HTMLDocumentNode *doc; + nsIDOMWindow *dom_window;
struct list children; struct list script_hosts; diff --git a/dlls/mshtml/range.c b/dlls/mshtml/range.c index 738818d93fb..e9b0b0edfef 100644 --- a/dlls/mshtml/range.c +++ b/dlls/mshtml/range.c @@ -1287,7 +1287,12 @@ static HRESULT WINAPI HTMLTxtRange_select(IHTMLTxtRange *iface)
TRACE("(%p)\n", This);
- nsres = nsIDOMWindow_GetSelection(This->doc->outer_window->nswindow, &nsselection); + if(!This->doc->window) { + FIXME("no window\n"); + return E_FAIL; + } + + nsres = nsIDOMWindow_GetSelection(This->doc->window->dom_window, &nsselection); if(NS_FAILED(nsres)) { ERR("GetSelection failed: %08lx\n", nsres); return E_FAIL;
From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/tests/events.c | 1 - dlls/mshtml/xmlhttprequest.c | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-)
diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index e5b9984e546..8d5b2f671a8 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -3304,7 +3304,6 @@ static void test_window_refs(IHTMLDocument2 *doc) IHTMLWindow2_Release(child);
hres = IHTMLXMLHttpRequestFactory_create(xhr_factory, &xhr); - todo_wine ok(hres == S_OK, "create failed: %08lx\n", hres); IHTMLXMLHttpRequestFactory_Release(xhr_factory); if(hres == S_OK) IHTMLXMLHttpRequest_Release(xhr); diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 20049a13ee7..5314e5a15cb 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -1686,10 +1686,7 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor
TRACE("(%p)->(%p)\n", This, p);
- if(!This->window->base.outer_window) - return E_FAIL; - - nsxhr = create_nsxhr(This->window->base.outer_window->nswindow); + nsxhr = create_nsxhr(This->window->dom_window); if(!nsxhr) return E_FAIL;
From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/editor.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/editor.c b/dlls/mshtml/editor.c index 478c30932c1..e4a16956e46 100644 --- a/dlls/mshtml/editor.c +++ b/dlls/mshtml/editor.c @@ -203,7 +203,10 @@ static nsISelection *get_ns_selection(HTMLDocumentNode *doc) nsISelection *nsselection = NULL; nsresult nsres;
- nsres = nsIDOMWindow_GetSelection(doc->outer_window->nswindow, &nsselection); + if(!doc->window) + return NULL; + + nsres = nsIDOMWindow_GetSelection(doc->window->dom_window, &nsselection); if(NS_FAILED(nsres)) ERR("GetSelection failed %08lx\n", nsres);
From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/olecmd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/olecmd.c b/dlls/mshtml/olecmd.c index 27690b44e79..76ed84341cf 100644 --- a/dlls/mshtml/olecmd.c +++ b/dlls/mshtml/olecmd.c @@ -69,7 +69,10 @@ static nsIClipboardCommands *get_clipboard_commands(HTMLDocumentNode *doc) nsIDocShell *doc_shell; nsresult nsres;
- nsres = get_nsinterface((nsISupports*)doc->outer_window->nswindow, &IID_nsIDocShell, (void**)&doc_shell); + if(!doc->window) + return NULL; + + nsres = get_nsinterface((nsISupports*)doc->window->dom_window, &IID_nsIDocShell, (void**)&doc_shell); if(NS_FAILED(nsres)) { ERR("Could not get nsIDocShell interface\n"); return NULL;
Gabriel Ivăncescu (@insn) commented about dlls/mshtml/tests/events.c:
IHTMLWindow2_Release(child); hres = IHTMLXMLHttpRequestFactory_create(xhr_factory, &xhr);
- todo_wine ok(hres == S_OK, "create failed: %08lx\n", hres); IHTMLXMLHttpRequestFactory_Release(xhr_factory); if(hres == S_OK) IHTMLXMLHttpRequest_Release(xhr);
Just a small nitpick, I'd remove this `if(hres == S_OK)` here, since it shouldn't fail now.
Other than that LGTM. I also tested it for leaks because I'm paranoid.
I found one interesting bit on native, that's probably not important for us, but seeing as I wasted time testing it I want to share it. Looks like native XHR keeps a dangling ref to the outer window and crashes in `create` if outer window is dead (not with a NULL, but actual invalid memory access on freed memory). But not important to replicate. Thankfully the current test keeps it alive so it's not flaky.
This merge request was approved by Gabriel Ivăncescu.