From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/function.c | 14 ++++++++++---- dlls/jscript/jscript.c | 4 ++-- dlls/jscript/jscript.h | 2 +- dlls/jscript/jsdisp.idl | 2 +- dlls/mshtml/dispex.c | 4 ++-- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/tests/documentmode.js | 10 ++++++++++ dlls/mshtml/xmlhttprequest.c | 27 ++++++++++++++++++++++++++- 8 files changed, 53 insertions(+), 11 deletions(-)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 7206b5e46f0..24847e17686 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -74,6 +74,7 @@ typedef struct { typedef struct { FunctionInstance function; IWineJSDispatchHost *host_iface; + const WCHAR *method_name; } HostConstructor;
typedef struct { @@ -1130,6 +1131,9 @@ static HRESULT HostConstructor_call(script_ctx_t *ctx, FunctionInstance *func, j HRESULT hres = S_OK; unsigned i;
+ if(function->method_name && !(flags & DISPATCH_METHOD)) + return E_UNEXPECTED; + flags &= ~DISPATCH_JSCRIPT_INTERNAL_MASK; if(argc > ARRAYSIZE(buf) && !(dp.rgvarg = malloc(argc * sizeof(*dp.rgvarg)))) return E_OUTOFMEMORY; @@ -1159,10 +1163,11 @@ static HRESULT HostConstructor_call(script_ctx_t *ctx, FunctionInstance *func, j return hres; }
-static HRESULT HostConstructor_toString(FunctionInstance *function, jsstr_t **ret) +static HRESULT HostConstructor_toString(FunctionInstance *func, jsstr_t **ret) { - *ret = jsstr_alloc(L"\nfunction() {\n [native code]\n}\n"); - return *ret ? S_OK : E_OUTOFMEMORY; + HostConstructor *function = (HostConstructor*)func; + + return native_function_string(function->method_name, ret); }
static function_code_t *HostConstructor_get_code(FunctionInstance *function) @@ -1187,7 +1192,7 @@ static const function_vtbl_t HostConstructorVtbl = { HostConstructor_gc_traverse };
-HRESULT init_host_constructor(script_ctx_t *ctx, IWineJSDispatchHost *host_constr, IWineJSDispatch **ret) +HRESULT init_host_constructor(script_ctx_t *ctx, IWineJSDispatchHost *host_constr, const WCHAR *method_name, IWineJSDispatch **ret) { HostConstructor *function; HRESULT hres; @@ -1197,6 +1202,7 @@ HRESULT init_host_constructor(script_ctx_t *ctx, IWineJSDispatchHost *host_const if(FAILED(hres)) return hres; function->host_iface = host_constr; + function->method_name = method_name;
*ret = &function->function.dispex.IWineJSDispatch_iface; return S_OK; diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index c26ebbcc56e..9a74d010ab5 100644 --- a/dlls/jscript/jscript.c +++ b/dlls/jscript/jscript.c @@ -1459,10 +1459,10 @@ static HRESULT WINAPI WineJScript_InitHostObject(IWineJScript *iface, IWineJSDis }
static HRESULT WINAPI WineJScript_InitHostConstructor(IWineJScript *iface, IWineJSDispatchHost *constr, - IWineJSDispatch **ret) + const WCHAR *method_name, IWineJSDispatch **ret) { JScript *This = impl_from_IWineJScript(iface); - return init_host_constructor(This->ctx, constr, ret); + return init_host_constructor(This->ctx, constr, method_name, ret); }
static const IWineJScriptVtbl WineJScriptVtbl = { diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 04298ec3985..d42dd3a8a8a 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -241,7 +241,7 @@ HRESULT create_dispex(script_ctx_t*,const builtin_info_t*,jsdisp_t*,jsdisp_t**); HRESULT init_dispex(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*); HRESULT init_dispex_from_constr(jsdisp_t*,script_ctx_t*,const builtin_info_t*,jsdisp_t*); HRESULT init_host_object(script_ctx_t*,IWineJSDispatchHost*,IWineJSDispatch*,UINT32,IWineJSDispatch**); -HRESULT init_host_constructor(script_ctx_t*,IWineJSDispatchHost*,IWineJSDispatch**); +HRESULT init_host_constructor(script_ctx_t*,IWineJSDispatchHost*,const WCHAR*,IWineJSDispatch**);
HRESULT disp_call(script_ctx_t*,IDispatch*,DISPID,WORD,unsigned,jsval_t*,jsval_t*); HRESULT disp_call_name(script_ctx_t*,IDispatch*,const WCHAR*,WORD,unsigned,jsval_t*,jsval_t*); diff --git a/dlls/jscript/jsdisp.idl b/dlls/jscript/jsdisp.idl index 58e57ce2fdc..0815a8903d8 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -84,5 +84,5 @@ interface IWineJSDispatchHost : IDispatchEx interface IWineJScript : IUnknown { HRESULT InitHostObject(IWineJSDispatchHost *host_obj, IWineJSDispatch *prototype, UINT32 flags, IWineJSDispatch **ret); - HRESULT InitHostConstructor(IWineJSDispatchHost *constr, IWineJSDispatch **ret); + HRESULT InitHostConstructor(IWineJSDispatchHost *constr, const WCHAR *method_name, IWineJSDispatch **ret); } diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index c208d976e41..9ea42cb3fdb 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1891,7 +1891,7 @@ static void init_host_object(DispatchEx *dispex, HTMLInnerWindow *script_global, if(FAILED(hres = get_prototype(script_global, dispex->info->desc->constructor_id, &prototype))) return; hres = IWineJScript_InitHostConstructor(script_global->jscript, &dispex->IWineJSDispatchHost_iface, - &dispex->jsdisp); + NULL, &dispex->jsdisp); if(SUCCEEDED(hres)) { VARIANT v; V_VT(&v) = VT_DISPATCH; @@ -2919,7 +2919,7 @@ const void *dispex_get_vtbl(DispatchEx *dispex) return dispex->info->vtbl; }
-static void init_dispatch_from_desc(DispatchEx *dispex, dispex_data_t *info, HTMLInnerWindow *script_global, DispatchEx *prototype) +void init_dispatch_from_desc(DispatchEx *dispex, dispex_data_t *info, HTMLInnerWindow *script_global, DispatchEx *prototype) { dispex->IWineJSDispatchHost_iface.lpVtbl = &JSDispatchHostVtbl; dispex->dynamic_data = NULL; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 50e0c869280..573a0b6bf63 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -619,6 +619,7 @@ extern void (__cdecl *describe_cc_node)(nsCycleCollectingAutoRefCnt*,const char* extern void (__cdecl *note_cc_edge)(nsISupports*,const char*,nsCycleCollectionTraversalCallback*);
void init_dispatch(DispatchEx*,dispex_static_data_t*,HTMLInnerWindow*,compat_mode_t); +void init_dispatch_from_desc(DispatchEx*,dispex_data_t*,HTMLInnerWindow*,DispatchEx*); void init_dispatch_with_owner(DispatchEx*,dispex_static_data_t*,DispatchEx*); HTMLInnerWindow *get_script_global(DispatchEx*); void dispex_props_unlink(DispatchEx*); diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 55df3d746e4..ca1b5b03ddc 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -4012,4 +4012,14 @@ sync_test("constructors", function() { } ok(window.Image.prototype === window.HTMLImageElement.prototype, "Image.prototype != HTMLImageElement.prototype"); ok(window.Option.prototype === window.HTMLOptionElement.prototype, "Option.prototype != HTMLOptionElement.prototype"); + + ok(typeof(XMLHttpRequest.create) === "function", "XMLHttpRequest.create not a function"); + ok(XMLHttpRequest.create() instanceof XMLHttpRequest, "XMLHttpRequest.create did not return XMLHttpRequest instance"); + ok(XMLHttpRequest.create.call(Object) instanceof XMLHttpRequest, "XMLHttpRequest.create with Object 'this' did not return XMLHttpRequest instance"); + try { + new XMLHttpRequest.create(); + ok(false, "new XMLHttpRequest.create() did not throw"); + }catch(e) { + ok(e.number === 0x0ffff - 0x80000000, "new XMLHttpRequest.create() threw " + e.number); + } }); diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 5845d56514c..f675cf84770 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -1625,10 +1625,35 @@ static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex = {
static HRESULT HTMLXMLHttpRequestFactory_init(struct constructor *constr) { + struct constructor *create; + HRESULT hres; + constr->iface.lpVtbl = (const IUnknownVtbl*)&HTMLXMLHttpRequestFactoryVtbl; init_dispatch(&constr->dispex, &HTMLXMLHttpRequestFactory_dispex, constr->window, dispex_compat_mode(&constr->window->event_target.dispex)); - return S_OK; + + if(!constr->window->jscript) + return S_OK; + + if(!(create = malloc(sizeof(*create)))) + return E_OUTOFMEMORY; + create->iface = constr->iface; + create->window = constr->window; + IHTMLWindow2_AddRef(&constr->window->base.IHTMLWindow2_iface); + + init_dispatch_from_desc(&create->dispex, constr->dispex.info, NULL, NULL); + + hres = IWineJScript_InitHostConstructor(create->window->jscript, &create->dispex.IWineJSDispatchHost_iface, + L"create", &create->dispex.jsdisp); + if(SUCCEEDED(hres)) { + VARIANT v; + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = (IDispatch*)&create->dispex.IWineJSDispatchHost_iface; + hres = IWineJSDispatch_DefineProperty(constr->dispex.jsdisp, L"create", PROPF_WRITABLE | PROPF_CONFIGURABLE, v); + } + + IWineJSDispatchHost_Release(&create->dispex.IWineJSDispatchHost_iface); + return hres; }
static const tid_t HTMLXMLHttpRequest_iface_tids[] = {