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"
34 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
36 static HRESULT
bstr_to_nsacstr(BSTR bstr
, nsACString
*str
)
38 char *cstr
= heap_strdupWtoU(bstr
);
41 nsACString_Init(str
, cstr
);
46 static HRESULT
variant_to_nsastr(VARIANT var
, nsAString
*ret
)
52 nsAString_Init(ret
, NULL
);
55 nsAString_InitDepend(ret
, V_BSTR(&var
));
58 FIXME("Unsupported VARIANT: %s\n", debugstr_variant(&var
));
63 /* IHTMLXMLHttpRequest */
65 EventTarget event_target
;
66 IHTMLXMLHttpRequest IHTMLXMLHttpRequest_iface
;
68 nsIXMLHttpRequest
*nsxhr
;
71 static inline HTMLXMLHttpRequest
*impl_from_IHTMLXMLHttpRequest(IHTMLXMLHttpRequest
*iface
)
73 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequest
, IHTMLXMLHttpRequest_iface
);
76 static HRESULT WINAPI
HTMLXMLHttpRequest_QueryInterface(IHTMLXMLHttpRequest
*iface
, REFIID riid
, void **ppv
)
78 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
80 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
82 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
83 *ppv
= &This
->IHTMLXMLHttpRequest_iface
;
84 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
85 *ppv
= &This
->IHTMLXMLHttpRequest_iface
;
86 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequest
, riid
)) {
87 *ppv
= &This
->IHTMLXMLHttpRequest_iface
;
88 }else if(dispex_query_interface(&This
->event_target
.dispex
, riid
, ppv
)) {
89 return *ppv
? S_OK
: E_NOINTERFACE
;
92 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
96 IUnknown_AddRef((IUnknown
*)*ppv
);
100 static ULONG WINAPI
HTMLXMLHttpRequest_AddRef(IHTMLXMLHttpRequest
*iface
)
102 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
103 LONG ref
= InterlockedIncrement(&This
->ref
);
105 TRACE("(%p) ref=%d\n", This
, ref
);
110 static ULONG WINAPI
HTMLXMLHttpRequest_Release(IHTMLXMLHttpRequest
*iface
)
112 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
113 LONG ref
= InterlockedDecrement(&This
->ref
);
115 TRACE("(%p) ref=%d\n", This
, ref
);
118 release_dispex(&This
->event_target
.dispex
);
119 nsIXMLHttpRequest_Release(This
->nsxhr
);
126 static HRESULT WINAPI
HTMLXMLHttpRequest_GetTypeInfoCount(IHTMLXMLHttpRequest
*iface
, UINT
*pctinfo
)
128 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
129 return IDispatchEx_GetTypeInfoCount(&This
->event_target
.dispex
.IDispatchEx_iface
, pctinfo
);
132 static HRESULT WINAPI
HTMLXMLHttpRequest_GetTypeInfo(IHTMLXMLHttpRequest
*iface
, UINT iTInfo
,
133 LCID lcid
, ITypeInfo
**ppTInfo
)
135 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
137 return IDispatchEx_GetTypeInfo(&This
->event_target
.dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
140 static HRESULT WINAPI
HTMLXMLHttpRequest_GetIDsOfNames(IHTMLXMLHttpRequest
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
141 LCID lcid
, DISPID
*rgDispId
)
143 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
145 return IDispatchEx_GetIDsOfNames(&This
->event_target
.dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
149 static HRESULT WINAPI
HTMLXMLHttpRequest_Invoke(IHTMLXMLHttpRequest
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
150 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
152 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
154 return IDispatchEx_Invoke(&This
->event_target
.dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
, wFlags
,
155 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
158 static HRESULT WINAPI
HTMLXMLHttpRequest_get_readyState(IHTMLXMLHttpRequest
*iface
, LONG
*p
)
160 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
161 FIXME("(%p)->(%p)\n", This
, p
);
165 static HRESULT WINAPI
HTMLXMLHttpRequest_get_responseBody(IHTMLXMLHttpRequest
*iface
, VARIANT
*p
)
167 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
168 FIXME("(%p)->(%p)\n", This
, p
);
172 static HRESULT WINAPI
HTMLXMLHttpRequest_get_responseText(IHTMLXMLHttpRequest
*iface
, BSTR
*p
)
174 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
175 FIXME("(%p)->(%p)\n", This
, p
);
179 static HRESULT WINAPI
HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest
*iface
, IDispatch
**p
)
181 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
182 FIXME("(%p)->(%p)\n", This
, p
);
186 static HRESULT WINAPI
HTMLXMLHttpRequest_get_status(IHTMLXMLHttpRequest
*iface
, LONG
*p
)
188 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
189 FIXME("(%p)->(%p)\n", This
, p
);
193 static HRESULT WINAPI
HTMLXMLHttpRequest_get_statusText(IHTMLXMLHttpRequest
*iface
, BSTR
*p
)
195 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
196 FIXME("(%p)->(%p)\n", This
, p
);
200 static HRESULT WINAPI
HTMLXMLHttpRequest_put_onreadystatechange(IHTMLXMLHttpRequest
*iface
, VARIANT v
)
202 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
204 TRACE("(%p)->(%s)\n", This
, debugstr_variant(&v
));
206 return set_event_handler(&This
->event_target
, EVENTID_READYSTATECHANGE
, &v
);
209 static HRESULT WINAPI
HTMLXMLHttpRequest_get_onreadystatechange(IHTMLXMLHttpRequest
*iface
, VARIANT
*p
)
211 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
213 TRACE("(%p)->(%p)\n", This
, p
);
215 return get_event_handler(&This
->event_target
, EVENTID_READYSTATECHANGE
, p
);
218 static HRESULT WINAPI
HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest
*iface
)
220 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
221 FIXME("(%p)->()\n", This
);
225 static HRESULT WINAPI
HTMLXMLHttpRequest_open(IHTMLXMLHttpRequest
*iface
, BSTR bstrMethod
, BSTR bstrUrl
, VARIANT varAsync
, VARIANT varUser
, VARIANT varPassword
)
227 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
228 nsACString method
, url
;
229 nsAString user
, password
;
233 TRACE("(%p)->(%s %s %s %s %s)\n", This
, debugstr_w(bstrMethod
), debugstr_w(bstrUrl
), debugstr_variant(&varAsync
), debugstr_variant(&varUser
), debugstr_variant(&varPassword
));
235 if(V_VT(&varAsync
) != VT_BOOL
) {
236 FIXME("varAsync not supported: %s\n", debugstr_variant(&varAsync
));
240 /* Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27),
241 * synchronous requests on the main thread have been deprecated due to the negative
242 * effects to the user experience.
244 if(!V_BOOL(&varAsync
)) {
245 FIXME("Synchronous request is not supported yet\n");
249 hres
= variant_to_nsastr(varUser
, &user
);
252 hres
= variant_to_nsastr(varPassword
, &password
);
254 nsAString_Finish(&user
);
258 hres
= bstr_to_nsacstr(bstrMethod
, &method
);
260 nsAString_Finish(&user
);
261 nsAString_Finish(&password
);
264 hres
= bstr_to_nsacstr(bstrUrl
, &url
);
266 nsAString_Finish(&user
);
267 nsAString_Finish(&password
);
268 nsACString_Finish(&method
);
272 nsres
= nsIXMLHttpRequest_Open(This
->nsxhr
, &method
, &url
, TRUE
,
273 &user
, &password
, 0);
275 nsACString_Finish(&method
);
276 nsACString_Finish(&url
);
277 nsAString_Finish(&user
);
278 nsAString_Finish(&password
);
280 if(NS_FAILED(nsres
)) {
281 ERR("nsIXMLHttpRequest_Open failed: %08x\n", nsres
);
288 static HRESULT WINAPI
HTMLXMLHttpRequest_send(IHTMLXMLHttpRequest
*iface
, VARIANT varBody
)
290 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
291 FIXME("(%p)->(%s)\n", This
, debugstr_variant(&varBody
));
295 static HRESULT WINAPI
HTMLXMLHttpRequest_getAllResponseHeaders(IHTMLXMLHttpRequest
*iface
, BSTR
*p
)
297 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
298 FIXME("(%p)->(%p)\n", This
, p
);
302 static HRESULT WINAPI
HTMLXMLHttpRequest_getResponseHeader(IHTMLXMLHttpRequest
*iface
, BSTR bstrHeader
, BSTR
*p
)
304 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
305 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(bstrHeader
), p
);
309 static HRESULT WINAPI
HTMLXMLHttpRequest_setRequestHeader(IHTMLXMLHttpRequest
*iface
, BSTR bstrHeader
, BSTR bstrValue
)
311 HTMLXMLHttpRequest
*This
= impl_from_IHTMLXMLHttpRequest(iface
);
312 FIXME("(%p)->(%s %s)\n", This
, debugstr_w(bstrHeader
), debugstr_w(bstrValue
));
316 static const IHTMLXMLHttpRequestVtbl HTMLXMLHttpRequestVtbl
= {
317 HTMLXMLHttpRequest_QueryInterface
,
318 HTMLXMLHttpRequest_AddRef
,
319 HTMLXMLHttpRequest_Release
,
320 HTMLXMLHttpRequest_GetTypeInfoCount
,
321 HTMLXMLHttpRequest_GetTypeInfo
,
322 HTMLXMLHttpRequest_GetIDsOfNames
,
323 HTMLXMLHttpRequest_Invoke
,
324 HTMLXMLHttpRequest_get_readyState
,
325 HTMLXMLHttpRequest_get_responseBody
,
326 HTMLXMLHttpRequest_get_responseText
,
327 HTMLXMLHttpRequest_get_responseXML
,
328 HTMLXMLHttpRequest_get_status
,
329 HTMLXMLHttpRequest_get_statusText
,
330 HTMLXMLHttpRequest_put_onreadystatechange
,
331 HTMLXMLHttpRequest_get_onreadystatechange
,
332 HTMLXMLHttpRequest_abort
,
333 HTMLXMLHttpRequest_open
,
334 HTMLXMLHttpRequest_send
,
335 HTMLXMLHttpRequest_getAllResponseHeaders
,
336 HTMLXMLHttpRequest_getResponseHeader
,
337 HTMLXMLHttpRequest_setRequestHeader
340 static inline HTMLXMLHttpRequest
*impl_from_DispatchEx(DispatchEx
*iface
)
342 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequest
, event_target
.dispex
);
345 static void HTMLXMLHttpRequest_bind_event(DispatchEx
*dispex
, int eid
)
347 HTMLXMLHttpRequest
*This
= impl_from_DispatchEx(dispex
);
349 FIXME("(%p)\n", This
);
351 assert(eid
== EVENTID_READYSTATECHANGE
);
354 static dispex_static_data_vtbl_t HTMLXMLHttpRequest_dispex_vtbl
= {
360 HTMLXMLHttpRequest_bind_event
363 static const tid_t HTMLXMLHttpRequest_iface_tids
[] = {
364 IHTMLXMLHttpRequest_tid
,
367 static dispex_static_data_t HTMLXMLHttpRequest_dispex
= {
368 &HTMLXMLHttpRequest_dispex_vtbl
,
369 DispHTMLXMLHttpRequest_tid
,
371 HTMLXMLHttpRequest_iface_tids
375 /* IHTMLXMLHttpRequestFactory */
376 static inline HTMLXMLHttpRequestFactory
*impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory
*iface
)
378 return CONTAINING_RECORD(iface
, HTMLXMLHttpRequestFactory
, IHTMLXMLHttpRequestFactory_iface
);
381 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_QueryInterface(IHTMLXMLHttpRequestFactory
*iface
, REFIID riid
, void **ppv
)
383 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
385 TRACE("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
387 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
388 *ppv
= &This
->IHTMLXMLHttpRequestFactory_iface
;
389 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
390 *ppv
= &This
->IHTMLXMLHttpRequestFactory_iface
;
391 }else if(IsEqualGUID(&IID_IHTMLXMLHttpRequestFactory
, riid
)) {
392 *ppv
= &This
->IHTMLXMLHttpRequestFactory_iface
;
393 }else if(dispex_query_interface(&This
->dispex
, riid
, ppv
)) {
394 return *ppv
? S_OK
: E_NOINTERFACE
;
397 WARN("(%p)->(%s %p)\n", This
, debugstr_mshtml_guid(riid
), ppv
);
398 return E_NOINTERFACE
;
401 IUnknown_AddRef((IUnknown
*)*ppv
);
405 static ULONG WINAPI
HTMLXMLHttpRequestFactory_AddRef(IHTMLXMLHttpRequestFactory
*iface
)
407 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
408 LONG ref
= InterlockedIncrement(&This
->ref
);
410 TRACE("(%p) ref=%d\n", This
, ref
);
415 static ULONG WINAPI
HTMLXMLHttpRequestFactory_Release(IHTMLXMLHttpRequestFactory
*iface
)
417 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
418 LONG ref
= InterlockedDecrement(&This
->ref
);
420 TRACE("(%p) ref=%d\n", This
, ref
);
423 release_dispex(&This
->dispex
);
430 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_GetTypeInfoCount(IHTMLXMLHttpRequestFactory
*iface
, UINT
*pctinfo
)
432 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
433 return IDispatchEx_GetTypeInfoCount(&This
->dispex
.IDispatchEx_iface
, pctinfo
);
436 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_GetTypeInfo(IHTMLXMLHttpRequestFactory
*iface
, UINT iTInfo
,
437 LCID lcid
, ITypeInfo
**ppTInfo
)
439 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
441 return IDispatchEx_GetTypeInfo(&This
->dispex
.IDispatchEx_iface
, iTInfo
, lcid
, ppTInfo
);
444 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_GetIDsOfNames(IHTMLXMLHttpRequestFactory
*iface
, REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
,
445 LCID lcid
, DISPID
*rgDispId
)
447 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
449 return IDispatchEx_GetIDsOfNames(&This
->dispex
.IDispatchEx_iface
, riid
, rgszNames
, cNames
,
453 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_Invoke(IHTMLXMLHttpRequestFactory
*iface
, DISPID dispIdMember
, REFIID riid
, LCID lcid
,
454 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
456 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
458 return IDispatchEx_Invoke(&This
->dispex
.IDispatchEx_iface
, dispIdMember
, riid
, lcid
, wFlags
,
459 pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
462 static HRESULT WINAPI
HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactory
*iface
, IHTMLXMLHttpRequest
**p
)
464 HTMLXMLHttpRequestFactory
*This
= impl_from_IHTMLXMLHttpRequestFactory(iface
);
465 HTMLXMLHttpRequest
*ret
;
466 nsIXMLHttpRequest
*nsxhr
;
468 TRACE("(%p)->(%p)\n", This
, p
);
470 nsxhr
= create_nsxhr(This
->window
->base
.outer_window
->nswindow
);
474 ret
= heap_alloc_zero(sizeof(*ret
));
476 nsIXMLHttpRequest_Release(nsxhr
);
477 return E_OUTOFMEMORY
;
481 ret
->IHTMLXMLHttpRequest_iface
.lpVtbl
= &HTMLXMLHttpRequestVtbl
;
482 init_dispex(&ret
->event_target
.dispex
, (IUnknown
*)&ret
->IHTMLXMLHttpRequest_iface
,
483 &HTMLXMLHttpRequest_dispex
);
486 *p
= &ret
->IHTMLXMLHttpRequest_iface
;
490 static const IHTMLXMLHttpRequestFactoryVtbl HTMLXMLHttpRequestFactoryVtbl
= {
491 HTMLXMLHttpRequestFactory_QueryInterface
,
492 HTMLXMLHttpRequestFactory_AddRef
,
493 HTMLXMLHttpRequestFactory_Release
,
494 HTMLXMLHttpRequestFactory_GetTypeInfoCount
,
495 HTMLXMLHttpRequestFactory_GetTypeInfo
,
496 HTMLXMLHttpRequestFactory_GetIDsOfNames
,
497 HTMLXMLHttpRequestFactory_Invoke
,
498 HTMLXMLHttpRequestFactory_create
501 static const tid_t HTMLXMLHttpRequestFactory_iface_tids
[] = {
502 IHTMLXMLHttpRequestFactory_tid
,
505 static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex
= {
507 IHTMLXMLHttpRequestFactory_tid
,
509 HTMLXMLHttpRequestFactory_iface_tids
512 HRESULT
HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow
* window
, HTMLXMLHttpRequestFactory
**ret_ptr
)
514 HTMLXMLHttpRequestFactory
*ret
;
516 ret
= heap_alloc(sizeof(*ret
));
518 return E_OUTOFMEMORY
;
520 ret
->IHTMLXMLHttpRequestFactory_iface
.lpVtbl
= &HTMLXMLHttpRequestFactoryVtbl
;
522 ret
->window
= window
;
524 init_dispex(&ret
->dispex
, (IUnknown
*)&ret
->IHTMLXMLHttpRequestFactory_iface
,
525 &HTMLXMLHttpRequestFactory_dispex
);