2 * Copyright 2015 Zhenbo Li
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/debug.h"
31 #include "mshtml_private.h"
32 #include "htmlevent.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
39 #define MSHTML_DISPID_HTMLXMLHTTPREQUEST_ONLOAD MSHTML_DISPID_CUSTOM_MIN
41 static HRESULT
bstr_to_nsacstr(BSTR bstr
, nsACString
*str
)
43 char *cstr
= heap_strdupWtoU(bstr
);
46 nsACString_Init(str
, cstr
);
51 static HRESULT
variant_to_nsastr(VARIANT var
, nsAString
*ret
)
57 nsAString_Init(ret
, NULL
);
60 nsAString_InitDepend(ret
, V_BSTR(&var
));
63 FIXME("Unsupported VARIANT: %s\n", debugstr_variant(&var
));
68 static HRESULT
return_nscstr(nsresult nsres
, nsACString
*nscstr
, BSTR
*p
)
73 if(NS_FAILED(nsres
)) {
74 ERR("failed: %08x\n", nsres
);
75 nsACString_Finish(nscstr
);
79 nsACString_GetData(nscstr
, &str
);
82 len
= MultiByteToWideChar(CP_UTF8
, 0, str
, -1, NULL
, 0);
83 *p
= SysAllocStringLen(NULL
, len
- 1);
85 nsACString_Finish(nscstr
);
88 MultiByteToWideChar(CP_UTF8
, 0, str
, -1, *p
, len
);
93 nsACString_Finish(nscstr
);
98 nsIDOMEventListener nsIDOMEventListener_iface
;
100 HTMLXMLHttpRequest
*xhr
;
101 BOOL readystatechange_event
;
103 } XMLHttpReqEventListener
;
105 struct HTMLXMLHttpRequest
{
106 EventTarget event_target
;
107 IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface
;
108 IProvideClassInfo2 IProvideClassInfo2_iface
;
110 nsIXMLHttpRequest
*nsxhr
;
111 XMLHttpReqEventListener
*event_listener
;
114 static void detach_xhr_event_listener(XMLHttpReqEventListener
*event_listener
)
116 nsIDOMEventTarget
*event_target
;
120 nsres
= nsIXMLHttpRequest_QueryInterface(event_listener
->xhr
->nsxhr
, &IID_nsIDOMEventTarget
, (void**)&event_target
);
121 assert(nsres
== NS_OK
);
123 if(event_listener
->readystatechange_event
) {
124 nsAString_InitDepend(&str
, L
"onreadystatechange");
125 nsres
= nsIDOMEventTarget_RemoveEventListener(event_target
, &str
, &event_listener
->nsIDOMEventListener_iface
, FALSE
);
126 nsAString_Finish(&str
);
127 assert(nsres
== NS_OK
);
130 if(event_listener
->load_event
) {
131 nsAString_InitDepend(&str
, L
"load");
132 nsres
= nsIDOMEventTarget_RemoveEventListener(event_target
, &str
, &event_listener
->nsIDOMEventListener_iface
, FALSE
);
133 nsAString_Finish(&str
);
134 assert(nsres
== NS_OK
);
137 nsIDOMEventTarget_Release(event_target
);
139 event_listener
->xhr
->event_listener
= NULL
;
140 event_listener
->xhr
= NULL
;
141 nsIDOMEventListener_Release(&event_listener
->nsIDOMEventListener_iface
);
145 static inline XMLHttpReqEventListener
*impl_from_nsIDOMEventListener(nsIDOMEventListener
*iface
)
147 return CONTAINING_RECORD(iface
, XMLHttpReqEventListener
, nsIDOMEventListener_iface
);
150 static nsresult NSAPI
XMLHttpReqEventListener_QueryInterface(nsIDOMEventListener
*iface
,
151 nsIIDRef riid
, void **result
)
153 XMLHttpReqEventListener
*This
= impl_from_nsIDOMEventListener(iface
);
155 if(IsEqualGUID(&IID_nsISupports
, riid
)) {
156 TRACE("(%p)->(IID_nsISupports, %p)\n", This
, result
);
157 *result
= &This
->nsIDOMEventListener_iface
;
158 }else if(IsEqualGUID(&IID_nsIDOMEventListener
, riid
)) {
159 TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This
, result
);
160 *result
= &This
->nsIDOMEventListener_iface
;
163 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), result
);
164 return NS_NOINTERFACE
;
167 nsIDOMEventListener_AddRef(&This
->nsIDOMEventListener_iface
);
171 static nsrefcnt NSAPI
XMLHttpReqEventListener_AddRef(nsIDOMEventListener
*iface
)
173 XMLHttpReqEventListener
*This
= impl_from_nsIDOMEventListener(iface
);
174 LONG ref
= InterlockedIncrement(&This
->ref
);
176 TRACE("(%p) ref=%d\n", This
, ref
);
181 static nsrefcnt NSAPI
XMLHttpReqEventListener_Release(nsIDOMEventListener
*iface
)
183 XMLHttpReqEventListener
*This
= impl_from_nsIDOMEventListener(iface
);
184 LONG ref
= InterlockedDecrement(&This
->ref
);
186 TRACE("(%p) ref=%d\n", This
, ref
);
196 static nsresult NSAPI
XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener
*iface
, nsIDOMEvent
*nsevent
)
198 XMLHttpReqEventListener
*This
= impl_from_nsIDOMEventListener(iface
);
202 TRACE("(%p)\n", This
);
207 hres
= create_event_from_nsevent(nsevent
, &event
);
208 if(SUCCEEDED(hres
) ){
209 dispatch_event(&This
->xhr
->event_target
, event
);
210 IDOMEvent_Release(&event
->IDOMEvent_iface
);
215 static const nsIDOMEventListenerVtbl XMLHttpReqEventListenerVtbl
= {
216 XMLHttpReqEventListener_QueryInterface
,
217 XMLHttpReqEventListener_AddRef
,
218 XMLHttpReqEventListener_Release
,
219 XMLHttpReqEventListener_HandleEvent
222 static inline HTMLXMLHttpRequest
*impl_from_IHTMLXMLHttpRequest(IHTMLXMLHttpRequest
*iface
)
224 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequest
, IHTMLXMLHttpRequest_iface
);
227 static HRESULT WINAPI
HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest
*iface
, REFIID riid
, void **ppv
)
229 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
231 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
233 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
234 *ppv
= &This
->IHTMLXMLHttpRequest_iface
;
235 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
236 *ppv
= &This
->IHTMLXMLHttpRequest_iface
;
237 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest
, riid
)) {
238 *ppv
= &This
->IHTMLXMLHttpRequest_iface
;
239 }else if(IsEqualGUID(&IID_IProvideClassInfo
, riid
)) {
240 *ppv
= &This
->IProvideClassInfo2_iface
;
241 }else if(IsEqualGUID(&IID_IProvideClassInfo2
, riid
)) {
242 *ppv
= &This
->IProvideClassInfo2_iface
;
244 return EventTarget_QI(&This
->event_target
, riid
, ppv
);
247 IUnknown_AddRef((IUnknown
*)*ppv
);
251 static ULONG WINAPI
HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest
*iface
)
253 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
254 LONG ref
= InterlockedIncrement(&This
->ref
);
256 TRACE("(%p) ref=%d\n", This
, ref
);
261 static ULONG WINAPI
HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest
*iface
)
263 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
264 LONG ref
= InterlockedDecrement(&This
->ref
);
266 TRACE("(%p) ref=%d\n", This
, ref
);
269 if(This
->event_listener
)
270 detach_xhr_event_listener(This
->event_listener
);
271 release_event_target(&This
->event_target
);
272 release_dispex(&This
->event_target
.dispex
);
273 nsIXMLHttpRequest_Release(This
->nsxhr
);
280 static HRESULT WINAPI
HTMLXMLHttpRequest_GetTypeInfoCount(IHTMLXMLHttpRequest
*iface
, UINT
*pctinfo
)
282 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
283 return IDispatchEx_GetTypeInfoCount(&This
->event_target
.dispex
.IDispatchEx_iface
, pctinfo
);
286 static HRESULT WINAPI
HTMLXMLHttpRequest_GetTypeInfo(IHTMLXMLHttpRequest
*iface
, UINT iTInfo
,
287 LCID lcid
, ITypeInfo
**ppTInfo
)
289 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
291 return IDispatchEx_GetTypeInfo(&This
->event_target
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
294 static HRESULT WINAPI
HTMLXMLHttpRequest_GetIDsOfNames(IHTMLXMLHttpRequest
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
295 LCID lcid
, DISPID
*rgDispId
)
297 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
299 return IDispatchEx_GetIDsOfNames(&This
->event_target
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
303 static HRESULT WINAPI
HTMLXMLHttpRequest_Invoke(IHTMLXMLHttpRequest
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
304 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
306 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
308 return IDispatchEx_Invoke(&This
->event_target
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
, wFlags
,
309 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
312 static HRESULT WINAPI
HTMLXMLHttpRequest_get_readyState(IHTMLXMLHttpRequest
*iface
, LONG
*p
)
314 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
318 TRACE("(%p)->(%p)\n", This
, p
);
322 nsres
= nsIXMLHttpRequest_GetReadyState(This
->nsxhr
, &val
);
323 if(NS_FAILED(nsres
)) {
324 ERR("nsIXMLHttpRequest_GetReadyState failed: %08x\n", nsres
);
331 static HRESULT WINAPI
HTMLXMLHttpRequest_get_responseBody(IHTMLXMLHttpRequest
*iface
, VARIANT
*p
)
333 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
334 FIXME("(%p)->(%p)\n", This
, p
);
338 static HRESULT WINAPI
HTMLXMLHttpRequest_get_responseText(IHTMLXMLHttpRequest
*iface
, BSTR
*p
)
340 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
344 TRACE("(%p)->(%p)\n", This
, p
);
349 nsAString_Init(&nsstr
, NULL
);
350 nsres
= nsIXMLHttpRequest_GetResponseText(This
->nsxhr
, &nsstr
);
351 return return_nsstr(nsres
, &nsstr
, p
);
354 static HRESULT WINAPI
HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest
*iface
, IDispatch
**p
)
356 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
357 IXMLDOMDocument
*xmldoc
= NULL
;
361 IObjectSafety
*safety
;
363 TRACE("(%p)->(%p)\n", This
, p
);
365 hres
= CoCreateInstance(&CLSID_DOMDocument
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IXMLDOMDocument
, (void**)&xmldoc
);
367 ERR("CoCreateInstance failed: %08x\n", hres
);
371 hres
= IHTMLXMLHttpRequest_get_responseText(iface
, &str
);
373 IXMLDOMDocument_Release(xmldoc
);
374 ERR("get_responseText failed: %08x\n", hres
);
378 hres
= IXMLDOMDocument_loadXML(xmldoc
, str
, &vbool
);
380 if(hres
!= S_OK
|| vbool
!= VARIANT_TRUE
)
381 WARN("loadXML failed: %08x, returning an empty xmldoc\n", hres
);
383 hres
= IXMLDOMDocument_QueryInterface(xmldoc
, &IID_IObjectSafety
, (void**)&safety
);
384 assert(SUCCEEDED(hres
));
385 hres
= IObjectSafety_SetInterfaceSafetyOptions(safety
, NULL
,
386 INTERFACESAFE_FOR_UNTRUSTED_CALLER
| INTERFACESAFE_FOR_UNTRUSTED_DATA
| INTERFACE_USES_SECURITY_MANAGER
,
387 INTERFACESAFE_FOR_UNTRUSTED_CALLER
| INTERFACESAFE_FOR_UNTRUSTED_DATA
| INTERFACE_USES_SECURITY_MANAGER
);
388 assert(SUCCEEDED(hres
));
389 IObjectSafety_Release(safety
);
391 *p
= (IDispatch
*)xmldoc
;
395 static HRESULT WINAPI
HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest
*iface
, LONG
*p
)
397 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
400 TRACE("(%p)->(%p)\n", This
, p
);
405 nsres
= nsIXMLHttpRequest_GetStatus(This
->nsxhr
, &val
);
406 if(NS_FAILED(nsres
)) {
407 ERR("nsIXMLHttpRequest_GetStatus failed: %08x\n", nsres
);
412 return E_FAIL
; /* WinAPI thinks this is an error */
417 static HRESULT WINAPI
HTMLXMLHttpRequest_get_statusText(IHTMLXMLHttpRequest
*iface
, BSTR
*p
)
419 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
425 TRACE("(%p)->(%p)\n", This
, p
);
430 hres
= IHTMLXMLHttpRequest_get_readyState(iface
, &state
);
439 nsACString_Init(&nscstr
, NULL
);
440 nsres
= nsIXMLHttpRequest_GetStatusText(This
->nsxhr
, &nscstr
);
441 return return_nscstr(nsres
, &nscstr
, p
);
444 static HRESULT WINAPI
HTMLXMLHttpRequest_put_onreadystatechange(IHTMLXMLHttpRequest
*iface
, VARIANT v
)
446 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
448 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
450 return set_event_handler(&This
->event_target
, EVENTID_READYSTATECHANGE
, &v
);
453 static HRESULT WINAPI
HTMLXMLHttpRequest_get_onreadystatechange(IHTMLXMLHttpRequest
*iface
, VARIANT
*p
)
455 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
457 TRACE("(%p)->(%p)\n", This
, p
);
459 return get_event_handler(&This
->event_target
, EVENTID_READYSTATECHANGE
, p
);
462 static HRESULT WINAPI
HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest
*iface
)
464 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
467 TRACE("(%p)->()\n", This
);
469 nsres
= nsIXMLHttpRequest_SlowAbort(This
->nsxhr
);
470 if(NS_FAILED(nsres
)) {
471 ERR("nsIXMLHttpRequest_SlowAbort failed: %08x\n", nsres
);
478 static HRESULT WINAPI
HTMLXMLHttpRequest_open(IHTMLXMLHttpRequest
*iface
, BSTR bstrMethod
, BSTR bstrUrl
, VARIANT varAsync
, VARIANT varUser
, VARIANT varPassword
)
480 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
481 nsACString method
, url
;
482 nsAString user
, password
;
486 TRACE("(%p)->(%s %s %s %s %s)\n", This
, debugstr_w(bstrMethod
), debugstr_w(bstrUrl
), debugstr_variant(&varAsync
), debugstr_variant(&varUser
), debugstr_variant(&varPassword
));
488 if(V_VT(&varAsync
) != VT_BOOL
) {
489 FIXME("varAsync not supported: %s\n", debugstr_variant(&varAsync
));
493 /* Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27),
494 * synchronous requests on the main thread have been deprecated due to the negative
495 * effects to the user experience.
497 if(!V_BOOL(&varAsync
)) {
498 FIXME("Synchronous request is not supported yet\n");
502 hres
= variant_to_nsastr(varUser
, &user
);
505 hres
= variant_to_nsastr(varPassword
, &password
);
507 nsAString_Finish(&user
);
511 hres
= bstr_to_nsacstr(bstrMethod
, &method
);
513 nsAString_Finish(&user
);
514 nsAString_Finish(&password
);
517 hres
= bstr_to_nsacstr(bstrUrl
, &url
);
519 nsAString_Finish(&user
);
520 nsAString_Finish(&password
);
521 nsACString_Finish(&method
);
525 nsres
= nsIXMLHttpRequest_Open(This
->nsxhr
, &method
, &url
, TRUE
,
526 &user
, &password
, 0);
528 nsACString_Finish(&method
);
529 nsACString_Finish(&url
);
530 nsAString_Finish(&user
);
531 nsAString_Finish(&password
);
533 if(NS_FAILED(nsres
)) {
534 ERR("nsIXMLHttpRequest_Open failed: %08x\n", nsres
);
541 static HRESULT WINAPI
HTMLXMLHttpRequest_send(IHTMLXMLHttpRequest
*iface
, VARIANT varBody
)
543 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
544 nsIWritableVariant
*nsbody
= NULL
;
545 nsresult nsres
= NS_OK
;
547 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varBody
));
549 switch(V_VT(&varBody
)) {
557 nsbody
= create_nsvariant();
559 return E_OUTOFMEMORY
;
561 nsAString_InitDepend(&nsstr
, V_BSTR(&varBody
));
562 nsres
= nsIWritableVariant_SetAsAString(nsbody
, &nsstr
);
563 nsAString_Finish(&nsstr
);
567 FIXME("unsupported body type %s\n", debugstr_variant(&varBody
));
571 if(NS_SUCCEEDED(nsres
))
572 nsres
= nsIXMLHttpRequest_Send(This
->nsxhr
, (nsIVariant
*)nsbody
);
574 nsIWritableVariant_Release(nsbody
);
575 if(NS_FAILED(nsres
)) {
576 ERR("nsIXMLHttpRequest_Send failed: %08x\n", nsres
);
583 static HRESULT WINAPI
HTMLXMLHttpRequest_getAllResponseHeaders(IHTMLXMLHttpRequest
*iface
, BSTR
*p
)
585 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
591 TRACE("(%p)->(%p)\n", This
, p
);
596 hres
= IHTMLXMLHttpRequest_get_readyState(iface
, &state
);
605 nsACString_Init(&nscstr
, NULL
);
606 nsres
= nsIXMLHttpRequest_GetAllResponseHeaders(This
->nsxhr
, &nscstr
);
607 return return_nscstr(nsres
, &nscstr
, p
);
610 static HRESULT WINAPI
HTMLXMLHttpRequest_getResponseHeader(IHTMLXMLHttpRequest
*iface
, BSTR bstrHeader
, BSTR
*p
)
612 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
613 nsACString header
, ret
;
618 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(bstrHeader
), p
);
625 hres
= IHTMLXMLHttpRequest_get_readyState(iface
, &state
);
634 cstr
= heap_strdupWtoU(bstrHeader
);
635 nsACString_InitDepend(&header
, cstr
);
636 nsACString_Init(&ret
, NULL
);
638 nsres
= nsIXMLHttpRequest_GetResponseHeader(This
->nsxhr
, &header
, &ret
);
640 nsACString_Finish(&header
);
642 return return_nscstr(nsres
, &ret
, p
);
645 static HRESULT WINAPI
HTMLXMLHttpRequest_setRequestHeader(IHTMLXMLHttpRequest
*iface
, BSTR bstrHeader
, BSTR bstrValue
)
647 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
648 char *header_u
, *value_u
;
649 nsACString header
, value
;
652 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(bstrHeader
), debugstr_w(bstrValue
));
654 header_u
= heap_strdupWtoU(bstrHeader
);
655 if(bstrHeader
&& !header_u
)
656 return E_OUTOFMEMORY
;
658 value_u
= heap_strdupWtoU(bstrValue
);
659 if(bstrValue
&& !value_u
) {
661 return E_OUTOFMEMORY
;
664 nsACString_InitDepend(&header
, header_u
);
665 nsACString_InitDepend(&value
, value_u
);
666 nsres
= nsIXMLHttpRequest_SetRequestHeader(This
->nsxhr
, &header
, &value
);
667 nsACString_Finish(&header
);
668 nsACString_Finish(&value
);
671 if(NS_FAILED(nsres
)) {
672 ERR("SetRequestHeader failed: %08x\n", nsres
);
679 static const IHTMLXMLHttpRequestVtbl HTMLXMLHttpRequestVtbl
= {
680 HTMLXMLHttpRequest_QueryInterface
,
681 HTMLXMLHttpRequest_AddRef
,
682 HTMLXMLHttpRequest_Release
,
683 HTMLXMLHttpRequest_GetTypeInfoCount
,
684 HTMLXMLHttpRequest_GetTypeInfo
,
685 HTMLXMLHttpRequest_GetIDsOfNames
,
686 HTMLXMLHttpRequest_Invoke
,
687 HTMLXMLHttpRequest_get_readyState
,
688 HTMLXMLHttpRequest_get_responseBody
,
689 HTMLXMLHttpRequest_get_responseText
,
690 HTMLXMLHttpRequest_get_responseXML
,
691 HTMLXMLHttpRequest_get_status
,
692 HTMLXMLHttpRequest_get_statusText
,
693 HTMLXMLHttpRequest_put_onreadystatechange
,
694 HTMLXMLHttpRequest_get_onreadystatechange
,
695 HTMLXMLHttpRequest_abort
,
696 HTMLXMLHttpRequest_open
,
697 HTMLXMLHttpRequest_send
,
698 HTMLXMLHttpRequest_getAllResponseHeaders
,
699 HTMLXMLHttpRequest_getResponseHeader
,
700 HTMLXMLHttpRequest_setRequestHeader
703 static inline HTMLXMLHttpRequest
*impl_from_IProvideClassInfo2(IProvideClassInfo2
*iface
)
705 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequest
, IProvideClassInfo2_iface
);
708 static HRESULT WINAPI
ProvideClassInfo_QueryInterface(IProvideClassInfo2
*iface
, REFIID riid
, void **ppv
)
710 HTMLXMLHttpRequest
*This
= impl_from_IProvideClassInfo2(iface
);
711 return IHTMLXMLHttpRequest_QueryInterface(&This
->IHTMLXMLHttpRequest_iface
, riid
, ppv
);
714 static ULONG WINAPI
ProvideClassInfo_AddRef(IProvideClassInfo2
*iface
)
716 HTMLXMLHttpRequest
*This
= impl_from_IProvideClassInfo2(iface
);
717 return IHTMLXMLHttpRequest_AddRef(&This
->IHTMLXMLHttpRequest_iface
);
720 static ULONG WINAPI
ProvideClassInfo_Release(IProvideClassInfo2
*iface
)
722 HTMLXMLHttpRequest
*This
= impl_from_IProvideClassInfo2(iface
);
723 return IHTMLXMLHttpRequest_Release(&This
->IHTMLXMLHttpRequest_iface
);
726 static HRESULT WINAPI
ProvideClassInfo_GetClassInfo(IProvideClassInfo2
*iface
, ITypeInfo
**ppTI
)
728 HTMLXMLHttpRequest
*This
= impl_from_IProvideClassInfo2(iface
);
729 TRACE("(%p)->(%p)\n", This
, ppTI
);
730 return get_class_typeinfo(&CLSID_HTMLXMLHttpRequest
, ppTI
);
733 static HRESULT WINAPI
ProvideClassInfo2_GetGUID(IProvideClassInfo2
*iface
, DWORD dwGuidKind
, GUID
*pGUID
)
735 HTMLXMLHttpRequest
*This
= impl_from_IProvideClassInfo2(iface
);
736 FIXME("(%p)->(%u %p)\n", This
, dwGuidKind
, pGUID
);
740 static const IProvideClassInfo2Vtbl ProvideClassInfo2Vtbl
= {
741 ProvideClassInfo_QueryInterface
,
742 ProvideClassInfo_AddRef
,
743 ProvideClassInfo_Release
,
744 ProvideClassInfo_GetClassInfo
,
745 ProvideClassInfo2_GetGUID
,
748 static inline HTMLXMLHttpRequest
*impl_from_DispatchEx(DispatchEx
*iface
)
750 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequest
, event_target
.dispex
);
753 static HRESULT
HTMLXMLHttpRequest_get_dispid(DispatchEx
*dispex
, BSTR name
, DWORD flags
, DISPID
*dispid
)
755 /* onload event handler property is supported, but not exposed by any interface. We implement as a custom property. */
756 if(!wcscmp(L
"onload", name
)) {
757 *dispid
= MSHTML_DISPID_HTMLXMLHTTPREQUEST_ONLOAD
;
761 return DISP_E_UNKNOWNNAME
;
764 static HRESULT
HTMLXMLHttpRequest_invoke(DispatchEx
*dispex
, DISPID id
, LCID lcid
, WORD flags
, DISPPARAMS
*params
,
765 VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
767 HTMLXMLHttpRequest
*This
= impl_from_DispatchEx(dispex
);
769 if(id
== MSHTML_DISPID_HTMLXMLHTTPREQUEST_ONLOAD
) {
771 case DISPATCH_PROPERTYGET
:
772 TRACE("(%p) get onload\n", This
);
773 return get_event_handler(&This
->event_target
, EVENTID_LOAD
, res
);
775 case DISPATCH_PROPERTYPUT
:
776 if(params
->cArgs
!= 1 || (params
->cNamedArgs
== 1 && *params
->rgdispidNamedArgs
!= DISPID_PROPERTYPUT
)
777 || params
->cNamedArgs
> 1) {
778 FIXME("invalid args\n");
782 TRACE("(%p)->(%p) set onload\n", This
, params
->rgvarg
);
783 return set_event_handler(&This
->event_target
, EVENTID_LOAD
, params
->rgvarg
);
786 FIXME("Unimplemented flags %x\n", flags
);
791 return DISP_E_UNKNOWNNAME
;
794 static nsISupports
*HTMLXMLHttpRequest_get_gecko_target(DispatchEx
*dispex
)
796 HTMLXMLHttpRequest
*This
= impl_from_DispatchEx(dispex
);
797 return (nsISupports
*)This
->nsxhr
;
800 static void HTMLXMLHttpRequest_bind_event(DispatchEx
*dispex
, eventid_t eid
)
802 HTMLXMLHttpRequest
*This
= impl_from_DispatchEx(dispex
);
803 nsIDOMEventTarget
*nstarget
;
804 const WCHAR
*type_name
;
808 TRACE("(%p)\n", This
);
811 case EVENTID_READYSTATECHANGE
:
812 type_name
= L
"readystatechange";
821 if(!This
->event_listener
) {
822 This
->event_listener
= heap_alloc(sizeof(*This
->event_listener
));
823 if(!This
->event_listener
)
826 This
->event_listener
->nsIDOMEventListener_iface
.lpVtbl
= &XMLHttpReqEventListenerVtbl
;
827 This
->event_listener
->ref
= 1;
828 This
->event_listener
->xhr
= This
;
829 This
->event_listener
->readystatechange_event
= FALSE
;
830 This
->event_listener
->load_event
= FALSE
;
833 nsres
= nsIXMLHttpRequest_QueryInterface(This
->nsxhr
, &IID_nsIDOMEventTarget
, (void**)&nstarget
);
834 assert(nsres
== NS_OK
);
836 nsAString_InitDepend(&type_str
, type_name
);
837 nsres
= nsIDOMEventTarget_AddEventListener(nstarget
, &type_str
, &This
->event_listener
->nsIDOMEventListener_iface
, FALSE
, TRUE
, 2);
838 nsAString_Finish(&type_str
);
840 ERR("AddEventListener(%s) failed: %08x\n", debugstr_w(type_name
), nsres
);
842 nsIDOMEventTarget_Release(nstarget
);
844 if(eid
== EVENTID_READYSTATECHANGE
)
845 This
->event_listener
->readystatechange_event
= TRUE
;
847 This
->event_listener
->load_event
= TRUE
;
850 static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl
= {
853 HTMLXMLHttpRequest_get_dispid
,
854 HTMLXMLHttpRequest_invoke
856 HTMLXMLHttpRequest_get_gecko_target
,
857 HTMLXMLHttpRequest_bind_event
860 static const tid_t HTMLXMLHttpRequest_iface_tids
[] = {
861 IHTMLXMLHttpRequest_tid
,
864 static dispex_static_data_t HTMLXMLHttpRequest_dispex
= {
865 &HTMLXMLHttpRequest_event_target_vtbl
.dispex_vtbl
,
866 DispHTMLXMLHttpRequest_tid
,
867 HTMLXMLHttpRequest_iface_tids
,
868 EventTarget_init_dispex_info
872 /* IHTMLXMLHttpRequestFactory */
873 static inline HTMLXMLHttpRequestFactory
*impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory
*iface
)
875 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequestFactory
, IHTMLXMLHttpRequestFactory_iface
);
878 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_QueryInterface(IHTMLXMLHttpRequestFactory
*iface
, REFIID riid
, void **ppv
)
880 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
882 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
884 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
885 *ppv
= &This
->IHTMLXMLHttpRequestFactory_iface
;
886 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
887 *ppv
= &This
->IHTMLXMLHttpRequestFactory_iface
;
888 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequestFactory
, riid
)) {
889 *ppv
= &This
->IHTMLXMLHttpRequestFactory_iface
;
890 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
891 return *ppv
? S_OK
: E_NOINTERFACE
;
894 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
895 return E_NOINTERFACE
;
898 IUnknown_AddRef((IUnknown
*)*ppv
);
902 static ULONG WINAPI
HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory
*iface
)
904 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
905 LONG ref
= InterlockedIncrement(&This
->ref
);
907 TRACE("(%p) ref=%d\n", This
, ref
);
912 static ULONG WINAPI
HTMLXMLHttpRequestFactory_Release(IHTMLXMLHttpRequestFactory
*iface
)
914 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
915 LONG ref
= InterlockedDecrement(&This
->ref
);
917 TRACE("(%p) ref=%d\n", This
, ref
);
920 release_dispex(&This
->dispex
);
927 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_GetTypeInfoCount(IHTMLXMLHttpRequestFactory
*iface
, UINT
*pctinfo
)
929 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
930 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
933 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_GetTypeInfo(IHTMLXMLHttpRequestFactory
*iface
, UINT iTInfo
,
934 LCID lcid
, ITypeInfo
**ppTInfo
)
936 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
938 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
941 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_GetIDsOfNames(IHTMLXMLHttpRequestFactory
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
942 LCID lcid
, DISPID
*rgDispId
)
944 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
946 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
950 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_Invoke(IHTMLXMLHttpRequestFactory
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
951 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
953 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
955 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
, wFlags
,
956 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
959 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactory
*iface
, IHTMLXMLHttpRequest
**p
)
961 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
962 HTMLXMLHttpRequest
*ret
;
963 nsIXMLHttpRequest
*nsxhr
;
965 TRACE("(%p)->(%p)\n", This
, p
);
967 nsxhr
= create_nsxhr(This
->window
->base
.outer_window
->nswindow
);
971 ret
= heap_alloc_zero(sizeof(*ret
));
973 nsIXMLHttpRequest_Release(nsxhr
);
974 return E_OUTOFMEMORY
;
978 ret
->IHTMLXMLHttpRequest_iface
.lpVtbl
= &HTMLXMLHttpRequestVtbl
;
979 ret
->IProvideClassInfo2_iface
.lpVtbl
= &ProvideClassInfo2Vtbl
;
980 EventTarget_Init(&ret
->event_target
, (IUnknown
*)&ret
->IHTMLXMLHttpRequest_iface
,
981 &HTMLXMLHttpRequest_dispex
, This
->window
->doc
->document_mode
);
984 *p
= &ret
->IHTMLXMLHttpRequest_iface
;
988 static const IHTMLXMLHttpRequestFactoryVtbl HTMLXMLHttpRequestFactoryVtbl
= {
989 HTMLXMLHttpRequestFactory_QueryInterface
,
990 HTMLXMLHttpRequestFactory_AddRef
,
991 HTMLXMLHttpRequestFactory_Release
,
992 HTMLXMLHttpRequestFactory_GetTypeInfoCount
,
993 HTMLXMLHttpRequestFactory_GetTypeInfo
,
994 HTMLXMLHttpRequestFactory_GetIDsOfNames
,
995 HTMLXMLHttpRequestFactory_Invoke
,
996 HTMLXMLHttpRequestFactory_create
999 static inline HTMLXMLHttpRequestFactory
*factory_from_DispatchEx(DispatchEx
*iface
)
1001 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequestFactory
, dispex
);
1004 static HRESULT
HTMLXMLHttpRequestFactory_value(DispatchEx
*iface
, LCID lcid
, WORD flags
, DISPPARAMS
*params
,
1005 VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
1007 HTMLXMLHttpRequestFactory
*This
= factory_from_DispatchEx(iface
);
1008 IHTMLXMLHttpRequest
*xhr
;
1013 if(flags
!= DISPATCH_CONSTRUCT
) {
1014 FIXME("flags %x not supported\n", flags
);
1018 hres
= IHTMLXMLHttpRequestFactory_create(&This
->IHTMLXMLHttpRequestFactory_iface
, &xhr
);
1022 V_VT(res
) = VT_DISPATCH
;
1023 V_DISPATCH(res
) = (IDispatch
*)xhr
;
1027 static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl
= {
1028 HTMLXMLHttpRequestFactory_value
1031 static const tid_t HTMLXMLHttpRequestFactory_iface_tids
[] = {
1032 IHTMLXMLHttpRequestFactory_tid
,
1035 static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex
= {
1036 &HTMLXMLHttpRequestFactory_dispex_vtbl
,
1037 IHTMLXMLHttpRequestFactory_tid
,
1038 HTMLXMLHttpRequestFactory_iface_tids
1041 HRESULT
HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow
* window
, HTMLXMLHttpRequestFactory
**ret_ptr
)
1043 HTMLXMLHttpRequestFactory
*ret
;
1045 ret
= heap_alloc(sizeof(*ret
));
1047 return E_OUTOFMEMORY
;
1049 ret
->IHTMLXMLHttpRequestFactory_iface
.lpVtbl
= &HTMLXMLHttpRequestFactoryVtbl
;
1051 ret
->window
= window
;
1053 init_dispex(&ret
->dispex
, (IUnknown
*)&ret
->IHTMLXMLHttpRequestFactory_iface
,
1054 &HTMLXMLHttpRequestFactory_dispex
);