The first (unrelated) patch was my fault for messing it up the first time on the last MR, and it seems to have been lost on your changes. Sorry for the noise.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlelem.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 826d131df77..f8fa285999e 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -4857,6 +4857,7 @@ static HRESULT WINAPI HTMLElement6_setAttributeNS(IHTMLElement6 *iface, VARIANT return hres; nsAString_GetData(&ns_str, &ns); if((!ns || !ns[0]) && wcschr(strAttributeName, ':')) { + nsAString_Finish(&ns_str); /* FIXME: Return NamespaceError */ return E_FAIL; }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
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)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Also basic implementation of arraybuffer/blob with invalid state, mostly to show how the tests will look.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/xhr.js | 47 +++++++++++++++++++++++++++++++++++- dlls/mshtml/xmlhttprequest.c | 41 +++++++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index 68f3a68caee..d60a449678b 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -245,10 +245,55 @@ function test_responseType() { xhr.send("responseType test"); }
+function test_response() { + var xhr = new XMLHttpRequest(), i = 0; + if(!("response" in xhr)) { next_test(); return; } + + var types = [ + [ "text", "application/octet-stream", function() { + if(xhr.readyState < 3) + ok(xhr.response === "", "response for text with state " + state + " = " + xhr.response); + else if(xhr.readyState === 4) + ok(xhr.response === xml, "response for text = " + xhr.response); + }], + [ "arraybuffer", "image/png", function() { + if(xhr.readyState < 4) + ok(xhr.response === undefined, "response for arraybuffer with state " + state + " = " + xhr.response); + }], + [ "blob", "wine/test", function() { + if(xhr.readyState < 4) + ok(xhr.response === undefined, "response for blob with state " + state + " = " + xhr.response); + }] + ]; + + function onreadystatechange() { + types[i][2](); + if(xhr.readyState < 4) + return; + if(++i >= types.length) { + next_test(); + return; + } + xhr = new XMLHttpRequest(); + xhr.open("POST", "echo.php?content-type=" + types[i][1], true); + xhr.onreadystatechange = onreadystatechange; + xhr.setRequestHeader("X-Test", "True"); + xhr.responseType = types[i][0]; + xhr.send(xml); + } + + xhr.open("POST", "echo.php?content-type=" + types[i][1], true); + xhr.onreadystatechange = onreadystatechange; + xhr.setRequestHeader("X-Test", "True"); + xhr.responseType = types[i][0]; + xhr.send(xml); +} + var tests = [ test_xhr, test_content_types, test_abort, test_timeout, - test_responseType + test_responseType, + test_response ]; diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 6f639d3b821..e01c9791f6f 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -938,10 +938,47 @@ static HRESULT WINAPI HTMLXMLHttpRequest_private_Invoke(IWineXMLHttpRequestPriva static HRESULT WINAPI HTMLXMLHttpRequest_private_get_response(IWineXMLHttpRequestPrivate *iface, VARIANT *p) { HTMLXMLHttpRequest *This = impl_from_IWineXMLHttpRequestPrivate(iface); + HRESULT hres = S_OK; + nsresult nsres; + UINT16 state;
- FIXME("(%p)->(%p)\n", This, p); + TRACE("(%p)->(%p)\n", This, p);
- return E_NOTIMPL; + switch(This->response_type) { + case response_type_empty: + case response_type_text: + hres = IHTMLXMLHttpRequest_get_responseText(&This->IHTMLXMLHttpRequest_iface, &V_BSTR(p)); + if(SUCCEEDED(hres)) + V_VT(p) = VT_BSTR; + break; + + case response_type_doc: + FIXME("response_type_doc\n"); + return E_NOTIMPL; + + case response_type_arraybuf: + case response_type_blob: + nsres = nsIXMLHttpRequest_GetReadyState(This->nsxhr, &state); + if(NS_FAILED(nsres) || state < 4) { + V_VT(p) = VT_EMPTY; + break; + } + if(This->response_type == response_type_arraybuf) { + FIXME("response_type_arraybuf\n"); + return E_NOTIMPL; + } + FIXME("response_type_blob\n"); + return E_NOTIMPL; + + case response_type_stream: + FIXME("response_type_stream\n"); + return E_NOTIMPL; + + default: + assert(0); + } + + return hres; }
static HRESULT WINAPI HTMLXMLHttpRequest_private_put_responseType(IWineXMLHttpRequestPrivate *iface, BSTR v)
This merge request was approved by Jacek Caban.