-- v7: mshtml: Define "create" from XMLHttpRequest constructor as a jscript prop mshtml: Define the constructor's prototype on mshtml side. mshtml: Consolidate the functional constructors into a common struct mshtml: Rename struct constructor to stub_constructor.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 375f9be5402..518d009db41 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -3052,26 +3052,26 @@ HRESULT get_prototype(HTMLInnerWindow *script_global, object_id_t id, DispatchEx return S_OK; }
-struct constructor +struct stub_constructor { DispatchEx dispex; object_id_t id; };
-static inline struct constructor *constr_from_DispatchEx(DispatchEx *iface) +static inline struct stub_constructor *stub_constructor_from_DispatchEx(DispatchEx *iface) { - return CONTAINING_RECORD(iface, struct constructor, dispex); + return CONTAINING_RECORD(iface, struct stub_constructor, dispex); }
-static void constructor_destructor(DispatchEx *dispex) +static void stub_constructor_destructor(DispatchEx *dispex) { - struct constructor *constr = constr_from_DispatchEx(dispex); + struct stub_constructor *constr = stub_constructor_from_DispatchEx(dispex); free(constr); }
-static HRESULT constructor_find_dispid(DispatchEx *dispex, const WCHAR *name, DWORD flags, DISPID *dispid) +static HRESULT stub_constructor_find_dispid(DispatchEx *dispex, const WCHAR *name, DWORD flags, DISPID *dispid) { - struct constructor *constr = constr_from_DispatchEx(dispex); + struct stub_constructor *constr = stub_constructor_from_DispatchEx(dispex); HTMLInnerWindow *script_global; DispatchEx *prototype; HRESULT hres; @@ -3094,21 +3094,21 @@ static HRESULT constructor_find_dispid(DispatchEx *dispex, const WCHAR *name, DW return hres; }
-static const char *constructor_get_name(DispatchEx *dispex) +static const char *stub_constructor_get_name(DispatchEx *dispex) { - struct constructor *constr = constr_from_DispatchEx(dispex); + struct stub_constructor *constr = stub_constructor_from_DispatchEx(dispex); return object_names[constr->id - 1]; }
-static const dispex_static_data_vtbl_t constructor_dispex_vtbl = { - .destructor = constructor_destructor, - .find_dispid = constructor_find_dispid, - .get_name = constructor_get_name, +static const dispex_static_data_vtbl_t stub_constructor_dispex_vtbl = { + .destructor = stub_constructor_destructor, + .find_dispid = stub_constructor_find_dispid, + .get_name = stub_constructor_get_name, };
-static dispex_static_data_t constructor_dispex = { +static dispex_static_data_t stub_constructor_dispex = { .name = "Constructor", - .vtbl = &constructor_dispex_vtbl, + .vtbl = &stub_constructor_dispex_vtbl, .js_flags = HOSTOBJ_CONSTRUCTOR, };
@@ -3127,14 +3127,14 @@ HRESULT get_constructor(HTMLInnerWindow *script_global, object_id_t id, Dispatch if(FAILED(hres)) return hres; }else { - struct constructor *constr; + struct stub_constructor *constr;
assert(script_global->doc->document_mode >= COMPAT_MODE_IE9);
if(!(constr = calloc(sizeof(*constr), 1))) return E_OUTOFMEMORY;
- init_dispatch(&constr->dispex, &constructor_dispex, script_global, + init_dispatch(&constr->dispex, &stub_constructor_dispex, script_global, dispex_compat_mode(&script_global->event_target.dispex)); constr->id = id; script_global->constructors[id] = &constr->dispex;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 43 +++++++++++++++++++- dlls/mshtml/htmlimg.c | 71 +++++++------------------------- dlls/mshtml/htmlselect.c | 71 +++++++------------------------- dlls/mshtml/mshtml_private.h | 31 +++++++------- dlls/mshtml/mutation.c | 38 +++++------------- dlls/mshtml/xmlhttprequest.c | 78 +++++++----------------------------- 6 files changed, 111 insertions(+), 221 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 518d009db41..d590fd46f37 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -3052,6 +3052,31 @@ HRESULT get_prototype(HTMLInnerWindow *script_global, object_id_t id, DispatchEx return S_OK; }
+void constructor_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct constructor *This = constructor_from_DispatchEx(dispex); + + if(This->window) + note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); +} + +void constructor_unlink(DispatchEx *dispex) +{ + struct constructor *This = constructor_from_DispatchEx(dispex); + + if(This->window) { + HTMLInnerWindow *window = This->window; + This->window = NULL; + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + } +} + +void constructor_destructor(DispatchEx *dispex) +{ + struct constructor *This = constructor_from_DispatchEx(dispex); + free(This); +} + struct stub_constructor { DispatchEx dispex; @@ -3115,6 +3140,7 @@ static dispex_static_data_t stub_constructor_dispex = { HRESULT get_constructor(HTMLInnerWindow *script_global, object_id_t id, DispatchEx **ret) { dispex_static_data_t *info; + HRESULT hres;
if(script_global->constructors[id]) { *ret = script_global->constructors[id]; @@ -3123,9 +3149,22 @@ HRESULT get_constructor(HTMLInnerWindow *script_global, object_id_t id, Dispatch
info = object_descriptors[id]; if(info->init_constructor) { - HRESULT hres = info->init_constructor(script_global, &script_global->constructors[id]); - if(FAILED(hres)) + struct constructor *constr = malloc(sizeof(*constr)); + + if(!constr) + return E_OUTOFMEMORY; + + constr->window = script_global; + IHTMLWindow2_AddRef(&script_global->base.IHTMLWindow2_iface); + + hres = info->init_constructor(constr); + if(FAILED(hres)) { + IHTMLWindow2_Release(&script_global->base.IHTMLWindow2_iface); + free(constr); return hres; + } + + script_global->constructors[id] = &constr->dispex; }else { struct stub_constructor *constr;
diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index 942cf885cc4..fda2037f392 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -707,9 +707,9 @@ HRESULT HTMLImgElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, HTML return S_OK; }
-static inline HTMLImageElementFactory *impl_from_IHTMLImageElementFactory(IHTMLImageElementFactory *iface) +static inline struct constructor *impl_from_IHTMLImageElementFactory(IHTMLImageElementFactory *iface) { - return CONTAINING_RECORD(iface, HTMLImageElementFactory, IHTMLImageElementFactory_iface); + return CONTAINING_RECORD(iface, struct constructor, iface); }
DISPEX_IDISPATCH_IMPL(HTMLImageElementFactory, IHTMLImageElementFactory, @@ -742,7 +742,7 @@ static LONG var_to_size(const VARIANT *v) static HRESULT WINAPI HTMLImageElementFactory_create(IHTMLImageElementFactory *iface, VARIANT width, VARIANT height, IHTMLImgElement **img_elem) { - HTMLImageElementFactory *This = impl_from_IHTMLImageElementFactory(iface); + struct constructor *This = impl_from_IHTMLImageElementFactory(iface); HTMLDocumentNode *doc = This->window->doc; IHTMLImgElement *img; HTMLElement *elem; @@ -796,51 +796,21 @@ static const IHTMLImageElementFactoryVtbl HTMLImageElementFactoryVtbl = { HTMLImageElementFactory_create };
-static inline HTMLImageElementFactory *impl_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLImageElementFactory, dispex); -} - static void *HTMLImageElementFactory_query_interface(DispatchEx *dispex, REFIID riid) { - HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); + struct constructor *This = constructor_from_DispatchEx(dispex);
if(IsEqualGUID(&IID_IHTMLImageElementFactory, riid)) - return &This->IHTMLImageElementFactory_iface; + return &This->iface;
return NULL; }
-static void HTMLImageElementFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) -{ - HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); - - if(This->window) - note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); -} - -static void HTMLImageElementFactory_unlink(DispatchEx *dispex) -{ - HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); - - if(This->window) { - HTMLInnerWindow *window = This->window; - This->window = NULL; - IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); - } -} - -static void HTMLImageElementFactory_destructor(DispatchEx *dispex) -{ - HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); - free(This); -} - static HRESULT HTMLImageElementFactory_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { - HTMLImageElementFactory *This = impl_from_DispatchEx(dispex); + struct constructor *This = constructor_from_DispatchEx(dispex); IHTMLImgElement *img; VARIANT empty, *width, *height; HRESULT hres; @@ -853,7 +823,7 @@ static HRESULT HTMLImageElementFactory_value(DispatchEx *dispex, LCID lcid, width = argc >= 1 ? params->rgvarg + (params->cArgs - 1) : ∅ height = argc >= 2 ? params->rgvarg + (params->cArgs - 2) : ∅
- hres = IHTMLImageElementFactory_create(&This->IHTMLImageElementFactory_iface, *width, *height, + hres = IHTMLImageElementFactory_create((IHTMLImageElementFactory*)&This->iface, *width, *height, &img); if(FAILED(hres)) return hres; @@ -872,35 +842,24 @@ static void HTMLImageElementFactory_init_dispex_info(dispex_data_t *info, compat
static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = { .query_interface = HTMLImageElementFactory_query_interface, - .destructor = HTMLImageElementFactory_destructor, - .traverse = HTMLImageElementFactory_traverse, - .unlink = HTMLImageElementFactory_unlink, + .destructor = constructor_destructor, + .traverse = constructor_traverse, + .unlink = constructor_unlink, .value = HTMLImageElementFactory_value, };
-static HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow *window, DispatchEx **ret_val) +static HRESULT HTMLImageElementFactory_init(struct constructor *constr) { - HTMLImageElementFactory *ret; - - ret = malloc(sizeof(HTMLImageElementFactory)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IHTMLImageElementFactory_iface.lpVtbl = &HTMLImageElementFactoryVtbl; - ret->window = window; - IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); - - init_dispatch(&ret->dispex, &Image_dispex, window, - dispex_compat_mode(&window->event_target.dispex)); - - *ret_val = &ret->dispex; + constr->iface.lpVtbl = (const IUnknownVtbl*)&HTMLImageElementFactoryVtbl; + init_dispatch(&constr->dispex, &Image_dispex, constr->window, + dispex_compat_mode(&constr->window->event_target.dispex)); return S_OK; }
dispex_static_data_t Image_dispex = { .name = "Function", .constructor_id = OBJID_HTMLImageElement, - .init_constructor = HTMLImageElementFactory_Create, + .init_constructor = HTMLImageElementFactory_init, .vtbl = &HTMLImageElementFactory_dispex_vtbl, .disp_tid = IHTMLImageElementFactory_tid, .init_info = HTMLImageElementFactory_init_dispex_info, diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index 29875d91d7e..232f9104bc7 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -374,9 +374,9 @@ HRESULT HTMLOptionElement_Create(HTMLDocumentNode *doc, nsIDOMElement *nselem, H return S_OK; }
-static inline HTMLOptionElementFactory *impl_from_IHTMLOptionElementFactory(IHTMLOptionElementFactory *iface) +static inline struct constructor *impl_from_IHTMLOptionElementFactory(IHTMLOptionElementFactory *iface) { - return CONTAINING_RECORD(iface, HTMLOptionElementFactory, IHTMLOptionElementFactory_iface); + return CONTAINING_RECORD(iface, struct constructor, iface); }
DISPEX_IDISPATCH_IMPL(HTMLOptionElementFactory, IHTMLOptionElementFactory, @@ -386,7 +386,7 @@ static HRESULT WINAPI HTMLOptionElementFactory_create(IHTMLOptionElementFactory VARIANT text, VARIANT value, VARIANT defaultselected, VARIANT selected, IHTMLOptionElement **optelem) { - HTMLOptionElementFactory *This = impl_from_IHTMLOptionElementFactory(iface); + struct constructor *This = impl_from_IHTMLOptionElementFactory(iface); nsIDOMElement *nselem; HTMLDOMNode *node; HRESULT hres; @@ -438,51 +438,21 @@ static const IHTMLOptionElementFactoryVtbl HTMLOptionElementFactoryVtbl = { HTMLOptionElementFactory_create };
-static inline HTMLOptionElementFactory *HTMLOptionElementFactory_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLOptionElementFactory, dispex); -} - static void *HTMLOptionElementFactory_query_interface(DispatchEx *dispex, REFIID riid) { - HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); + struct constructor *This = constructor_from_DispatchEx(dispex);
if(IsEqualGUID(&IID_IHTMLOptionElementFactory, riid)) - return &This->IHTMLOptionElementFactory_iface; + return &This->iface;
return NULL; }
-static void HTMLOptionElementFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) -{ - HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); - - if(This->window) - note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); -} - -static void HTMLOptionElementFactory_unlink(DispatchEx *dispex) -{ - HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); - - if(This->window) { - HTMLInnerWindow *window = This->window; - This->window = NULL; - IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); - } -} - -static void HTMLOptionElementFactory_destructor(DispatchEx *dispex) -{ - HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); - free(This); -} - static HRESULT HTMLOptionElementFactory_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { - HTMLOptionElementFactory *This = HTMLOptionElementFactory_from_DispatchEx(dispex); + struct constructor *This = constructor_from_DispatchEx(dispex); unsigned int i, argc = params->cArgs - params->cNamedArgs; IHTMLOptionElement *opt; VARIANT empty, *arg[4]; @@ -499,7 +469,7 @@ static HRESULT HTMLOptionElementFactory_value(DispatchEx *dispex, LCID lcid, for(i = 0; i < ARRAY_SIZE(arg); i++) arg[i] = argc > i ? ¶ms->rgvarg[params->cArgs - 1 - i] : ∅
- hres = IHTMLOptionElementFactory_create(&This->IHTMLOptionElementFactory_iface, + hres = IHTMLOptionElementFactory_create((IHTMLOptionElementFactory*)&This->iface, *arg[0], *arg[1], *arg[2], *arg[3], &opt); if(FAILED(hres)) return hres; @@ -518,35 +488,24 @@ static void HTMLOptionElementFactory_init_dispex_info(dispex_data_t *info, compa
static const dispex_static_data_vtbl_t HTMLOptionElementFactory_dispex_vtbl = { .query_interface = HTMLOptionElementFactory_query_interface, - .destructor = HTMLOptionElementFactory_destructor, - .traverse = HTMLOptionElementFactory_traverse, - .unlink = HTMLOptionElementFactory_unlink, + .destructor = constructor_destructor, + .traverse = constructor_traverse, + .unlink = constructor_unlink, .value = HTMLOptionElementFactory_value, };
-static HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow *window, DispatchEx **ret_ptr) +static HRESULT HTMLOptionElementFactory_init(struct constructor *constr) { - HTMLOptionElementFactory *ret; - - ret = malloc(sizeof(*ret)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IHTMLOptionElementFactory_iface.lpVtbl = &HTMLOptionElementFactoryVtbl; - ret->window = window; - IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); - - init_dispatch(&ret->dispex, &Option_dispex, window, - dispex_compat_mode(&window->event_target.dispex)); - - *ret_ptr = &ret->dispex; + constr->iface.lpVtbl = (const IUnknownVtbl*)&HTMLOptionElementFactoryVtbl; + init_dispatch(&constr->dispex, &Option_dispex, constr->window, + dispex_compat_mode(&constr->window->event_target.dispex)); return S_OK; }
dispex_static_data_t Option_dispex = { .name = "Function", .constructor_id = OBJID_HTMLOptionElement, - .init_constructor = HTMLOptionElementFactory_Create, + .init_constructor = HTMLOptionElementFactory_init, .vtbl = &HTMLOptionElementFactory_dispex_vtbl, .disp_tid = IHTMLOptionElementFactory_tid, .init_info = HTMLOptionElementFactory_init_dispex_info, diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index cf8c2a5162b..50e0c869280 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -92,6 +92,7 @@ typedef struct ConnectionPoint ConnectionPoint; typedef struct BSCallback BSCallback; typedef struct EventTarget EventTarget; typedef struct ScriptHost ScriptHost; +struct constructor;
#define TID_LIST \ XIID(NULL) \ @@ -520,7 +521,7 @@ struct dispex_static_data_t { const tid_t disp_tid; const tid_t* const iface_tids; void (*init_info)(dispex_data_t*,compat_mode_t); - HRESULT (*init_constructor)(HTMLInnerWindow*,DispatchEx**); + HRESULT (*init_constructor)(struct constructor*); dispex_data_t *info_cache[COMPAT_MODE_CNT]; dispex_data_t *prototype_info[COMPAT_MODE_CNT - COMPAT_MODE_IE9]; dispex_data_t *delayed_init_info; @@ -657,6 +658,20 @@ typedef enum {
dispex_prop_type_t get_dispid_type(DISPID);
+struct constructor { + DispatchEx dispex; + IUnknown iface; + HTMLInnerWindow *window; +}; + +static inline struct constructor *constructor_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, struct constructor, dispex); +} +void constructor_traverse(DispatchEx*,nsCycleCollectionTraversalCallback*); +void constructor_unlink(DispatchEx*); +void constructor_destructor(DispatchEx*); + typedef enum { GLOBAL_SCRIPTVAR, GLOBAL_ELEMENTVAR, @@ -677,20 +692,6 @@ struct EventTarget { struct wine_rb_tree handler_map; };
-typedef struct { - DispatchEx dispex; - IHTMLOptionElementFactory IHTMLOptionElementFactory_iface; - - HTMLInnerWindow *window; -} HTMLOptionElementFactory; - -typedef struct { - DispatchEx dispex; - IHTMLImageElementFactory IHTMLImageElementFactory_iface; - - HTMLInnerWindow *window; -} HTMLImageElementFactory; - struct HTMLLocation { DispatchEx dispex; IHTMLLocation IHTMLLocation_iface; diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 91cc61b6191..0ba3ce4a62f 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -1198,7 +1198,7 @@ static void mutation_observer_destructor(DispatchEx *dispex) free(This); }
-static HRESULT create_mutation_observer_ctor(HTMLInnerWindow *script_global, DispatchEx **ret); +static HRESULT init_mutation_observer_ctor(struct constructor*);
static const dispex_static_data_vtbl_t mutation_observer_dispex_vtbl = { .query_interface = mutation_observer_query_interface, @@ -1213,7 +1213,7 @@ static const tid_t mutation_observer_iface_tids[] = { }; dispex_static_data_t MutationObserver_dispex = { .id = OBJID_MutationObserver, - .init_constructor = create_mutation_observer_ctor, + .init_constructor = init_mutation_observer_ctor, .vtbl = &mutation_observer_dispex_vtbl, .disp_tid = IWineMSHTMLMutationObserver_tid, .iface_tids = mutation_observer_iface_tids, @@ -1247,22 +1247,11 @@ struct mutation_observer_ctor { DispatchEx dispex; };
-static inline struct mutation_observer_ctor *mutation_observer_ctor_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, struct mutation_observer_ctor, dispex); -} - -static void mutation_observer_ctor_destructor(DispatchEx *dispex) -{ - struct mutation_observer_ctor *This = mutation_observer_ctor_from_DispatchEx(dispex); - free(This); -} - static HRESULT mutation_observer_ctor_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { - struct mutation_observer_ctor *This = mutation_observer_ctor_from_DispatchEx(dispex); + struct constructor *This = constructor_from_DispatchEx(dispex); VARIANT *callback; IWineMSHTMLMutationObserver *mutation_observer; HRESULT hres; @@ -1305,7 +1294,9 @@ static HRESULT mutation_observer_ctor_value(DispatchEx *dispex, LCID lcid, }
static const dispex_static_data_vtbl_t mutation_observer_ctor_dispex_vtbl = { - .destructor = mutation_observer_ctor_destructor, + .destructor = constructor_destructor, + .traverse = constructor_traverse, + .unlink = constructor_unlink, .value = mutation_observer_ctor_value };
@@ -1315,20 +1306,9 @@ static dispex_static_data_t mutation_observer_ctor_dispex = { .vtbl = &mutation_observer_ctor_dispex_vtbl, };
-static HRESULT create_mutation_observer_ctor(HTMLInnerWindow *script_global, DispatchEx **ret) +static HRESULT init_mutation_observer_ctor(struct constructor *constr) { - struct mutation_observer_ctor *obj; - - obj = calloc(1, sizeof(*obj)); - if(!obj) - { - ERR("No memory.\n"); - return E_OUTOFMEMORY; - } - - init_dispatch(&obj->dispex, &mutation_observer_ctor_dispex, script_global, - dispex_compat_mode(&script_global->event_target.dispex)); - - *ret = &obj->dispex; + init_dispatch(&constr->dispex, &mutation_observer_ctor_dispex, constr->window, + dispex_compat_mode(&constr->window->event_target.dispex)); return S_OK; } diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 109ef990f67..5845d56514c 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -36,13 +36,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
-typedef struct { - DispatchEx dispex; - IHTMLXMLHttpRequestFactory IHTMLXMLHttpRequestFactory_iface; - - HTMLInnerWindow *window; -} HTMLXMLHttpRequestFactory; - static HRESULT bstr_to_nsacstr(BSTR bstr, nsACString *str) { char *cstr = strdupWtoU(bstr); @@ -1490,9 +1483,9 @@ static const event_target_vtbl_t HTMLXMLHttpRequest_event_target_vtbl = { };
/* IHTMLXMLHttpRequestFactory */ -static inline HTMLXMLHttpRequestFactory *impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory *iface) +static inline struct constructor *impl_from_IHTMLXMLHttpRequestFactory(IHTMLXMLHttpRequestFactory *iface) { - return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, IHTMLXMLHttpRequestFactory_iface); + return CONTAINING_RECORD(iface, struct constructor, iface); }
DISPEX_IDISPATCH_IMPL(HTMLXMLHttpRequestFactory, IHTMLXMLHttpRequestFactory, @@ -1500,7 +1493,7 @@ DISPEX_IDISPATCH_IMPL(HTMLXMLHttpRequestFactory, IHTMLXMLHttpRequestFactory,
static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactory *iface, IHTMLXMLHttpRequest **p) { - HTMLXMLHttpRequestFactory *This = impl_from_IHTMLXMLHttpRequestFactory(iface); + struct constructor *This = impl_from_IHTMLXMLHttpRequestFactory(iface); HTMLXMLHttpRequest *ret; nsIXMLHttpRequest *nsxhr; nsIDOMEventTarget *nstarget; @@ -1577,50 +1570,20 @@ static const IHTMLXMLHttpRequestFactoryVtbl HTMLXMLHttpRequestFactoryVtbl = { HTMLXMLHttpRequestFactory_create };
-static inline HTMLXMLHttpRequestFactory *factory_from_DispatchEx(DispatchEx *iface) -{ - return CONTAINING_RECORD(iface, HTMLXMLHttpRequestFactory, dispex); -} - static void *HTMLXMLHttpRequestFactory_query_interface(DispatchEx *dispex, REFIID riid) { - HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); + struct constructor *This = constructor_from_DispatchEx(dispex);
if(IsEqualGUID(&IID_IHTMLXMLHttpRequestFactory, riid)) - return &This->IHTMLXMLHttpRequestFactory_iface; + return &This->iface;
return NULL; }
-static void HTMLXMLHttpRequestFactory_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) -{ - HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); - - if(This->window) - note_cc_edge((nsISupports*)&This->window->base.IHTMLWindow2_iface, "window", cb); -} - -static void HTMLXMLHttpRequestFactory_unlink(DispatchEx *dispex) -{ - HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); - - if(This->window) { - HTMLInnerWindow *window = This->window; - This->window = NULL; - IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); - } -} - -static void HTMLXMLHttpRequestFactory_destructor(DispatchEx *dispex) -{ - HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(dispex); - free(This); -} - static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) { - HTMLXMLHttpRequestFactory *This = factory_from_DispatchEx(iface); + struct constructor *This = constructor_from_DispatchEx(iface); IHTMLXMLHttpRequest *xhr; HRESULT hres;
@@ -1631,7 +1594,7 @@ static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WOR return E_NOTIMPL; }
- hres = IHTMLXMLHttpRequestFactory_create(&This->IHTMLXMLHttpRequestFactory_iface, &xhr); + hres = IHTMLXMLHttpRequestFactory_create((IHTMLXMLHttpRequestFactory*)&This->iface, &xhr); if(FAILED(hres)) return hres;
@@ -1642,9 +1605,9 @@ static HRESULT HTMLXMLHttpRequestFactory_value(DispatchEx *iface, LCID lcid, WOR
static const dispex_static_data_vtbl_t HTMLXMLHttpRequestFactory_dispex_vtbl = { .query_interface = HTMLXMLHttpRequestFactory_query_interface, - .destructor = HTMLXMLHttpRequestFactory_destructor, - .traverse = HTMLXMLHttpRequestFactory_traverse, - .unlink = HTMLXMLHttpRequestFactory_unlink, + .destructor = constructor_destructor, + .traverse = constructor_traverse, + .unlink = constructor_unlink, .value = HTMLXMLHttpRequestFactory_value };
@@ -1660,22 +1623,11 @@ static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex = { .iface_tids = HTMLXMLHttpRequestFactory_iface_tids, };
-static HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow *window, DispatchEx **ret_ptr) +static HRESULT HTMLXMLHttpRequestFactory_init(struct constructor *constr) { - HTMLXMLHttpRequestFactory *ret; - - ret = malloc(sizeof(*ret)); - if(!ret) - return E_OUTOFMEMORY; - - ret->IHTMLXMLHttpRequestFactory_iface.lpVtbl = &HTMLXMLHttpRequestFactoryVtbl; - ret->window = window; - IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); - - init_dispatch(&ret->dispex, &HTMLXMLHttpRequestFactory_dispex, window, - dispex_compat_mode(&window->event_target.dispex)); - - *ret_ptr = &ret->dispex; + 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; }
@@ -1685,7 +1637,7 @@ static const tid_t HTMLXMLHttpRequest_iface_tids[] = { }; dispex_static_data_t XMLHttpRequest_dispex = { .id = OBJID_XMLHttpRequest, - .init_constructor = HTMLXMLHttpRequestFactory_Create, + .init_constructor = HTMLXMLHttpRequestFactory_init, .vtbl = &HTMLXMLHttpRequest_event_target_vtbl.dispex_vtbl, .disp_tid = DispHTMLXMLHttpRequest_tid, .iface_tids = HTMLXMLHttpRequest_iface_tids,
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/dispex.c | 16 ++++++++++++++++ dlls/jscript/function.c | 10 +--------- dlls/jscript/jscript.c | 4 ++-- dlls/jscript/jscript.h | 2 +- dlls/jscript/jsdisp.idl | 3 ++- dlls/mshtml/dispex.c | 9 ++++++++- 6 files changed, 30 insertions(+), 14 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index d5ed3adf4fb..2231ffe7a13 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -2402,6 +2402,21 @@ static HRESULT WINAPI WineJSDispatch_GetPropertyFlags(IWineJSDispatch *iface, DI return S_OK; }
+static HRESULT WINAPI WineJSDispatch_DefineProperty(IWineJSDispatch *iface, const WCHAR *name, unsigned flags, VARIANT v) +{ + jsdisp_t *This = impl_from_IWineJSDispatch(iface); + HRESULT hres; + jsval_t val; + + hres = variant_to_jsval(This->ctx, &v, &val); + if(FAILED(hres)) + return hres; + + hres = jsdisp_define_data_property(This, name, flags, val); + jsval_release(val); + return hres; +} + static HRESULT WINAPI WineJSDispatch_GetScriptGlobal(IWineJSDispatch *iface, IWineJSDispatchHost **ret) { jsdisp_t *This = impl_from_IWineJSDispatch(iface); @@ -2435,6 +2450,7 @@ static IWineJSDispatchVtbl DispatchExVtbl = { DispatchEx_GetNameSpaceParent, WineJSDispatch_Free, WineJSDispatch_GetPropertyFlags, + WineJSDispatch_DefineProperty, WineJSDispatch_GetScriptGlobal, };
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 9f1f53a96ae..7206b5e46f0 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -1187,8 +1187,7 @@ static const function_vtbl_t HostConstructorVtbl = { HostConstructor_gc_traverse };
-HRESULT init_host_constructor(script_ctx_t *ctx, IWineJSDispatchHost *host_constr, IWineJSDispatch *prototype, - IWineJSDispatch **ret) +HRESULT init_host_constructor(script_ctx_t *ctx, IWineJSDispatchHost *host_constr, IWineJSDispatch **ret) { HostConstructor *function; HRESULT hres; @@ -1199,13 +1198,6 @@ HRESULT init_host_constructor(script_ctx_t *ctx, IWineJSDispatchHost *host_const return hres; function->host_iface = host_constr;
- hres = jsdisp_define_data_property(&function->function.dispex, L"prototype", PROPF_WRITABLE | PROPF_CONFIGURABLE, - jsval_disp((IDispatch *)prototype)); - if(FAILED(hres)) { - IWineJSDispatch_Free(&function->function.dispex.IWineJSDispatch_iface); - return hres; - } - *ret = &function->function.dispex.IWineJSDispatch_iface; return S_OK; } diff --git a/dlls/jscript/jscript.c b/dlls/jscript/jscript.c index c42109b4143..c26ebbcc56e 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 *prototype, IWineJSDispatch **ret) + IWineJSDispatch **ret) { JScript *This = impl_from_IWineJScript(iface); - return init_host_constructor(This->ctx, constr, prototype, ret); + return init_host_constructor(This->ctx, constr, ret); }
static const IWineJScriptVtbl WineJScriptVtbl = { diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index e9207c231d8..04298ec3985 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*,IWineJSDispatch**); +HRESULT init_host_constructor(script_ctx_t*,IWineJSDispatchHost*,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 5f1384bce78..58e57ce2fdc 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -52,6 +52,7 @@ interface IWineJSDispatch : IDispatchEx { void Free(); HRESULT GetPropertyFlags(DISPID id, UINT32 *ret); + HRESULT DefineProperty(const WCHAR *name, unsigned int flags, VARIANT v); HRESULT GetScriptGlobal(IWineJSDispatchHost **ret); }
@@ -83,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 *prototype, IWineJSDispatch **ret); + HRESULT InitHostConstructor(IWineJSDispatchHost *constr, IWineJSDispatch **ret); } diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index d590fd46f37..c208d976e41 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1887,10 +1887,17 @@ static void init_host_object(DispatchEx *dispex, HTMLInnerWindow *script_global, if(script_global->jscript && !dispex->jsdisp) { if(dispex->info->desc->constructor_id) { DispatchEx *prototype; + if(FAILED(hres = get_prototype(script_global, dispex->info->desc->constructor_id, &prototype))) return; hres = IWineJScript_InitHostConstructor(script_global->jscript, &dispex->IWineJSDispatchHost_iface, - prototype->jsdisp, &dispex->jsdisp); + &dispex->jsdisp); + if(SUCCEEDED(hres)) { + VARIANT v; + V_VT(&v) = VT_DISPATCH; + V_DISPATCH(&v) = (IDispatch*)&prototype->IWineJSDispatchHost_iface; + hres = IWineJSDispatch_DefineProperty(dispex->jsdisp, L"prototype", PROPF_WRITABLE | PROPF_CONFIGURABLE, v); + } }else hres = IWineJScript_InitHostObject(script_global->jscript, &dispex->IWineJSDispatchHost_iface, prototype ? prototype->jsdisp : NULL,
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[] = {
I went with name/flags pair instead of struct property_info because the latter is mostly for external prop internals, which we shouldn't mess with. Converting the variant already takes care of it.
It doesn't allow us to define accessors anyway, and if we ever need to, we'll probably need to use something like property_desc_t or add more arguments or something. But no need to complicate it for now IMO.
Jacek Caban (@jacek) commented about dlls/jscript/function.c:
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);
It looks like `native_function_string` doesn't really expect a NULL name, it ends up adding an extra space in the prefix. Seems like we're missing a test for this case.
Other than that, looks good to me.
Jacek Caban (@jacek) commented about dlls/jscript/jsdisp.idl:
{ void Free(); HRESULT GetPropertyFlags(DISPID id, UINT32 *ret);
- HRESULT DefineProperty(const WCHAR *name, unsigned int flags, VARIANT v);
Please pass variant as a pointer, like other functions do.
On Thu Apr 24 19:15:13 2025 +0000, Jacek Caban wrote:
It looks like `native_function_string` doesn't really expect a NULL name, it ends up adding an extra space in the prefix. Seems like we're missing a test for this case. Other than that, looks good to me.
To be fair it looks like it's actually wrong anyway, it should use the constructor's name. I made it work on mshtml side now, let me know if I should move it to jscript, the only issue I see is that the dispex name is in ASCII (due to gecko), so we'd need to convert it to WCHAR somehow without allocating, probably in a buffer? I think it's better this way though.