Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com ---
Simplifies the next patch.
dlls/mshtml/htmlelem.c | 40 ++++++++++++++++++++++++++++-------- dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/nsembed.c | 22 ++++++++++++++++++++ 3 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index f5500a3..07dea49 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -1086,34 +1086,56 @@ static HRESULT WINAPI HTMLElement_setAttribute(IHTMLElement *iface, BSTR strAttr VARIANT AttributeValue, LONG lFlags) { HTMLElement *This = impl_from_IHTMLElement(iface); + compat_mode_t compat_mode = dispex_compat_mode(&This->node.event_target.dispex); + BOOL stringify = compat_mode >= COMPAT_MODE_IE8; + nsAString name_str, value_str; + BOOL needs_free = FALSE; + nsresult nsres; DISPID dispid; HRESULT hres;
TRACE("(%p)->(%s %s %08x)\n", This, debugstr_w(strAttributeName), debugstr_variant(&AttributeValue), lFlags);
- if(This->dom_element && dispex_compat_mode(&This->node.event_target.dispex) >= COMPAT_MODE_IE8) { - nsAString name_str, value_str; - nsresult nsres; - - hres = variant_to_nsstr(&AttributeValue, 0, &value_str); + if(stringify) { + hres = variant_to_nsstr(&AttributeValue, VARIANT_TO_NSSTR_BSTR_DEPEND, &value_str); if(FAILED(hres)) return hres;
+ if((V_VT(&AttributeValue) & ~VT_BYREF) != VT_BSTR) + needs_free = TRUE; + + V_VT(&AttributeValue) = VT_BSTR; + nsAString_GetData(&value_str, (const WCHAR**)&V_BSTR(&AttributeValue)); + + if(!V_BSTR(&AttributeValue)) { + V_VT(&AttributeValue) = VT_NULL; + needs_free = FALSE; + } + } + + if(stringify && This->dom_element) { nsAString_InitDepend(&name_str, strAttributeName); nsres = nsIDOMElement_SetAttribute(This->dom_element, &name_str, &value_str); nsAString_Finish(&name_str); - nsAString_Finish(&value_str); if(NS_FAILED(nsres)) WARN("SetAttribute failed: %08x\n", nsres); - return map_nsresult(nsres); + hres = map_nsresult(nsres); + goto done; }
hres = IDispatchEx_GetDispID(&This->node.event_target.dispex.IDispatchEx_iface, strAttributeName, (lFlags&ATTRFLAG_CASESENSITIVE ? fdexNameCaseSensitive : fdexNameCaseInsensitive) | fdexNameEnsure, &dispid); if(FAILED(hres)) - return hres; + goto done; + + hres = set_elem_attr_value_by_dispid(This, dispid, &AttributeValue);
- return set_elem_attr_value_by_dispid(This, dispid, &AttributeValue); +done: + if(stringify) + nsAString_Finish(&value_str); + if(needs_free) + SysFreeString(V_BSTR(&AttributeValue)); + return hres; }
HRESULT get_elem_attr_value_by_dispid(HTMLElement *elem, DISPID dispid, VARIANT *ret) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 66cd10a..3f04c62 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -1016,6 +1016,7 @@ HRESULT variant_to_nsstr(VARIANT*,DWORD,nsAString*) DECLSPEC_HIDDEN; HRESULT return_nsform(nsresult,nsIDOMHTMLFormElement*,IHTMLFormElement**) DECLSPEC_HIDDEN;
#define VARIANT_TO_NSSTR_HEX_INT 0x01 +#define VARIANT_TO_NSSTR_BSTR_DEPEND 0x02
nsICommandParams *create_nscommand_params(void) DECLSPEC_HIDDEN; HRESULT nsnode_to_nsstring(nsIDOMNode*,nsAString*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 18056e7..10d8bcf 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -1012,6 +1012,13 @@ HRESULT variant_to_nsstr(VARIANT *v, DWORD flags, nsAString *nsstr)
case VT_I4: wsprintfW(buf, (flags & VARIANT_TO_NSSTR_HEX_INT) ? L"#%06x" : L"%d", V_I4(v)); + if(flags & VARIANT_TO_NSSTR_BSTR_DEPEND) { + BSTR bstr = SysAllocString(buf); + if(!bstr) + return E_OUTOFMEMORY; + nsAString_InitDepend(nsstr, bstr); + break; + } nsAString_Init(nsstr, buf); break;
@@ -1022,6 +1029,10 @@ HRESULT variant_to_nsstr(VARIANT *v, DWORD flags, nsAString *nsstr) if(FAILED(hres)) return hres;
+ if(flags & VARIANT_TO_NSSTR_BSTR_DEPEND) { + nsAString_InitDepend(nsstr, V_BSTR(&var)); + break; + } nsAString_Init(nsstr, V_BSTR(&var)); SysFreeString(V_BSTR(&var)); break; @@ -1040,11 +1051,22 @@ HRESULT variant_to_nsstr(VARIANT *v, DWORD flags, nsAString *nsstr) return hres;
if(V_VT(&var) == VT_BSTR) { + if(flags & VARIANT_TO_NSSTR_BSTR_DEPEND) { + nsAString_InitDepend(nsstr, V_BSTR(&var)); + break; + } nsAString_Init(nsstr, V_BSTR(&var)); SysFreeString(V_BSTR(&var)); break; } if(V_VT(&var) == (VT_BSTR | VT_BYREF)) { + if(flags & VARIANT_TO_NSSTR_BSTR_DEPEND) { + BSTR bstr = SysAllocString(*V_BSTRREF(&var)); + if(!bstr) + return E_OUTOFMEMORY; + nsAString_InitDepend(nsstr, bstr); + break; + } nsAString_Init(nsstr, *V_BSTRREF(&var)); break; }