mshtml: Fix dispex hooks handling for function objects.
Based on patch by Gabriel Ivăncescu. Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
46f08b169b
commit
b650e768be
|
@ -842,7 +842,7 @@ static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
|
||||||
case DISPATCH_METHOD:
|
case DISPATCH_METHOD:
|
||||||
if(!This->obj)
|
if(!This->obj)
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
hres = typeinfo_invoke(This->obj, This->info, flags, params, res, ei);
|
hres = dispex_call_builtin(This->obj, This->info->id, params, res, ei, caller);
|
||||||
break;
|
break;
|
||||||
case DISPATCH_PROPERTYGET: {
|
case DISPATCH_PROPERTYGET: {
|
||||||
unsigned name_len;
|
unsigned name_len;
|
||||||
|
@ -1168,13 +1168,23 @@ static HRESULT builtin_propput(DispatchEx *This, func_info_t *func, DISPPARAMS *
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISPPARAMS *dp, VARIANT *res, IServiceProvider *caller)
|
static HRESULT invoke_builtin_function(DispatchEx *This, func_info_t *func, DISPPARAMS *dp,
|
||||||
|
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||||
{
|
{
|
||||||
VARIANT arg_buf[MAX_ARGS], *arg_ptrs[MAX_ARGS], *arg, retv, ret_ref, vhres;
|
VARIANT arg_buf[MAX_ARGS], *arg_ptrs[MAX_ARGS], *arg, retv, ret_ref, vhres;
|
||||||
unsigned i, nconv = 0;
|
unsigned i, nconv = 0;
|
||||||
IUnknown *iface;
|
IUnknown *iface;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
|
|
||||||
|
if(func->hook) {
|
||||||
|
hres = func->hook(This, DISPATCH_METHOD, dp, res, ei, caller);
|
||||||
|
if(hres != S_FALSE)
|
||||||
|
return hres;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!func->call_vtbl_off)
|
||||||
|
return typeinfo_invoke(This, func, DISPATCH_METHOD, dp, res, ei);
|
||||||
|
|
||||||
if(dp->cArgs + func->default_value_cnt < func->argc) {
|
if(dp->cArgs + func->default_value_cnt < func->argc) {
|
||||||
FIXME("Invalid argument count (expected %u, got %u)\n", func->argc, dp->cArgs);
|
FIXME("Invalid argument count (expected %u, got %u)\n", func->argc, dp->cArgs);
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
@ -1296,10 +1306,7 @@ static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(func->call_vtbl_off)
|
hres = invoke_builtin_function(This, func, dp, res, ei, caller);
|
||||||
hres = invoke_builtin_function(This, func, dp, res, caller);
|
|
||||||
else
|
|
||||||
hres = typeinfo_invoke(This, func, flags, dp, res, ei);
|
|
||||||
break;
|
break;
|
||||||
case DISPATCH_PROPERTYGET: {
|
case DISPATCH_PROPERTYGET: {
|
||||||
func_obj_entry_t *entry;
|
func_obj_entry_t *entry;
|
||||||
|
@ -1364,15 +1371,15 @@ static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD
|
||||||
if(FAILED(hres))
|
if(FAILED(hres))
|
||||||
return hres;
|
return hres;
|
||||||
|
|
||||||
|
if(func->func_disp_idx != -1)
|
||||||
|
return function_invoke(This, func, flags, dp, res, ei, caller);
|
||||||
|
|
||||||
if(func->hook) {
|
if(func->hook) {
|
||||||
hres = func->hook(This, lcid, flags, dp, res, ei, caller);
|
hres = func->hook(This, flags, dp, res, ei, caller);
|
||||||
if(hres != S_FALSE)
|
if(hres != S_FALSE)
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(func->func_disp_idx != -1)
|
|
||||||
return function_invoke(This, func, flags, dp, res, ei, caller);
|
|
||||||
|
|
||||||
switch(flags) {
|
switch(flags) {
|
||||||
case DISPATCH_PROPERTYPUT:
|
case DISPATCH_PROPERTYPUT:
|
||||||
if(res)
|
if(res)
|
||||||
|
@ -1412,6 +1419,19 @@ static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT dispex_call_builtin(DispatchEx *dispex, DISPID id, DISPPARAMS *dp,
|
||||||
|
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||||
|
{
|
||||||
|
func_info_t *func;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
hres = get_builtin_func(dispex->info, id, &func);
|
||||||
|
if(FAILED(hres))
|
||||||
|
return hres;
|
||||||
|
|
||||||
|
return invoke_builtin_function(dispex, func, dp, res, ei, caller);
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
|
HRESULT remove_attribute(DispatchEx *This, DISPID id, VARIANT_BOOL *success)
|
||||||
{
|
{
|
||||||
switch(get_dispid_type(id)) {
|
switch(get_dispid_type(id)) {
|
||||||
|
|
|
@ -6643,7 +6643,7 @@ static IHTMLEventObj *HTMLElement_set_current_event(DispatchEx *dispex, IHTMLEve
|
||||||
return default_set_current_event(This->node.doc->window, event);
|
return default_set_current_event(This->node.doc->window, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT IHTMLElement6_setAttribute_hook(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *dp,
|
static HRESULT IHTMLElement6_setAttribute_hook(DispatchEx *dispex, WORD flags, DISPPARAMS *dp,
|
||||||
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||||
{
|
{
|
||||||
VARIANT args[2];
|
VARIANT args[2];
|
||||||
|
@ -6667,8 +6667,7 @@ static HRESULT IHTMLElement6_setAttribute_hook(DispatchEx *dispex, LCID lcid, WO
|
||||||
return hres;
|
return hres;
|
||||||
args[1] = dp->rgvarg[dp->cArgs - 1];
|
args[1] = dp->rgvarg[dp->cArgs - 1];
|
||||||
|
|
||||||
hres = IDispatchEx_InvokeEx(&dispex->IDispatchEx_iface, DISPID_IHTMLELEMENT6_IE9_SETATTRIBUTE,
|
hres = dispex_call_builtin(dispex, DISPID_IHTMLELEMENT6_IE9_SETATTRIBUTE, &new_dp, res, ei, caller);
|
||||||
lcid, flags, &new_dp, res, ei, caller);
|
|
||||||
VariantClear(&args[0]);
|
VariantClear(&args[0]);
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3314,7 +3314,7 @@ static HRESULT WINAPI EventTarget_dispatchEvent(IEventTarget *iface, IDOMEvent *
|
||||||
return dispatch_event_object(This, event, DISPATCH_STANDARD, result);
|
return dispatch_event_object(This, event, DISPATCH_STANDARD, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT IEventTarget_addEventListener_hook(DispatchEx *dispex, LCID lcid, WORD flags,
|
static HRESULT IEventTarget_addEventListener_hook(DispatchEx *dispex, WORD flags,
|
||||||
DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||||
{
|
{
|
||||||
/* If only two arguments were given, implicitly set capture to false */
|
/* If only two arguments were given, implicitly set capture to false */
|
||||||
|
@ -3328,14 +3328,13 @@ static HRESULT IEventTarget_addEventListener_hook(DispatchEx *dispex, LCID lcid,
|
||||||
|
|
||||||
TRACE("implicit capture\n");
|
TRACE("implicit capture\n");
|
||||||
|
|
||||||
return IDispatchEx_InvokeEx(&dispex->IDispatchEx_iface, DISPID_IEVENTTARGET_ADDEVENTLISTENER,
|
return dispex_call_builtin(dispex, DISPID_IEVENTTARGET_ADDEVENTLISTENER, &new_dp, res, ei, caller);
|
||||||
lcid, flags, &new_dp, res, ei, caller);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_FALSE; /* fallback to default */
|
return S_FALSE; /* fallback to default */
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT IEventTarget_removeEventListener_hook(DispatchEx *dispex, LCID lcid, WORD flags,
|
static HRESULT IEventTarget_removeEventListener_hook(DispatchEx *dispex, WORD flags,
|
||||||
DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||||
{
|
{
|
||||||
/* If only two arguments were given, implicitly set capture to false */
|
/* If only two arguments were given, implicitly set capture to false */
|
||||||
|
@ -3349,8 +3348,7 @@ static HRESULT IEventTarget_removeEventListener_hook(DispatchEx *dispex, LCID lc
|
||||||
|
|
||||||
TRACE("implicit capture\n");
|
TRACE("implicit capture\n");
|
||||||
|
|
||||||
return IDispatchEx_InvokeEx(&dispex->IDispatchEx_iface, DISPID_IEVENTTARGET_REMOVEEVENTLISTENER,
|
return dispex_call_builtin(dispex, DISPID_IEVENTTARGET_REMOVEEVENTLISTENER, &new_dp, res, ei, caller);
|
||||||
lcid, flags, &new_dp, res, ei, caller);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_FALSE; /* fallback to default */
|
return S_FALSE; /* fallback to default */
|
||||||
|
|
|
@ -337,7 +337,7 @@ typedef struct {
|
||||||
dispex_data_t *delayed_init_info;
|
dispex_data_t *delayed_init_info;
|
||||||
} dispex_static_data_t;
|
} dispex_static_data_t;
|
||||||
|
|
||||||
typedef HRESULT (*dispex_hook_invoke_t)(DispatchEx*,LCID,WORD,DISPPARAMS*,VARIANT*,
|
typedef HRESULT (*dispex_hook_invoke_t)(DispatchEx*,WORD,DISPPARAMS*,VARIANT*,
|
||||||
EXCEPINFO*,IServiceProvider*);
|
EXCEPINFO*,IServiceProvider*);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -397,6 +397,8 @@ const void *dispex_get_vtbl(DispatchEx*) DECLSPEC_HIDDEN;
|
||||||
void dispex_info_add_interface(dispex_data_t*,tid_t,const dispex_hook_t*) DECLSPEC_HIDDEN;
|
void dispex_info_add_interface(dispex_data_t*,tid_t,const dispex_hook_t*) DECLSPEC_HIDDEN;
|
||||||
compat_mode_t dispex_compat_mode(DispatchEx*) DECLSPEC_HIDDEN;
|
compat_mode_t dispex_compat_mode(DispatchEx*) DECLSPEC_HIDDEN;
|
||||||
HRESULT dispex_to_string(DispatchEx*,BSTR*) DECLSPEC_HIDDEN;
|
HRESULT dispex_to_string(DispatchEx*,BSTR*) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT dispex_call_builtin(DispatchEx *dispex, DISPID id, DISPPARAMS *dp,
|
||||||
|
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DISPEXPROP_CUSTOM,
|
DISPEXPROP_CUSTOM,
|
||||||
|
|
|
@ -1166,6 +1166,18 @@ sync_test("elem_attr", function() {
|
||||||
r = elem.removeAttribute("testattr");
|
r = elem.removeAttribute("testattr");
|
||||||
ok(r === (v < 9 ? true : undefined), "testattr removeAttribute with custom valueOf returned " + r);
|
ok(r === (v < 9 ? true : undefined), "testattr removeAttribute with custom valueOf returned " + r);
|
||||||
ok(elem.testattr === (v < 9 ? undefined : arr), "removed testattr with custom valueOf = " + elem.testattr);
|
ok(elem.testattr === (v < 9 ? undefined : arr), "removed testattr with custom valueOf = " + elem.testattr);
|
||||||
|
|
||||||
|
var func = elem.setAttribute;
|
||||||
|
try {
|
||||||
|
func("testattr", arr);
|
||||||
|
todo_wine_if(v >= 9).
|
||||||
|
ok(v < 9, "expected exception setting testattr via func");
|
||||||
|
}catch(ex) {
|
||||||
|
ok(v >= 9, "did not expect exception setting testattr via func");
|
||||||
|
elem.setAttribute("testattr", arr);
|
||||||
|
}
|
||||||
|
r = elem.getAttribute("testattr");
|
||||||
|
ok(r === (v < 8 ? arr : (v < 10 ? "arrval" : "42")), "testattr after setAttribute (as func) = " + r);
|
||||||
delete arr.valueOf;
|
delete arr.valueOf;
|
||||||
delete arr.toString;
|
delete arr.toString;
|
||||||
|
|
||||||
|
@ -1177,7 +1189,7 @@ sync_test("elem_attr", function() {
|
||||||
ok(r === (v < 9 ? true : undefined), "id removeAttribute returned " + r);
|
ok(r === (v < 9 ? true : undefined), "id removeAttribute returned " + r);
|
||||||
ok(elem.id === "", "removed id = " + elem.id);
|
ok(elem.id === "", "removed id = " + elem.id);
|
||||||
|
|
||||||
var func = function() { };
|
func = function() { };
|
||||||
elem.onclick = func;
|
elem.onclick = func;
|
||||||
ok(elem.onclick === func, "onclick = " + elem.onclick);
|
ok(elem.onclick === func, "onclick = " + elem.onclick);
|
||||||
r = elem.getAttribute("onclick");
|
r = elem.getAttribute("onclick");
|
||||||
|
|
|
@ -475,7 +475,7 @@ static HRESULT WINAPI HTMLXMLHttpRequest_abort(IHTMLXMLHttpRequest *iface)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT HTMLXMLHttpRequest_open_hook(DispatchEx *dispex, LCID lcid, WORD flags,
|
static HRESULT HTMLXMLHttpRequest_open_hook(DispatchEx *dispex, WORD flags,
|
||||||
DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
DISPPARAMS *dp, VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
|
||||||
{
|
{
|
||||||
/* If only two arguments were given, implicitly set async to false */
|
/* If only two arguments were given, implicitly set async to false */
|
||||||
|
@ -491,8 +491,7 @@ static HRESULT HTMLXMLHttpRequest_open_hook(DispatchEx *dispex, LCID lcid, WORD
|
||||||
|
|
||||||
TRACE("implicit async\n");
|
TRACE("implicit async\n");
|
||||||
|
|
||||||
return IDispatchEx_InvokeEx(&dispex->IDispatchEx_iface, DISPID_IHTMLXMLHTTPREQUEST_OPEN,
|
return dispex_call_builtin(dispex, DISPID_IHTMLXMLHTTPREQUEST_OPEN, &new_dp, res, ei, caller);
|
||||||
lcid, flags, &new_dp, res, ei, caller);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return S_FALSE; /* fallback to default */
|
return S_FALSE; /* fallback to default */
|
||||||
|
|
Loading…
Reference in New Issue