Module: wine Branch: master Commit: 434c6e2d325d05f5a69f597df0ed4df7034a5ba3 URL: https://gitlab.winehq.org/wine/wine/-/commit/434c6e2d325d05f5a69f597df0ed4df...
Author: Gabriel Ivăncescu gabrielopcode@gmail.com Date: Mon Jul 25 21:54:04 2022 +0300
mshtml: Inform Gecko of progress done via OnProgress.
Currently we don't support 64-bit progress values (BINDSTATUS_64BIT_PROGRESS is not implemented in wine), so this is limited to 4 GB.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
---
dlls/mshtml/binding.h | 4 ++- dlls/mshtml/navigate.c | 68 ++++++++++++++++++++++++++++++++++++------------ dlls/mshtml/nsiface.idl | 11 ++++++++ dlls/mshtml/script.c | 2 +- dlls/mshtml/tests/xhr.js | 2 -- 5 files changed, 67 insertions(+), 20 deletions(-)
diff --git a/dlls/mshtml/binding.h b/dlls/mshtml/binding.h index 9a043864927..5d2915a836b 100644 --- a/dlls/mshtml/binding.h +++ b/dlls/mshtml/binding.h @@ -104,6 +104,8 @@ struct nsChannelBSC { nsChannel *nschannel; nsIStreamListener *nslistener; nsISupports *nscontext; + ULONG progress; + ULONG total; BOOL is_js; BOOL is_doc_channel; BOOL response_processed; @@ -117,7 +119,7 @@ struct BSCallbackVtbl { HRESULT (*start_binding)(BSCallback*); HRESULT (*stop_binding)(BSCallback*,HRESULT); HRESULT (*read_data)(BSCallback*,IStream*); - HRESULT (*on_progress)(BSCallback*,ULONG,LPCWSTR); + HRESULT (*on_progress)(BSCallback*,ULONG,ULONG,ULONG,LPCWSTR); HRESULT (*on_response)(BSCallback*,DWORD,LPCWSTR); HRESULT (*beginning_transaction)(BSCallback*,WCHAR**); }; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 6f684630cd6..ef764bde58c 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -326,7 +326,7 @@ static HRESULT WINAPI BindStatusCallback_OnProgress(IBindStatusCallback *iface, TRACE("%p)->(%lu %lu %lu %s)\n", This, ulProgress, ulProgressMax, ulStatusCode, debugstr_w(szStatusText));
- return This->vtbl->on_progress(This, ulStatusCode, szStatusText); + return This->vtbl->on_progress(This, ulProgress, ulProgressMax, ulStatusCode, szStatusText); }
static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *iface, @@ -1067,6 +1067,37 @@ static void on_stop_nsrequest(nsChannelBSC *This, HRESULT result) } }
+static void notify_progress(nsChannelBSC *This) +{ + nsChannel *nschannel = This->nschannel; + nsIProgressEventSink *sink = NULL; + nsresult nsres; + + if(!nschannel) + return; + + if(nschannel->notif_callback) + if(NS_FAILED(nsIInterfaceRequestor_GetInterface(nschannel->notif_callback, &IID_nsIProgressEventSink, (void**)&sink))) + sink = NULL; + + if(!sink && nschannel->load_group) { + nsIRequestObserver *req_observer; + + if(NS_SUCCEEDED(nsILoadGroup_GetGroupObserver(nschannel->load_group, &req_observer)) && req_observer) { + nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIProgressEventSink, (void**)&sink); + nsIRequestObserver_Release(req_observer); + if(NS_FAILED(nsres)) + sink = NULL; + } + } + + if(sink) { + nsIProgressEventSink_OnProgress(sink, (nsIRequest*)&nschannel->nsIHttpChannel_iface, This->nscontext, + This->progress, (This->total == ~0) ? -1 : This->total); + nsIProgressEventSink_Release(sink); + } +} + static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) { DWORD read; @@ -1147,6 +1178,8 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) return hres; }
+ notify_progress(This); + nsres = nsIStreamListener_OnDataAvailable(This->nslistener, (nsIRequest*)&This->nschannel->nsIHttpChannel_iface, This->nscontext, &This->nsstream->nsIInputStream_iface, This->bsc.read-This->nsstream->buf_size, @@ -1656,7 +1689,7 @@ static void handle_extern_mime_navigation(nsChannelBSC *This) IUri_Release(uri); }
-static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCWSTR status_text) +static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG total, ULONG status_code, LPCWSTR status_text) { nsChannelBSC *This = nsChannelBSC_from_BSCallback(bsc);
@@ -1684,21 +1717,24 @@ static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCW DWORD status, size = sizeof(DWORD); HRESULT hres;
- if(!This->bsc.binding) - break; - - hres = IBinding_QueryInterface(This->bsc.binding, &IID_IWinInetHttpInfo, (void**)&http_info); - if(FAILED(hres)) - break; - - hres = IWinInetHttpInfo_QueryInfo(http_info, - HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL, NULL); - IWinInetHttpInfo_Release(http_info); - if(FAILED(hres) || status == HTTP_STATUS_OK) - break; - - handle_navigation_error(This, status); + if(This->bsc.binding) { + hres = IBinding_QueryInterface(This->bsc.binding, &IID_IWinInetHttpInfo, (void**)&http_info); + if(SUCCEEDED(hres)) { + hres = IWinInetHttpInfo_QueryInfo(http_info, + HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &status, &size, NULL, NULL); + IWinInetHttpInfo_Release(http_info); + if(SUCCEEDED(hres) && status != HTTP_STATUS_OK) + handle_navigation_error(This, status); + } + } + /* fall through */ } + case BINDSTATUS_DOWNLOADINGDATA: + case BINDSTATUS_ENDDOWNLOADDATA: + /* Defer it to just before calling OnDataAvailable, otherwise it can have wrong state */ + This->progress = progress; + This->total = total; + break; }
return S_OK; diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index c4b479b16e3..f6e0a909278 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -771,6 +771,17 @@ interface nsIChannelEventSink : nsISupports nsIAsyncVerifyRedirectCallback *callback); }
+[ + object, + uuid(87d55fba-cb7e-4f38-84c1-5c6c2b2a55e9), + local +] +interface nsIProgressEventSink : nsISupports +{ + nsresult OnProgress(nsIRequest *aRequest, nsISupports *aContext, int64_t aProgress, int64_t aProgressMax); + nsresult OnStatus(nsIRequest *aRequest, nsISupports *aContext, nsresult aStatus, const char16_t *aStatusArg); +} + [ object, uuid(79de76e5-994e-4f6b-81aa-42d9adb6e67e), diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c index e49449a61f8..769ca72db6f 100644 --- a/dlls/mshtml/script.c +++ b/dlls/mshtml/script.c @@ -1053,7 +1053,7 @@ static HRESULT ScriptBSC_read_data(BSCallback *bsc, IStream *stream) return S_OK; }
-static HRESULT ScriptBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCWSTR status_text) +static HRESULT ScriptBSC_on_progress(BSCallback *bsc, ULONG progress, ULONG total, ULONG status_code, LPCWSTR status_text) { return S_OK; } diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index cc8a03dadb4..dd3750632c7 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -59,9 +59,7 @@ function test_xhr() { for(var i = 0; i < props.length; i++) ok(props[i] in e, props[i] + " not available in loadend"); ok(e.lengthComputable === true, "lengthComputable in loadend = " + e.lengthComputable); - todo_wine. ok(e.loaded === xml.length, "loaded in loadend = " + e.loaded); - todo_wine. ok(e.total === xml.length, "total in loadend = " + e.total); next_test(); };