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
28 #include "wine/debug.h"
30 #include "mshtml_private.h"
31 #include "htmlevent.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
39 static HRESULT
bstr_to_nsacstr(BSTR bstr
, nsACString
*str
)
41 char *cstr
= strdupWtoU(bstr
);
44 nsACString_Init(str
, cstr
);
49 static HRESULT
variant_to_nsastr(VARIANT var
, nsAString
*ret
)
55 nsAString_Init(ret
, NULL
);
58 nsAString_InitDepend(ret
, V_BSTR(&var
));
61 FIXME("Unsupported VARIANT: %s\n", debugstr_variant(&var
));
66 static HRESULT
return_nscstr(nsresult nsres
, nsACString
*nscstr
, BSTR
*p
)
71 if(NS_FAILED(nsres
)) {
72 ERR("failed: %08lx\n", nsres
);
73 nsACString_Finish(nscstr
);
77 nsACString_GetData(nscstr
, &str
);
80 len
= MultiByteToWideChar(CP_UTF8
, 0, str
, -1, NULL
, 0);
81 *p
= SysAllocStringLen(NULL
, len
- 1);
83 nsACString_Finish(nscstr
);
86 MultiByteToWideChar(CP_UTF8
, 0, str
, -1, *p
, len
);
91 nsACString_Finish(nscstr
);
95 static const eventid_t events
[] = {
96 EVENTID_READYSTATECHANGE
,
110 response_type_arraybuf
,
115 static const struct {
117 const WCHAR
*nsxhr_str
;
118 } response_type_desc
[] = {
119 [response_type_empty
] = { L
"", L
"" },
120 [response_type_text
] = { L
"text", L
"" },
121 [response_type_doc
] = { L
"document", L
"" }, /* FIXME */
122 [response_type_arraybuf
] = { L
"arraybuffer", L
"arraybuffer" },
123 [response_type_blob
] = { L
"blob", L
"arraybuffer" },
124 [response_type_stream
] = { L
"ms-stream", L
"arraybuffer" } /* FIXME */
128 nsIDOMEventListener nsIDOMEventListener_iface
;
130 HTMLXMLHttpRequest
*xhr
;
131 } XMLHttpReqEventListener
;
133 struct HTMLXMLHttpRequest
{
134 EventTarget event_target
;
135 IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface
;
136 IHTMLXMLHttpRequest2 IHTMLXMLHttpRequest2_iface
;
137 IWineXMLHttpRequestPrivate IWineXMLHttpRequestPrivate_iface
;
138 IProvideClassInfo2 IProvideClassInfo2_iface
;
142 response_type_t response_type
;
145 DWORD pending_events_magic
;
146 HTMLInnerWindow
*window
;
147 nsIXMLHttpRequest
*nsxhr
;
148 XMLHttpReqEventListener
*event_listener
;
149 DOMEvent
*pending_progress_event
;
152 static void detach_xhr_event_listener(XMLHttpReqEventListener
*event_listener
)
154 nsIDOMEventTarget
*event_target
;
159 nsres
= nsIXMLHttpRequest_QueryInterface(event_listener
->xhr
->nsxhr
, &IID_nsIDOMEventTarget
, (void**)&event_target
);
160 assert(nsres
== NS_OK
);
162 for(i
= 0; i
< ARRAY_SIZE(events
) ; i
++) {
163 nsAString_InitDepend(&str
, get_event_name(events
[i
]));
164 nsres
= nsIDOMEventTarget_RemoveEventListener(event_target
, &str
, &event_listener
->nsIDOMEventListener_iface
, FALSE
);
165 nsAString_Finish(&str
);
166 assert(nsres
== NS_OK
);
169 nsIDOMEventTarget_Release(event_target
);
171 event_listener
->xhr
= NULL
;
172 nsIDOMEventListener_Release(&event_listener
->nsIDOMEventListener_iface
);
175 static void synthesize_pending_events(HTMLXMLHttpRequest
*xhr
)
177 DWORD magic
= xhr
->pending_events_magic
;
178 UINT16 ready_state
= xhr
->ready_state
;
179 BOOLEAN send_load
, send_loadend
;
183 if(xhr
->magic
!= magic
)
186 /* Make sure further events are synthesized with a new task */
187 xhr
->pending_events_magic
= magic
- 1;
189 /* Synthesize the necessary events that led us to this current state */
190 nsIXMLHttpRequest_GetReadyState(xhr
->nsxhr
, &ready_state
);
191 if(ready_state
== READYSTATE_UNINITIALIZED
)
194 /* Synchronous XHRs only send readyState changes before DONE in IE9 and below */
195 if(xhr
->synchronous
&& dispex_compat_mode(&xhr
->event_target
.dispex
) > COMPAT_MODE_IE9
) {
196 if(ready_state
< READYSTATE_INTERACTIVE
) {
197 xhr
->ready_state
= ready_state
;
200 xhr
->ready_state
= max(xhr
->ready_state
, READYSTATE_INTERACTIVE
);
203 IHTMLXMLHttpRequest_AddRef(&xhr
->IHTMLXMLHttpRequest_iface
);
205 send_loadend
= send_load
= (xhr
->ready_state
!= ready_state
&& ready_state
== READYSTATE_COMPLETE
);
207 if(xhr
->pending_progress_event
&&
208 xhr
->ready_state
== (xhr
->pending_progress_event
->event_id
== EVENTID_PROGRESS
? READYSTATE_INTERACTIVE
: READYSTATE_COMPLETE
))
210 DOMEvent
*pending_progress_event
= xhr
->pending_progress_event
;
211 xhr
->pending_progress_event
= NULL
;
213 if(pending_progress_event
->event_id
!= EVENTID_PROGRESS
) {
218 dispatch_event(&xhr
->event_target
, pending_progress_event
);
219 IDOMEvent_Release(&pending_progress_event
->IDOMEvent_iface
);
220 if(xhr
->magic
!= magic
)
224 if(xhr
->ready_state
>= ready_state
)
228 hres
= create_document_event(xhr
->window
->doc
, EVENTID_READYSTATECHANGE
, &event
);
229 if(SUCCEEDED(hres
)) {
230 dispatch_event(&xhr
->event_target
, event
);
231 IDOMEvent_Release(&event
->IDOMEvent_iface
);
232 if(xhr
->magic
!= magic
)
238 hres
= create_document_event(xhr
->window
->doc
, EVENTID_LOAD
, &event
);
239 if(SUCCEEDED(hres
)) {
240 dispatch_event(&xhr
->event_target
, event
);
241 IDOMEvent_Release(&event
->IDOMEvent_iface
);
242 if(xhr
->magic
!= magic
)
248 hres
= create_document_event(xhr
->window
->doc
, EVENTID_LOADEND
, &event
);
249 if(SUCCEEDED(hres
)) {
250 dispatch_event(&xhr
->event_target
, event
);
251 IDOMEvent_Release(&event
->IDOMEvent_iface
);
252 if(xhr
->magic
!= magic
)
258 IHTMLXMLHttpRequest_Release(&xhr
->IHTMLXMLHttpRequest_iface
);
261 static nsresult
sync_xhr_send(HTMLXMLHttpRequest
*xhr
, nsIVariant
*nsbody
)
263 thread_data_t
*thread_data
= get_thread_data(TRUE
);
264 HTMLXMLHttpRequest
*prev_blocking_xhr
;
265 HTMLInnerWindow
*window
= xhr
->window
;
269 return NS_ERROR_OUT_OF_MEMORY
;
270 prev_blocking_xhr
= thread_data
->blocking_xhr
;
272 /* Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27),
273 * synchronous requests on the main thread have been deprecated due to the negative
274 * effects to the user experience. However, they still work. The larger issue is that
275 * it is broken because it still dispatches async XHR and some other events, while all
276 * other major browsers don't, including IE, so we have to filter them out during Send.
278 * They will need to be queued and dispatched later, after Send returns, otherwise it
279 * breaks JavaScript single-threaded expectations (JS code will switch from blocking in
280 * Send to executing some event handler, then returning back to Send, messing its state).
282 * Of course we can't just delay dispatching the events, because the state won't match
283 * for each event later on, to what it's supposed to be (most notably, XHR's readyState).
284 * We'll keep snapshots and synthesize them when unblocked for async XHR events.
286 * Note that while queuing an event this way would not work correctly with their default
287 * behavior in Gecko (preventDefault() can't be called because we need to *delay* the
288 * default, rather than prevent it completely), Gecko does suppress events reaching the
289 * document during the sync XHR event loop, so those we do not handle manually. If we
290 * find an event that has defaults on Gecko's side and isn't delayed by Gecko, we need
291 * to figure out a way to handle it...
293 * For details (and bunch of problems to consider) see: https://bugzil.la/697151
295 window
->base
.outer_window
->readystate_locked
++;
296 window
->blocking_depth
++;
297 thread_data
->blocking_xhr
= xhr
;
298 nsres
= nsIXMLHttpRequest_Send(xhr
->nsxhr
, nsbody
);
299 thread_data
->blocking_xhr
= prev_blocking_xhr
;
300 window
->base
.outer_window
->readystate_locked
--;
302 if(!--window
->blocking_depth
)
303 unblock_tasks_and_timers(thread_data
);
305 /* Process any pending events now since they were part of the blocked send() above */
306 synthesize_pending_events(xhr
);
311 struct pending_xhr_events_task
{
313 HTMLXMLHttpRequest
*xhr
;
316 static void pending_xhr_events_proc(event_task_t
*_task
)
318 struct pending_xhr_events_task
*task
= (struct pending_xhr_events_task
*)_task
;
319 synthesize_pending_events(task
->xhr
);
322 static void pending_xhr_events_destr(event_task_t
*_task
)
327 static inline XMLHttpReqEventListener
*impl_from_nsIDOMEventListener(nsIDOMEventListener
*iface
)
329 return CONTAINING_RECORD(iface
, XMLHttpReqEventListener
, nsIDOMEventListener_iface
);
332 static nsresult NSAPI
XMLHttpReqEventListener_QueryInterface(nsIDOMEventListener
*iface
,
333 nsIIDRef riid
, void **result
)
335 XMLHttpReqEventListener
*This
= impl_from_nsIDOMEventListener(iface
);
337 if(IsEqualGUID(&IID_nsISupports
, riid
)) {
338 TRACE("(%p)->(IID_nsISupports, %p)\n", This
, result
);
339 *result
= &This
->nsIDOMEventListener_iface
;
340 }else if(IsEqualGUID(&IID_nsIDOMEventListener
, riid
)) {
341 TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This
, result
);
342 *result
= &This
->nsIDOMEventListener_iface
;
345 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), result
);
346 return NS_NOINTERFACE
;
349 nsIDOMEventListener_AddRef(&This
->nsIDOMEventListener_iface
);
353 static nsrefcnt NSAPI
XMLHttpReqEventListener_AddRef(nsIDOMEventListener
*iface
)
355 XMLHttpReqEventListener
*This
= impl_from_nsIDOMEventListener(iface
);
356 LONG ref
= InterlockedIncrement(&This
->ref
);
358 TRACE("(%p) ref=%ld\n", This
, ref
);
363 static nsrefcnt NSAPI
XMLHttpReqEventListener_Release(nsIDOMEventListener
*iface
)
365 XMLHttpReqEventListener
*This
= impl_from_nsIDOMEventListener(iface
);
366 LONG ref
= InterlockedDecrement(&This
->ref
);
368 TRACE("(%p) ref=%ld\n", This
, ref
);
378 static nsresult NSAPI
XMLHttpReqEventListener_HandleEvent(nsIDOMEventListener
*iface
, nsIDOMEvent
*nsevent
)
380 XMLHttpReqEventListener
*This
= impl_from_nsIDOMEventListener(iface
);
381 HTMLXMLHttpRequest
*blocking_xhr
= NULL
;
382 thread_data_t
*thread_data
;
383 compat_mode_t compat_mode
;
389 TRACE("(%p)\n", This
);
394 ready_state
= This
->xhr
->ready_state
;
395 if(NS_SUCCEEDED(nsIXMLHttpRequest_GetReadyState(This
->xhr
->nsxhr
, &val
)))
398 if((thread_data
= get_thread_data(FALSE
)))
399 blocking_xhr
= thread_data
->blocking_xhr
;
401 compat_mode
= dispex_compat_mode(&This
->xhr
->event_target
.dispex
);
402 hres
= create_event_from_nsevent(nsevent
, compat_mode
, &event
);
404 if(!blocking_xhr
|| This
->xhr
== blocking_xhr
)
405 This
->xhr
->ready_state
= ready_state
;
406 return NS_ERROR_OUT_OF_MEMORY
;
410 BOOL has_pending_events
= (This
->xhr
->magic
== This
->xhr
->pending_events_magic
);
412 if(has_pending_events
|| This
->xhr
!= blocking_xhr
) {
413 switch(event
->event_id
) {
414 case EVENTID_PROGRESS
:
417 case EVENTID_TIMEOUT
:
418 if(This
->xhr
->pending_progress_event
)
419 IDOMEvent_Release(&This
->xhr
->pending_progress_event
->IDOMEvent_iface
);
420 This
->xhr
->pending_progress_event
= event
;
423 IDOMEvent_Release(&event
->IDOMEvent_iface
);
427 if(!has_pending_events
) {
428 if(!This
->xhr
->synchronous
) {
429 struct pending_xhr_events_task
*task
;
431 remove_target_tasks(This
->xhr
->task_magic
);
433 if(!(task
= malloc(sizeof(*task
))))
434 return NS_ERROR_OUT_OF_MEMORY
;
436 task
->header
.target_magic
= This
->xhr
->task_magic
;
437 task
->header
.thread_blocked
= TRUE
;
438 task
->header
.proc
= pending_xhr_events_proc
;
439 task
->header
.destr
= pending_xhr_events_destr
;
440 task
->header
.window
= This
->xhr
->window
;
441 task
->xhr
= This
->xhr
;
442 IHTMLWindow2_AddRef(&This
->xhr
->window
->base
.IHTMLWindow2_iface
);
444 list_add_after(thread_data
->pending_xhr_events_tail
, &task
->header
.entry
);
445 thread_data
->pending_xhr_events_tail
= &task
->header
.entry
;
447 This
->xhr
->pending_events_magic
= This
->xhr
->magic
;
451 /* Synthesize pending events that a nested sync XHR might have blocked us on */
452 if(This
->xhr
== blocking_xhr
)
453 synthesize_pending_events(This
->xhr
);
457 /* Workaround weird Gecko behavior with nested sync XHRs, where it sends readyState changes
458 for OPENED (or possibly other states than DONE), unlike IE10+ and non-nested sync XHRs... */
459 if(ready_state
< READYSTATE_COMPLETE
&& event
->event_id
== EVENTID_READYSTATECHANGE
) {
460 IDOMEvent_Release(&event
->IDOMEvent_iface
);
461 This
->xhr
->ready_state
= ready_state
;
465 /* IE10+ only send readystatechange event when it is DONE for sync XHRs, but older modes
466 send all the others here, including OPENED state change (even if it was opened earlier). */
467 if(compat_mode
< COMPAT_MODE_IE10
&& This
->xhr
->ready_state
< READYSTATE_COMPLETE
&& (
468 event
->event_id
== EVENTID_READYSTATECHANGE
|| event
->event_id
== EVENTID_PROGRESS
|| event
->event_id
== EVENTID_LOADSTART
)) {
469 DOMEvent
*readystatechange_event
;
470 DWORD magic
= This
->xhr
->magic
;
473 for(i
= READYSTATE_LOADING
; i
< READYSTATE_COMPLETE
; i
++) {
474 hres
= create_document_event(This
->xhr
->window
->doc
, EVENTID_READYSTATECHANGE
, &readystatechange_event
);
478 This
->xhr
->ready_state
= i
;
479 dispatch_event(&This
->xhr
->event_target
, readystatechange_event
);
480 IDOMEvent_Release(&readystatechange_event
->IDOMEvent_iface
);
482 if(This
->xhr
->magic
!= magic
) {
483 IDOMEvent_Release(&event
->IDOMEvent_iface
);
490 This
->xhr
->ready_state
= ready_state
;
491 dispatch_event(&This
->xhr
->event_target
, event
);
492 IDOMEvent_Release(&event
->IDOMEvent_iface
);
496 static const nsIDOMEventListenerVtbl XMLHttpReqEventListenerVtbl
= {
497 XMLHttpReqEventListener_QueryInterface
,
498 XMLHttpReqEventListener_AddRef
,
499 XMLHttpReqEventListener_Release
,
500 XMLHttpReqEventListener_HandleEvent
503 static inline HTMLXMLHttpRequest
*impl_from_IHTMLXMLHttpRequest(IHTMLXMLHttpRequest
*iface
)
505 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequest
, IHTMLXMLHttpRequest_iface
);
508 static HRESULT WINAPI
HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest
*iface
, REFIID riid
, void **ppv
)
510 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
512 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
514 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
515 *ppv
= &This
->IHTMLXMLHttpRequest_iface
;
516 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
517 *ppv
= &This
->IHTMLXMLHttpRequest_iface
;
518 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest
, riid
)) {
519 *ppv
= &This
->IHTMLXMLHttpRequest_iface
;
520 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest2
, riid
)) {
521 *ppv
= &This
->IHTMLXMLHttpRequest2_iface
;
522 }else if(IsEqualGUID(&IID_IWineXMLHttpRequestPrivate
, riid
)) {
523 *ppv
= &This
->IWineXMLHttpRequestPrivate_iface
;
524 }else if(IsEqualGUID(&IID_IProvideClassInfo
, riid
)) {
525 *ppv
= &This
->IProvideClassInfo2_iface
;
526 }else if(IsEqualGUID(&IID_IProvideClassInfo2
, riid
)) {
527 *ppv
= &This
->IProvideClassInfo2_iface
;
529 return EventTarget_QI(&This
->event_target
, riid
, ppv
);
532 IUnknown_AddRef((IUnknown
*)*ppv
);
536 static ULONG WINAPI
HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest
*iface
)
538 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
539 LONG ref
= InterlockedIncrement(&This
->ref
);
541 TRACE("(%p) ref=%ld\n", This
, ref
);
546 static ULONG WINAPI
HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest
*iface
)
548 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
549 LONG ref
= InterlockedDecrement(&This
->ref
);
551 TRACE("(%p) ref=%ld\n", This
, ref
);
554 remove_target_tasks(This
->task_magic
);
555 detach_xhr_event_listener(This
->event_listener
);
556 if(This
->pending_progress_event
)
557 IDOMEvent_Release(&This
->pending_progress_event
->IDOMEvent_iface
);
558 IHTMLWindow2_Release(&This
->window
->base
.IHTMLWindow2_iface
);
559 release_event_target(&This
->event_target
);
560 release_dispex(&This
->event_target
.dispex
);
561 nsIXMLHttpRequest_Release(This
->nsxhr
);
568 static HRESULT WINAPI
HTMLXMLHttpRequest_GetTypeInfoCount(IHTMLXMLHttpRequest
*iface
, UINT
*pctinfo
)
570 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
571 return IDispatchEx_GetTypeInfoCount(&This
->event_target
.dispex
.IDispatchEx_iface
, pctinfo
);
574 static HRESULT WINAPI
HTMLXMLHttpRequest_GetTypeInfo(IHTMLXMLHttpRequest
*iface
, UINT iTInfo
,
575 LCID lcid
, ITypeInfo
**ppTInfo
)
577 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
579 return IDispatchEx_GetTypeInfo(&This
->event_target
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
582 static HRESULT WINAPI
HTMLXMLHttpRequest_GetIDsOfNames(IHTMLXMLHttpRequest
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
583 LCID lcid
, DISPID
*rgDispId
)
585 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
587 return IDispatchEx_GetIDsOfNames(&This
->event_target
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
591 static HRESULT WINAPI
HTMLXMLHttpRequest_Invoke(IHTMLXMLHttpRequest
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
592 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
594 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
596 return IDispatchEx_Invoke(&This
->event_target
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
, wFlags
,
597 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
600 static HRESULT WINAPI
HTMLXMLHttpRequest_get_readyState(IHTMLXMLHttpRequest
*iface
, LONG
*p
)
602 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
604 TRACE("(%p)->(%p)\n", This
, p
);
608 *p
= This
->ready_state
;
612 static HRESULT WINAPI
HTMLXMLHttpRequest_get_responseBody(IHTMLXMLHttpRequest
*iface
, VARIANT
*p
)
614 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
615 FIXME("(%p)->(%p)\n", This
, p
);
619 static HRESULT WINAPI
HTMLXMLHttpRequest_get_responseText(IHTMLXMLHttpRequest
*iface
, BSTR
*p
)
621 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
625 TRACE("(%p)->(%p)\n", This
, p
);
630 if(This
->ready_state
< READYSTATE_INTERACTIVE
) {
635 nsAString_Init(&nsstr
, NULL
);
636 nsres
= nsIXMLHttpRequest_GetResponseText(This
->nsxhr
, &nsstr
);
637 return return_nsstr(nsres
, &nsstr
, p
);
640 static HRESULT WINAPI
HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest
*iface
, IDispatch
**p
)
642 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
643 IXMLDOMDocument
*xmldoc
= NULL
;
647 IObjectSafety
*safety
;
649 TRACE("(%p)->(%p)\n", This
, p
);
651 if(This
->ready_state
< READYSTATE_COMPLETE
) {
656 if(dispex_compat_mode(&This
->event_target
.dispex
) >= COMPAT_MODE_IE10
) {
657 nsIDOMDocument
*nsdoc
;
660 nsres
= nsIXMLHttpRequest_GetResponseXML(This
->nsxhr
, &nsdoc
);
662 return map_nsresult(nsres
);
667 nsIDOMDocument_Release(nsdoc
);
670 hres
= CoCreateInstance(&CLSID_DOMDocument
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IXMLDOMDocument
, (void**)&xmldoc
);
672 ERR("CoCreateInstance failed: %08lx\n", hres
);
676 hres
= IHTMLXMLHttpRequest_get_responseText(iface
, &str
);
678 IXMLDOMDocument_Release(xmldoc
);
679 ERR("get_responseText failed: %08lx\n", hres
);
683 hres
= IXMLDOMDocument_loadXML(xmldoc
, str
, &vbool
);
685 if(hres
!= S_OK
|| vbool
!= VARIANT_TRUE
)
686 WARN("loadXML failed: %08lx, returning an empty xmldoc\n", hres
);
688 hres
= IXMLDOMDocument_QueryInterface(xmldoc
, &IID_IObjectSafety
, (void**)&safety
);
689 assert(SUCCEEDED(hres
));
690 hres
= IObjectSafety_SetInterfaceSafetyOptions(safety
, NULL
,
691 INTERFACESAFE_FOR_UNTRUSTED_CALLER
| INTERFACESAFE_FOR_UNTRUSTED_DATA
| INTERFACE_USES_SECURITY_MANAGER
,
692 INTERFACESAFE_FOR_UNTRUSTED_CALLER
| INTERFACESAFE_FOR_UNTRUSTED_DATA
| INTERFACE_USES_SECURITY_MANAGER
);
693 assert(SUCCEEDED(hres
));
694 IObjectSafety_Release(safety
);
696 *p
= (IDispatch
*)xmldoc
;
700 static HRESULT WINAPI
HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest
*iface
, LONG
*p
)
702 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
705 TRACE("(%p)->(%p)\n", This
, p
);
710 if(This
->ready_state
< READYSTATE_LOADED
) {
715 nsres
= nsIXMLHttpRequest_GetStatus(This
->nsxhr
, &val
);
716 if(NS_FAILED(nsres
)) {
717 ERR("nsIXMLHttpRequest_GetStatus failed: %08lx\n", nsres
);
722 return E_FAIL
; /* WinAPI thinks this is an error */
727 static HRESULT WINAPI
HTMLXMLHttpRequest_get_statusText(IHTMLXMLHttpRequest
*iface
, BSTR
*p
)
729 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
733 TRACE("(%p)->(%p)\n", This
, p
);
738 if(This
->ready_state
< READYSTATE_LOADED
) {
743 nsACString_Init(&nscstr
, NULL
);
744 nsres
= nsIXMLHttpRequest_GetStatusText(This
->nsxhr
, &nscstr
);
745 return return_nscstr(nsres
, &nscstr
, p
);
748 static HRESULT WINAPI
HTMLXMLHttpRequest_put_onreadystatechange(IHTMLXMLHttpRequest
*iface
, VARIANT v
)
750 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
752 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
754 return set_event_handler(&This
->event_target
, EVENTID_READYSTATECHANGE
, &v
);
757 static HRESULT WINAPI
HTMLXMLHttpRequest_get_onreadystatechange(IHTMLXMLHttpRequest
*iface
, VARIANT
*p
)
759 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
761 TRACE("(%p)->(%p)\n", This
, p
);
763 return get_event_handler(&This
->event_target
, EVENTID_READYSTATECHANGE
, p
);
766 static HRESULT WINAPI
HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest
*iface
)
768 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
769 DWORD prev_magic
= This
->magic
;
773 TRACE("(%p)->()\n", This
);
776 nsres
= nsIXMLHttpRequest_SlowAbort(This
->nsxhr
);
777 if(NS_FAILED(nsres
)) {
778 ERR("nsIXMLHttpRequest_SlowAbort failed: %08lx\n", nsres
);
779 This
->magic
= prev_magic
;
783 /* Gecko changed to READYSTATE_UNINITIALIZED if it did abort */
784 nsres
= nsIXMLHttpRequest_GetReadyState(This
->nsxhr
, &ready_state
);
785 if(NS_SUCCEEDED(nsres
))
786 This
->ready_state
= ready_state
;
790 static HRESULT
HTMLXMLHttpRequest_open_hook(DispatchEx
*dispex
, WORD flags
,
791 DISPPARAMS
*dp
, VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
793 /* If only two arguments were given, implicitly set async to false */
794 if((flags
& DISPATCH_METHOD
) && dp
->cArgs
== 2 && !dp
->cNamedArgs
) {
796 DISPPARAMS new_dp
= {args
, NULL
, ARRAY_SIZE(args
), 0};
797 V_VT(args
) = VT_EMPTY
;
798 V_VT(args
+1) = VT_EMPTY
;
799 V_VT(args
+2) = VT_BOOL
;
800 V_BOOL(args
+2) = VARIANT_TRUE
;
801 args
[3] = dp
->rgvarg
[0];
802 args
[4] = dp
->rgvarg
[1];
804 TRACE("implicit async\n");
806 return dispex_call_builtin(dispex
, DISPID_IHTMLXMLHTTPREQUEST_OPEN
, &new_dp
, res
, ei
, caller
);
809 return S_FALSE
; /* fallback to default */
812 static HRESULT WINAPI
HTMLXMLHttpRequest_open(IHTMLXMLHttpRequest
*iface
, BSTR bstrMethod
, BSTR bstrUrl
, VARIANT varAsync
, VARIANT varUser
, VARIANT varPassword
)
814 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
815 BOOLEAN prev_synchronous
;
816 nsAString user
, password
;
817 nsACString method
, url
;
818 unsigned opt_argc
= 1;
823 TRACE("(%p)->(%s %s %s %s %s)\n", This
, debugstr_w(bstrMethod
), debugstr_w(bstrUrl
), debugstr_variant(&varAsync
), debugstr_variant(&varUser
), debugstr_variant(&varPassword
));
825 if(V_VT(&varAsync
) != VT_BOOL
) {
826 LCID lcid
= MAKELCID(MAKELANGID(LANG_ENGLISH
,SUBLANG_ENGLISH_US
),SORT_DEFAULT
);
827 hres
= VariantChangeTypeEx(&varAsync
, &varAsync
, lcid
, 0, VT_BOOL
);
829 WARN("Failed to convert varAsync to BOOL: %#lx\n", hres
);
834 hres
= variant_to_nsastr(varUser
, &user
);
837 hres
= variant_to_nsastr(varPassword
, &password
);
839 nsAString_Finish(&user
);
843 hres
= bstr_to_nsacstr(bstrMethod
, &method
);
845 nsAString_Finish(&user
);
846 nsAString_Finish(&password
);
849 hres
= bstr_to_nsacstr(bstrUrl
, &url
);
851 nsAString_Finish(&user
);
852 nsAString_Finish(&password
);
853 nsACString_Finish(&method
);
857 /* Set this here, Gecko dispatches nested sync XHR readyState changes for OPENED (see HandleEvent) */
858 prev_magic
= This
->magic
;
859 prev_synchronous
= This
->synchronous
;
860 This
->synchronous
= !V_BOOL(&varAsync
);
863 if(V_VT(&varPassword
) != VT_EMPTY
&& V_VT(&varPassword
) != VT_ERROR
)
865 else if(V_VT(&varUser
) != VT_EMPTY
&& V_VT(&varUser
) != VT_ERROR
)
867 nsres
= nsIXMLHttpRequest_Open(This
->nsxhr
, &method
, &url
, !!V_BOOL(&varAsync
), &user
, &password
, opt_argc
);
869 nsACString_Finish(&method
);
870 nsACString_Finish(&url
);
871 nsAString_Finish(&user
);
872 nsAString_Finish(&password
);
874 if(NS_FAILED(nsres
)) {
875 ERR("nsIXMLHttpRequest_Open failed: %08lx\n", nsres
);
876 This
->magic
= prev_magic
;
877 This
->synchronous
= prev_synchronous
;
884 static HRESULT WINAPI
HTMLXMLHttpRequest_send(IHTMLXMLHttpRequest
*iface
, VARIANT varBody
)
886 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
887 nsIWritableVariant
*nsbody
= NULL
;
888 nsresult nsres
= NS_OK
;
890 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&varBody
));
892 switch(V_VT(&varBody
)) {
900 nsbody
= create_nsvariant();
902 return E_OUTOFMEMORY
;
904 nsAString_InitDepend(&nsstr
, V_BSTR(&varBody
));
905 nsres
= nsIWritableVariant_SetAsAString(nsbody
, &nsstr
);
906 nsAString_Finish(&nsstr
);
910 FIXME("unsupported body type %s\n", debugstr_variant(&varBody
));
914 if(NS_SUCCEEDED(nsres
)) {
915 if(This
->synchronous
)
916 nsres
= sync_xhr_send(This
, (nsIVariant
*)nsbody
);
918 nsres
= nsIXMLHttpRequest_Send(This
->nsxhr
, (nsIVariant
*)nsbody
);
922 nsIWritableVariant_Release(nsbody
);
923 if(NS_FAILED(nsres
)) {
924 ERR("nsIXMLHttpRequest_Send failed: %08lx\n", nsres
);
925 return map_nsresult(nsres
);
931 static HRESULT WINAPI
HTMLXMLHttpRequest_getAllResponseHeaders(IHTMLXMLHttpRequest
*iface
, BSTR
*p
)
933 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
937 TRACE("(%p)->(%p)\n", This
, p
);
942 if(This
->ready_state
< READYSTATE_LOADED
) {
947 nsACString_Init(&nscstr
, NULL
);
948 nsres
= nsIXMLHttpRequest_GetAllResponseHeaders(This
->nsxhr
, &nscstr
);
949 return return_nscstr(nsres
, &nscstr
, p
);
952 static HRESULT WINAPI
HTMLXMLHttpRequest_getResponseHeader(IHTMLXMLHttpRequest
*iface
, BSTR bstrHeader
, BSTR
*p
)
954 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
955 nsACString header
, ret
;
958 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(bstrHeader
), p
);
965 if(This
->ready_state
< READYSTATE_LOADED
) {
970 cstr
= strdupWtoU(bstrHeader
);
971 nsACString_InitDepend(&header
, cstr
);
972 nsACString_Init(&ret
, NULL
);
974 nsres
= nsIXMLHttpRequest_GetResponseHeader(This
->nsxhr
, &header
, &ret
);
976 nsACString_Finish(&header
);
978 return return_nscstr(nsres
, &ret
, p
);
981 static HRESULT WINAPI
HTMLXMLHttpRequest_setRequestHeader(IHTMLXMLHttpRequest
*iface
, BSTR bstrHeader
, BSTR bstrValue
)
983 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
984 char *header_u
, *value_u
;
985 nsACString header
, value
;
988 TRACE("(%p)->(%s %s)\n", This
, debugstr_w(bstrHeader
), debugstr_w(bstrValue
));
990 header_u
= strdupWtoU(bstrHeader
);
991 if(bstrHeader
&& !header_u
)
992 return E_OUTOFMEMORY
;
994 value_u
= strdupWtoU(bstrValue
);
995 if(bstrValue
&& !value_u
) {
997 return E_OUTOFMEMORY
;
1000 nsACString_InitDepend(&header
, header_u
);
1001 nsACString_InitDepend(&value
, value_u
);
1002 nsres
= nsIXMLHttpRequest_SetRequestHeader(This
->nsxhr
, &header
, &value
);
1003 nsACString_Finish(&header
);
1004 nsACString_Finish(&value
);
1007 if(NS_FAILED(nsres
)) {
1008 ERR("SetRequestHeader failed: %08lx\n", nsres
);
1015 static const IHTMLXMLHttpRequestVtbl HTMLXMLHttpRequestVtbl
= {
1016 HTMLXMLHttpRequest_QueryInterface
,
1017 HTMLXMLHttpRequest_AddRef
,
1018 HTMLXMLHttpRequest_Release
,
1019 HTMLXMLHttpRequest_GetTypeInfoCount
,
1020 HTMLXMLHttpRequest_GetTypeInfo
,
1021 HTMLXMLHttpRequest_GetIDsOfNames
,
1022 HTMLXMLHttpRequest_Invoke
,
1023 HTMLXMLHttpRequest_get_readyState
,
1024 HTMLXMLHttpRequest_get_responseBody
,
1025 HTMLXMLHttpRequest_get_responseText
,
1026 HTMLXMLHttpRequest_get_responseXML
,
1027 HTMLXMLHttpRequest_get_status
,
1028 HTMLXMLHttpRequest_get_statusText
,
1029 HTMLXMLHttpRequest_put_onreadystatechange
,
1030 HTMLXMLHttpRequest_get_onreadystatechange
,
1031 HTMLXMLHttpRequest_abort
,
1032 HTMLXMLHttpRequest_open
,
1033 HTMLXMLHttpRequest_send
,
1034 HTMLXMLHttpRequest_getAllResponseHeaders
,
1035 HTMLXMLHttpRequest_getResponseHeader
,
1036 HTMLXMLHttpRequest_setRequestHeader
1039 static inline HTMLXMLHttpRequest
*impl_from_IHTMLXMLHttpRequest2(IHTMLXMLHttpRequest2
*iface
)
1041 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequest
, IHTMLXMLHttpRequest2_iface
);
1044 static HRESULT WINAPI
HTMLXMLHttpRequest2_QueryInterface(IHTMLXMLHttpRequest2
*iface
, REFIID riid
, void **ppv
)
1046 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1047 return IHTMLXMLHttpRequest_QueryInterface(&This
->IHTMLXMLHttpRequest_iface
, riid
, ppv
);
1050 static ULONG WINAPI
HTMLXMLHttpRequest2_AddRef(IHTMLXMLHttpRequest2
*iface
)
1052 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1053 return IHTMLXMLHttpRequest_AddRef(&This
->IHTMLXMLHttpRequest_iface
);
1056 static ULONG WINAPI
HTMLXMLHttpRequest2_Release(IHTMLXMLHttpRequest2
*iface
)
1058 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1059 return IHTMLXMLHttpRequest_Release(&This
->IHTMLXMLHttpRequest_iface
);
1062 static HRESULT WINAPI
HTMLXMLHttpRequest2_GetTypeInfoCount(IHTMLXMLHttpRequest2
*iface
, UINT
*pctinfo
)
1064 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1065 return IDispatchEx_GetTypeInfoCount(&This
->event_target
.dispex
.IDispatchEx_iface
, pctinfo
);
1068 static HRESULT WINAPI
HTMLXMLHttpRequest2_GetTypeInfo(IHTMLXMLHttpRequest2
*iface
, UINT iTInfo
,
1069 LCID lcid
, ITypeInfo
**ppTInfo
)
1071 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1072 return IDispatchEx_GetTypeInfo(&This
->event_target
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1075 static HRESULT WINAPI
HTMLXMLHttpRequest2_GetIDsOfNames(IHTMLXMLHttpRequest2
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
1076 LCID lcid
, DISPID
*rgDispId
)
1078 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1079 return IDispatchEx_GetIDsOfNames(&This
->event_target
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1083 static HRESULT WINAPI
HTMLXMLHttpRequest2_Invoke(IHTMLXMLHttpRequest2
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
1084 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1086 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1087 return IDispatchEx_Invoke(&This
->event_target
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
, wFlags
,
1088 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1091 static HRESULT WINAPI
HTMLXMLHttpRequest2_put_timeout(IHTMLXMLHttpRequest2
*iface
, LONG v
)
1093 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1095 TRACE("(%p)->(%ld)\n", This
, v
);
1098 return E_INVALIDARG
;
1099 return map_nsresult(nsIXMLHttpRequest_SetTimeout(This
->nsxhr
, v
));
1102 static HRESULT WINAPI
HTMLXMLHttpRequest2_get_timeout(IHTMLXMLHttpRequest2
*iface
, LONG
*p
)
1104 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1108 TRACE("(%p)->(%p)\n", This
, p
);
1113 nsres
= nsIXMLHttpRequest_GetTimeout(This
->nsxhr
, &timeout
);
1115 return map_nsresult(nsres
);
1118 static HRESULT WINAPI
HTMLXMLHttpRequest2_put_ontimeout(IHTMLXMLHttpRequest2
*iface
, VARIANT v
)
1120 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1122 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
1124 return set_event_handler(&This
->event_target
, EVENTID_TIMEOUT
, &v
);
1127 static HRESULT WINAPI
HTMLXMLHttpRequest2_get_ontimeout(IHTMLXMLHttpRequest2
*iface
, VARIANT
*p
)
1129 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest2(iface
);
1131 TRACE("(%p)->(%p)\n", This
, p
);
1133 return get_event_handler(&This
->event_target
, EVENTID_TIMEOUT
, p
);
1136 static const IHTMLXMLHttpRequest2Vtbl HTMLXMLHttpRequest2Vtbl
= {
1137 HTMLXMLHttpRequest2_QueryInterface
,
1138 HTMLXMLHttpRequest2_AddRef
,
1139 HTMLXMLHttpRequest2_Release
,
1140 HTMLXMLHttpRequest2_GetTypeInfoCount
,
1141 HTMLXMLHttpRequest2_GetTypeInfo
,
1142 HTMLXMLHttpRequest2_GetIDsOfNames
,
1143 HTMLXMLHttpRequest2_Invoke
,
1144 HTMLXMLHttpRequest2_put_timeout
,
1145 HTMLXMLHttpRequest2_get_timeout
,
1146 HTMLXMLHttpRequest2_put_ontimeout
,
1147 HTMLXMLHttpRequest2_get_ontimeout
1150 static inline HTMLXMLHttpRequest
*impl_from_IWineXMLHttpRequestPrivate(IWineXMLHttpRequestPrivate
*iface
)
1152 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequest
, IWineXMLHttpRequestPrivate_iface
);
1155 static HRESULT WINAPI
HTMLXMLHttpRequest_private_QueryInterface(IWineXMLHttpRequestPrivate
*iface
, REFIID riid
, void **ppv
)
1157 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1158 return IHTMLXMLHttpRequest_QueryInterface(&This
->IHTMLXMLHttpRequest_iface
, riid
, ppv
);
1161 static ULONG WINAPI
HTMLXMLHttpRequest_private_AddRef(IWineXMLHttpRequestPrivate
*iface
)
1163 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1164 return IHTMLXMLHttpRequest_AddRef(&This
->IHTMLXMLHttpRequest_iface
);
1167 static ULONG WINAPI
HTMLXMLHttpRequest_private_Release(IWineXMLHttpRequestPrivate
*iface
)
1169 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1170 return IHTMLXMLHttpRequest_Release(&This
->IHTMLXMLHttpRequest_iface
);
1173 static HRESULT WINAPI
HTMLXMLHttpRequest_private_GetTypeInfoCount(IWineXMLHttpRequestPrivate
*iface
, UINT
*pctinfo
)
1175 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1176 return IDispatchEx_GetTypeInfoCount(&This
->event_target
.dispex
.IDispatchEx_iface
, pctinfo
);
1179 static HRESULT WINAPI
HTMLXMLHttpRequest_private_GetTypeInfo(IWineXMLHttpRequestPrivate
*iface
, UINT iTInfo
,
1180 LCID lcid
, ITypeInfo
**ppTInfo
)
1182 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1183 return IDispatchEx_GetTypeInfo(&This
->event_target
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1186 static HRESULT WINAPI
HTMLXMLHttpRequest_private_GetIDsOfNames(IWineXMLHttpRequestPrivate
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
1187 LCID lcid
, DISPID
*rgDispId
)
1189 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1190 return IDispatchEx_GetIDsOfNames(&This
->event_target
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1194 static HRESULT WINAPI
HTMLXMLHttpRequest_private_Invoke(IWineXMLHttpRequestPrivate
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
1195 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1197 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1198 return IDispatchEx_Invoke(&This
->event_target
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
, wFlags
,
1199 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1202 static HRESULT WINAPI
HTMLXMLHttpRequest_private_get_response(IWineXMLHttpRequestPrivate
*iface
, VARIANT
*p
)
1204 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1205 HRESULT hres
= S_OK
;
1207 TRACE("(%p)->(%p)\n", This
, p
);
1209 switch(This
->response_type
) {
1210 case response_type_empty
:
1211 case response_type_text
:
1212 hres
= IHTMLXMLHttpRequest_get_responseText(&This
->IHTMLXMLHttpRequest_iface
, &V_BSTR(p
));
1217 case response_type_doc
:
1218 FIXME("response_type_doc\n");
1221 case response_type_arraybuf
:
1222 case response_type_blob
:
1223 if(This
->ready_state
< READYSTATE_COMPLETE
) {
1227 if(This
->response_type
== response_type_arraybuf
) {
1228 FIXME("response_type_arraybuf\n");
1231 FIXME("response_type_blob\n");
1234 case response_type_stream
:
1235 FIXME("response_type_stream\n");
1245 static HRESULT WINAPI
HTMLXMLHttpRequest_private_put_responseType(IWineXMLHttpRequestPrivate
*iface
, BSTR v
)
1247 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1252 TRACE("(%p)->(%s)\n", This
, debugstr_w(v
));
1254 if(This
->ready_state
< READYSTATE_LOADING
|| This
->ready_state
> READYSTATE_INTERACTIVE
) {
1255 /* FIXME: Return InvalidStateError */
1259 for(i
= 0; i
< ARRAY_SIZE(response_type_desc
); i
++)
1260 if(!wcscmp(v
, response_type_desc
[i
].str
))
1262 if(i
>= ARRAY_SIZE(response_type_desc
))
1265 nsAString_InitDepend(&nsstr
, response_type_desc
[i
].nsxhr_str
);
1266 nsres
= nsIXMLHttpRequest_SetResponseType(This
->nsxhr
, &nsstr
);
1267 nsAString_Finish(&nsstr
);
1268 if(NS_FAILED(nsres
))
1269 return map_nsresult(nsres
);
1271 This
->response_type
= i
;
1275 static HRESULT WINAPI
HTMLXMLHttpRequest_private_get_responseType(IWineXMLHttpRequestPrivate
*iface
, BSTR
*p
)
1277 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1279 TRACE("(%p)->(%p)\n", This
, p
);
1281 *p
= SysAllocString(response_type_desc
[This
->response_type
].str
);
1282 return *p
? S_OK
: E_OUTOFMEMORY
;
1285 static HRESULT WINAPI
HTMLXMLHttpRequest_private_get_upload(IWineXMLHttpRequestPrivate
*iface
, IDispatch
**p
)
1287 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1289 FIXME("(%p)->(%p)\n", This
, p
);
1294 static HRESULT WINAPI
HTMLXMLHttpRequest_private_put_withCredentials(IWineXMLHttpRequestPrivate
*iface
, VARIANT_BOOL v
)
1296 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1298 TRACE("(%p)->(%x)\n", This
, v
);
1300 return map_nsresult(nsIXMLHttpRequest_SetWithCredentials(This
->nsxhr
, !!v
));
1303 static HRESULT WINAPI
HTMLXMLHttpRequest_private_get_withCredentials(IWineXMLHttpRequestPrivate
*iface
, VARIANT_BOOL
*p
)
1305 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1309 TRACE("(%p)->(%p)\n", This
, p
);
1311 nsres
= nsIXMLHttpRequest_GetWithCredentials(This
->nsxhr
, &b
);
1312 if(NS_FAILED(nsres
))
1313 return map_nsresult(nsres
);
1314 *p
= b
? VARIANT_TRUE
: VARIANT_FALSE
;
1318 static HRESULT WINAPI
HTMLXMLHttpRequest_private_overrideMimeType(IWineXMLHttpRequestPrivate
*iface
, BSTR mimeType
)
1320 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1321 static const WCHAR generic_type
[] = L
"application/octet-stream";
1322 const WCHAR
*type
= NULL
;
1323 WCHAR
*lowercase
= NULL
;
1327 TRACE("(%p)->(%s)\n", This
, debugstr_w(mimeType
));
1331 if(!(lowercase
= wcsdup(mimeType
)))
1332 return E_OUTOFMEMORY
;
1336 type
= generic_type
;
1339 nsAString_InitDepend(&nsstr
, type
);
1340 nsres
= nsIXMLHttpRequest_SlowOverrideMimeType(This
->nsxhr
, &nsstr
);
1341 nsAString_Finish(&nsstr
);
1343 return map_nsresult(nsres
);
1346 static HRESULT WINAPI
HTMLXMLHttpRequest_private_put_onerror(IWineXMLHttpRequestPrivate
*iface
, VARIANT v
)
1348 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1350 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
1352 return set_event_handler(&This
->event_target
, EVENTID_ERROR
, &v
);
1355 static HRESULT WINAPI
HTMLXMLHttpRequest_private_get_onerror(IWineXMLHttpRequestPrivate
*iface
, VARIANT
*p
)
1357 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1359 TRACE("(%p)->(%p)\n", This
, p
);
1361 return get_event_handler(&This
->event_target
, EVENTID_ERROR
, p
);
1364 static HRESULT WINAPI
HTMLXMLHttpRequest_private_put_onabort(IWineXMLHttpRequestPrivate
*iface
, VARIANT v
)
1366 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1368 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
1370 return set_event_handler(&This
->event_target
, EVENTID_ABORT
, &v
);
1373 static HRESULT WINAPI
HTMLXMLHttpRequest_private_get_onabort(IWineXMLHttpRequestPrivate
*iface
, VARIANT
*p
)
1375 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1377 TRACE("(%p)->(%p)\n", This
, p
);
1379 return get_event_handler(&This
->event_target
, EVENTID_ABORT
, p
);
1382 static HRESULT WINAPI
HTMLXMLHttpRequest_private_put_onprogress(IWineXMLHttpRequestPrivate
*iface
, VARIANT v
)
1384 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1386 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
1388 return set_event_handler(&This
->event_target
, EVENTID_PROGRESS
, &v
);
1391 static HRESULT WINAPI
HTMLXMLHttpRequest_private_get_onprogress(IWineXMLHttpRequestPrivate
*iface
, VARIANT
*p
)
1393 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1395 TRACE("(%p)->(%p)\n", This
, p
);
1397 return get_event_handler(&This
->event_target
, EVENTID_PROGRESS
, p
);
1400 static HRESULT WINAPI
HTMLXMLHttpRequest_private_put_onloadstart(IWineXMLHttpRequestPrivate
*iface
, VARIANT v
)
1402 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1404 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
1406 return set_event_handler(&This
->event_target
, EVENTID_LOADSTART
, &v
);
1409 static HRESULT WINAPI
HTMLXMLHttpRequest_private_get_onloadstart(IWineXMLHttpRequestPrivate
*iface
, VARIANT
*p
)
1411 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1413 TRACE("(%p)->(%p)\n", This
, p
);
1415 return get_event_handler(&This
->event_target
, EVENTID_LOADSTART
, p
);
1418 static HRESULT WINAPI
HTMLXMLHttpRequest_private_put_onloadend(IWineXMLHttpRequestPrivate
*iface
, VARIANT v
)
1420 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1422 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
1424 return set_event_handler(&This
->event_target
, EVENTID_LOADEND
, &v
);
1427 static HRESULT WINAPI
HTMLXMLHttpRequest_private_get_onloadend(IWineXMLHttpRequestPrivate
*iface
, VARIANT
*p
)
1429 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1431 TRACE("(%p)->(%p)\n", This
, p
);
1433 return get_event_handler(&This
->event_target
, EVENTID_LOADEND
, p
);
1436 static HRESULT WINAPI
HTMLXMLHttpRequest_private_put_onload(IWineXMLHttpRequestPrivate
*iface
, VARIANT v
)
1438 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1440 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
1442 return set_event_handler(&This
->event_target
, EVENTID_LOAD
, &v
);
1445 static HRESULT WINAPI
HTMLXMLHttpRequest_private_get_onload(IWineXMLHttpRequestPrivate
*iface
, VARIANT
*p
)
1447 HTMLXMLHttpRequest
*This
= impl_from_IWineXMLHttpRequestPrivate(iface
);
1449 TRACE("(%p)->(%p)\n", This
, p
);
1451 return get_event_handler(&This
->event_target
, EVENTID_LOAD
, p
);
1454 static const IWineXMLHttpRequestPrivateVtbl WineXMLHttpRequestPrivateVtbl
= {
1455 HTMLXMLHttpRequest_private_QueryInterface
,
1456 HTMLXMLHttpRequest_private_AddRef
,
1457 HTMLXMLHttpRequest_private_Release
,
1458 HTMLXMLHttpRequest_private_GetTypeInfoCount
,
1459 HTMLXMLHttpRequest_private_GetTypeInfo
,
1460 HTMLXMLHttpRequest_private_GetIDsOfNames
,
1461 HTMLXMLHttpRequest_private_Invoke
,
1462 HTMLXMLHttpRequest_private_get_response
,
1463 HTMLXMLHttpRequest_private_put_responseType
,
1464 HTMLXMLHttpRequest_private_get_responseType
,
1465 HTMLXMLHttpRequest_private_get_upload
,
1466 HTMLXMLHttpRequest_private_put_withCredentials
,
1467 HTMLXMLHttpRequest_private_get_withCredentials
,
1468 HTMLXMLHttpRequest_private_overrideMimeType
,
1469 HTMLXMLHttpRequest_private_put_onerror
,
1470 HTMLXMLHttpRequest_private_get_onerror
,
1471 HTMLXMLHttpRequest_private_put_onabort
,
1472 HTMLXMLHttpRequest_private_get_onabort
,
1473 HTMLXMLHttpRequest_private_put_onprogress
,
1474 HTMLXMLHttpRequest_private_get_onprogress
,
1475 HTMLXMLHttpRequest_private_put_onloadstart
,
1476 HTMLXMLHttpRequest_private_get_onloadstart
,
1477 HTMLXMLHttpRequest_private_put_onloadend
,
1478 HTMLXMLHttpRequest_private_get_onloadend
,
1479 HTMLXMLHttpRequest_private_put_onload
,
1480 HTMLXMLHttpRequest_private_get_onload
1483 static inline HTMLXMLHttpRequest
*impl_from_IProvideClassInfo2(IProvideClassInfo2
*iface
)
1485 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequest
, IProvideClassInfo2_iface
);
1488 static HRESULT WINAPI
ProvideClassInfo_QueryInterface(IProvideClassInfo2
*iface
, REFIID riid
, void **ppv
)
1490 HTMLXMLHttpRequest
*This
= impl_from_IProvideClassInfo2(iface
);
1491 return IHTMLXMLHttpRequest_QueryInterface(&This
->IHTMLXMLHttpRequest_iface
, riid
, ppv
);
1494 static ULONG WINAPI
ProvideClassInfo_AddRef(IProvideClassInfo2
*iface
)
1496 HTMLXMLHttpRequest
*This
= impl_from_IProvideClassInfo2(iface
);
1497 return IHTMLXMLHttpRequest_AddRef(&This
->IHTMLXMLHttpRequest_iface
);
1500 static ULONG WINAPI
ProvideClassInfo_Release(IProvideClassInfo2
*iface
)
1502 HTMLXMLHttpRequest
*This
= impl_from_IProvideClassInfo2(iface
);
1503 return IHTMLXMLHttpRequest_Release(&This
->IHTMLXMLHttpRequest_iface
);
1506 static HRESULT WINAPI
ProvideClassInfo_GetClassInfo(IProvideClassInfo2
*iface
, ITypeInfo
**ppTI
)
1508 HTMLXMLHttpRequest
*This
= impl_from_IProvideClassInfo2(iface
);
1509 TRACE("(%p)->(%p)\n", This
, ppTI
);
1510 return get_class_typeinfo(&CLSID_HTMLXMLHttpRequest
, ppTI
);
1513 static HRESULT WINAPI
ProvideClassInfo2_GetGUID(IProvideClassInfo2
*iface
, DWORD dwGuidKind
, GUID
*pGUID
)
1515 HTMLXMLHttpRequest
*This
= impl_from_IProvideClassInfo2(iface
);
1516 FIXME("(%p)->(%lu %p)\n", This
, dwGuidKind
, pGUID
);
1520 static const IProvideClassInfo2Vtbl ProvideClassInfo2Vtbl
= {
1521 ProvideClassInfo_QueryInterface
,
1522 ProvideClassInfo_AddRef
,
1523 ProvideClassInfo_Release
,
1524 ProvideClassInfo_GetClassInfo
,
1525 ProvideClassInfo2_GetGUID
,
1528 static inline HTMLXMLHttpRequest
*impl_from_DispatchEx(DispatchEx
*iface
)
1530 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequest
, event_target
.dispex
);
1533 static nsISupports
*HTMLXMLHttpRequest_get_gecko_target(DispatchEx
*dispex
)
1535 HTMLXMLHttpRequest
*This
= impl_from_DispatchEx(dispex
);
1536 return (nsISupports
*)This
->nsxhr
;
1539 static void HTMLXMLHttpRequest_bind_event(DispatchEx
*dispex
, eventid_t eid
)
1541 /* Do nothing. To be able to track state and queue events manually, when blocked
1542 * by sync XHRs in their send() event loop, we always register the handlers. */
1545 static void HTMLXMLHttpRequest_init_dispex_info(dispex_data_t
*info
, compat_mode_t compat_mode
)
1547 static const dispex_hook_t xhr_hooks
[] = {
1548 {DISPID_IHTMLXMLHTTPREQUEST_OPEN
, HTMLXMLHttpRequest_open_hook
},
1551 static const dispex_hook_t private_hooks
[] = {
1552 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSE
},
1553 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_RESPONSETYPE
},
1554 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_UPLOAD
},
1555 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_WITHCREDENTIALS
},
1556 {DISPID_EVPROP_ONERROR
},
1557 {DISPID_EVPROP_ONABORT
},
1558 {DISPID_EVPROP_PROGRESS
},
1559 {DISPID_EVPROP_LOADSTART
},
1560 {DISPID_EVPROP_LOADEND
},
1563 {DISPID_IWINEXMLHTTPREQUESTPRIVATE_OVERRIDEMIMETYPE
},
1566 const dispex_hook_t
*const private_ie10_hooks
= private_hooks
+ ARRAY_SIZE(private_hooks
) - 2;
1568 EventTarget_init_dispex_info(info
, compat_mode
);
1569 dispex_info_add_interface(info
, IHTMLXMLHttpRequest_tid
, compat_mode
>= COMPAT_MODE_IE10
? xhr_hooks
: NULL
);
1570 dispex_info_add_interface(info
, IWineXMLHttpRequestPrivate_tid
,
1571 compat_mode
< COMPAT_MODE_IE10
? private_hooks
:
1572 compat_mode
< COMPAT_MODE_IE11
? private_ie10_hooks
: NULL
);
1575 static event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl
= {
1579 HTMLXMLHttpRequest_get_gecko_target
,
1580 HTMLXMLHttpRequest_bind_event
1583 static const tid_t HTMLXMLHttpRequest_iface_tids
[] = {
1584 IHTMLXMLHttpRequest2_tid
,
1587 static dispex_static_data_t HTMLXMLHttpRequest_dispex
= {
1589 &HTMLXMLHttpRequest_event_target_vtbl
.dispex_vtbl
,
1590 DispHTMLXMLHttpRequest_tid
,
1591 HTMLXMLHttpRequest_iface_tids
,
1592 HTMLXMLHttpRequest_init_dispex_info
1596 /* IHTMLXMLHttpRequestFactory */
1597 static inline HTMLXMLHttpRequestFactory
*impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory
*iface
)
1599 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequestFactory
, IHTMLXMLHttpRequestFactory_iface
);
1602 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_QueryInterface(IHTMLXMLHttpRequestFactory
*iface
, REFIID riid
, void **ppv
)
1604 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
1606 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
1608 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
1609 *ppv
= &This
->IHTMLXMLHttpRequestFactory_iface
;
1610 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
1611 *ppv
= &This
->IHTMLXMLHttpRequestFactory_iface
;
1612 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequestFactory
, riid
)) {
1613 *ppv
= &This
->IHTMLXMLHttpRequestFactory_iface
;
1614 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
1615 return *ppv
? S_OK
: E_NOINTERFACE
;
1618 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
1619 return E_NOINTERFACE
;
1622 IUnknown_AddRef((IUnknown
*)*ppv
);
1626 static ULONG WINAPI
HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory
*iface
)
1628 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
1629 LONG ref
= InterlockedIncrement(&This
->ref
);
1631 TRACE("(%p) ref=%ld\n", This
, ref
);
1636 static ULONG WINAPI
HTMLXMLHttpRequestFactory_Release(IHTMLXMLHttpRequestFactory
*iface
)
1638 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
1639 LONG ref
= InterlockedDecrement(&This
->ref
);
1641 TRACE("(%p) ref=%ld\n", This
, ref
);
1644 release_dispex(&This
->dispex
);
1651 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_GetTypeInfoCount(IHTMLXMLHttpRequestFactory
*iface
, UINT
*pctinfo
)
1653 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
1654 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
1657 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_GetTypeInfo(IHTMLXMLHttpRequestFactory
*iface
, UINT iTInfo
,
1658 LCID lcid
, ITypeInfo
**ppTInfo
)
1660 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
1662 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
1665 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_GetIDsOfNames(IHTMLXMLHttpRequestFactory
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
1666 LCID lcid
, DISPID
*rgDispId
)
1668 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
1670 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
1674 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_Invoke(IHTMLXMLHttpRequestFactory
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
1675 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1677 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
1679 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
, wFlags
,
1680 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1683 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactory
*iface
, IHTMLXMLHttpRequest
**p
)
1685 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
1686 HTMLXMLHttpRequest
*ret
;
1687 nsIXMLHttpRequest
*nsxhr
;
1688 nsIDOMEventTarget
*nstarget
;
1689 XMLHttpReqEventListener
*event_listener
;
1693 TRACE("(%p)->(%p)\n", This
, p
);
1695 nsxhr
= create_nsxhr(This
->window
->base
.outer_window
->nswindow
);
1699 ret
= calloc(1, sizeof(*ret
));
1701 nsIXMLHttpRequest_Release(nsxhr
);
1702 return E_OUTOFMEMORY
;
1705 event_listener
= malloc(sizeof(*event_listener
));
1706 if(!event_listener
) {
1708 nsIXMLHttpRequest_Release(nsxhr
);
1709 return E_OUTOFMEMORY
;
1713 ret
->window
= This
->window
;
1714 ret
->task_magic
= get_task_target_magic();
1715 IHTMLWindow2_AddRef(&This
->window
->base
.IHTMLWindow2_iface
);
1717 ret
->IHTMLXMLHttpRequest_iface
.lpVtbl
= &HTMLXMLHttpRequestVtbl
;
1718 ret
->IHTMLXMLHttpRequest2_iface
.lpVtbl
= &HTMLXMLHttpRequest2Vtbl
;
1719 ret
->IWineXMLHttpRequestPrivate_iface
.lpVtbl
= &WineXMLHttpRequestPrivateVtbl
;
1720 ret
->IProvideClassInfo2_iface
.lpVtbl
= &ProvideClassInfo2Vtbl
;
1721 EventTarget_Init(&ret
->event_target
, (IUnknown
*)&ret
->IHTMLXMLHttpRequest_iface
,
1722 &HTMLXMLHttpRequest_dispex
, This
->window
->doc
->document_mode
);
1725 /* Always register the handlers because we need them to track state */
1726 event_listener
->nsIDOMEventListener_iface
.lpVtbl
= &XMLHttpReqEventListenerVtbl
;
1727 event_listener
->ref
= 1;
1728 event_listener
->xhr
= ret
;
1729 ret
->event_listener
= event_listener
;
1731 nsres
= nsIXMLHttpRequest_QueryInterface(nsxhr
, &IID_nsIDOMEventTarget
, (void**)&nstarget
);
1732 assert(nsres
== NS_OK
);
1734 for(i
= 0; i
< ARRAY_SIZE(events
); i
++) {
1735 const WCHAR
*name
= get_event_name(events
[i
]);
1738 nsAString_InitDepend(&type_str
, name
);
1739 nsres
= nsIDOMEventTarget_AddEventListener(nstarget
, &type_str
, &event_listener
->nsIDOMEventListener_iface
, FALSE
, TRUE
, 2);
1740 nsAString_Finish(&type_str
);
1741 if(NS_FAILED(nsres
)) {
1742 WARN("AddEventListener(%s) failed: %08lx\n", debugstr_w(name
), nsres
);
1743 IHTMLXMLHttpRequest_Release(&ret
->IHTMLXMLHttpRequest_iface
);
1744 return map_nsresult(nsres
);
1747 nsIDOMEventTarget_Release(nstarget
);
1749 *p
= &ret
->IHTMLXMLHttpRequest_iface
;
1753 static const IHTMLXMLHttpRequestFactoryVtbl HTMLXMLHttpRequestFactoryVtbl
= {
1754 HTMLXMLHttpRequestFactory_QueryInterface
,
1755 HTMLXMLHttpRequestFactory_AddRef
,
1756 HTMLXMLHttpRequestFactory_Release
,
1757 HTMLXMLHttpRequestFactory_GetTypeInfoCount
,
1758 HTMLXMLHttpRequestFactory_GetTypeInfo
,
1759 HTMLXMLHttpRequestFactory_GetIDsOfNames
,
1760 HTMLXMLHttpRequestFactory_Invoke
,
1761 HTMLXMLHttpRequestFactory_create
1764 static inline HTMLXMLHttpRequestFactory
*factory_from_DispatchEx(DispatchEx
*iface
)
1766 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequestFactory
, dispex
);
1769 static HRESULT
HTMLXMLHttpRequestFactory_value(DispatchEx
*iface
, LCID lcid
, WORD flags
, DISPPARAMS
*params
,
1770 VARIANT
*res
, EXCEPINFO
*ei
, IServiceProvider
*caller
)
1772 HTMLXMLHttpRequestFactory
*This
= factory_from_DispatchEx(iface
);
1773 IHTMLXMLHttpRequest
*xhr
;
1778 if(flags
!= DISPATCH_CONSTRUCT
) {
1779 FIXME("flags %x not supported\n", flags
);
1783 hres
= IHTMLXMLHttpRequestFactory_create(&This
->IHTMLXMLHttpRequestFactory_iface
, &xhr
);
1787 V_VT(res
) = VT_DISPATCH
;
1788 V_DISPATCH(res
) = (IDispatch
*)xhr
;
1792 static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl
= {
1793 HTMLXMLHttpRequestFactory_value
1796 static const tid_t HTMLXMLHttpRequestFactory_iface_tids
[] = {
1797 IHTMLXMLHttpRequestFactory_tid
,
1800 static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex
= {
1802 &HTMLXMLHttpRequestFactory_dispex_vtbl
,
1803 IHTMLXMLHttpRequestFactory_tid
,
1804 HTMLXMLHttpRequestFactory_iface_tids
1807 HRESULT
HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow
* window
, HTMLXMLHttpRequestFactory
**ret_ptr
)
1809 HTMLXMLHttpRequestFactory
*ret
;
1811 ret
= malloc(sizeof(*ret
));
1813 return E_OUTOFMEMORY
;
1815 ret
->IHTMLXMLHttpRequestFactory_iface
.lpVtbl
= &HTMLXMLHttpRequestFactoryVtbl
;
1817 ret
->window
= window
;
1819 init_dispatch(&ret
->dispex
, (IUnknown
*)&ret
->IHTMLXMLHttpRequestFactory_iface
,
1820 &HTMLXMLHttpRequestFactory_dispex
, dispex_compat_mode(&window
->event_target
.dispex
));