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 { ...@@ -128,7 +128,6 @@ typedef struct {
nsIDOMEventListener nsIDOMEventListener_iface; nsIDOMEventListener nsIDOMEventListener_iface;
LONG ref; LONG ref;
HTMLXMLHttpRequest *xhr; HTMLXMLHttpRequest *xhr;
DWORD events_mask;
} XMLHttpReqEventListener; } XMLHttpReqEventListener;
struct HTMLXMLHttpRequest { struct HTMLXMLHttpRequest {
...@@ -146,16 +145,14 @@ struct HTMLXMLHttpRequest { ...@@ -146,16 +145,14 @@ struct HTMLXMLHttpRequest {
static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener) static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener)
{ {
nsIDOMEventTarget *event_target; nsIDOMEventTarget *event_target;
DWORD events_mask, i;
nsAString str;
nsresult nsres; nsresult nsres;
nsAString str;
unsigned i;
nsres = nsIXMLHttpRequest_QueryInterface(event_listener->xhr->nsxhr, &IID_nsIDOMEventTarget, (void**)&event_target); nsres = nsIXMLHttpRequest_QueryInterface(event_listener->xhr->nsxhr, &IID_nsIDOMEventTarget, (void**)&event_target);
assert(nsres == NS_OK); assert(nsres == NS_OK);
for(events_mask = event_listener->events_mask, i = 0; events_mask; events_mask >>= 1, i++) { for(i = 0; i < ARRAY_SIZE(events) ; i++) {
if(!(events_mask & 1))
continue;
nsAString_InitDepend(&str, get_event_name(events[i])); nsAString_InitDepend(&str, get_event_name(events[i]));
nsres = nsIDOMEventTarget_RemoveEventListener(event_target, &str, &event_listener->nsIDOMEventListener_iface, FALSE); nsres = nsIDOMEventTarget_RemoveEventListener(event_target, &str, &event_listener->nsIDOMEventListener_iface, FALSE);
nsAString_Finish(&str); nsAString_Finish(&str);
...@@ -164,7 +161,6 @@ static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener) ...@@ -164,7 +161,6 @@ static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener)
nsIDOMEventTarget_Release(event_target); nsIDOMEventTarget_Release(event_target);
event_listener->xhr->event_listener = NULL;
event_listener->xhr = NULL; event_listener->xhr = NULL;
nsIDOMEventListener_Release(&event_listener->nsIDOMEventListener_iface); nsIDOMEventListener_Release(&event_listener->nsIDOMEventListener_iface);
} }
...@@ -298,8 +294,7 @@ static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface) ...@@ -298,8 +294,7 @@ static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface)
TRACE("(%p) ref=%ld\n", This, ref); TRACE("(%p) ref=%ld\n", This, ref);
if(!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_event_target(&This->event_target);
release_dispex(&This->event_target.dispex); release_dispex(&This->event_target.dispex);
nsIXMLHttpRequest_Release(This->nsxhr); nsIXMLHttpRequest_Release(This->nsxhr);
...@@ -1287,45 +1282,8 @@ static nsISupports *HTMLXMLHttpRequest_get_gecko_target(DispatchEx *dispex) ...@@ -1287,45 +1282,8 @@ static nsISupports *HTMLXMLHttpRequest_get_gecko_target(DispatchEx *dispex)
static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, eventid_t eid) static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, eventid_t eid)
{ {
HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex); /* Do nothing. To be able to track state and queue events manually, when blocked
nsIDOMEventTarget *nstarget; * by sync XHRs in their send() event loop, we always register the handlers. */
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;
} }
static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode) 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 ...@@ -1471,6 +1429,10 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor
HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface); HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface);
HTMLXMLHttpRequest *ret; HTMLXMLHttpRequest *ret;
nsIXMLHttpRequest *nsxhr; nsIXMLHttpRequest *nsxhr;
nsIDOMEventTarget *nstarget;
XMLHttpReqEventListener *event_listener;
nsresult nsres;
unsigned i;
TRACE("(%p)->(%p)\n", This, p); TRACE("(%p)->(%p)\n", This, p);
...@@ -1483,6 +1445,14 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor ...@@ -1483,6 +1445,14 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor
nsIXMLHttpRequest_Release(nsxhr); nsIXMLHttpRequest_Release(nsxhr);
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
event_listener = malloc(sizeof(*event_listener));
if(!event_listener) {
free(ret);
nsIXMLHttpRequest_Release(nsxhr);
return E_OUTOFMEMORY;
}
ret->nsxhr = nsxhr; ret->nsxhr = nsxhr;
ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl; ret->IHTMLXMLHttpRequest_iface.lpVtbl = &HTMLXMLHttpRequestVtbl;
...@@ -1493,6 +1463,30 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor ...@@ -1493,6 +1463,30 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor
&HTMLXMLHttpRequest_dispex, This->window->doc->document_mode); &HTMLXMLHttpRequest_dispex, This->window->doc->document_mode);
ret->ref = 1; 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; *p = &ret->IHTMLXMLHttpRequest_iface;
return S_OK; 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