Commit 110dad9c authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Set outer window to uninitialized page when document obj is released.

parent 9afcf7c8
...@@ -6196,7 +6196,7 @@ HRESULT create_document_node(nsIDOMDocument *nsdoc, GeckoBrowser *browser, HTMLI ...@@ -6196,7 +6196,7 @@ HRESULT create_document_node(nsIDOMDocument *nsdoc, GeckoBrowser *browser, HTMLI
lock_document_mode(doc); lock_document_mode(doc);
} }
if(!doc_obj->window || (window && is_main_content_window(window->base.outer_window))) if(doc_obj && (!doc_obj->window || (window && is_main_content_window(window->base.outer_window))))
doc->cp_container.forward_container = &doc_obj->cp_container; doc->cp_container.forward_container = &doc_obj->cp_container;
/* Share reference with HTMLDOMNode */ /* Share reference with HTMLDOMNode */
......
...@@ -2906,7 +2906,7 @@ static HRESULT WINAPI HTMLPrivateWindow_GetAddressBarUrl(IHTMLPrivateWindow *ifa ...@@ -2906,7 +2906,7 @@ static HRESULT WINAPI HTMLPrivateWindow_GetAddressBarUrl(IHTMLPrivateWindow *ifa
if(!url) if(!url)
return E_INVALIDARG; return E_INVALIDARG;
*url = SysAllocString(This->outer_window->url); *url = SysAllocString(This->outer_window->url ? This->outer_window->url : L"about:blank");
return S_OK; return S_OK;
} }
...@@ -4564,11 +4564,13 @@ HRESULT update_window_doc(HTMLInnerWindow *window) ...@@ -4564,11 +4564,13 @@ HRESULT update_window_doc(HTMLInnerWindow *window)
if(is_main_content_window(outer_window) || !outer_window->browser->content_window) { if(is_main_content_window(outer_window) || !outer_window->browser->content_window) {
HTMLDocumentObj *doc_obj = outer_window->browser->doc; HTMLDocumentObj *doc_obj = outer_window->browser->doc;
if(doc_obj) {
if(doc_obj->doc_node) if(doc_obj->doc_node)
IHTMLDOMNode_Release(&doc_obj->doc_node->node.IHTMLDOMNode_iface); IHTMLDOMNode_Release(&doc_obj->doc_node->node.IHTMLDOMNode_iface);
doc_obj->doc_node = window->doc; doc_obj->doc_node = window->doc;
IHTMLDOMNode_AddRef(&window->doc->node.IHTMLDOMNode_iface); IHTMLDOMNode_AddRef(&window->doc->node.IHTMLDOMNode_iface);
} }
}
return hres; return hres;
} }
...@@ -1012,7 +1012,8 @@ static HRESULT on_start_nsrequest(nsChannelBSC *This) ...@@ -1012,7 +1012,8 @@ static HRESULT on_start_nsrequest(nsChannelBSC *This)
if(This->bsc.binding) if(This->bsc.binding)
process_document_response_headers(This->bsc.window->doc, This->bsc.binding); process_document_response_headers(This->bsc.window->doc, This->bsc.binding);
if(This->bsc.window->base.outer_window->readystate != READYSTATE_LOADING) if(This->bsc.window->base.outer_window->readystate != READYSTATE_LOADING &&
This->bsc.window->base.outer_window->browser->doc)
set_ready_state(This->bsc.window->base.outer_window, READYSTATE_LOADING); set_ready_state(This->bsc.window->base.outer_window, READYSTATE_LOADING);
} }
...@@ -1370,7 +1371,7 @@ static HRESULT nsChannelBSC_init_bindinfo(BSCallback *bsc) ...@@ -1370,7 +1371,7 @@ static HRESULT nsChannelBSC_init_bindinfo(BSCallback *bsc)
HRESULT hres; HRESULT hres;
if(This->is_doc_channel && This->bsc.window && This->bsc.window->base.outer_window if(This->is_doc_channel && This->bsc.window && This->bsc.window->base.outer_window
&& (browser = This->bsc.window->base.outer_window->browser)) { && (browser = This->bsc.window->base.outer_window->browser) && browser->doc) {
if(browser->doc->hostinfo.dwFlags & DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION) if(browser->doc->hostinfo.dwFlags & DOCHOSTUIFLAG_ENABLE_REDIRECT_NOTIFICATION)
This->bsc.bindinfo_options |= BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS; This->bsc.bindinfo_options |= BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS;
} }
......
...@@ -208,6 +208,8 @@ static nsresult handle_focus(HTMLDocumentNode *doc, nsIDOMEvent *event) ...@@ -208,6 +208,8 @@ static nsresult handle_focus(HTMLDocumentNode *doc, nsIDOMEvent *event)
TRACE("(%p)\n", doc); TRACE("(%p)\n", doc);
if(!doc->doc_obj)
return NS_ERROR_FAILURE;
doc_obj = doc->doc_obj; doc_obj = doc->doc_obj;
if(!doc_obj->focus) { if(!doc_obj->focus) {
...@@ -220,7 +222,7 @@ static nsresult handle_focus(HTMLDocumentNode *doc, nsIDOMEvent *event) ...@@ -220,7 +222,7 @@ static nsresult handle_focus(HTMLDocumentNode *doc, nsIDOMEvent *event)
static nsresult handle_keypress(HTMLDocumentNode *doc, nsIDOMEvent *event) static nsresult handle_keypress(HTMLDocumentNode *doc, nsIDOMEvent *event)
{ {
if(!doc->browser) if(!doc->browser || !doc->browser->doc)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
TRACE("(%p)->(%p)\n", doc, event); TRACE("(%p)->(%p)\n", doc, event);
...@@ -391,7 +393,7 @@ static nsresult handle_beforeunload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent) ...@@ -391,7 +393,7 @@ static nsresult handle_beforeunload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent)
DOMEvent *event; DOMEvent *event;
HRESULT hres; HRESULT hres;
if(!(window = doc->window)) if(!(window = doc->window) || doc->unload_sent)
return NS_OK; return NS_OK;
/* Gecko dispatches this to the document, but IE dispatches it to the window */ /* Gecko dispatches this to the document, but IE dispatches it to the window */
......
...@@ -1082,7 +1082,7 @@ static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListen ...@@ -1082,7 +1082,7 @@ static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListen
TRACE("canceled\n"); TRACE("canceled\n");
nsres = NS_BINDING_ABORTED; nsres = NS_BINDING_ABORTED;
} }
}else if(window->browser->doc->mime) { }else if(window->browser->doc && window->browser->doc->mime) {
free(This->content_type); free(This->content_type);
This->content_type = strdupWtoA(window->browser->doc->mime); This->content_type = strdupWtoA(window->browser->doc->mime);
} }
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "mshtml_private.h" #include "mshtml_private.h"
#include "htmlevent.h" #include "htmlevent.h"
#include "binding.h"
WINE_DEFAULT_DEBUG_CHANNEL(mshtml); WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
...@@ -2079,8 +2080,10 @@ void HTMLDocumentNode_OleObj_Init(HTMLDocumentNode *This) ...@@ -2079,8 +2080,10 @@ void HTMLDocumentNode_OleObj_Init(HTMLDocumentNode *This)
This->IObjectWithSite_iface.lpVtbl = &DocNodeObjectWithSiteVtbl; This->IObjectWithSite_iface.lpVtbl = &DocNodeObjectWithSiteVtbl;
This->IOleContainer_iface.lpVtbl = &DocNodeOleContainerVtbl; This->IOleContainer_iface.lpVtbl = &DocNodeOleContainerVtbl;
This->IObjectSafety_iface.lpVtbl = &DocNodeObjectSafetyVtbl; This->IObjectSafety_iface.lpVtbl = &DocNodeObjectSafetyVtbl;
if(This->doc_obj) {
This->doc_obj->extent.cx = 1; This->doc_obj->extent.cx = 1;
This->doc_obj->extent.cy = 1; This->doc_obj->extent.cy = 1;
}
} }
static void HTMLDocumentObj_OleObj_Init(HTMLDocumentObj *This) static void HTMLDocumentObj_OleObj_Init(HTMLDocumentObj *This)
...@@ -3403,6 +3406,60 @@ static ULONG WINAPI HTMLDocumentObj_AddRef(IUnknown *iface) ...@@ -3403,6 +3406,60 @@ static ULONG WINAPI HTMLDocumentObj_AddRef(IUnknown *iface)
return ref; return ref;
} }
static void set_window_uninitialized(HTMLOuterWindow *window)
{
nsChannelBSC *channelbsc;
nsWineURI *nsuri;
IMoniker *mon;
HRESULT hres;
IUri *uri;
window->readystate = READYSTATE_UNINITIALIZED;
set_current_uri(window, NULL);
if(window->mon) {
IMoniker_Release(window->mon);
window->mon = NULL;
}
if(!window->base.inner_window)
return;
hres = create_uri(L"about:blank", 0, &uri);
if(FAILED(hres))
return;
hres = create_doc_uri(uri, &nsuri);
IUri_Release(uri);
if(FAILED(hres))
return;
hres = CreateURLMoniker(NULL, L"about:blank", &mon);
if(SUCCEEDED(hres)) {
hres = create_channelbsc(mon, NULL, NULL, 0, TRUE, &channelbsc);
IMoniker_Release(mon);
if(SUCCEEDED(hres)) {
channelbsc->bsc.bindf = 0; /* synchronous binding */
if(window->base.inner_window->doc)
remove_target_tasks(window->base.inner_window->task_magic);
abort_window_bindings(window->base.inner_window);
window->base.inner_window->doc->unload_sent = TRUE;
hres = load_nsuri(window, nsuri, NULL, channelbsc, LOAD_FLAGS_BYPASS_CACHE);
if(SUCCEEDED(hres))
hres = create_pending_window(window, channelbsc);
IBindStatusCallback_Release(&channelbsc->bsc.IBindStatusCallback_iface);
}
}
nsISupports_Release((nsISupports*)nsuri);
if(FAILED(hres))
return;
window->load_flags |= BINDING_REPLACE;
start_binding(window->pending_window, &window->pending_window->bscallback->bsc, NULL);
}
static ULONG WINAPI HTMLDocumentObj_Release(IUnknown *iface) static ULONG WINAPI HTMLDocumentObj_Release(IUnknown *iface)
{ {
HTMLDocumentObj *This = impl_from_IUnknown(iface); HTMLDocumentObj *This = impl_from_IUnknown(iface);
...@@ -3412,8 +3469,15 @@ static ULONG WINAPI HTMLDocumentObj_Release(IUnknown *iface) ...@@ -3412,8 +3469,15 @@ static ULONG WINAPI HTMLDocumentObj_Release(IUnknown *iface)
if(!ref) { if(!ref) {
if(This->doc_node) { if(This->doc_node) {
This->doc_node->doc_obj = NULL; HTMLDocumentNode *doc_node = This->doc_node;
IHTMLDOMNode_Release(&This->doc_node->node.IHTMLDOMNode_iface);
if(This->nscontainer)
This->nscontainer->doc = NULL;
This->doc_node = NULL;
doc_node->doc_obj = NULL;
set_window_uninitialized(This->window);
IHTMLDOMNode_Release(&doc_node->node.IHTMLDOMNode_iface);
} }
if(This->window) if(This->window)
IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface);
......
...@@ -5999,6 +5999,151 @@ static void test_empty_document(void) ...@@ -5999,6 +5999,151 @@ static void test_empty_document(void)
IHTMLDocument2_Release(doc); IHTMLDocument2_Release(doc);
} }
static void test_document_close(void)
{
IHTMLPrivateWindow *priv_window;
IHTMLDocument2 *doc, *doc_node;
IHTMLDocument3 *doc3;
IHTMLElement *elem;
DWORD cookie;
HRESULT hres;
VARIANT v;
BSTR bstr;
LONG ref;
MSG msg;
doc = create_document_with_origin(input_doc_str);
if(!doc)
return;
hres = IHTMLDocument2_get_parentWindow(doc, &window);
ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres);
hres = IHTMLWindow2_get_document(window, &doc_node);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLPrivateWindow, (void**)&priv_window);
ok(hres == S_OK, "Could not get IHTMLPrivateWindow) interface: %08lx\n", hres);
hres = IHTMLPrivateWindow_GetAddressBarUrl(priv_window, &bstr);
ok(hres == S_OK, "GetAddressBarUrl failed: %08lx\n", hres);
ok(!wcscmp(bstr, L"http://winetest.example.org/"), "unexpected address bar: %s\n", wine_dbgstr_w(bstr));
IHTMLPrivateWindow_Release(priv_window);
SysFreeString(bstr);
elem = get_elem_id(doc_node, L"inputid");
IHTMLElement_Release(elem);
set_client_site(doc, FALSE);
IHTMLDocument2_Release(doc);
hres = IHTMLWindow2_get_document(window, &doc);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
ok(doc != doc_node, "doc == doc_node\n");
hres = IHTMLDocument2_get_readyState(doc_node, &bstr);
ok(hres == S_OK, "get_readyState failed: %08lx\n", hres);
ok(!wcscmp(bstr, L"uninitialized"), "readyState = %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
hres = IHTMLDocument2_get_readyState(doc, &bstr);
ok(hres == S_OK, "get_readyState failed: %08lx\n", hres);
ok(!wcscmp(bstr, L"uninitialized"), "readyState = %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLPrivateWindow, (void**)&priv_window);
ok(hres == S_OK, "Could not get IHTMLPrivateWindow) interface: %08lx\n", hres);
hres = IHTMLPrivateWindow_GetAddressBarUrl(priv_window, &bstr);
ok(hres == S_OK, "GetAddressBarUrl failed: %08lx\n", hres);
ok(!wcscmp(bstr, L"about:blank"), "unexpected address bar: %s\n", wine_dbgstr_w(bstr));
IHTMLPrivateWindow_Release(priv_window);
SysFreeString(bstr);
bstr = SysAllocString(L"inputid");
doc3 = get_doc3_iface((IUnknown*)doc);
hres = IHTMLDocument3_getElementById(doc3, bstr, &elem);
ok(hres == S_OK, "getElementById returned: %08lx\n", hres);
ok(elem == NULL, "elem != NULL\n");
IHTMLDocument3_Release(doc3);
SysFreeString(bstr);
IHTMLDocument2_Release(doc_node);
IHTMLDocument2_Release(doc);
IHTMLWindow2_Release(window);
window = NULL;
doc = create_document();
if(!doc)
return;
set_client_site(doc, TRUE);
hres = IHTMLDocument2_get_parentWindow(doc, &window);
ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres);
hres = IHTMLWindow2_get_document(window, &doc_node);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
set_client_site(doc, FALSE);
IHTMLDocument2_Release(doc);
hres = IHTMLWindow2_get_document(window, &doc);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
ok(doc != doc_node, "doc == doc_node\n");
IHTMLDocument2_Release(doc_node);
IHTMLDocument2_Release(doc);
IHTMLWindow2_Release(window);
window = NULL;
doc = create_document();
if(!doc)
return;
set_client_site(doc, TRUE);
hres = IHTMLDocument2_get_parentWindow(doc, &window);
ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres);
hres = IHTMLWindow2_get_document(window, &doc_node);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
doc_load_string(doc, empty_doc_ie9_str);
cookie = register_cp((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
while(!doc_complete && GetMessageA(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
unregister_cp((IUnknown*)doc, &IID_IPropertyNotifySink, cookie);
document_mode = 9;
V_VT(&v) = VT_DISPATCH;
V_DISPATCH(&v) = (IDispatch*)&onunload_obj;
hres = IHTMLWindow2_put_onunload(window, v);
ok(hres == S_OK, "put_onunload failed: %08lx\n", hres);
V_VT(&v) = VT_DISPATCH;
V_DISPATCH(&v) = (IDispatch*)&onbeforeunload_obj;
hres = IHTMLWindow2_put_onbeforeunload(window, v);
ok(hres == S_OK, "put_onbeforeunload failed: %08lx\n", hres);
IOleDocumentView_Release(view);
view = NULL;
ref = IHTMLDocument2_Release(doc);
ok(ref == 0, "ref = %ld\n", ref);
hres = IHTMLWindow2_get_document(window, &doc);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
ok(doc != doc_node, "doc == doc_node\n");
IHTMLDocument2_Release(doc_node);
IHTMLDocument2_Release(doc);
V_VT(&v) = VT_EMPTY;
IHTMLWindow2_put_onunload(window, v);
IHTMLWindow2_put_onbeforeunload(window, v);
IHTMLWindow2_Release(window);
window = NULL;
}
static void test_storage_events(const char *doc_str) static void test_storage_events(const char *doc_str)
{ {
static struct { static struct {
...@@ -6372,6 +6517,9 @@ START_TEST(events) ...@@ -6372,6 +6517,9 @@ START_TEST(events)
test_sync_xhr_events(empty_doc_ie9_str); test_sync_xhr_events(empty_doc_ie9_str);
} }
/* Test this last since it doesn't close the view properly. */
test_document_close();
DestroyWindow(container_hwnd); DestroyWindow(container_hwnd);
}else { }else {
#if !defined(__i386__) && !defined(__x86_64__) #if !defined(__i386__) && !defined(__x86_64__)
......
...@@ -8461,10 +8461,12 @@ static void test_doc_domain(IHTMLDocument2 *doc) ...@@ -8461,10 +8461,12 @@ static void test_doc_domain(IHTMLDocument2 *doc)
static void test_HTMLDocument_http(BOOL with_wbapp) static void test_HTMLDocument_http(BOOL with_wbapp)
{ {
IHTMLDocument2 *doc, *doc_node;
IHTMLWindow2 *window;
IMoniker *http_mon; IMoniker *http_mon;
IHTMLDocument2 *doc;
ULONG ref;
HRESULT hres; HRESULT hres;
ULONG ref;
BSTR bstr;
trace("Testing HTMLDocument (http%s)...\n", with_wbapp ? " with IWebBrowserApp" : ""); trace("Testing HTMLDocument (http%s)...\n", with_wbapp ? " with IWebBrowserApp" : "");
...@@ -8529,12 +8531,42 @@ static void test_HTMLDocument_http(BOOL with_wbapp) ...@@ -8529,12 +8531,42 @@ static void test_HTMLDocument_http(BOOL with_wbapp)
test_IsDirty(doc, S_FALSE); test_IsDirty(doc, S_FALSE);
test_GetCurMoniker((IUnknown*)doc, NULL, prev_url, support_wbapp); test_GetCurMoniker((IUnknown*)doc, NULL, prev_url, support_wbapp);
hres = IHTMLDocument2_get_parentWindow(doc, &window);
ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres);
hres = IHTMLWindow2_get_document(window, &doc_node);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
hres = IHTMLDocument2_get_readyState(doc_node, &bstr);
ok(hres == S_OK, "get_readyState failed: %08lx\n", hres);
todo_wine_if(support_wbapp)
ok(!wcscmp(bstr, support_wbapp ? L"interactive" : L"complete"), "readyState = %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
if(view) if(view)
IOleDocumentView_Release(view); IOleDocumentView_Release(view);
view = NULL; view = NULL;
release_document(doc); release_document(doc);
hres = IHTMLWindow2_get_document(window, &doc);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
ok(doc != doc_node, "doc == doc_node\n");
hres = IHTMLDocument2_get_readyState(doc_node, &bstr);
ok(hres == S_OK, "get_readyState failed: %08lx\n", hres);
ok(!wcscmp(bstr, L"uninitialized"), "readyState = %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
hres = IHTMLDocument2_get_readyState(doc, &bstr);
ok(hres == S_OK, "get_readyState failed: %08lx\n", hres);
ok(!wcscmp(bstr, L"uninitialized"), "readyState = %s\n", wine_dbgstr_w(bstr));
SysFreeString(bstr);
IHTMLDocument2_Release(doc_node);
IHTMLDocument2_Release(doc);
IHTMLWindow2_Release(window);
ref = IMoniker_Release(http_mon); ref = IMoniker_Release(http_mon);
ok(!ref, "ref=%ld, expected 0\n", ref); ok(!ref, "ref=%ld, expected 0\n", ref);
} }
......
...@@ -4525,7 +4525,10 @@ static void test_exec_script(IHTMLDocument2 *doc, const WCHAR *codew, const WCHA ...@@ -4525,7 +4525,10 @@ static void test_exec_script(IHTMLDocument2 *doc, const WCHAR *codew, const WCHA
static void test_simple_script(void) static void test_simple_script(void)
{ {
IHTMLDocument2 *doc_node;
IHTMLWindow2 *window;
IHTMLDocument2 *doc; IHTMLDocument2 *doc;
HRESULT hres;
doc = create_document(); doc = create_document();
if(!doc) if(!doc)
...@@ -4596,6 +4599,12 @@ static void test_simple_script(void) ...@@ -4596,6 +4599,12 @@ static void test_simple_script(void)
if(window_dispex) if(window_dispex)
IDispatchEx_Release(window_dispex); IDispatchEx_Release(window_dispex);
hres = IHTMLDocument2_get_parentWindow(doc, &window);
ok(hres == S_OK, "get_parentWindow failed: %08lx\n", hres);
hres = IHTMLWindow2_get_document(window, &doc_node);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
SET_EXPECT(SetScriptState_DISCONNECTED); SET_EXPECT(SetScriptState_DISCONNECTED);
SET_EXPECT(Close); SET_EXPECT(Close);
SET_EXPECT(Close2); SET_EXPECT(Close2);
...@@ -4605,6 +4614,14 @@ static void test_simple_script(void) ...@@ -4605,6 +4614,14 @@ static void test_simple_script(void)
CHECK_CALLED(SetScriptState_DISCONNECTED); CHECK_CALLED(SetScriptState_DISCONNECTED);
CHECK_CALLED(Close); CHECK_CALLED(Close);
CHECK_CALLED(Close2); CHECK_CALLED(Close2);
hres = IHTMLWindow2_get_document(window, &doc);
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
ok(doc != doc_node, "doc == doc_node\n");
IHTMLDocument2_Release(doc_node);
IHTMLDocument2_Release(doc);
IHTMLWindow2_Release(window);
} }
static void run_from_moniker(IMoniker *mon) static void run_from_moniker(IMoniker *mon)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment