-- v8: mshtml: Return proper string from functional constructors' toString in 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..03b400a383f 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..bbb241b6699 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..05a35cbc00b 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 | 13 +++++++++++++ dlls/mshtml/xmlhttprequest.c | 27 ++++++++++++++++++++++++++- 8 files changed, 56 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 bbb241b6699..c55626fae66 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 05a35cbc00b..58c7fd448b8 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..5902ec04a30 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -4009,7 +4009,20 @@ sync_test("constructors", function() { r = ctors[i]; ok(window.hasOwnProperty(r), r + " not prop of window"); ok(!(r in Window.prototype), r + " is a prop of window's prototype"); + todo_wine. + ok(window[r].toString() === "\nfunction " + r + "() {\n [native code]\n}\n", r + ".toString() = " + window[r].toString()); } 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.toString() === "\nfunction create() {\n [native code]\n}\n", "XMLHttpRequest.create.toString() = " + XMLHttpRequest.create.toString()); + 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..da483970214 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[] = {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/function.c | 13 ++++++++++++- dlls/mshtml/dispex.c | 25 +++++++++++++++++++------ dlls/mshtml/htmlimg.c | 2 +- dlls/mshtml/htmlselect.c | 2 +- dlls/mshtml/mutation.c | 2 +- dlls/mshtml/tests/documentmode.js | 1 - dlls/mshtml/xmlhttprequest.c | 2 +- 7 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 24847e17686..567e2596969 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -1166,8 +1166,19 @@ static HRESULT HostConstructor_call(script_ctx_t *ctx, FunctionInstance *func, j static HRESULT HostConstructor_toString(FunctionInstance *func, jsstr_t **ret) { HostConstructor *function = (HostConstructor*)func; + HRESULT hres; + BSTR str; + + if(function->method_name) + return native_function_string(function->method_name, ret); + + hres = IWineJSDispatchHost_ToString(function->host_iface, &str); + if(FAILED(hres)) + return hres;
- return native_function_string(function->method_name, ret); + *ret = jsstr_alloc(str); + SysFreeString(str); + return *ret ? S_OK : E_OUTOFMEMORY; }
static function_code_t *HostConstructor_get_code(FunctionInstance *function) diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 58c7fd448b8..1e31cb66db1 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1943,20 +1943,30 @@ compat_mode_t dispex_compat_mode(DispatchEx *dispex)
HRESULT dispex_to_string(DispatchEx *dispex, BSTR *ret) { + static const WCHAR func_prefix[10] = L"\nfunction "; + static const WCHAR func_suffix[] = L"() {\n [native code]\n}\n"; static const WCHAR prefix[8] = L"[object "; static const WCHAR suffix[] = L"]"; - WCHAR buf[ARRAY_SIZE(prefix) + ARRAY_SIZE(dispex->info->desc->prototype_name) + ARRAY_SIZE(suffix)], *p = buf; + WCHAR buf[ARRAY_SIZE(func_prefix) + ARRAY_SIZE(dispex->info->desc->prototype_name) + ARRAY_SIZE(func_suffix)], *p = buf; compat_mode_t compat_mode = dispex_compat_mode(dispex); const char *name;
if(!ret) return E_INVALIDARG;
- memcpy(p, prefix, sizeof(prefix)); - p += ARRAY_SIZE(prefix); if(compat_mode < COMPAT_MODE_IE9) - p--; + wcscpy(buf, L"[object]"); else { + BOOL is_func = dispex->info->desc->constructor_id; + + if(is_func) { + memcpy(p, func_prefix, sizeof(func_prefix)); + p += ARRAY_SIZE(func_prefix); + }else { + memcpy(p, prefix, sizeof(prefix)); + p += ARRAY_SIZE(prefix); + } + if(!ensure_real_info(dispex)) return E_OUTOFMEMORY; name = dispex->info->name; @@ -1964,9 +1974,12 @@ HRESULT dispex_to_string(DispatchEx *dispex, BSTR *ret) name = dispex->info->vtbl->get_name(dispex); while(*name) *p++ = *name++; - assert(p + ARRAY_SIZE(suffix) - buf <= ARRAY_SIZE(buf)); + + if(is_func) + memcpy(p, func_suffix, sizeof(func_suffix)); + else + memcpy(p, suffix, sizeof(suffix)); } - memcpy(p, suffix, sizeof(suffix));
*ret = SysAllocString(buf); return *ret ? S_OK : E_OUTOFMEMORY; diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index fda2037f392..40c2c2dd09b 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -857,7 +857,7 @@ static HRESULT HTMLImageElementFactory_init(struct constructor *constr) }
dispex_static_data_t Image_dispex = { - .name = "Function", + .name = "Image", .constructor_id = OBJID_HTMLImageElement, .init_constructor = HTMLImageElementFactory_init, .vtbl = &HTMLImageElementFactory_dispex_vtbl, diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index 232f9104bc7..a126f977697 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -503,7 +503,7 @@ static HRESULT HTMLOptionElementFactory_init(struct constructor *constr) }
dispex_static_data_t Option_dispex = { - .name = "Function", + .name = "Option", .constructor_id = OBJID_HTMLOptionElement, .init_constructor = HTMLOptionElementFactory_init, .vtbl = &HTMLOptionElementFactory_dispex_vtbl, diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 0ba3ce4a62f..b5ec41136ea 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -1301,7 +1301,7 @@ static const dispex_static_data_vtbl_t mutation_observer_ctor_dispex_vtbl = { };
static dispex_static_data_t mutation_observer_ctor_dispex = { - .name = "Function", + .name = "MutationObserver", .constructor_id = OBJID_MutationObserver, .vtbl = &mutation_observer_ctor_dispex_vtbl, }; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 5902ec04a30..f9967e8a6bd 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -4009,7 +4009,6 @@ sync_test("constructors", function() { r = ctors[i]; ok(window.hasOwnProperty(r), r + " not prop of window"); ok(!(r in Window.prototype), r + " is a prop of window's prototype"); - todo_wine. ok(window[r].toString() === "\nfunction " + r + "() {\n [native code]\n}\n", r + ".toString() = " + window[r].toString()); } ok(window.Image.prototype === window.HTMLImageElement.prototype, "Image.prototype != HTMLImageElement.prototype"); diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index da483970214..3097792c620 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -1616,7 +1616,7 @@ static const tid_t HTMLXMLHttpRequestFactory_iface_tids[] = { 0 }; static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex = { - .name = "Function", + .name = "XMLHttpRequest", .constructor_id = OBJID_XMLHttpRequest, .vtbl = &HTMLXMLHttpRequestFactory_dispex_vtbl, .disp_tid = IHTMLXMLHttpRequestFactory_tid,
This merge request was approved by Jacek Caban.