mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 16:47:17 +00:00
mshtml: Set outer window to uninitialized page when document obj is released.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
9afcf7c8e0
commit
110dad9ca5
|
@ -6196,7 +6196,7 @@ HRESULT create_document_node(nsIDOMDocument *nsdoc, GeckoBrowser *browser, HTMLI
|
|||
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;
|
||||
|
||||
/* Share reference with HTMLDOMNode */
|
||||
|
|
|
@ -2906,7 +2906,7 @@ static HRESULT WINAPI HTMLPrivateWindow_GetAddressBarUrl(IHTMLPrivateWindow *ifa
|
|||
if(!url)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -4564,10 +4564,12 @@ HRESULT update_window_doc(HTMLInnerWindow *window)
|
|||
|
||||
if(is_main_content_window(outer_window) || !outer_window->browser->content_window) {
|
||||
HTMLDocumentObj *doc_obj = outer_window->browser->doc;
|
||||
if(doc_obj->doc_node)
|
||||
IHTMLDOMNode_Release(&doc_obj->doc_node->node.IHTMLDOMNode_iface);
|
||||
doc_obj->doc_node = window->doc;
|
||||
IHTMLDOMNode_AddRef(&window->doc->node.IHTMLDOMNode_iface);
|
||||
if(doc_obj) {
|
||||
if(doc_obj->doc_node)
|
||||
IHTMLDOMNode_Release(&doc_obj->doc_node->node.IHTMLDOMNode_iface);
|
||||
doc_obj->doc_node = window->doc;
|
||||
IHTMLDOMNode_AddRef(&window->doc->node.IHTMLDOMNode_iface);
|
||||
}
|
||||
}
|
||||
|
||||
return hres;
|
||||
|
|
|
@ -1012,7 +1012,8 @@ static HRESULT on_start_nsrequest(nsChannelBSC *This)
|
|||
|
||||
if(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);
|
||||
}
|
||||
|
||||
|
@ -1370,7 +1371,7 @@ static HRESULT nsChannelBSC_init_bindinfo(BSCallback *bsc)
|
|||
HRESULT hres;
|
||||
|
||||
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)
|
||||
This->bsc.bindinfo_options |= BINDINFO_OPTIONS_DISABLEAUTOREDIRECTS;
|
||||
}
|
||||
|
|
|
@ -208,6 +208,8 @@ static nsresult handle_focus(HTMLDocumentNode *doc, nsIDOMEvent *event)
|
|||
|
||||
TRACE("(%p)\n", doc);
|
||||
|
||||
if(!doc->doc_obj)
|
||||
return NS_ERROR_FAILURE;
|
||||
doc_obj = doc->doc_obj;
|
||||
|
||||
if(!doc_obj->focus) {
|
||||
|
@ -220,7 +222,7 @@ static nsresult handle_focus(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;
|
||||
|
||||
TRACE("(%p)->(%p)\n", doc, event);
|
||||
|
@ -391,7 +393,7 @@ static nsresult handle_beforeunload(HTMLDocumentNode *doc, nsIDOMEvent *nsevent)
|
|||
DOMEvent *event;
|
||||
HRESULT hres;
|
||||
|
||||
if(!(window = doc->window))
|
||||
if(!(window = doc->window) || doc->unload_sent)
|
||||
return NS_OK;
|
||||
|
||||
/* 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
|
|||
TRACE("canceled\n");
|
||||
nsres = NS_BINDING_ABORTED;
|
||||
}
|
||||
}else if(window->browser->doc->mime) {
|
||||
}else if(window->browser->doc && window->browser->doc->mime) {
|
||||
free(This->content_type);
|
||||
This->content_type = strdupWtoA(window->browser->doc->mime);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "mshtml_private.h"
|
||||
#include "htmlevent.h"
|
||||
#include "binding.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
|
||||
|
||||
|
@ -2079,8 +2080,10 @@ void HTMLDocumentNode_OleObj_Init(HTMLDocumentNode *This)
|
|||
This->IObjectWithSite_iface.lpVtbl = &DocNodeObjectWithSiteVtbl;
|
||||
This->IOleContainer_iface.lpVtbl = &DocNodeOleContainerVtbl;
|
||||
This->IObjectSafety_iface.lpVtbl = &DocNodeObjectSafetyVtbl;
|
||||
This->doc_obj->extent.cx = 1;
|
||||
This->doc_obj->extent.cy = 1;
|
||||
if(This->doc_obj) {
|
||||
This->doc_obj->extent.cx = 1;
|
||||
This->doc_obj->extent.cy = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void HTMLDocumentObj_OleObj_Init(HTMLDocumentObj *This)
|
||||
|
@ -3403,6 +3406,60 @@ static ULONG WINAPI HTMLDocumentObj_AddRef(IUnknown *iface)
|
|||
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)
|
||||
{
|
||||
HTMLDocumentObj *This = impl_from_IUnknown(iface);
|
||||
|
@ -3412,8 +3469,15 @@ static ULONG WINAPI HTMLDocumentObj_Release(IUnknown *iface)
|
|||
|
||||
if(!ref) {
|
||||
if(This->doc_node) {
|
||||
This->doc_node->doc_obj = NULL;
|
||||
IHTMLDOMNode_Release(&This->doc_node->node.IHTMLDOMNode_iface);
|
||||
HTMLDocumentNode *doc_node = This->doc_node;
|
||||
|
||||
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)
|
||||
IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface);
|
||||
|
|
|
@ -5999,6 +5999,151 @@ static void test_empty_document(void)
|
|||
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 struct {
|
||||
|
@ -6372,6 +6517,9 @@ START_TEST(events)
|
|||
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);
|
||||
}else {
|
||||
#if !defined(__i386__) && !defined(__x86_64__)
|
||||
|
|
|
@ -8461,10 +8461,12 @@ static void test_doc_domain(IHTMLDocument2 *doc)
|
|||
|
||||
static void test_HTMLDocument_http(BOOL with_wbapp)
|
||||
{
|
||||
IHTMLDocument2 *doc, *doc_node;
|
||||
IHTMLWindow2 *window;
|
||||
IMoniker *http_mon;
|
||||
IHTMLDocument2 *doc;
|
||||
ULONG ref;
|
||||
HRESULT hres;
|
||||
ULONG ref;
|
||||
BSTR bstr;
|
||||
|
||||
trace("Testing HTMLDocument (http%s)...\n", with_wbapp ? " with IWebBrowserApp" : "");
|
||||
|
||||
|
@ -8529,12 +8531,42 @@ static void test_HTMLDocument_http(BOOL with_wbapp)
|
|||
test_IsDirty(doc, S_FALSE);
|
||||
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)
|
||||
IOleDocumentView_Release(view);
|
||||
view = NULL;
|
||||
|
||||
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);
|
||||
ok(!ref, "ref=%ld, expected 0\n", ref);
|
||||
}
|
||||
|
|
|
@ -4525,7 +4525,10 @@ static void test_exec_script(IHTMLDocument2 *doc, const WCHAR *codew, const WCHA
|
|||
|
||||
static void test_simple_script(void)
|
||||
{
|
||||
IHTMLDocument2 *doc_node;
|
||||
IHTMLWindow2 *window;
|
||||
IHTMLDocument2 *doc;
|
||||
HRESULT hres;
|
||||
|
||||
doc = create_document();
|
||||
if(!doc)
|
||||
|
@ -4596,6 +4599,12 @@ static void test_simple_script(void)
|
|||
if(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(Close);
|
||||
SET_EXPECT(Close2);
|
||||
|
@ -4605,6 +4614,14 @@ static void test_simple_script(void)
|
|||
CHECK_CALLED(SetScriptState_DISCONNECTED);
|
||||
CHECK_CALLED(Close);
|
||||
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)
|
||||
|
|
Loading…
Reference in a new issue