From: Jacob Czekalla jczekalla@codeweavers.com
Documents such as iframes do not currently receive BeforeNavigate2 events. --- dlls/mshtml/nsio.c | 46 +++++++++++++++++++++++++++++++++++++ dlls/mshtml/tests/htmldoc.c | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c index a5564e1b6e4..9e9d3efd7d6 100644 --- a/dlls/mshtml/nsio.c +++ b/dlls/mshtml/nsio.c @@ -1000,12 +1000,51 @@ static void start_binding_task_destr(task_t *_task) IBindStatusCallback_Release(&task->bscallback->bsc.IBindStatusCallback_iface); }
+static HRESULT fire_beforenavigate2(nsChannel *This, IDocObjectService *doc_object_service, HTMLOuterWindow *window) +{ + BSTR frame_name = NULL, display_uri = NULL; + BOOL cancel = FALSE; + HRESULT hres; + IServiceProvider *service_provider = NULL; + IWebBrowser2 *web_browser = NULL; + + hres = IUri_GetDisplayUri(This->uri->uri, &display_uri); + if (FAILED(hres)) + return NS_ERROR_UNEXPECTED; + hres = IHTMLWindow2_get_name(&window->base.IHTMLWindow2_iface, &frame_name); + if (FAILED(hres)) + { + SysFreeString(display_uri); + return NS_ERROR_UNEXPECTED; + } + hres = IHTMLWindow2_QueryInterface(&window->base.IHTMLWindow2_iface, &IID_IServiceProvider, (void**)&service_provider); + if (SUCCEEDED(hres)) + { + hres = IServiceProvider_QueryService(service_provider, &SID_SWebBrowserApp, &IID_IWebBrowser2, (void**)&web_browser); + IServiceProvider_Release(service_provider); + } + if (FAILED(hres)) + { + SysFreeString(frame_name); + SysFreeString(display_uri); + return NS_ERROR_UNEXPECTED; + } + hres = IDocObjectService_FireBeforeNavigate2(doc_object_service, (IDispatch*)web_browser, display_uri, 0, frame_name, NULL, 0, NULL, FALSE, &cancel); + IWebBrowser2_Release(web_browser); + SysFreeString(display_uri); + SysFreeString(frame_name); + if (cancel) + return NS_BINDING_ABORTED; + return S_OK; +} + static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc_channel, UINT32 load_type, nsIStreamListener *listener, nsISupports *context) { nsChannelBSC *bscallback; IMoniker *mon = NULL; HRESULT hres; + IDocObjectService *doc_object_service;
hres = CreateURLMonikerEx2(NULL, This->uri->uri, &mon, 0); if(FAILED(hres)) { @@ -1024,6 +1063,13 @@ static nsresult async_open(nsChannel *This, HTMLOuterWindow *window, BOOL is_doc channelbsc_set_channel(bscallback, This, listener, context);
if(is_doc_channel) { + doc_object_service = window->base.outer_window->browser->doc->doc_object_service; + if (doc_object_service) + { + hres = fire_beforenavigate2(This, doc_object_service, window); + if (FAILED(hres)) + return hres; + } hres = create_pending_window(window, bscallback); if(SUCCEEDED(hres)) async_start_doc_binding(window, window->pending_window, (load_type & LOAD_CMD_RELOAD) ? BINDING_REFRESH : BINDING_NAVIGATED); diff --git a/dlls/mshtml/tests/htmldoc.c b/dlls/mshtml/tests/htmldoc.c index bd36c65f02d..7b17a98e242 100644 --- a/dlls/mshtml/tests/htmldoc.c +++ b/dlls/mshtml/tests/htmldoc.c @@ -8342,7 +8342,7 @@ static void test_iframe_download(int flags) todo_wine CHECK_CALLED_N(FireDownloadBegin, total_iframes); todo_wine CHECK_CALLED_N(FireDownloadComplete, total_iframes);
- todo_wine CHECK_CALLED_N(FireBeforeNavigate2, total_iframes); + CHECK_CALLED_N(FireBeforeNavigate2, total_iframes); todo_wine CHECK_CALLED_N(FireNavigateComplete2, total_documents); todo_wine CHECK_CALLED_N(FireDocumentComplete, total_documents);