mshtml: Added IHTMLElement::removeAttribute implementation.
This commit is contained in:
parent
30bed7eab3
commit
00293e9b0b
|
@ -52,8 +52,11 @@ struct dispex_data_t {
|
|||
typedef struct {
|
||||
VARIANT var;
|
||||
LPWSTR name;
|
||||
DWORD flags;
|
||||
} dynamic_prop_t;
|
||||
|
||||
#define DYNPROP_DELETED 0x01
|
||||
|
||||
typedef struct {
|
||||
DispatchEx dispex;
|
||||
const IUnknownVtbl *lpIUnknownVtbl;
|
||||
|
@ -442,7 +445,7 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags
|
|||
{
|
||||
const BOOL alloc = flags & fdexNameEnsure;
|
||||
dispex_dynamic_data_t *data;
|
||||
unsigned i;
|
||||
dynamic_prop_t *prop;
|
||||
|
||||
data = get_dynamic_data(This, alloc);
|
||||
if(!data) {
|
||||
|
@ -453,9 +456,14 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags
|
|||
return DISP_E_UNKNOWNNAME;
|
||||
}
|
||||
|
||||
for(i=0; i < data->prop_cnt; i++) {
|
||||
if(flags & fdexNameCaseInsensitive ? !strcmpiW(data->props[i].name, name) : !strcmpW(data->props[i].name, name)) {
|
||||
*ret = data->props+i;
|
||||
for(prop = data->props; prop < data->props+data->prop_cnt; prop++) {
|
||||
if(flags & fdexNameCaseInsensitive ? !strcmpiW(prop->name, name) : !strcmpW(prop->name, name)) {
|
||||
if(prop->flags & DYNPROP_DELETED) {
|
||||
if(!alloc)
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
prop->flags &= ~DYNPROP_DELETED;
|
||||
}
|
||||
*ret = prop;
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
|
@ -481,10 +489,16 @@ static HRESULT get_dynamic_prop(DispatchEx *This, const WCHAR *name, DWORD flags
|
|||
data->buf_size <<= 1;
|
||||
}
|
||||
|
||||
data->props[data->prop_cnt].name = heap_strdupW(name);
|
||||
VariantInit(&data->props[data->prop_cnt].var);
|
||||
*ret = data->props + data->prop_cnt++;
|
||||
prop = data->props + data->prop_cnt;
|
||||
|
||||
prop->name = heap_strdupW(name);
|
||||
if(!prop->name)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
VariantInit(&prop->var);
|
||||
prop->flags = 0;
|
||||
data->prop_cnt++;
|
||||
*ret = prop;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -795,6 +809,43 @@ static HRESULT invoke_builtin_prop(DispatchEx *This, DISPID id, LCID lcid, WORD
|
|||
return hres;
|
||||
}
|
||||
|
||||
HRESULT remove_prop(DispatchEx *This, BSTR name, VARIANT_BOOL *success)
|
||||
{
|
||||
dynamic_prop_t *prop;
|
||||
DISPID id;
|
||||
HRESULT hres;
|
||||
|
||||
hres = get_builtin_id(This, name, 0, &id);
|
||||
if(hres == S_OK) {
|
||||
DISPID named_id = DISPID_PROPERTYPUT;
|
||||
VARIANT var;
|
||||
DISPPARAMS dp = {&var,&named_id,1,1};
|
||||
EXCEPINFO ei;
|
||||
|
||||
V_VT(&var) = VT_EMPTY;
|
||||
memset(&ei, 0, sizeof(ei));
|
||||
hres = invoke_builtin_prop(This, id, 0, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
*success = VARIANT_TRUE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hres = get_dynamic_prop(This, name, 0, &prop);
|
||||
if(FAILED(hres)) {
|
||||
if(hres != DISP_E_UNKNOWNNAME)
|
||||
return hres;
|
||||
*success = VARIANT_FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
VariantClear(&prop->var);
|
||||
prop->flags |= DYNPROP_DELETED;
|
||||
*success = VARIANT_TRUE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#define DISPATCHEX_THIS(iface) DEFINE_THIS(DispatchEx, IDispatchEx, iface)
|
||||
|
||||
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
|
||||
|
@ -926,12 +977,12 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
|
||||
if(is_dynamic_dispid(id)) {
|
||||
DWORD idx = id - DISPID_DYNPROP_0;
|
||||
VARIANT *var;
|
||||
dynamic_prop_t *prop;
|
||||
|
||||
if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx)
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
|
||||
var = &This->dynamic_data->props[idx].var;
|
||||
prop = This->dynamic_data->props+idx;
|
||||
|
||||
switch(wFlags) {
|
||||
case DISPATCH_METHOD|DISPATCH_PROPERTYGET:
|
||||
|
@ -942,8 +993,8 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
DISPPARAMS dp = {NULL, &named_arg, 0, 1};
|
||||
IDispatchEx *dispex;
|
||||
|
||||
if(V_VT(var) != VT_DISPATCH) {
|
||||
FIXME("invoke vt %d\n", V_VT(var));
|
||||
if(V_VT(&prop->var) != VT_DISPATCH) {
|
||||
FIXME("invoke %s\n", debugstr_variant(&prop->var));
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
@ -962,14 +1013,14 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
V_VT(dp.rgvarg) = VT_DISPATCH;
|
||||
V_DISPATCH(dp.rgvarg) = (IDispatch*)DISPATCHEX(This);
|
||||
|
||||
hres = IDispatch_QueryInterface(V_DISPATCH(var), &IID_IDispatchEx, (void**)&dispex);
|
||||
hres = IDispatch_QueryInterface(V_DISPATCH(&prop->var), &IID_IDispatchEx, (void**)&dispex);
|
||||
TRACE("%s call\n", debugstr_w(This->dynamic_data->props[idx].name));
|
||||
if(SUCCEEDED(hres)) {
|
||||
hres = IDispatchEx_InvokeEx(dispex, DISPID_VALUE, lcid, wFlags, &dp, pvarRes, pei, pspCaller);
|
||||
IDispatchEx_Release(dispex);
|
||||
}else {
|
||||
ULONG err = 0;
|
||||
hres = IDispatch_Invoke(V_DISPATCH(var), DISPID_VALUE, &IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &err);
|
||||
hres = IDispatch_Invoke(V_DISPATCH(&prop->var), DISPID_VALUE, &IID_NULL, lcid, wFlags, pdp, pvarRes, pei, &err);
|
||||
}
|
||||
TRACE("%s ret %08x\n", debugstr_w(This->dynamic_data->props[idx].name), hres);
|
||||
|
||||
|
@ -977,7 +1028,9 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
return hres;
|
||||
}
|
||||
case DISPATCH_PROPERTYGET:
|
||||
return VariantCopy(pvarRes, var);
|
||||
if(prop->flags & DYNPROP_DELETED)
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
return VariantCopy(pvarRes, &prop->var);
|
||||
case DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF:
|
||||
case DISPATCH_PROPERTYPUT:
|
||||
if(pdp->cArgs != 1 || (pdp->cNamedArgs == 1 && *pdp->rgdispidNamedArgs != DISPID_PROPERTYPUT)
|
||||
|
@ -987,8 +1040,13 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
|
|||
}
|
||||
|
||||
TRACE("put %s\n", debugstr_variant(pdp->rgvarg));
|
||||
VariantClear(var);
|
||||
return VariantCopy(var, pdp->rgvarg);
|
||||
VariantClear(&prop->var);
|
||||
hres = VariantCopy(&prop->var, pdp->rgvarg);
|
||||
if(FAILED(hres))
|
||||
return hres;
|
||||
|
||||
prop->flags &= ~DYNPROP_DELETED;
|
||||
return S_OK;
|
||||
default:
|
||||
FIXME("unhandled wFlags %x\n", wFlags);
|
||||
return E_NOTIMPL;
|
||||
|
@ -1073,12 +1131,14 @@ static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex,
|
|||
if(!This->dynamic_data || This->dynamic_data->prop_cnt <= idx)
|
||||
return DISP_E_UNKNOWNNAME;
|
||||
|
||||
if(idx+1 == This->dynamic_data->prop_cnt) {
|
||||
while(++idx < This->dynamic_data->prop_cnt && This->dynamic_data->props[idx].flags & DYNPROP_DELETED);
|
||||
|
||||
if(idx == This->dynamic_data->prop_cnt) {
|
||||
*pid = DISPID_STARTENUM;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
*pid = id+1;
|
||||
*pid = DISPID_DYNPROP_0+idx;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -198,8 +198,10 @@ static HRESULT WINAPI HTMLElement_removeAttribute(IHTMLElement *iface, BSTR strA
|
|||
LONG lFlags, VARIANT_BOOL *pfSuccess)
|
||||
{
|
||||
HTMLElement *This = HTMLELEM_THIS(iface);
|
||||
FIXME("(%p)->()\n", This);
|
||||
return E_NOTIMPL;
|
||||
|
||||
TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(strAttributeName), lFlags, pfSuccess);
|
||||
|
||||
return remove_prop(&This->node.dispex, strAttributeName, pfSuccess);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI HTMLElement_put_className(IHTMLElement *iface, BSTR v)
|
||||
|
|
|
@ -171,6 +171,7 @@ void release_dispex(DispatchEx*);
|
|||
BOOL dispex_query_interface(DispatchEx*,REFIID,void**);
|
||||
HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**);
|
||||
HRESULT get_dispids(tid_t,DWORD*,DISPID**);
|
||||
HRESULT remove_prop(DispatchEx*,BSTR,VARIANT_BOOL*);
|
||||
|
||||
typedef struct HTMLWindow HTMLWindow;
|
||||
typedef struct HTMLDocumentNode HTMLDocumentNode;
|
||||
|
|
Loading…
Reference in New Issue