mshtml: Stringify attribute values in setAttribute using string hints in IE10+.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Gabriel Ivăncescu 2021-11-29 18:31:20 +02:00 committed by Alexandre Julliard
parent b89c47826d
commit f374e9ccc8
4 changed files with 37 additions and 3 deletions

View File

@ -1043,7 +1043,7 @@ static HRESULT get_builtin_id(DispatchEx *This, BSTR name, DWORD grfdex, DISPID
return DISP_E_UNKNOWNNAME; return DISP_E_UNKNOWNNAME;
} }
static HRESULT change_type(VARIANT *dst, VARIANT *src, VARTYPE vt, IServiceProvider *caller) HRESULT change_type(VARIANT *dst, VARIANT *src, VARTYPE vt, IServiceProvider *caller)
{ {
V_VT(dst) = VT_EMPTY; V_VT(dst) = VT_EMPTY;

View File

@ -6585,8 +6585,42 @@ 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,
VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
{
VARIANT args[2];
HRESULT hres;
DISPPARAMS new_dp = { args, NULL, 2, 0 };
if(!(flags & DISPATCH_METHOD) || dp->cArgs < 2 || dp->cNamedArgs)
return S_FALSE;
switch(V_VT(&dp->rgvarg[dp->cArgs - 2])) {
case VT_EMPTY:
case VT_BSTR:
case VT_NULL:
return S_FALSE;
default:
break;
}
hres = change_type(&args[0], &dp->rgvarg[dp->cArgs - 2], VT_BSTR, caller);
if(FAILED(hres))
return hres;
args[1] = dp->rgvarg[dp->cArgs - 1];
hres = IDispatchEx_InvokeEx(&dispex->IDispatchEx_iface, DISPID_IHTMLELEMENT6_IE9_SETATTRIBUTE,
lcid, flags, &new_dp, res, ei, caller);
VariantClear(&args[0]);
return hres;
}
void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
{ {
static const dispex_hook_t elem6_ie10_hooks[] = {
{DISPID_IHTMLELEMENT6_IE9_SETATTRIBUTE, IHTMLElement6_setAttribute_hook},
{DISPID_UNKNOWN}
};
static const dispex_hook_t elem2_ie11_hooks[] = { static const dispex_hook_t elem2_ie11_hooks[] = {
{DISPID_IHTMLELEMENT2_DOSCROLL, NULL}, {DISPID_IHTMLELEMENT2_DOSCROLL, NULL},
{DISPID_IHTMLELEMENT2_READYSTATE, NULL}, {DISPID_IHTMLELEMENT2_READYSTATE, NULL},
@ -6601,7 +6635,7 @@ void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
dispex_info_add_interface(info, IElementSelector_tid, NULL); dispex_info_add_interface(info, IElementSelector_tid, NULL);
if(mode >= COMPAT_MODE_IE9) { if(mode >= COMPAT_MODE_IE9) {
dispex_info_add_interface(info, IHTMLElement6_tid, NULL); dispex_info_add_interface(info, IHTMLElement6_tid, mode >= COMPAT_MODE_IE10 ? elem6_ie10_hooks : NULL);
dispex_info_add_interface(info, IElementTraversal_tid, NULL); dispex_info_add_interface(info, IElementTraversal_tid, NULL);
} }

View File

@ -384,6 +384,7 @@ extern void (__cdecl *note_cc_edge)(nsISupports*,const char*,nsCycleCollectionTr
void init_dispatch(DispatchEx*,IUnknown*,dispex_static_data_t*,compat_mode_t) DECLSPEC_HIDDEN; void init_dispatch(DispatchEx*,IUnknown*,dispex_static_data_t*,compat_mode_t) DECLSPEC_HIDDEN;
void release_dispex(DispatchEx*) DECLSPEC_HIDDEN; void release_dispex(DispatchEx*) DECLSPEC_HIDDEN;
BOOL dispex_query_interface(DispatchEx*,REFIID,void**) DECLSPEC_HIDDEN; BOOL dispex_query_interface(DispatchEx*,REFIID,void**) DECLSPEC_HIDDEN;
HRESULT change_type(VARIANT*,VARIANT*,VARTYPE,IServiceProvider*) DECLSPEC_HIDDEN;
HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**) DECLSPEC_HIDDEN; HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**) DECLSPEC_HIDDEN;
HRESULT get_dispids(tid_t,DWORD*,DISPID**) DECLSPEC_HIDDEN; HRESULT get_dispids(tid_t,DWORD*,DISPID**) DECLSPEC_HIDDEN;
HRESULT remove_attribute(DispatchEx*,DISPID,VARIANT_BOOL*) DECLSPEC_HIDDEN; HRESULT remove_attribute(DispatchEx*,DISPID,VARIANT_BOOL*) DECLSPEC_HIDDEN;

View File

@ -1136,7 +1136,6 @@ sync_test("elem_attr", function() {
ok(r === (v < 8 ? arr : (v < 9 ? "arrval" : null)), "testattr with custom valueOf = " + r); ok(r === (v < 8 ? arr : (v < 9 ? "arrval" : null)), "testattr with custom valueOf = " + r);
elem.setAttribute("testattr", arr); elem.setAttribute("testattr", arr);
r = elem.getAttribute("testattr"); r = elem.getAttribute("testattr");
todo_wine_if(v >= 10).
ok(r === (v < 8 ? arr : (v < 10 ? "arrval" : "42")), "testattr after setAttribute with custom valueOf = " + r); ok(r === (v < 8 ? arr : (v < 10 ? "arrval" : "42")), "testattr after setAttribute with custom valueOf = " + r);
ok(elem.testattr === arr, "elem.testattr after setAttribute with custom valueOf = " + elem.testattr); ok(elem.testattr === arr, "elem.testattr after setAttribute with custom valueOf = " + elem.testattr);
r = elem.removeAttribute("testattr"); r = elem.removeAttribute("testattr");