From: Gabriel Ivăncescu gabrielopcode@gmail.com
Note that events are actually sent to the new outer windows, even if we're detached.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstorage.c | 3 ++ dlls/mshtml/tests/events.c | 73 +++++++++++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 5 deletions(-)
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index efd4b2d88ae..87954e92496 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -322,6 +322,9 @@ static HRESULT send_storage_event(HTMLStorage *storage, BSTR key, BSTR old_value HRESULT hres = S_OK;
ctx.url = NULL; + if(!window->base.outer_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) diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index c11d53d611f..e6b0be7b039 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -3794,7 +3794,7 @@ static void test_create_event(IHTMLDocument2 *doc) }
static unsigned onstorage_expect_line; -static const WCHAR *onstorage_expect_key, *onstorage_expect_old_value, *onstorage_expect_new_value; +static const WCHAR *onstorage_expect_key, *onstorage_expect_old_value, *onstorage_expect_new_value, *onstorage_expect_url;
#define set_onstorage_expect(a,b,c) _set_onstorage_expect(__LINE__,a,b,c) static void _set_onstorage_expect(unsigned line, const WCHAR *key, const WCHAR *old_value, const WCHAR *new_value) @@ -3871,7 +3871,7 @@ static void test_storage_event(DISPPARAMS *params, BOOL doc_onstorage)
hres = IDOMStorageEvent_get_url(event, &bstr); ok_(__FILE__,line)(hres == S_OK, "get_url failed: %08lx\n", hres); - ok_(__FILE__,line)(!wcscmp(bstr, L"http://winetest.example.org/"), "url = %s\n", wine_dbgstr_w(bstr)); + ok_(__FILE__,line)(!wcscmp(bstr, onstorage_expect_url), "url = %s\n", wine_dbgstr_w(bstr)); SysFreeString(bstr);
IDOMStorageEvent_Release(event); @@ -6278,8 +6278,10 @@ static void test_storage_events(const char *doc_str) { &doc1_onstorage_obj, &doc1_onstoragecommit_obj, &window1_onstorage_obj }, { &doc2_onstorage_obj, &doc2_onstoragecommit_obj, &window2_onstorage_obj }, }; - IHTMLStorage *session_storage[2], *local_storage[2]; + IHTMLStorage *session_storage[2], *local_storage[2], *tmp_session_storage; IHTMLDocument2 *doc[2]; + IHTMLWindow6 *window6; + IHTMLWindow7 *window7; IHTMLDocument6 *doc6; BSTR key, value; HRESULT hres; @@ -6292,8 +6294,6 @@ static void test_storage_events(const char *doc_str)
document_mode = 0; for(i = 0; i < ARRAY_SIZE(doc); i++) { - IHTMLWindow6 *window6; - IHTMLWindow7 *window7; IHTMLWindow2 *window;
hres = IHTMLDocument2_get_parentWindow(doc[i], &window); @@ -6347,6 +6347,7 @@ static void test_storage_events(const char *doc_str) IHTMLWindow7_Release(window7); } } + onstorage_expect_url = L"http://winetest.example.org/";
/* local storage */ for(;;) { @@ -6474,6 +6475,68 @@ static void test_storage_events(const char *doc_str) CHECK_CALLED(doc1_onstorage); if(document_mode >= 9) CHECK_CALLED(window1_onstorage);
+ /* session storage used after navigation */ + navigate(doc[0], L"blank.html"); + onstorage_expect_url = L"http://winetest.example.org/blank.html"; + + /* FIXME: polling shouldn't be needed, but it's flaky on Wine currently */ + if(doc_str == empty_doc_ie9_str && SUCCEEDED(IHTMLDocument2_QueryInterface(doc[0], &IID_IHTMLDocument6, (void**)&doc6))) { + while(document_mode < 9) { + pump_msgs(NULL); + hres = IHTMLDocument6_get_documentMode(doc6, &var); + ok(hres == S_OK, "get_documentMode failed: %08lx\n", hres); + ok(V_VT(&var) == VT_R4, "V_VT(documentMode) = %u\n", V_VT(&var)); + document_mode = V_R4(&var); + } + IHTMLDocument6_Release(doc6); + } + + hres = IHTMLWindow2_QueryInterface(window, &IID_IHTMLWindow6, (void**)&window6); + ok(hres == S_OK, "Could not get IHTMLWindow6: %08lx\n", hres); + IHTMLWindow2_Release(window); + window = NULL; + + hres = IHTMLWindow6_get_sessionStorage(window6, &tmp_session_storage); + ok(hres == S_OK, "get_sessionStorage failed: %08lx\n", hres); + ok(tmp_session_storage != NULL, "session_storage == NULL\n"); + ok(tmp_session_storage != session_storage[0], "session_storage after navigation same as old session_storage\n"); + IHTMLStorage_Release(tmp_session_storage); + + hres = IHTMLWindow6_QueryInterface(window6, &IID_IHTMLWindow7, (void**)&window7); + IHTMLWindow6_Release(window6); + if(SUCCEEDED(hres)) { + V_VT(&var) = VT_DISPATCH; + V_DISPATCH(&var) = (IDispatch*)doc_onstorage_handlers[0].window_onstorage; + hres = IHTMLWindow7_put_onstorage(window7, var); + ok(hres == S_OK, "put_onstorage failed: %08lx\n", hres); + IHTMLWindow7_Release(window7); + } + + key = SysAllocString(L"afterNav"); + value = SysAllocString(L"1234"); + hres = IHTMLStorage_setItem(session_storage[0], key, value); + ok(hres == S_OK, "setItem failed: %08lx\n", hres); + SysFreeString(value); + if(document_mode >= 9) SET_EXPECT(window1_onstorage); + set_onstorage_expect(L"afterNav", NULL, L"1234"); + pump_msgs(document_mode >= 9 ? &called_window1_onstorage : NULL); + if(document_mode >= 9) CHECK_CALLED(window1_onstorage); + + V_VT(&var) = 0xdead; + hres = IHTMLStorage_getItem(session_storage[0], key, &var); + ok(hres == S_OK, "getItem failed: %08lx\n", hres); + ok(V_VT(&var) == VT_BSTR, "V_VT = %d\n", V_VT(&var)); + ok(!wcscmp(V_BSTR(&var), L"1234"), "value = %s\n", wine_dbgstr_w(V_BSTR(&var))); + SysFreeString(key); + VariantClear(&var); + + hres = IHTMLStorage_clear(session_storage[0]); + ok(hres == S_OK, "clear failed: %08lx\n", hres); + if(document_mode >= 9) SET_EXPECT(window1_onstorage); + set_onstorage_expect(NULL, NULL, NULL); + pump_msgs(document_mode >= 9 ? &called_window1_onstorage : NULL); + if(document_mode >= 9) CHECK_CALLED(window1_onstorage); + for(i = 0; i < ARRAY_SIZE(session_storage); i++) IHTMLStorage_Release(session_storage[i]);