From: Jacek Caban jacek@codeweavers.com
--- dlls/jscript/dispex.c | 37 +++++++++++++++++++------ dlls/jscript/jscript.h | 1 + dlls/jscript/jsdisp.idl | 1 + dlls/mshtml/dispex.c | 59 +++++++++++++++++++++++++--------------- dlls/mshtml/htmlwindow.c | 8 ++++++ 5 files changed, 76 insertions(+), 30 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c index 883fd6fc880..da9594a5e6e 100644 --- a/dlls/jscript/dispex.c +++ b/dlls/jscript/dispex.c @@ -2209,7 +2209,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IWineJSDispatch *iface, DISPID id, LCI return leave_script(This->ctx, hres); }
-static HRESULT delete_prop(dispex_prop_t *prop, BOOL *ret) +static HRESULT delete_prop(jsdisp_t *obj, dispex_prop_t *prop, BOOL *ret) { if(prop->type == PROP_PROTREF || prop->type == PROP_DELETED) { *ret = TRUE; @@ -2223,13 +2223,26 @@ static HRESULT delete_prop(dispex_prop_t *prop, BOOL *ret)
*ret = TRUE;
- if(prop->type == PROP_JSVAL) + switch(prop->type) { + case PROP_JSVAL: jsval_release(prop->u.val); - if(prop->type == PROP_ACCESSOR) { + break; + case PROP_ACCESSOR: if(prop->u.accessor.getter) jsdisp_release(prop->u.accessor.getter); if(prop->u.accessor.setter) jsdisp_release(prop->u.accessor.setter); + break; + case PROP_EXTERN: + if(obj->builtin_info->prop_delete) { + HRESULT hres; + hres = obj->builtin_info->prop_delete(obj, prop->u.id); + if(FAILED(hres)) + return hres; + } + break; + default: + break; } prop->type = PROP_DELETED; return S_OK; @@ -2255,7 +2268,7 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByName(IWineJSDispatch *iface, BSTR return S_OK; }
- return delete_prop(prop, &b); + return delete_prop(This, prop, &b); }
static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IWineJSDispatch *iface, DISPID id) @@ -2272,7 +2285,7 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IWineJSDispatch *iface, DI return DISP_E_MEMBERNOTFOUND; }
- return delete_prop(prop, &b); + return delete_prop(This, prop, &b); }
static HRESULT WINAPI DispatchEx_GetMemberProperties(IWineJSDispatch *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) @@ -2951,7 +2964,7 @@ HRESULT jsdisp_delete_idx(jsdisp_t *obj, DWORD idx) if(FAILED(hres) || !prop) return hres;
- hres = delete_prop(prop, &b); + hres = delete_prop(obj, prop, &b); if(FAILED(hres)) return hres; return b ? S_OK : JS_E_INVALID_ACTION; @@ -2969,7 +2982,7 @@ HRESULT disp_delete(IDispatch *disp, DISPID id, BOOL *ret)
prop = get_prop(jsdisp, id); if(prop) - hres = delete_prop(prop, ret); + hres = delete_prop(jsdisp, prop, ret); else hres = DISP_E_MEMBERNOTFOUND;
@@ -3045,7 +3058,7 @@ HRESULT disp_delete_name(script_ctx_t *ctx, IDispatch *disp, jsstr_t *name, BOOL
hres = find_prop_name(jsdisp, string_hash(ptr), ptr, FALSE, NULL, &prop); if(prop) { - hres = delete_prop(prop, ret); + hres = delete_prop(jsdisp, prop, ret); }else { *ret = TRUE; hres = S_OK; @@ -3409,6 +3422,13 @@ static HRESULT HostObject_next_prop(jsdisp_t *jsdisp, unsigned id, struct proper return IWineJSDispatchHost_NextProperty(This->host_iface, id, desc); }
+static HRESULT HostObject_prop_delete(jsdisp_t *jsdisp, unsigned id) +{ + HostObject *This = HostObject_from_jsdisp(jsdisp); + + return IWineJSDispatchHost_DeleteProperty(This->host_iface, id); +} + static HRESULT HostObject_to_string(jsdisp_t *jsdisp, jsstr_t **ret) { HostObject *This = HostObject_from_jsdisp(jsdisp); @@ -3432,6 +3452,7 @@ static const builtin_info_t HostObject_info = { .prop_get = HostObject_prop_get, .prop_put = HostObject_prop_put, .next_prop = HostObject_next_prop, + .prop_delete = HostObject_prop_delete, .to_string = HostObject_to_string, };
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h index 456f00171ed..3642bf171c8 100644 --- a/dlls/jscript/jscript.h +++ b/dlls/jscript/jscript.h @@ -190,6 +190,7 @@ typedef struct { HRESULT (*next_prop)(jsdisp_t*,unsigned,struct property_info*); HRESULT (*prop_get)(jsdisp_t*,unsigned,jsval_t*); HRESULT (*prop_put)(jsdisp_t*,unsigned,jsval_t); + HRESULT (*prop_delete)(jsdisp_t*,unsigned); HRESULT (*to_string)(jsdisp_t*,jsstr_t**); HRESULT (*gc_traverse)(struct gc_ctx*,enum gc_traverse_op,jsdisp_t*); } builtin_info_t; diff --git a/dlls/jscript/jsdisp.idl b/dlls/jscript/jsdisp.idl index f01ea95ce48..4030a0110a3 100644 --- a/dlls/jscript/jsdisp.idl +++ b/dlls/jscript/jsdisp.idl @@ -59,6 +59,7 @@ interface IWineJSDispatchHost : IDispatchEx HRESULT NextProperty(DISPID id, struct property_info *desc); HRESULT GetProperty(DISPID id, LCID lcid, VARIANT *r, EXCEPINFO *ei, IServiceProvider *caller); HRESULT SetProperty(DISPID id, LCID lcid, VARIANT *v, EXCEPINFO *ei, IServiceProvider *caller); + HRESULT DeleteProperty(DISPID id); HRESULT CallFunction(DISPID id, UINT32 iid, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller); HRESULT ToString(BSTR *str); } diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 0be5ba002a7..93dfe95c760 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -2097,6 +2097,32 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IWineJSDispatchHost *iface, DISPID id, } }
+static HRESULT dispex_prop_delete(DispatchEx *dispex, DISPID id) +{ + if(is_custom_dispid(id) && dispex->info->desc->vtbl->delete) + return dispex->info->desc->vtbl->delete(dispex, id); + + if(dispex_compat_mode(dispex) < COMPAT_MODE_IE8) { + /* Not implemented by IE */ + return E_NOTIMPL; + } + + if(is_dynamic_dispid(id)) { + DWORD idx = id - DISPID_DYNPROP_0; + dynamic_prop_t *prop; + + if(!get_dynamic_data(dispex) || idx >= dispex->dynamic_data->prop_cnt) + return S_OK; + + prop = dispex->dynamic_data->props + idx; + VariantClear(&prop->var); + prop->flags |= DYNPROP_DELETED; + return S_OK; + } + + return S_OK; +} + static HRESULT WINAPI DispatchEx_DeleteMemberByName(IWineJSDispatchHost *iface, BSTR name, DWORD grfdex) { DispatchEx *This = impl_from_IWineJSDispatchHost(iface); @@ -2133,28 +2159,7 @@ static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IWineJSDispatchHost *iface return E_OUTOFMEMORY; if(This->jsdisp) return IWineJSDispatch_DeleteMemberByDispID(This->jsdisp, id); - if(is_custom_dispid(id) && This->info->desc->vtbl->delete) - return This->info->desc->vtbl->delete(This, id); - - if(dispex_compat_mode(This) < COMPAT_MODE_IE8) { - /* Not implemented by IE */ - return E_NOTIMPL; - } - - if(is_dynamic_dispid(id)) { - DWORD idx = id - DISPID_DYNPROP_0; - dynamic_prop_t *prop; - - if(!get_dynamic_data(This) || idx >= This->dynamic_data->prop_cnt) - return S_OK; - - prop = This->dynamic_data->props + idx; - VariantClear(&prop->var); - prop->flags |= DYNPROP_DELETED; - return S_OK; - } - - return S_OK; + return dispex_prop_delete(This, id); }
static HRESULT WINAPI DispatchEx_GetMemberProperties(IWineJSDispatchHost *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex) @@ -2427,6 +2432,15 @@ static HRESULT WINAPI JSDispatchHost_SetProperty(IWineJSDispatchHost *iface, DIS return dispex_prop_put(This, id, lcid, v, ei, caller); }
+static HRESULT WINAPI JSDispatchHost_DeleteProperty(IWineJSDispatchHost *iface, DISPID id) +{ + DispatchEx *This = impl_from_IWineJSDispatchHost(iface); + + TRACE("%s (%p)->(%lx)\n", This->info->desc->name, This, id); + + return dispex_prop_delete(This, id); +} + static HRESULT WINAPI JSDispatchHost_CallFunction(IWineJSDispatchHost *iface, DISPID id, UINT32 iid, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller) { @@ -2474,6 +2488,7 @@ static IWineJSDispatchHostVtbl JSDispatchHostVtbl = { JSDispatchHost_NextProperty, JSDispatchHost_GetProperty, JSDispatchHost_SetProperty, + JSDispatchHost_DeleteProperty, JSDispatchHost_CallFunction, JSDispatchHost_ToString, }; diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index b936a9a844a..41bef9c7fcf 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -3485,6 +3485,13 @@ static HRESULT WINAPI WindowDispEx_SetProperty(IWineJSDispatchHost *iface, DISPI id, lcid, v, ei, caller); }
+static HRESULT WINAPI WindowDispEx_DeleteProperty(IWineJSDispatchHost *iface, DISPID id) +{ + HTMLOuterWindow *This = impl_from_IWineJSDispatchHost(iface); + + return IWineJSDispatchHost_DeleteProperty(&This->base.inner_window->event_target.dispex.IWineJSDispatchHost_iface, id); +} + static HRESULT WINAPI WindowDispEx_CallFunction(IWineJSDispatchHost *iface, DISPID id, UINT32 iid, DISPPARAMS *dp, VARIANT *ret, EXCEPINFO *ei, IServiceProvider *caller) { @@ -3522,6 +3529,7 @@ static const IWineJSDispatchHostVtbl WindowDispExVtbl = { WindowDispEx_NextProperty, WindowDispEx_GetProperty, WindowDispEx_SetProperty, + WindowDispEx_DeleteProperty, WindowDispEx_CallFunction, WindowDispEx_ToString, };