From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 1 + dlls/mshtml/htmlimg.c | 17 ++++++----- dlls/mshtml/htmlwindow.c | 51 +++++++++++++++---------------- dlls/mshtml/mshtml_private.h | 18 ++++++++--- dlls/mshtml/tests/documentmode.js | 16 ++++++++++ 5 files changed, 65 insertions(+), 38 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 95cddfd9c17..858242d3878 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -2978,6 +2978,7 @@ dispex_static_data_t *object_descriptors[] = { NULL, #define X(name) &name ## _dispex, ALL_PROTOTYPES + ALL_ALT_CTORS #undef X };
diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c index f6a4b992ab6..5973e134064 100644 --- a/dlls/mshtml/htmlimg.c +++ b/dlls/mshtml/htmlimg.c @@ -877,15 +877,16 @@ static const dispex_static_data_vtbl_t HTMLImageElementFactory_dispex_vtbl = { .value = HTMLImageElementFactory_value, };
-static dispex_static_data_t HTMLImageElementFactory_dispex = { - .name = "Function", - .constructor_id = PROT_HTMLImageElement, - .vtbl = &HTMLImageElementFactory_dispex_vtbl, - .disp_tid = IHTMLImageElementFactory_tid, - .iface_tids = HTMLImageElementFactory_iface_tids, +dispex_static_data_t HTMLImageElementFactory_dispex = { + .name = "Function", + .constructor_id = PROT_HTMLImageElement, + .init_constructor = HTMLImageElementFactory_Create, + .vtbl = &HTMLImageElementFactory_dispex_vtbl, + .disp_tid = IHTMLImageElementFactory_tid, + .iface_tids = HTMLImageElementFactory_iface_tids, };
-HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow *window, HTMLImageElementFactory **ret_val) +HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow *window, DispatchEx **ret_val) { HTMLImageElementFactory *ret;
@@ -900,6 +901,6 @@ HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow *window, HTMLImageElement init_dispatch(&ret->dispex, &HTMLImageElementFactory_dispex, window, dispex_compat_mode(&window->event_target.dispex));
- *ret_val = ret; + *ret_val = &ret->dispex; return S_OK; } diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c7e45439545..29c2a6e8e64 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -676,18 +676,14 @@ static HRESULT WINAPI HTMLWindow2_get_Image(IHTMLWindow2 *iface, IHTMLImageEleme
TRACE("(%p)->(%p)\n", This, p);
- if(!window->image_factory) { - HRESULT hres; - - hres = HTMLImageElementFactory_Create(window, &window->image_factory); + if(!window->constructors[CTOR_HTMLImageElementFactory]) { + HRESULT hres = HTMLImageElementFactory_Create(window, &window->constructors[CTOR_HTMLImageElementFactory]); if(FAILED(hres)) return hres; }
- *p = &window->image_factory->IHTMLImageElementFactory_iface; - IHTMLImageElementFactory_AddRef(*p); - - return S_OK; + return IWineJSDispatchHost_QueryInterface(&window->constructors[CTOR_HTMLImageElementFactory]->IWineJSDispatchHost_iface, + &IID_IHTMLImageElementFactory, (void**)p); }
static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocation **p) @@ -3700,8 +3696,6 @@ static void HTMLWindow_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCa note_cc_edge((nsISupports*)&This->doc->node.IHTMLDOMNode_iface, "doc", cb); if(This->console) note_cc_edge((nsISupports*)This->console, "console", cb); - if(This->image_factory) - 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->screen) @@ -3742,11 +3736,6 @@ static void HTMLWindow_unlink(DispatchEx *dispex)
release_event_target(&This->event_target);
- if(This->image_factory) { - HTMLImageElementFactory *image_factory = This->image_factory; - This->image_factory = NULL; - IHTMLImageElementFactory_Release(&image_factory->IHTMLImageElementFactory_iface); - } if(This->option_factory) { HTMLOptionElementFactory *option_factory = This->option_factory; This->option_factory = NULL; @@ -3818,18 +3807,24 @@ static int CDECL cmp_name(const void *x, const void *y)
static HRESULT HTMLWindow_find_dispid(DispatchEx *dispex, const WCHAR *name, DWORD grfdex, DISPID *dispid) { + compat_mode_t compat_mode = dispex_compat_mode(dispex); HTMLInnerWindow *This = impl_from_DispatchEx(dispex); HTMLOuterWindow *frame; global_prop_t *prop; HTMLElement *elem; HRESULT hres;
- if(dispex_compat_mode(dispex) >= COMPAT_MODE_IE9) { + if(compat_mode >= COMPAT_MODE_IE9) { const WCHAR **constr_name = bsearch(&name, constructor_names, ARRAYSIZE(constructor_names) , sizeof(constructor_names[0]), cmp_name); - if(constr_name) { - prototype_id_t id = constr_name - constructor_names + 1; - compat_mode_t compat_mode = dispex_compat_mode(dispex); + prototype_id_t id = 0; + + if(constr_name) + id = constr_name - constructor_names + 1; + else if(!wcscmp(name, L"Image")) + id = CTOR_HTMLImageElementFactory; + + if(id) { DispatchEx *constr; VARIANT v;
@@ -4188,15 +4183,18 @@ static HRESULT IHTMLWindow6_postMessage_hook(DispatchEx *dispex, WORD flags, DIS
static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compat_mode) { - static const dispex_hook_t window2_hooks[] = { - {DISPID_IHTMLWINDOW2_LOCATION, IHTMLWindow2_location_hook}, - {DISPID_UNKNOWN} - }; static const dispex_hook_t window2_ie11_hooks[] = { - {DISPID_IHTMLWINDOW2_LOCATION, IHTMLWindow2_location_hook}, - {DISPID_IHTMLWINDOW2_EXECSCRIPT, NULL}, + {DISPID_IHTMLWINDOW2_EXECSCRIPT}, + + /* IE9+ */ + {DISPID_IHTMLWINDOW2_IMAGE}, + + /* Common for all modes */ + {DISPID_IHTMLWINDOW2_LOCATION, IHTMLWindow2_location_hook}, {DISPID_UNKNOWN} }; + const dispex_hook_t *const window2_ie9_hooks = window2_ie11_hooks + 1; + const dispex_hook_t *const window2_hooks = window2_ie9_hooks + 1; static const dispex_hook_t window3_hooks[] = { {DISPID_IHTMLWINDOW3_SETTIMEOUT, IHTMLWindow3_setTimeout_hook}, {DISPID_UNKNOWN} @@ -4228,7 +4226,8 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa 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); + dispex_info_add_interface(info, IHTMLWindow2_tid, compat_mode >= COMPAT_MODE_IE11 ? window2_ie11_hooks : + compat_mode >= COMPAT_MODE_IE9 ? window2_ie9_hooks : window2_hooks); EventTarget_init_dispex_info(info, compat_mode); }
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index f306cff68c6..58dad8a68e0 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -504,12 +504,22 @@ typedef struct { X(Window) \ X(XMLHttpRequest)
+/* Extra constructors without new prototypes */ +#define ALL_ALT_CTORS \ + X(HTMLImageElementFactory) + typedef enum { PROT_NONE, #define X(name) PROT_##name, ALL_PROTOTYPES #undef X PROT_LAST, + + PROT_LAST_ = PROT_LAST - 1, /* align alt ctors enum */ +#define X(name) CTOR_##name, + ALL_ALT_CTORS +#undef X + CTOR_LAST } prototype_id_t;
struct dispex_static_data_t { @@ -533,9 +543,10 @@ struct dispex_static_data_t {
#define X(name) extern dispex_static_data_t name ## _dispex; ALL_PROTOTYPES +ALL_ALT_CTORS #undef X
-extern dispex_static_data_t *object_descriptors[PROT_LAST]; +extern dispex_static_data_t *object_descriptors[CTOR_LAST];
typedef HRESULT (*dispex_hook_invoke_t)(DispatchEx*,WORD,DISPPARAMS*,VARIANT*, EXCEPINFO*,IServiceProvider*); @@ -771,7 +782,6 @@ struct HTMLInnerWindow {
IHTMLEventObj *event;
- HTMLImageElementFactory *image_factory; HTMLOptionElementFactory *option_factory; IHTMLScreen *screen; OmHistory *history; @@ -801,7 +811,7 @@ struct HTMLInnerWindow { ULONG redirect_count;
DispatchEx *prototypes[PROT_LAST]; - DispatchEx *constructors[PROT_LAST]; + DispatchEx *constructors[CTOR_LAST];
ULONGLONG navigation_start_time; ULONGLONG unload_event_start_time; @@ -1170,7 +1180,7 @@ HRESULT update_window_doc(HTMLInnerWindow*); HTMLOuterWindow *mozwindow_to_window(const mozIDOMWindowProxy*); void get_top_window(HTMLOuterWindow*,HTMLOuterWindow**); HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow*,HTMLOptionElementFactory**); -HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow*,HTMLImageElementFactory**); +HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow*,DispatchEx**); HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,DispatchEx**); HRESULT create_location(HTMLOuterWindow*,HTMLLocation**); HRESULT create_navigator(HTMLInnerWindow*,IOmNavigator**); diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index d304fbadd62..e9a2f0172d0 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3995,3 +3995,19 @@ sync_test("prototype props", function() { check(Text, [ "removeNode", "replaceNode", "replaceWholeText", "splitText", "swapNode", "wholeText" ], [ "replaceWholeText", "wholeText" ]); check(UIEvent, [ "detail", "initUIEvent", "view" ], null, [ "deviceSessionId" ]); }); + +sync_test("constructors", function() { + var v = document.documentMode, i, r; + if(v < 9) + return; + + var ctors = [ "Image", "MutationObserver", "XMLHttpRequest" ]; + for(i = 0; i < ctors.length; i++) { + r = ctors[i]; + if(!(r in window)) + continue; + ok(window.hasOwnProperty(r), r + " not prop of window"); + ok(!Object.getPrototypeOf(window).hasOwnProperty(r), r + " is a prop of window's prototype"); + } + ok(window.Image.prototype === window.HTMLImageElement.prototype, "Image.prototype != HTMLImageElement.prototype"); +});