Commit 06b1679e authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Register all event handlers when creating the XMLHttpRequest.

So we can properly track state for synchronous XHRs. Signed-off-by: 's avatarGabriel Ivăncescu <gabrielopcode@gmail.com>
parent 59bdd9d0
......@@ -128,7 +128,6 @@ typedef struct {
nsIDOMEventListener nsIDOMEventListener_iface;
LONG ref;
HTMLXMLHttpRequest *xhr;
DWORD events_mask;
} XMLHttpReqEventListener;
struct HTMLXMLHttpRequest {
......@@ -146,16 +145,14 @@ struct HTMLXMLHttpRequest {
static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener)
{
nsIDOMEventTarget *event_target;
DWORD events_mask, i;
nsAString str;
nsresult nsres;
nsAString str;
unsigned i;
nsres = nsIXMLHttpRequest_QueryInterface(event_listener->xhr->nsxhr, &IID_nsIDOMEventTarget, (void**)&event_target);
assert(nsres == NS_OK);
for(events_mask = event_listener->events_mask, i = 0; events_mask; events_mask >>= 1, i++) {
if(!(events_mask & 1))
continue;
for(i = 0; i < ARRAY_SIZE(events) ; i++) {
nsAString_InitDepend(&str, get_event_name(events[i]));
nsres = nsIDOMEventTarget_RemoveEventListener(event_target, &str, &event_listener->nsIDOMEventListener_iface, FALSE);
nsAString_Finish(&str);
......@@ -164,7 +161,6 @@ static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener)
nsIDOMEventTarget_Release(event_target);
event_listener->xhr->event_listener = NULL;
event_listener->xhr = NULL;
nsIDOMEventListener_Release(&event_listener->nsIDOMEventListener_iface);
}
......@@ -298,8 +294,7 @@ static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface)
TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) {
if(This->event_listener)
detach_xhr_event_listener(This->event_listener);
detach_xhr_event_listener(This->event_listener);
release_event_target(&This->event_target);
release_dispex(&This->event_target.dispex);
nsIXMLHttpRequest_Release(This->nsxhr);
......@@ -1287,45 +1282,8 @@ static nsISupports *HTMLXMLHttpRequest_get_gecko_target(DispatchEx *dispex)
static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, eventid_t eid)
{
HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
nsIDOMEventTarget *nstarget;
nsAString type_str;
const WCHAR *name;
nsresult nsres;
unsigned i;
TRACE("(%p)\n", This);
for(i = 0; i < ARRAY_SIZE(events); i++)
if(eid == events[i])
break;
if(i >= ARRAY_SIZE(events))
return;
if(!This->event_listener) {
This->event_listener = malloc(sizeof(*This->event_listener));
if(!This->event_listener)
return;
This->event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl;
This->event_listener->ref = 1;
This->event_listener->xhr = This;
This->event_listener->events_mask = 0;
}
nsres = nsIXMLHttpRequest_QueryInterface(This->nsxhr, &IID_nsIDOMEventTarget, (void**)&nstarget);
assert(nsres == NS_OK);
name = get_event_name(events[i]);
nsAString_InitDepend(&type_str, name);
nsres = nsIDOMEventTarget_AddEventListener(nstarget, &type_str, &This->event_listener->nsIDOMEventListener_iface, FALSE, TRUE, 2);
nsAString_Finish(&type_str);
if(NS_FAILED(nsres))
ERR("AddEventListener(%s) failed: %08lx\n", debugstr_w(name), nsres);
nsIDOMEventTarget_Release(nstarget);
This->event_listener->events_mask |= 1 << i;
/* Do nothing. To be able to track state and queue events manually, when blocked
* by sync XHRs in their send() event loop, we always register the handlers. */
}
static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode)
......@@ -1471,6 +1429,10 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor
HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
HTMLXMLHttpRequest *ret;
nsIXMLHttpRequest *nsxhr;
nsIDOMEventTarget *nstarget;
XMLHttpReqEventListener *event_listener;
nsresult nsres;
unsigned i;
TRACE("(%p)->(%p)\n", This, p);
......@@ -1483,6 +1445,14 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor
nsIXMLHttpRequest_Release(nsxhr);
return E_OUTOFMEMORY;
}
event_listener = malloc(sizeof(*event_listener));
if(!event_listener) {
free(ret);
nsIXMLHttpRequest_Release(nsxhr);
return E_OUTOFMEMORY;
}
ret->nsxhr = nsxhr;
ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl;
......@@ -1493,6 +1463,30 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor
&HTMLXMLHttpRequest_dispex, This->window->doc->document_mode);
ret->ref = 1;
/* Always register the handlers because we need them to track state */
event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl;
event_listener->ref = 1;
event_listener->xhr = ret;
ret->event_listener = event_listener;
nsres = nsIXMLHttpRequest_QueryInterface(nsxhr, &IID_nsIDOMEventTarget, (void**)&nstarget);
assert(nsres == NS_OK);
for(i = 0; i < ARRAY_SIZE(events); i++) {
const WCHAR *name = get_event_name(events[i]);
nsAString type_str;
nsAString_InitDepend(&type_str, name);
nsres = nsIDOMEventTarget_AddEventListener(nstarget, &type_str, &event_listener->nsIDOMEventListener_iface, FALSE, TRUE, 2);
nsAString_Finish(&type_str);
if(NS_FAILED(nsres)) {
WARN("AddEventListener(%s) failed: %08lx\n", debugstr_w(name), nsres);
IHTMLXMLHttpRequest_Release(&ret->IHTMLXMLHttpRequest_iface);
return map_nsresult(nsres);
}
}
nsIDOMEventTarget_Release(nstarget);
*p = &ret->IHTMLXMLHttpRequest_iface;
return S_OK;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment