From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/xhr.js | 2 +- dlls/mshtml/tests/xmlhttprequest.c | 8 ++++---- dlls/mshtml/xmlhttprequest.c | 33 +++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index c6d8b400af0..7799480e14a 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -155,7 +155,7 @@ function test_sync_xhr() {
window.setTimeout(function() { var r = a.join(","); - todo_wine_if(document.documentMode < 10 || document.documentMode >= 11). + todo_wine_if(document.documentMode >= 11). ok(r === "0,1,2,3," + (document.documentMode < 10 ? "sync_xhr(1),sync_xhr(2),sync_xhr(3)," : "") + "sync_xhr(4)," + (document.documentMode < 10 ? "nested(1),nested(2),nested(3)," : "") + "nested(4),click," + (document.documentMode < 11 ? "dblclick," : "") + diff --git a/dlls/mshtml/tests/xmlhttprequest.c b/dlls/mshtml/tests/xmlhttprequest.c index 2415ac8eb0f..6226461a502 100644 --- a/dlls/mshtml/tests/xmlhttprequest.c +++ b/dlls/mshtml/tests/xmlhttprequest.c @@ -712,11 +712,11 @@ static void test_sync_xhr(IHTMLDocument2 *doc, const WCHAR *xml_url, const WCHAR loading_cnt = 0; hres = IHTMLXMLHttpRequest_send(xhr, vempty); ok(hres == S_OK, "send failed: %08lx\n", hres); - todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_opened); - todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_headers_received); - todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_loading); + CHECK_CALLED(xmlhttprequest_onreadystatechange_opened); + CHECK_CALLED(xmlhttprequest_onreadystatechange_headers_received); + CHECK_CALLED(xmlhttprequest_onreadystatechange_loading); CHECK_CALLED(xmlhttprequest_onreadystatechange_done); - todo_wine ok(loading_cnt == 1, "loading_cnt = %d\n", loading_cnt); + ok(loading_cnt == 1, "loading_cnt = %d\n", loading_cnt);
text = NULL; hres = IHTMLXMLHttpRequest_getResponseHeader(xhr, content_type, &text); diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index b932e9df0a7..39fc4526817 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -142,6 +142,7 @@ struct HTMLXMLHttpRequest { size_t responseText_length; response_type_t response_type; BOOL synchronous; + HTMLInnerWindow *window; nsIXMLHttpRequest *nsxhr; XMLHttpReqEventListener *event_listener; }; @@ -274,6 +275,7 @@ static nsresult NSAPI XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener *i XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface); thread_data_t *thread_data; size_t responseText_length; + compat_mode_t compat_mode; const PRUnichar *text; nsAString nsstr; DOMEvent *event; @@ -304,7 +306,8 @@ static nsresult NSAPI XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener *i } }
- hres = create_event_from_nsevent(nsevent, dispex_compat_mode(&This->xhr->event_target.dispex), &event); + compat_mode = dispex_compat_mode(&This->xhr->event_target.dispex); + hres = create_event_from_nsevent(nsevent, compat_mode, &event); if(SUCCEEDED(hres) ){ if(!(thread_data = get_thread_data(FALSE)) || thread_data->blocking_event_dispatch_depth == ~0) thread_data = NULL; @@ -336,6 +339,31 @@ static nsresult NSAPI XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener *i
/* Temporarily increase the dispatch depth to allow this event to be dispatched */ thread_data->event_dispatch_depth++; + + /* IE10+ only send readystatechange event when it is DONE for sync XHRs, but older modes + send all the others here, including OPENED state change (even if it was opened earlier). */ + if(compat_mode < COMPAT_MODE_IE10 && This->xhr->readyState < 4 && ( + event->event_id == EVENTID_READYSTATECHANGE || event->event_id == EVENTID_PROGRESS || event->event_id == EVENTID_LOADSTART)) { + DOMEvent *readystatechange_event; + unsigned i; + + for(i = 1; i < 4; i++) { + hres = create_document_event(This->xhr->window->doc, EVENTID_READYSTATECHANGE, &readystatechange_event); + if(FAILED(hres)) + break; + + This->xhr->readyState = i; + dispatch_event(&This->xhr->event_target, readystatechange_event); + IDOMEvent_Release(&readystatechange_event->IDOMEvent_iface); + + /* Check if it was aborted (or somehow changed) in the handler */ + if(This->xhr->readyState != i) { + IDOMEvent_Release(&event->IDOMEvent_iface); + thread_data->event_dispatch_depth--; + return NS_OK; + } + } + } }
This->xhr->readyState = readyState; @@ -415,6 +443,7 @@ static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface) if(!ref) { if(This->event_listener) detach_xhr_event_listener(This->event_listener); + IHTMLWindow2_Release(&This->window->base.IHTMLWindow2_iface); release_event_target(&This->event_target); release_dispex(&This->event_target.dispex); nsIXMLHttpRequest_Release(This->nsxhr); @@ -1593,6 +1622,8 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor return E_OUTOFMEMORY; } ret->nsxhr = nsxhr; + ret->window = This->window; + IHTMLWindow2_AddRef(&This->window->base.IHTMLWindow2_iface);
ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl; ret->IHTMLXMLHttpRequest2_iface.lpVtbl = &HTMLXMLHttpRequest2Vtbl;