Module: wine Branch: master Commit: 6537c36df492cbca018ab7defd83980920044c79 URL: https://gitlab.winehq.org/wine/wine/-/commit/6537c36df492cbca018ab7defd83980...
Author: Gabriel Ivăncescu gabrielopcode@gmail.com Date: Thu Jul 28 16:05:35 2022 +0300
mshtml: Implement responseType prop for XMLHttpRequest.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com
---
dlls/mshtml/tests/xhr.js | 57 ++++++++++++++++++++++++++++++++++++++++++- dlls/mshtml/xmlhttprequest.c | 58 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 110 insertions(+), 5 deletions(-)
diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index dd3750632c7..68f3a68caee 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -191,9 +191,64 @@ function test_timeout() { xhr.send("Timeout Test"); }
+function test_responseType() { + var i, xhr = new XMLHttpRequest(); + if(!("responseType" in xhr)) { next_test(); return; } + + ok(xhr.responseType === "", "default responseType = " + xhr.responseType); + try { + xhr.responseType = ""; + ok(false, "setting responseType before open() did not throw exception"); + }catch(ex) { + todo_wine. + ok(ex.name === "InvalidStateError", "setting responseType before open() threw " + ex.name); + } + try { + xhr.responseType = "invalid response type"; + ok(false, "setting invalid responseType before open() did not throw exception"); + }catch(ex) { + todo_wine. + ok(ex.name === "InvalidStateError", "setting invalid responseType before open() threw " + ex.name); + } + + xhr.open("POST", "echo.php", true); + xhr.setRequestHeader("X-Test", "True"); + ok(xhr.responseType === "", "default responseType after open() = " + xhr.responseType); + + var types = [ "text", "", "document", "arraybuffer", "blob", "ms-stream" ]; + for(i = 0; i < types.length; i++) { + xhr.responseType = types[i]; + ok(xhr.responseType === types[i], "responseType = " + xhr.responseType + ", expected " + types[i]); + } + + types = [ "json", "teXt", "Document", "moz-chunked-text", "moz-blob", null ]; + for(i = 0; i < types.length; i++) { + xhr.responseType = types[i]; + ok(xhr.responseType === "ms-stream", "responseType (after set to " + types[i] + ") = " + xhr.responseType); + } + + xhr.responseType = ""; + xhr.onreadystatechange = function() { + if(xhr.readyState < 3) { + xhr.responseType = ""; + return; + } + try { + xhr.responseType = ""; + ok(false, "setting responseType with state " + xhr.readyState + " did not throw exception"); + }catch(ex) { + todo_wine. + ok(ex.name === "InvalidStateError", "setting responseType with state " + xhr.readyState + " threw " + ex.name); + } + } + xhr.onloadend = function() { next_test(); } + xhr.send("responseType test"); +} + var tests = [ test_xhr, test_content_types, test_abort, - test_timeout + test_timeout, + test_responseType ]; diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index b17fa418c6c..6f639d3b821 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -103,6 +103,27 @@ static const eventid_t events[] = { EVENTID_TIMEOUT, };
+typedef enum { + response_type_empty, + response_type_text, + response_type_doc, + response_type_arraybuf, + response_type_blob, + response_type_stream +} response_type_t; + +static const struct { + const WCHAR *str; + const WCHAR *nsxhr_str; +} response_type_desc[] = { + [response_type_empty] = { L"", L"" }, + [response_type_text] = { L"text", L"" }, + [response_type_doc] = { L"document", L"" }, /* FIXME */ + [response_type_arraybuf] = { L"arraybuffer", L"arraybuffer" }, + [response_type_blob] = { L"blob", L"arraybuffer" }, + [response_type_stream] = { L"ms-stream", L"arraybuffer" } /* FIXME */ +}; + typedef struct { nsIDOMEventListener nsIDOMEventListener_iface; LONG ref; @@ -117,6 +138,7 @@ struct HTMLXMLHttpRequest { IWineXMLHttpRequestPrivate IWineXMLHttpRequestPrivate_iface; IProvideClassInfo2 IProvideClassInfo2_iface; LONG ref; + response_type_t response_type; nsIXMLHttpRequest *nsxhr; XMLHttpReqEventListener *event_listener; }; @@ -925,19 +947,47 @@ static HRESULT WINAPI HTMLXMLHttpRequest_private_get_response(IWineXMLHttpReques static HRESULT WINAPI HTMLXMLHttpRequest_private_put_responseType(IWineXMLHttpRequestPrivate *iface, BSTR v) { HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface); + nsAString nsstr; + nsresult nsres; + HRESULT hres; + unsigned i; + LONG state;
- FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + TRACE("(%p)->(%s)\n", This, debugstr_w(v));
- return E_NOTIMPL; + hres = IHTMLXMLHttpRequest_get_readyState(&This->IHTMLXMLHttpRequest_iface, &state); + if(FAILED(hres)) + return hres; + + if(state < 1 || state > 2) { + /* FIXME: Return InvalidStateError */ + return E_FAIL; + } + + for(i = 0; i < ARRAY_SIZE(response_type_desc); i++) + if(!wcscmp(v, response_type_desc[i].str)) + break; + if(i >= ARRAY_SIZE(response_type_desc)) + return S_OK; + + nsAString_InitDepend(&nsstr, response_type_desc[i].nsxhr_str); + nsres = nsIXMLHttpRequest_SetResponseType(This->nsxhr, &nsstr); + nsAString_Finish(&nsstr); + if(NS_FAILED(nsres)) + return map_nsresult(nsres); + + This->response_type = i; + return S_OK; }
static HRESULT WINAPI HTMLXMLHttpRequest_private_get_responseType(IWineXMLHttpRequestPrivate *iface, BSTR *p) { HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface);
- FIXME("(%p)->(%p)\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- return E_NOTIMPL; + *p = SysAllocString(response_type_desc[This->response_type].str); + return *p ? S_OK : E_OUTOFMEMORY; }
static HRESULT WINAPI HTMLXMLHttpRequest_private_get_upload(IWineXMLHttpRequestPrivate *iface, IDispatch **p)