mshtml: Added support for binding XHR events.
This commit is contained in:
parent
7a3c9889e3
commit
8d85da757a
|
@ -256,7 +256,7 @@ static eventid_t attr_to_eid(LPCWSTR str)
|
|||
return EVENTID_LAST;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
struct HTMLEventObj {
|
||||
DispatchEx dispex;
|
||||
IHTMLEventObj IHTMLEventObj_iface;
|
||||
|
||||
|
@ -268,7 +268,7 @@ typedef struct {
|
|||
VARIANT return_value;
|
||||
BOOL prevent_default;
|
||||
BOOL cancel_bubble;
|
||||
} HTMLEventObj;
|
||||
};
|
||||
|
||||
static inline HTMLEventObj *impl_from_IHTMLEventObj(IHTMLEventObj *iface)
|
||||
{
|
||||
|
@ -966,7 +966,7 @@ static BOOL is_cp_event(cp_static_data_t *data, DISPID dispid)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static void call_event_handlers(HTMLDocumentNode *doc, HTMLEventObj *event_obj, EventTarget *event_target,
|
||||
void call_event_handlers(HTMLDocumentNode *doc, HTMLEventObj *event_obj, EventTarget *event_target,
|
||||
ConnectionPointContainer *cp_container, eventid_t eid, IDispatch *this_obj)
|
||||
{
|
||||
event_target_t *data = get_event_target_data(event_target, FALSE);
|
||||
|
|
|
@ -67,6 +67,9 @@ HRESULT create_event_obj(IHTMLEventObj**) DECLSPEC_HIDDEN;
|
|||
void bind_target_event(HTMLDocumentNode*,EventTarget*,const WCHAR*,IDispatch*) DECLSPEC_HIDDEN;
|
||||
HRESULT ensure_doc_nsevent_handler(HTMLDocumentNode*,eventid_t) DECLSPEC_HIDDEN;
|
||||
|
||||
typedef struct HTMLEventObj HTMLEventObj;
|
||||
void call_event_handlers(HTMLDocumentNode*,HTMLEventObj*,EventTarget*,ConnectionPointContainer*,eventid_t,IDispatch*);
|
||||
|
||||
void init_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN;
|
||||
void release_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN;
|
||||
void add_nsevent_listener(HTMLDocumentNode*,nsIDOMNode*,LPCWSTR) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -504,7 +504,7 @@ static void test_async_xhr(IHTMLDocument2 *doc, const char *xml_url)
|
|||
SET_EXPECT(xmlhttprequest_onreadystatechange_opened);
|
||||
hres = IHTMLXMLHttpRequest_open(xhr, method, url, vbool, vempty, vempty);
|
||||
ok(hres == S_OK, "open failed: %08x\n", hres);
|
||||
todo_wine CHECK_CALLED(xmlhttprequest_onreadystatechange_opened);
|
||||
CHECK_CALLED(xmlhttprequest_onreadystatechange_opened);
|
||||
|
||||
SysFreeString(method);
|
||||
SysFreeString(url);
|
||||
|
|
|
@ -60,14 +60,117 @@ static HRESULT variant_to_nsastr(VARIANT var, nsAString *ret)
|
|||
}
|
||||
}
|
||||
|
||||
/* IHTMLXMLHttpRequest */
|
||||
typedef struct XMLHttpReqEventListener XMLHttpReqEventListener;
|
||||
|
||||
typedef struct {
|
||||
EventTarget event_target;
|
||||
IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface;
|
||||
LONG ref;
|
||||
nsIXMLHttpRequest *nsxhr;
|
||||
XMLHttpReqEventListener *event_listener;
|
||||
} HTMLXMLHttpRequest;
|
||||
|
||||
struct XMLHttpReqEventListener {
|
||||
nsIDOMEventListener nsIDOMEventListener_iface;
|
||||
LONG ref;
|
||||
HTMLXMLHttpRequest *xhr;
|
||||
};
|
||||
|
||||
static void detach_xhr_event_listener(XMLHttpReqEventListener *event_listener)
|
||||
{
|
||||
nsIDOMEventTarget *event_target;
|
||||
nsAString str;
|
||||
nsresult nsres;
|
||||
|
||||
static const WCHAR readystatechangeW[] =
|
||||
{'o','n','r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
|
||||
|
||||
nsres = nsIXMLHttpRequest_QueryInterface(event_listener->xhr->nsxhr, &IID_nsIDOMEventTarget, (void**)&event_target);
|
||||
assert(nsres == NS_OK);
|
||||
|
||||
nsAString_InitDepend(&str, readystatechangeW);
|
||||
nsres = nsIDOMEventTarget_RemoveEventListener(event_target, &str, &event_listener->nsIDOMEventListener_iface, FALSE);
|
||||
nsAString_Finish(&str);
|
||||
nsIDOMEventTarget_Release(event_target);
|
||||
|
||||
event_listener->xhr->event_listener = NULL;
|
||||
event_listener->xhr = NULL;
|
||||
nsIDOMEventListener_Release(&event_listener->nsIDOMEventListener_iface);
|
||||
}
|
||||
|
||||
|
||||
static inline XMLHttpReqEventListener *impl_from_nsIDOMEventListener(nsIDOMEventListener *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, XMLHttpReqEventListener, nsIDOMEventListener_iface);
|
||||
}
|
||||
|
||||
static nsresult NSAPI XMLHttpReqEventListener_QueryInterface(nsIDOMEventListener *iface,
|
||||
nsIIDRef riid, void **result)
|
||||
{
|
||||
XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
|
||||
|
||||
if(IsEqualGUID(&IID_nsISupports, riid)) {
|
||||
TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
|
||||
*result = &This->nsIDOMEventListener_iface;
|
||||
}else if(IsEqualGUID(&IID_nsIDOMEventListener, riid)) {
|
||||
TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This, result);
|
||||
*result = &This->nsIDOMEventListener_iface;
|
||||
}else {
|
||||
*result = NULL;
|
||||
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
nsIDOMEventListener_AddRef(&This->nsIDOMEventListener_iface);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsrefcnt NSAPI XMLHttpReqEventListener_AddRef(nsIDOMEventListener *iface)
|
||||
{
|
||||
XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
|
||||
LONG ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static nsrefcnt NSAPI XMLHttpReqEventListener_Release(nsIDOMEventListener *iface)
|
||||
{
|
||||
XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
|
||||
LONG ref = InterlockedDecrement(&This->ref);
|
||||
|
||||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
assert(!This->xhr);
|
||||
heap_free(This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static nsresult NSAPI XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener *iface, nsIDOMEvent *event)
|
||||
{
|
||||
XMLHttpReqEventListener *This = impl_from_nsIDOMEventListener(iface);
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
if(!This->xhr)
|
||||
return NS_OK;
|
||||
|
||||
call_event_handlers(NULL, NULL, &This->xhr->event_target, NULL, EVENTID_READYSTATECHANGE,
|
||||
(IDispatch*)&This->xhr->IHTMLXMLHttpRequest_iface);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static const nsIDOMEventListenerVtbl XMLHttpReqEventListenerVtbl = {
|
||||
XMLHttpReqEventListener_QueryInterface,
|
||||
XMLHttpReqEventListener_AddRef,
|
||||
XMLHttpReqEventListener_Release,
|
||||
XMLHttpReqEventListener_HandleEvent
|
||||
};
|
||||
|
||||
static inline HTMLXMLHttpRequest *impl_from_IHTMLXMLHttpRequest(IHTMLXMLHttpRequest *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, HTMLXMLHttpRequest, IHTMLXMLHttpRequest_iface);
|
||||
|
@ -115,6 +218,8 @@ static ULONG WINAPI HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest *iface)
|
|||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
if(This->event_listener)
|
||||
detach_xhr_event_listener(This->event_listener);
|
||||
release_dispex(&This->event_target.dispex);
|
||||
nsIXMLHttpRequest_Release(This->nsxhr);
|
||||
heap_free(This);
|
||||
|
@ -357,10 +462,36 @@ static inline HTMLXMLHttpRequest *impl_from_DispatchEx(DispatchEx *iface)
|
|||
static void HTMLXMLHttpRequest_bind_event(DispatchEx *dispex, int eid)
|
||||
{
|
||||
HTMLXMLHttpRequest *This = impl_from_DispatchEx(dispex);
|
||||
nsIDOMEventTarget *nstarget;
|
||||
nsAString type_str;
|
||||
nsresult nsres;
|
||||
|
||||
FIXME("(%p)\n", This);
|
||||
static const WCHAR readystatechangeW[] = {'r','e','a','d','y','s','t','a','t','e','c','h','a','n','g','e',0};
|
||||
|
||||
TRACE("(%p)\n", This);
|
||||
|
||||
assert(eid == EVENTID_READYSTATECHANGE);
|
||||
|
||||
if(This->event_listener)
|
||||
return;
|
||||
|
||||
This->event_listener = heap_alloc(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;
|
||||
|
||||
nsres = nsIXMLHttpRequest_QueryInterface(This->nsxhr, &IID_nsIDOMEventTarget, (void**)&nstarget);
|
||||
assert(nsres == NS_OK);
|
||||
|
||||
nsAString_InitDepend(&type_str, readystatechangeW);
|
||||
nsres = nsIDOMEventTarget_AddEventListener(nstarget, &type_str, &This->event_listener->nsIDOMEventListener_iface, FALSE, TRUE, 2);
|
||||
nsAString_Finish(&type_str);
|
||||
nsIDOMEventTarget_Release(nstarget);
|
||||
if(NS_FAILED(nsres))
|
||||
ERR("AddEventListener failed: %08x\n", nsres);
|
||||
}
|
||||
|
||||
static dispex_static_data_vtbl_t HTMLXMLHttpRequest_dispex_vtbl = {
|
||||
|
|
Loading…
Reference in New Issue