From: Jacek Caban jacek@codeweavers.com
--- dlls/mshtml/dispex.c | 24 +++++++++++++------ dlls/mshtml/htmlwindow.c | 19 +++++----------- dlls/mshtml/mshtml_private.h | 14 ++++-------- dlls/mshtml/tests/documentmode.js | 3 +++ dlls/mshtml/tests/es5.js | 15 ++++++++++++ dlls/mshtml/xmlhttprequest.c | 38 +++++++++++++++++++------------ 6 files changed, 69 insertions(+), 44 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index c464d6f5607..65139c88b77 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -2934,7 +2934,7 @@ static dispex_static_data_t constructor_dispex = {
HRESULT get_constructor(HTMLInnerWindow *script_global, prototype_id_t id, DispatchEx **ret) { - struct constructor *constr; + dispex_static_data_t *info;
assert(script_global->doc->document_mode >= COMPAT_MODE_IE9);
@@ -2943,13 +2943,23 @@ HRESULT get_constructor(HTMLInnerWindow *script_global, prototype_id_t id, Dispa return S_OK; }
- if(!(constr = calloc(sizeof(*constr), 1))) - return E_OUTOFMEMORY; + info = object_descriptors[id]; + if(info->init_constructor) { + HRESULT hres = info->init_constructor(script_global, &script_global->constructors[id]); + if(FAILED(hres)) + return hres; + }else { + struct constructor *constr; + if(!(constr = calloc(sizeof(*constr), 1))) + return E_OUTOFMEMORY; + + init_dispatch(&constr->dispex, &constructor_dispex, script_global, + dispex_compat_mode(&script_global->event_target.dispex)); + constr->id = id; + script_global->constructors[id] = &constr->dispex; + }
- init_dispatch(&constr->dispex, &constructor_dispex, script_global, - dispex_compat_mode(&script_global->event_target.dispex)); - constr->id = id; - *ret = script_global->constructors[id] = &constr->dispex; + *ret = script_global->constructors[id]; return S_OK;
} diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c9ad3dbd0c3..6c6ad2178eb 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -1921,17 +1921,16 @@ static HRESULT WINAPI HTMLWindow5_get_XMLHttpRequest(IHTMLWindow5 *iface, VARIAN return S_OK; }
- if(!window->xhr_factory) { + if(!window->constructors[PROT_XMLHttpRequest]) { HRESULT hres;
- hres = HTMLXMLHttpRequestFactory_Create(window, &window->xhr_factory); - if(FAILED(hres)) { + hres = HTMLXMLHttpRequestFactory_Create(window, &window->constructors[PROT_XMLHttpRequest]); + if(FAILED(hres)) return hres; - } }
V_VT(p) = VT_DISPATCH; - V_DISPATCH(p) = (IDispatch*)&window->xhr_factory->IHTMLXMLHttpRequestFactory_iface; + V_DISPATCH(p) = (IDispatch*)&window->constructors[PROT_XMLHttpRequest]->IWineJSDispatchHost_iface; IDispatch_AddRef(V_DISPATCH(p));
return S_OK; @@ -3709,8 +3708,6 @@ static void HTMLWindow_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCa note_cc_edge((nsISupports*)&This->image_factory->IHTMLImageElementFactory_iface, "image_factory", cb); if(This->option_factory) note_cc_edge((nsISupports*)&This->option_factory->IHTMLOptionElementFactory_iface, "option_factory", cb); - if(This->xhr_factory) - note_cc_edge((nsISupports*)&This->xhr_factory->IHTMLXMLHttpRequestFactory_iface, "xhr_factory", cb); if(This->mutation_observer_ctor) note_cc_edge((nsISupports*)This->mutation_observer_ctor, "mutation_observer_ctor", cb); if(This->screen) @@ -3761,11 +3758,6 @@ static void HTMLWindow_unlink(DispatchEx *dispex) This->option_factory = NULL; IHTMLOptionElementFactory_Release(&option_factory->IHTMLOptionElementFactory_iface); } - if(This->xhr_factory) { - HTMLXMLHttpRequestFactory *xhr_factory = This->xhr_factory; - This->xhr_factory = NULL; - IHTMLXMLHttpRequestFactory_Release(&xhr_factory->IHTMLXMLHttpRequestFactory_iface); - } unlink_ref(&This->mutation_observer_ctor); unlink_ref(&This->screen); if(This->history) { @@ -4184,7 +4176,8 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa compat_mode >= COMPAT_MODE_IE11 ? NULL : private_ie10_hooks);
dispex_info_add_interface(info, IHTMLWindow6_tid, window6_hooks); - dispex_info_add_interface(info, IHTMLWindow5_tid, NULL); + if(compat_mode < COMPAT_MODE_IE9) + dispex_info_add_interface(info, IHTMLWindow5_tid, NULL); dispex_info_add_interface(info, IHTMLWindow4_tid, compat_mode >= COMPAT_MODE_IE11 ? window4_ie11_hooks : NULL); dispex_info_add_interface(info, IHTMLWindow3_tid, compat_mode >= COMPAT_MODE_IE11 ? window3_ie11_hooks : window3_hooks); dispex_info_add_interface(info, IHTMLWindow2_tid, compat_mode >= COMPAT_MODE_IE11 ? window2_ie11_hooks : window2_hooks); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 9d5833b7e09..40b81df8f6b 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -417,7 +417,8 @@ typedef struct { X(Navigator) \ X(Node) \ X(Storage) \ - X(Window) + X(Window) \ + X(XMLHttpRequest)
typedef enum { PROT_NONE, @@ -433,6 +434,7 @@ typedef struct { 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**); 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; @@ -599,13 +601,6 @@ typedef struct { HTMLInnerWindow *window; } HTMLImageElementFactory;
-typedef struct { - DispatchEx dispex; - IHTMLXMLHttpRequestFactory IHTMLXMLHttpRequestFactory_iface; - - HTMLInnerWindow *window; -} HTMLXMLHttpRequestFactory; - struct HTMLLocation { DispatchEx dispex; IHTMLLocation IHTMLLocation_iface; @@ -689,7 +684,6 @@ struct HTMLInnerWindow {
HTMLImageElementFactory *image_factory; HTMLOptionElementFactory *option_factory; - HTMLXMLHttpRequestFactory *xhr_factory; IHTMLScreen *screen; OmHistory *history; IOmNavigator *navigator; @@ -1094,7 +1088,7 @@ HTMLOuterWindow *mozwindow_to_window(const mozIDOMWindowProxy*); void get_top_window(HTMLOuterWindow*,HTMLOuterWindow**); HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow*,HTMLOptionElementFactory**); HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow*,HTMLImageElementFactory**); -HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,HTMLXMLHttpRequestFactory**); +HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,DispatchEx**); HRESULT create_location(HTMLOuterWindow*,HTMLLocation**); HRESULT create_navigator(HTMLInnerWindow*,IOmNavigator**); HRESULT create_html_screen(HTMLInnerWindow*,IHTMLScreen**); diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 14c797a10da..e933358c706 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3136,6 +3136,9 @@ sync_test("prototypes", function() { } check(window, Window.prototype, "window"); check(Window.prototype, Object.prototype, "window prototype"); + check(new XMLHttpRequest(), XMLHttpRequest.prototype, "xhr"); + check(XMLHttpRequest.prototype, Object.prototype, "xhr prototype"); + check(XMLHttpRequest, Function.prototype, "xhr constructor"); check(document.createElement("img"), HTMLImageElement.prototype, "img elem"); check(HTMLImageElement.prototype, HTMLElement.prototype, "img elem prototype"); check(Image, Function.prototype, "Image constructor"); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index f049a526bf4..c44d6d6667d 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2761,6 +2761,21 @@ sync_test("prototypes", function() { ok(!Element.prototype.hasOwnProperty("removeChild"), "Element prototype has own removeChild property"); ok(Node.prototype.hasOwnProperty("removeChild"), "Node prototype does not have own removeChild property");
+ test_own_data_prop_desc(window, "XMLHttpRequest", true, false, true); + ok(typeof(XMLHttpRequest) === "function", "typeof(XMLHttpRequest) = " + typeof(XMLHttpRequest)); + ok(XMLHttpRequest.hasOwnProperty("create"), "XMLHttpRequest does not have create property"); + ok(Object.getPrototypeOf(XMLHttpRequest) === Function.prototype, + "Object.getPrototypeOf(XMLHttpRequest) = " + Object.getPrototypeOf(XMLHttpRequest)); + ok(XMLHttpRequest.prototype.constructor === XMLHttpRequest, + "XMLHttpRequest.prototype.constructor !== XMLHttpRequest"); + var xhr = new XMLHttpRequest(); + ok(Object.getPrototypeOf(xhr) === XMLHttpRequest.prototype, + "Object.getPrototypeOf(xhr) = " + Object.getPrototypeOf(xhr)); + constr = XMLHttpRequest; + XMLHttpRequest = 1; + ok(XMLHttpRequest === 1, "XMLHttpRequest = " + XMLHttpRequest); + XMLHttpRequest = constr; + ok(Image != HTMLImageElement, "Image == HTMLImageElement"); ok(typeof(HTMLImageElement) === "object", "typeof(HTMLImageElement) = " + typeof(HTMLImageElement)); ok(typeof(Image) === "function", "typeof(Image) = " + typeof(Image)); diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 0ab7fba2862..0798b2e2abb 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -36,6 +36,13 @@
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); @@ -1474,12 +1481,14 @@ static const tid_t HTMLXMLHttpRequest_iface_tids[] = { IHTMLXMLHttpRequest2_tid, 0 }; -static dispex_static_data_t HTMLXMLHttpRequest_dispex = { - "XMLHttpRequest", - &HTMLXMLHttpRequest_event_target_vtbl.dispex_vtbl, - DispHTMLXMLHttpRequest_tid, - HTMLXMLHttpRequest_iface_tids, - HTMLXMLHttpRequest_init_dispex_info +dispex_static_data_t XMLHttpRequest_dispex = { + .name = "XMLHttpRequest", + .id = PROT_XMLHttpRequest, + .init_constructor = HTMLXMLHttpRequestFactory_Create, + .vtbl = &HTMLXMLHttpRequest_event_target_vtbl.dispex_vtbl, + .disp_tid = DispHTMLXMLHttpRequest_tid, + .iface_tids = HTMLXMLHttpRequest_iface_tids, + .init_info = HTMLXMLHttpRequest_init_dispex_info, };
@@ -1530,7 +1539,7 @@ static HRESULT WINAPI HTMLXMLHttpRequestFactory_create(IHTMLXMLHttpRequestFactor ret->IHTMLXMLHttpRequest2_iface.lpVtbl = &HTMLXMLHttpRequest2Vtbl; ret->IWineXMLHttpRequestPrivate_iface.lpVtbl = &WineXMLHttpRequestPrivateVtbl; ret->IProvideClassInfo2_iface.lpVtbl = &ProvideClassInfo2Vtbl; - init_event_target(&ret->event_target, &HTMLXMLHttpRequest_dispex, This->window); + init_event_target(&ret->event_target, &XMLHttpRequest_dispex, This->window);
/* Always register the handlers because we need them to track state */ event_listener->nsIDOMEventListener_iface.lpVtbl = &XMLHttpReqEventListenerVtbl; @@ -1647,13 +1656,14 @@ static const tid_t HTMLXMLHttpRequestFactory_iface_tids[] = { 0 }; static dispex_static_data_t HTMLXMLHttpRequestFactory_dispex = { - "Function", - &HTMLXMLHttpRequestFactory_dispex_vtbl, - IHTMLXMLHttpRequestFactory_tid, - HTMLXMLHttpRequestFactory_iface_tids + .name = "Function", + .constructor_id = PROT_XMLHttpRequest, + .vtbl = &HTMLXMLHttpRequestFactory_dispex_vtbl, + .disp_tid = IHTMLXMLHttpRequestFactory_tid, + .iface_tids = HTMLXMLHttpRequestFactory_iface_tids, };
-HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpRequestFactory **ret_ptr) +HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, DispatchEx **ret_ptr) { HTMLXMLHttpRequestFactory *ret;
@@ -1665,9 +1675,9 @@ HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow* window, HTMLXMLHttpReq ret->window = window; IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
- init_dispatch(&ret->dispex, &HTMLXMLHttpRequestFactory_dispex, NULL, + init_dispatch(&ret->dispex, &HTMLXMLHttpRequestFactory_dispex, window, dispex_compat_mode(&window->event_target.dispex));
- *ret_ptr = ret; + *ret_ptr = &ret->dispex; return S_OK; }