This is for documents with multiple frames that are loaded asynchronously.
From: Jacob Czekalla jczekalla@codeweavers.com
This is to handle tests where events could be called multiple times. For example iframes being loaded during a navigate. --- dlls/ieframe/tests/webbrowser.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/dlls/ieframe/tests/webbrowser.c b/dlls/ieframe/tests/webbrowser.c index 521b18bb599..753e55972bf 100644 --- a/dlls/ieframe/tests/webbrowser.c +++ b/dlls/ieframe/tests/webbrowser.c @@ -55,16 +55,19 @@ DEFINE_GUID(IID_IProxyManager,0x00000008,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00, #define SET_EXPECT(func) \ do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
+#define SET_EXPECT_N(func, n) \ + do { called_ ## func = FALSE; expect_ ## func = n; } while(0) + #define CHECK_EXPECT2(func) \ do { \ ok(expect_ ##func, "unexpected call " #func "\n"); \ - called_ ## func = TRUE; \ + called_ ## func += 1; \ }while(0)
#define CHECK_EXPECT(func) \ do { \ CHECK_EXPECT2(func); \ - expect_ ## func = FALSE; \ + if (expect_ ## func > 0) expect_ ## func -= 1; \ }while(0)
#define CHECK_CALLED(func) \ @@ -73,6 +76,12 @@ DEFINE_GUID(IID_IProxyManager,0x00000008,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00, expect_ ## func = called_ ## func = FALSE; \ }while(0)
+#define CHECK_CALLED_N(func, n) \ + do { \ + ok(called_ ## func == n, "expected " #func "\n"); \ + expect_ ## func = called_ ## func = FALSE; \ + }while(0) + #define CHECK_NOT_CALLED(func) \ do { \ ok(!called_ ## func, "unexpected " #func "\n"); \
From: Jacob Czekalla jczekalla@codeweavers.com
--- dlls/ieframe/tests/webbrowser.c | 160 +++++++++++++++++++++++++++++--- 1 file changed, 147 insertions(+), 13 deletions(-)
diff --git a/dlls/ieframe/tests/webbrowser.c b/dlls/ieframe/tests/webbrowser.c index 753e55972bf..a7664937d46 100644 --- a/dlls/ieframe/tests/webbrowser.c +++ b/dlls/ieframe/tests/webbrowser.c @@ -200,6 +200,7 @@ static LONG (WINAPI *pSetQueryNetSessionCount)(DWORD); #define DWL_HTTP 0x10 #define DWL_REFRESH 0x20 #define DWL_BACK_ENABLE 0x40 +#define DWL_IFRAME 0x80
static DWORD dwl_flags;
@@ -489,6 +490,7 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID }else if(IsEqualGUID(&CGID_ShellDocView, pguidCmdGroup)) { switch(nCmdID) { case 63: /* win10 */ + case 65: /* TODO */ case 105: /* TODO */ case 132: /* win10 */ case 133: /* IE11 */ @@ -731,17 +733,22 @@ static void test_OnBeforeNavigate(const VARIANT *disp, const VARIANT *url, const BSTR str;
ok(V_VT(disp) == VT_DISPATCH, "V_VT(disp)=%d, expected VT_DISPATCH\n", V_VT(disp)); - ok(V_DISPATCH(disp) != NULL, "V_DISPATCH(disp) == NULL\n"); - ok(V_DISPATCH(disp) == (IDispatch*)wb, "V_DISPATCH(disp)=%p, wb=%p\n", V_DISPATCH(disp), wb); + if (!(dwl_flags & DWL_IFRAME)) + { + ok(V_DISPATCH(disp) != NULL, "V_DISPATCH(disp) == NULL\n"); + ok(V_DISPATCH(disp) == (IDispatch*)wb, "V_DISPATCH(disp)=%p, wb=%p\n", V_DISPATCH(disp), wb); + }
ok(V_VT(url) == (VT_BYREF|VT_VARIANT), "V_VT(url)=%x, expected VT_BYREF|VT_VARIANT\n", V_VT(url)); ok(V_VARIANTREF(url) != NULL, "V_VARIANTREF(url) == NULL)\n"); if(V_VARIANTREF(url)) { - ok(V_VT(V_VARIANTREF(url)) == VT_BSTR, "V_VT(V_VARIANTREF(url))=%d, expected VT_BSTR\n", - V_VT(V_VARIANTREF(url))); + if (!(dwl_flags & DWL_IFRAME)) + ok(V_VT(V_VARIANTREF(url)) == VT_BSTR, "V_VT(V_VARIANTREF(url))=%d, expected VT_BSTR\n", + V_VT(V_VARIANTREF(url))); ok(V_BSTR(V_VARIANTREF(url)) != NULL, "V_BSTR(V_VARIANTREF(url)) == NULL\n"); - ok(!lstrcmpW(V_BSTR(V_VARIANTREF(url)), current_url), "unexpected url %s, expected %s\n", - wine_dbgstr_w(V_BSTR(V_VARIANTREF(url))), wine_dbgstr_w(current_url)); + if (!(dwl_flags & DWL_IFRAME)) + ok(!lstrcmpW(V_BSTR(V_VARIANTREF(url)), current_url), "unexpected url %s, expected %s\n", + wine_dbgstr_w(V_BSTR(V_VARIANTREF(url))), wine_dbgstr_w(current_url)); }
ok(V_VT(flags) == (VT_BYREF|VT_VARIANT), "V_VT(flags)=%x, expected VT_BYREF|VT_VARIANT\n", @@ -830,14 +837,18 @@ static void test_navigatecomplete2(DISPPARAMS *dp) ok(V_VT(dp->rgvarg) == (VT_BYREF|VT_VARIANT), "V_VT(dp->rgvarg) = %d\n", V_VT(dp->rgvarg)); v = V_VARIANTREF(dp->rgvarg); ok(V_VT(v) == VT_BSTR, "V_VT(url) = %d\n", V_VT(v)); - ok(!lstrcmpW(V_BSTR(v), current_url), "url=%s, expected %s\n", wine_dbgstr_w(V_BSTR(v)), - wine_dbgstr_w(current_url)); + if (!(dwl_flags & DWL_IFRAME)) + ok(!lstrcmpW(V_BSTR(v), current_url), "url=%s, expected %s\n", wine_dbgstr_w(V_BSTR(v)), + wine_dbgstr_w(current_url));
ok(V_VT(dp->rgvarg+1) == VT_DISPATCH, "V_VT(dp->rgvarg+1) = %d\n", V_VT(dp->rgvarg+1)); - ok(V_DISPATCH(dp->rgvarg+1) == (IDispatch*)wb, "V_DISPATCH=%p, wb=%p\n", V_DISPATCH(dp->rgvarg+1), wb); + if (!(dwl_flags & DWL_IFRAME)) + ok(V_DISPATCH(dp->rgvarg+1) == (IDispatch*)wb, "V_DISPATCH=%p, wb=%p\n", V_DISPATCH(dp->rgvarg+1), wb);
if(dwl_flags & (DWL_FROM_PUT_HREF|DWL_FROM_GOBACK|DWL_FROM_GOFORWARD)) test_ready_state(READYSTATE_COMPLETE, VARIANT_TRUE); + else if ((dwl_flags & DWL_IFRAME) && called_Invoke_NAVIGATECOMPLETE2 == 2) + test_ready_state(READYSTATE_INTERACTIVE, VARIANT_TRUE); else test_ready_state(READYSTATE_LOADING, VARIANT_TRUE); } @@ -854,13 +865,18 @@ static void test_documentcomplete(DISPPARAMS *dp) ok(V_VT(dp->rgvarg) == (VT_BYREF|VT_VARIANT), "V_VT(dp->rgvarg) = %d\n", V_VT(dp->rgvarg)); v = V_VARIANTREF(dp->rgvarg); ok(V_VT(v) == VT_BSTR, "V_VT(url) = %d\n", V_VT(v)); - ok(!lstrcmpW(V_BSTR(v), current_url), "url=%s, expected %s\n", wine_dbgstr_w(V_BSTR(v)), - wine_dbgstr_w(current_url)); + if (!(dwl_flags & DWL_IFRAME)) + ok(!lstrcmpW(V_BSTR(v), current_url), "url=%s, expected %s\n", wine_dbgstr_w(V_BSTR(v)), + wine_dbgstr_w(current_url));
ok(V_VT(dp->rgvarg+1) == VT_DISPATCH, "V_VT(dp->rgvarg+1) = %d\n", V_VT(dp->rgvarg+1)); - ok(V_DISPATCH(dp->rgvarg+1) == (IDispatch*)wb, "V_DISPATCH=%p, wb=%p\n", V_DISPATCH(dp->rgvarg+1), wb); + if (!(dwl_flags & DWL_IFRAME)) + ok(V_DISPATCH(dp->rgvarg+1) == (IDispatch*)wb, "V_DISPATCH=%p, wb=%p\n", V_DISPATCH(dp->rgvarg+1), wb);
- test_ready_state(READYSTATE_COMPLETE, VARIANT_FALSE); + if ((dwl_flags & DWL_IFRAME) && called_Invoke_DOCUMENTCOMPLETE == 1) + test_ready_state(READYSTATE_INTERACTIVE, VARIANT_FALSE); + else + test_ready_state(READYSTATE_COMPLETE, VARIANT_FALSE); }
static HRESULT WINAPI WebBrowserEvents2_Invoke(IDispatch *iface, DISPID dispIdMember, REFIID riid, @@ -917,6 +933,8 @@ static HRESULT WINAPI WebBrowserEvents2_Invoke(IDispatch *iface, DISPID dispIdMe pDispParams->rgvarg); if(dwl_flags & (DWL_FROM_PUT_HREF|DWL_FROM_GOFORWARD)) test_ready_state(READYSTATE_COMPLETE, VARIANT_FALSE); + else if (dwl_flags & DWL_IFRAME) + test_ready_state(READYSTATE_LOADING, VARIANT_TRUE); else test_ready_state(READYSTATE_LOADING, VARIANT_FALSE); break; @@ -3849,6 +3867,120 @@ static void init_test(IWebBrowser2 *webbrowser, DWORD flags) use_container_dochostui = !(flags & TEST_NODOCHOST); }
+static void test_iframe_Navigate2(void) +{ + MSG msg; + + dwl_flags |= DWL_IFRAME; + + SET_EXPECT_N(Exec_SETPROGRESSMAX, 2); + SET_EXPECT_N(Exec_SETPROGRESSPOS, 3); + SET_EXPECT_N(Exec_SETDOWNLOADSTATE_1, 2); + SET_EXPECT(TranslateUrl); + SET_EXPECT(Invoke_BEFORENAVIGATE2); + SET_EXPECT(DocHost_EnableModeless_FALSE); + SET_EXPECT(DocHost_EnableModeless_TRUE); + SET_EXPECT_N(Invoke_SETSECURELOCKICON, 6); + SET_EXPECT_N(Invoke_STATUSTEXTCHANGE, 7); + SET_EXPECT_N(SetStatusText, 7); + SET_EXPECT_N(EnableModeless_FALSE, 3); + SET_EXPECT_N(EnableModeless_TRUE, 3); + SET_EXPECT_N(Invoke_COMMANDSTATECHANGE_NAVIGATEBACK_FALSE, 3); + SET_EXPECT_N(Invoke_COMMANDSTATECHANGE_NAVIGATEFORWARD_FALSE, 3); + SET_EXPECT(QueryStatus_STOP); + SET_EXPECT(Invoke_COMMANDSTATECHANGE_UPDATECOMMANDS); + SET_EXPECT_N(Invoke_TITLECHANGE, 2); + SET_EXPECT_N(Invoke_NAVIGATECOMPLETE2, 2); + + SET_EXPECT_N(Exec_SETDOWNLOADSTATE_0, 2); + SET_EXPECT(GetDropTarget); + SET_EXPECT_N(Invoke_DOCUMENTCOMPLETE, 2); + SET_EXPECT_N(Invoke_PROGRESSCHANGE, 2); + + while(GetMessageW(&msg, NULL, 0, 0)) + { + DispatchMessageW(&msg); + if (called_Invoke_DOCUMENTCOMPLETE == 2) /* both the main document and iframe are complete */ + break; + } + + CHECK_CALLED_N(Exec_SETPROGRESSMAX, 2); + CHECK_CALLED_N(Exec_SETPROGRESSPOS, 3); + CHECK_CALLED_N(Exec_SETDOWNLOADSTATE_1, 2); + CHECK_CALLED(TranslateUrl); + CHECK_CALLED(Invoke_BEFORENAVIGATE2); + CHECK_CALLED(DocHost_EnableModeless_FALSE); + CHECK_CALLED(DocHost_EnableModeless_TRUE); + CHECK_CALLED_N(Invoke_SETSECURELOCKICON, 6); + CHECK_CALLED_N(Invoke_STATUSTEXTCHANGE, 7); + CHECK_CALLED_N(SetStatusText, 7); + CHECK_CALLED_N(EnableModeless_FALSE, 3); + CHECK_CALLED_N(EnableModeless_TRUE, 3); + CHECK_CALLED_N(Invoke_COMMANDSTATECHANGE_NAVIGATEBACK_FALSE, 3); + CHECK_CALLED_N(Invoke_COMMANDSTATECHANGE_NAVIGATEFORWARD_FALSE, 3); + CHECK_CALLED(QueryStatus_STOP); + CHECK_CALLED(Invoke_COMMANDSTATECHANGE_UPDATECOMMANDS); + CHECK_CALLED_N(Invoke_TITLECHANGE, 2); + CHECK_CALLED_N(Invoke_NAVIGATECOMPLETE2, 2); + + CHECK_CALLED_N(Exec_SETDOWNLOADSTATE_0, 2); + CHECK_CALLED(GetDropTarget); + CHECK_CALLED_N(Invoke_DOCUMENTCOMPLETE, 2); + CHECK_CALLED_N(Invoke_PROGRESSCHANGE, 2); + + dwl_flags &= ~DWL_IFRAME; +} + +static void test_iframes(void) +{ + IWebBrowser2 *webbrowser; + HANDLE file; + DWORD written; + + WCHAR file_path[MAX_PATH]; + WCHAR file_url[MAX_PATH] = L"File://"; + static const WCHAR file_name[] = L"wine_iframe_test.html"; + static const CHAR file_contents[] = "<html><iframe src="http://test.winehq.org/tests/hello.html%5C" style="width:0px; height:0px; border: 0px"></iframe></html>"; + + webbrowser = create_webbrowser(); + if(!webbrowser) + return; + + init_test(webbrowser, TEST_DOWNLOAD); + + test_ConnectionPoint(webbrowser, TRUE); + test_ClientSite(webbrowser, &ClientSite, TRUE); + test_DoVerb(webbrowser); + + GetTempPathW(MAX_PATH, file_path); + lstrcatW(file_path, file_name); + + file = CreateFileW(file_path, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); + if(file == INVALID_HANDLE_VALUE) + { + if (GetLastError() == ERROR_FILE_EXISTS) + DeleteFileW(file_path); + trace("CreateFileW failed\n"); + return; + } + WriteFile(file, file_contents, strlen(file_contents), &written, NULL); + if (written != strlen(file_contents)) + { + trace("WriteFile failed\n"); + DeleteFileW(file_path); + return; + } + CloseHandle(file); + + GetLongPathNameW(file_path, file_path, ARRAY_SIZE(file_path)); + lstrcatW(file_url, file_path); + + test_Navigate2(webbrowser, file_url); + test_iframe_Navigate2(); + + DeleteFileW(file_path); +} + static void test_WebBrowser(DWORD flags, BOOL do_close) { IWebBrowser2 *webbrowser; @@ -4556,6 +4688,8 @@ START_TEST(webbrowser) trace("Testing SetAdvise...\n"); test_SetAdvise(); test_com_aggregation(); + trace("Testing iframes...\n"); + test_iframes();
OleUninitialize(); }
From: Jacob Czekalla jczekalla@codeweavers.com
This is for documents with multiple frames that are loaded asynchronously. --- dlls/mshtml/nsio.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c index a5564e1b6e4..51e16c7812d 100644 --- a/dlls/mshtml/nsio.c +++ b/dlls/mshtml/nsio.c @@ -1006,6 +1006,9 @@ static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc nsChannelBSC *bscallback; IMoniker *mon = NULL; HRESULT hres; + BSTR frame_name = NULL, display_uri = NULL; + GeckoBrowser *browser; + BOOL cancel = FALSE;
hres = CreateURLMonikerEx2(NULL, This->uri->uri, &mon, 0); if(FAILED(hres)) { @@ -1023,6 +1026,34 @@ static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc
channelbsc_set_channel(bscallback, This, listener, context);
+ hres = IUri_GetDisplayUri(This->uri->uri, &display_uri); + if (FAILED(hres)) { + IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface); + return NS_ERROR_UNEXPECTED; + } + + hres = IHTMLWindow2_get_name(&window->base.IHTMLWindow2_iface, &frame_name); + if (FAILED(hres)) { + IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface); + SysFreeString(display_uri); + return NS_ERROR_UNEXPECTED; + } + + browser = window->base.outer_window->browser; + hres = IDocObjectService_FireBeforeNavigate2(browser->doc->doc_object_service, NULL, display_uri, 0, frame_name, NULL, 0, NULL, TRUE, &cancel); + SysFreeString(frame_name); + SysFreeString(display_uri); + if (FAILED(hres)) { + IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface); + return NS_ERROR_UNEXPECTED; + } + if (cancel) { + if (bscallback->bsc.binding) + IBinding_Abort(bscallback->bsc.binding); + IBindStatusCallback_Release(&bscallback->bsc.IBindStatusCallback_iface); + return NS_BINDING_ABORTED; + } + if(is_doc_channel) { hres = create_pending_window(window, bscallback); if(SUCCEEDED(hres))