diff --git a/dlls/mshtml/htmltable.c b/dlls/mshtml/htmltable.c index 08a0bf046bd..fd7c2653278 100644 --- a/dlls/mshtml/htmltable.c +++ b/dlls/mshtml/htmltable.c @@ -57,6 +57,57 @@ static inline HTMLTable *impl_from_IHTMLTable3(IHTMLTable3 *iface) return CONTAINING_RECORD(iface, HTMLTable, IHTMLTable3_iface); } +static HRESULT var2str(const VARIANT *p, nsAString *nsstr) +{ + BSTR str; + BOOL ret; + HRESULT hres; + + switch(V_VT(p)) { + case VT_BSTR: + return nsAString_Init(nsstr, V_BSTR(p))? + S_OK : E_OUTOFMEMORY; + case VT_R8: + hres = VarBstrFromR8(V_R8(p), 0, 0, &str); + break; + case VT_R4: + hres = VarBstrFromR4(V_R4(p), 0, 0, &str); + break; + case VT_I4: + hres = VarBstrFromI4(V_I4(p), 0, 0, &str); + break; + default: + FIXME("unsupported arg %s\n", debugstr_variant(p)); + return E_NOTIMPL; + } + if (FAILED(hres)) + return hres; + + ret = nsAString_Init(nsstr, str); + SysFreeString(str); + return ret ? S_OK : E_OUTOFMEMORY; +} + +static HRESULT nsstr_to_truncated_bstr(const nsAString *nsstr, BSTR *ret_ptr) +{ + const PRUnichar *str, *ptr, *end = NULL; + BSTR ret; + + nsAString_GetData(nsstr, &str); + + for(ptr = str; isdigitW(*ptr); ptr++); + if(*ptr == '.') { + for(end = ptr++; isdigitW(*ptr); ptr++); + if(*ptr) + end = NULL; + } + + ret = end ? SysAllocStringLen(str, end-str) : SysAllocString(str); + + *ret_ptr = ret; + return ret ? S_OK : E_OUTOFMEMORY; +} + static HRESULT WINAPI HTMLTable_QueryInterface(IHTMLTable *iface, REFIID riid, void **ppv) { @@ -395,15 +446,52 @@ static HRESULT WINAPI HTMLTable_get_rows(IHTMLTable *iface, IHTMLElementCollecti static HRESULT WINAPI HTMLTable_put_width(IHTMLTable *iface, VARIANT v) { HTMLTable *This = impl_from_IHTMLTable(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; + nsAString val; + HRESULT hres; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + hres = var2str(&v, &val); + + if (FAILED(hres)){ + ERR("Set Width(%s) failed when initializing a nsAString, err = %08x\n", + debugstr_variant(&v), hres); + return hres; + } + + nsres = nsIDOMHTMLTableElement_SetWidth(This->nstable, &val); + nsAString_Finish(&val); + + if (NS_FAILED(nsres)){ + ERR("Set Width(%s) failed, err = %08x\n", debugstr_variant(&v), nsres); + return E_FAIL; + } + return S_OK; } static HRESULT WINAPI HTMLTable_get_width(IHTMLTable *iface, VARIANT *p) { HTMLTable *This = impl_from_IHTMLTable(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString val; + BSTR bstr; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + nsAString_Init(&val, NULL); + nsres = nsIDOMHTMLTableElement_GetWidth(This->nstable, &val); + if (NS_FAILED(nsres)){ + ERR("Get Width failed!\n"); + nsAString_Finish(&val); + return E_FAIL; + } + + hres = nsstr_to_truncated_bstr(&val, &bstr); + nsAString_Finish(&val); + + V_VT(p) = VT_BSTR; + V_BSTR(p) = bstr; + return hres; } static HRESULT WINAPI HTMLTable_put_height(IHTMLTable *iface, VARIANT v) diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index b863ac20ee8..02e0d00c42b 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -5916,6 +5916,54 @@ static void test_table_elem(IHTMLElement *elem) ok(hres == S_OK, "put_bgColor failed: %08x\n", hres); VariantClear(&vDefaultbg); + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("11"); + hres = IHTMLTable_put_width(table, v); + ok(hres == S_OK, "put_width = %08x\n", hres); + VariantClear(&v); + IHTMLTable_get_width(table, &v); + ok(hres == S_OK, "get_width = %08x\n", hres); + ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("11.9"); + hres = IHTMLTable_put_width(table, v); + ok(hres == S_OK, "put_width = %08x\n", hres); + VariantClear(&v); + IHTMLTable_get_width(table, &v); + ok(hres == S_OK, "get_width = %08x\n", hres); + ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + V_VT(&v) = VT_BSTR; + V_BSTR(&v) = a2bstr("40.2%"); + hres = IHTMLTable_put_width(table, v); + ok(hres == S_OK, "put_width = %08x\n", hres); + VariantClear(&v); + IHTMLTable_get_width(table, &v); + ok(hres == S_OK, "get_width = %08x\n", hres); + ok(!strcmp_wa(V_BSTR(&v), "40.2%"), "Expected 40.2%%, got %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + V_VT(&v) = VT_I4; + V_I4(&v) = 11; + hres = IHTMLTable_put_width(table, v); + ok(hres == S_OK, "put_width = %08x\n", hres); + IHTMLTable_get_width(table, &v); + ok(hres == S_OK, "get_width = %08x\n", hres); + ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + V_VT(&v) = VT_R8; + V_R8(&v) = 11.9; + hres = IHTMLTable_put_width(table, v); + ok(hres == S_OK, "put_width = %08x\n", hres); + IHTMLTable_get_width(table, &v); + ok(hres == S_OK, "get_width = %08x\n", hres); + ok(!strcmp_wa(V_BSTR(&v), "11"), "Expected 11, got %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + IHTMLTable_Release(table); }