-- v2: mshtml: Move Option constructor to the window rather than the prototype. mshtml: Move Image constructor to the window rather than the prototype. mshtml: Validate builtin host functions in IE9+ using prototype_id rather
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/jscript/function.c | 2 +- dlls/jscript/jsdisp.idl | 4 ++-- dlls/mshtml/dispex.c | 26 +++++++++++++++++++------- dlls/mshtml/htmlwindow.c | 4 ++-- dlls/mshtml/tests/documentmode.js | 14 ++++++++++++++ 5 files changed, 38 insertions(+), 12 deletions(-)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c index 9f1f53a96ae..4fd49368ad9 100644 --- a/dlls/jscript/function.c +++ b/dlls/jscript/function.c @@ -67,7 +67,7 @@ typedef struct { FunctionInstance function; const WCHAR *name; UINT32 id; - UINT32 iid; + INT32 iid; UINT32 flags; } HostFunction;
diff --git a/dlls/jscript/jsdisp.idl b/dlls/jscript/jsdisp.idl index 5f1384bce78..cfd1beba55d 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -27,7 +27,7 @@ struct property_info UINT32 flags; const WCHAR *name; UINT32 index; - UINT32 iid; + INT32 iid; };
const unsigned int PROPF_METHOD = 0x0100; @@ -69,7 +69,7 @@ interface IWineJSDispatchHost : IDispatchEx HRESULT SetProperty(DISPID id, LCID lcid, VARIANT *v, EXCEPINFO *ei, IServiceProvider *caller); HRESULT DeleteProperty(DISPID id); HRESULT ConfigureProperty(DISPID id, UINT32 flags); - HRESULT CallFunction(DISPID id, UINT32 iid, DWORD flags, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller); + HRESULT CallFunction(DISPID id, INT32 iid, DWORD flags, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller); HRESULT Construct(LCID lcid, DWORD flags, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller); HRESULT GetOuterDispatch(IWineJSDispatchHost **ret); HRESULT ToString(BSTR *str); diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 77eec049912..8efbaf204fe 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -1075,7 +1075,7 @@ static HRESULT function_apply(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARI } }
- hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, func->info->tid, DISPATCH_METHOD, ¶ms, res, ei, caller); + hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, -func->info->tid, DISPATCH_METHOD, ¶ms, res, ei, caller);
fail: while(argc--) @@ -1102,7 +1102,7 @@ static HRESULT function_call(func_disp_t *func, DISPPARAMS *dp, LCID lcid, VARIA if(FAILED(hres)) return CTL_E_ILLEGALFUNCTIONCALL;
- hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, func->info->tid, DISPATCH_METHOD, ¶ms, res, ei, caller); + hres = IWineJSDispatchHost_CallFunction(this_iface, func->info->id, -func->info->tid, DISPATCH_METHOD, ¶ms, res, ei, caller); IWineJSDispatchHost_Release(this_iface); return (hres == E_UNEXPECTED) ? CTL_E_ILLEGALFUNCTIONCALL : hres; } @@ -2593,13 +2593,13 @@ static HRESULT get_host_property_descriptor(DispatchEx *This, DISPID id, struct desc->flags = PROPF_CONFIGURABLE; desc->name = func->name; if(func->func_disp_idx >= 0) { - desc->iid = func->tid; + desc->iid = This->info->desc->id; desc->flags |= PROPF_METHOD | PROPF_WRITABLE; }else { if(func->func_disp_idx == -1) desc->flags |= PROPF_ENUMERABLE; if(This->info->is_prototype) { - desc->iid = func->tid; + desc->iid = This->info->desc->id; if(func->put_vtbl_off) desc->flags |= PROPF_WRITABLE; }else { @@ -2700,19 +2700,31 @@ static HRESULT WINAPI JSDispatchHost_ConfigureProperty(IWineJSDispatchHost *ifac return S_OK; }
-static HRESULT WINAPI JSDispatchHost_CallFunction(IWineJSDispatchHost *iface, DISPID id, UINT32 iid, DWORD flags, +static HRESULT WINAPI JSDispatchHost_CallFunction(IWineJSDispatchHost *iface, DISPID id, INT32 iid, DWORD flags, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller) { DispatchEx *This = impl_from_IWineJSDispatchHost(iface); + dispex_static_data_t *desc = This->info->desc; func_info_t *func; HRESULT hres;
- TRACE("%s (%p)->(%lx %x %lx %p %p %p %p)\n", This->info->name, This, id, iid, flags, dp, ret, ei, caller); + TRACE("%s (%p)->(%lx %d %lx %p %p %p %p)\n", This->info->name, This, id, iid, flags, dp, ret, ei, caller);
hres = get_builtin_func(This->info, id, &func); - if(FAILED(hres) || func->tid != iid) + if(FAILED(hres)) return E_UNEXPECTED;
+ if(iid <= 0) { + if(func->tid != -iid) + return E_UNEXPECTED; + }else if(iid != desc->id) { + while(iid != desc->prototype_id) { + if(!desc->prototype_id) + return E_UNEXPECTED; + desc = object_descriptors[desc->prototype_id]; + } + } + switch(flags) { case DISPATCH_METHOD: assert(func->func_disp_idx >= 0); diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index ffcaf86a361..c7e45439545 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3491,8 +3491,8 @@ static HRESULT WINAPI WindowDispEx_ConfigureProperty(IWineJSDispatchHost *iface, return IWineJSDispatchHost_ConfigureProperty(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, id, flags); }
-static HRESULT WINAPI WindowDispEx_CallFunction(IWineJSDispatchHost *iface, DISPID id, UINT32 iid, DWORD flags, DISPPARAMS *dp, - VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller) +static HRESULT WINAPI WindowDispEx_CallFunction(IWineJSDispatchHost *iface, DISPID id, INT32 iid, DWORD flags, + DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller) { HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface);
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 5bbd8b098f6..d304fbadd62 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3131,6 +3131,13 @@ sync_test("__proto__", function() { ok(e.number === 0xa13b6 - 0x80000000 && e.name === "TypeError", "changing __proto__ on non-extensible object threw exception " + e.number + " (" + e.name + ")"); } + + obj = document.createElement("img"); + obj.__proto__ = ctor.prototype; + document.body.setAttribute.call(obj, "height", "101"); + r = document.body.getAttribute.call(obj, "height"); + ok(r === "101", "getAttribute(height) = " + r); + ok(!("getAttribute" in obj), "getAttribute exposed in obj"); });
sync_test("__defineGetter__", function() { @@ -3750,6 +3757,13 @@ sync_test("prototypes", function() { check(Attr.prototype, Node.prototype, "attr prototype"); check(document.createDocumentFragment(), DocumentFragment.prototype, "fragment"); check(DocumentFragment.prototype, Node.prototype, "fragment prototype"); + + try { + HTMLAreaElement.prototype.toString.call(document.createElement("a")); + ok(false, "Area element's toString on Anchor element didn't fail"); + } catch(e) { + ok(e.number == 0xffff - 0x80000000, "Area element's toString on Anchor element threw exception " + e.number); + } });
sync_test("prototype props", function() {
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 8efbaf204fe..26ea5165a12 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -2982,6 +2982,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"); +});
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlselect.c | 17 +++++++++-------- dlls/mshtml/htmlwindow.c | 24 ++++++++---------------- dlls/mshtml/mshtml_private.h | 6 +++--- dlls/mshtml/tests/documentmode.js | 3 ++- 4 files changed, 22 insertions(+), 28 deletions(-)
diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c index 2d02589db38..9bfe0afb45c 100644 --- a/dlls/mshtml/htmlselect.c +++ b/dlls/mshtml/htmlselect.c @@ -523,15 +523,16 @@ static const dispex_static_data_vtbl_t HTMLOptionElementFactory_dispex_vtbl = { .value = HTMLOptionElementFactory_value, };
-static dispex_static_data_t HTMLOptionElementFactory_dispex = { - .name = "Function", - .constructor_id = PROT_HTMLOptionElement, - .vtbl = &HTMLOptionElementFactory_dispex_vtbl, - .disp_tid = IHTMLOptionElementFactory_tid, - .iface_tids = HTMLOptionElementFactory_iface_tids, +dispex_static_data_t HTMLOptionElementFactory_dispex = { + .name = "Function", + .constructor_id = PROT_HTMLOptionElement, + .init_constructor = HTMLOptionElementFactory_Create, + .vtbl = &HTMLOptionElementFactory_dispex_vtbl, + .disp_tid = IHTMLOptionElementFactory_tid, + .iface_tids = HTMLOptionElementFactory_iface_tids, };
-HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow *window, HTMLOptionElementFactory **ret_ptr) +HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow *window, DispatchEx **ret_ptr) { HTMLOptionElementFactory *ret;
@@ -546,7 +547,7 @@ HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow *window, HTMLOptionEleme init_dispatch(&ret->dispex, &HTMLOptionElementFactory_dispex, window, dispex_compat_mode(&window->event_target.dispex));
- *ret_ptr = ret; + *ret_ptr = &ret->dispex; return S_OK; }
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 29c2a6e8e64..79d16b715de 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -1230,18 +1230,14 @@ static HRESULT WINAPI HTMLWindow2_get_Option(IHTMLWindow2 *iface, IHTMLOptionEle
TRACE("(%p)->(%p)\n", This, p);
- if(!window->option_factory) { - HRESULT hres; - - hres = HTMLOptionElementFactory_Create(window, &window->option_factory); + if(!window->constructors[CTOR_HTMLOptionElementFactory]) { + HRESULT hres = HTMLOptionElementFactory_Create(window, &window->constructors[CTOR_HTMLOptionElementFactory]); if(FAILED(hres)) return hres; }
- *p = &window->option_factory->IHTMLOptionElementFactory_iface; - IHTMLOptionElementFactory_AddRef(*p); - - return S_OK; + return IWineJSDispatchHost_QueryInterface(&window->constructors[CTOR_HTMLOptionElementFactory]->IWineJSDispatchHost_iface, + &IID_IHTMLOptionElementFactory, (void**)p); }
static HRESULT WINAPI HTMLWindow2_focus(IHTMLWindow2 *iface) @@ -3696,8 +3692,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->option_factory) - note_cc_edge((nsISupports*)&This->option_factory->IHTMLOptionElementFactory_iface, "option_factory", cb); if(This->screen) note_cc_edge((nsISupports*)This->screen, "screen", cb); if(This->history) @@ -3736,11 +3730,6 @@ static void HTMLWindow_unlink(DispatchEx *dispex)
release_event_target(&This->event_target);
- if(This->option_factory) { - HTMLOptionElementFactory *option_factory = This->option_factory; - This->option_factory = NULL; - IHTMLOptionElementFactory_Release(&option_factory->IHTMLOptionElementFactory_iface); - } unlink_ref(&This->screen); if(This->history) { OmHistory *history = This->history; @@ -3823,6 +3812,8 @@ static HRESULT HTMLWindow_find_dispid(DispatchEx *dispex, const WCHAR *name, DWO id = constr_name - constructor_names + 1; else if(!wcscmp(name, L"Image")) id = CTOR_HTMLImageElementFactory; + else if(!wcscmp(name, L"Option")) + id = CTOR_HTMLOptionElementFactory;
if(id) { DispatchEx *constr; @@ -4188,13 +4179,14 @@ static void HTMLWindow_init_dispex_info(dispex_data_t *info, compat_mode_t compa
/* IE9+ */ {DISPID_IHTMLWINDOW2_IMAGE}, + {DISPID_IHTMLWINDOW2_OPTION},
/* 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; + const dispex_hook_t *const window2_hooks = window2_ie9_hooks + 2; static const dispex_hook_t window3_hooks[] = { {DISPID_IHTMLWINDOW3_SETTIMEOUT, IHTMLWindow3_setTimeout_hook}, {DISPID_UNKNOWN} diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 58dad8a68e0..5575a07ff4f 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -506,7 +506,8 @@ typedef struct {
/* Extra constructors without new prototypes */ #define ALL_ALT_CTORS \ - X(HTMLImageElementFactory) + X(HTMLImageElementFactory) \ + X(HTMLOptionElementFactory)
typedef enum { PROT_NONE, @@ -782,7 +783,6 @@ struct HTMLInnerWindow {
IHTMLEventObj *event;
- HTMLOptionElementFactory *option_factory; IHTMLScreen *screen; OmHistory *history; IOmNavigator *navigator; @@ -1179,7 +1179,7 @@ HRESULT create_outer_window(GeckoBrowser*,mozIDOMWindowProxy*,HTMLOuterWindow*,H HRESULT update_window_doc(HTMLInnerWindow*); HTMLOuterWindow *mozwindow_to_window(const mozIDOMWindowProxy*); void get_top_window(HTMLOuterWindow*,HTMLOuterWindow**); -HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow*,HTMLOptionElementFactory**); +HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow*,DispatchEx**); HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow*,DispatchEx**); HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,DispatchEx**); HRESULT create_location(HTMLOuterWindow*,HTMLLocation**); diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index e9a2f0172d0..7b0152a6ecd 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -4001,7 +4001,7 @@ sync_test("constructors", function() { if(v < 9) return;
- var ctors = [ "Image", "MutationObserver", "XMLHttpRequest" ]; + var ctors = [ "Image", "MutationObserver", "Option", "XMLHttpRequest" ]; for(i = 0; i < ctors.length; i++) { r = ctors[i]; if(!(r in window)) @@ -4010,4 +4010,5 @@ sync_test("constructors", function() { 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"); + ok(window.Option.prototype === window.HTMLOptionElement.prototype, "Option.prototype != HTMLOptionElement.prototype"); });
Jacek Caban (@jacek) commented about dlls/mshtml/dispex.c:
TRACE("%s (%p)->(%lx %d %lx %p %p %p %p)\n", This->info->name, This, id, iid, flags, dp, ret, ei, caller);
hres = get_builtin_func(This->info, id, &func);
- if(FAILED(hres) || func->tid != iid)
if(FAILED(hres)) return E_UNEXPECTED;
if(iid <= 0) {
if(func->tid != -iid)
return E_UNEXPECTED;
}else if(iid != desc->id) {
while(iid != desc->prototype_id) {
if(!desc->prototype_id)
return E_UNEXPECTED;
desc = object_descriptors[desc->prototype_id];
}
Lookup shouldn't be needed here, I think we could store function's prototype id in `func_info_t`, like `on_prototype`.
Ah yeah, this way I'll also get rid of on_prototype while at it (can just compare the prototype_id to see if it's valid).