diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c
index 4605fdac0f0..9f56a561e0d 100644
--- a/dlls/mshtml/dispex.c
+++ b/dlls/mshtml/dispex.c
@@ -1043,7 +1043,7 @@ static HRESULT get_builtin_id(DispatchEx *This, BSTR name, DWORD grfdex, DISPID
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;
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index d54f729b2e5..3f7c60b0172 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -6585,8 +6585,42 @@ static IHTMLEventObj *HTMLElement_set_current_event(DispatchEx *dispex, IHTMLEve
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)
{
+ 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[] = {
{DISPID_IHTMLELEMENT2_DOSCROLL, 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);
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);
}
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 5cf53bb48c9..6978ed77c85 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -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 release_dispex(DispatchEx*) 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 get_dispids(tid_t,DWORD*,DISPID**) DECLSPEC_HIDDEN;
HRESULT remove_attribute(DispatchEx*,DISPID,VARIANT_BOOL*) DECLSPEC_HIDDEN;
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js
index 08fcde4ff75..c2fd8bd2774 100644
--- a/dlls/mshtml/tests/documentmode.js
+++ b/dlls/mshtml/tests/documentmode.js
@@ -1136,7 +1136,6 @@ sync_test("elem_attr", function() {
ok(r === (v < 8 ? arr : (v < 9 ? "arrval" : null)), "testattr with custom valueOf = " + r);
elem.setAttribute("testattr", arr);
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(elem.testattr === arr, "elem.testattr after setAttribute with custom valueOf = " + elem.testattr);
r = elem.removeAttribute("testattr");