Gabriel Ivăncescu : mshtml: Implement responseType prop for XMLHttpRequest.

Alexandre Julliard julliard at winehq.org
Thu Jul 28 16:01:12 CDT 2022


Module: wine
Branch: master
Commit: 6537c36df492cbca018ab7defd83980920044c79
URL:    https://gitlab.winehq.org/wine/wine/-/commit/6537c36df492cbca018ab7defd83980920044c79

Author: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Date:   Thu Jul 28 16:05:35 2022 +0300

mshtml: Implement responseType prop for XMLHttpRequest.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode at 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)




More information about the wine-cvs mailing list