Module: wine Branch: master Commit: 98fcf442dc3b476998cd5ed8e7489e580161b661 URL: http://source.winehq.org/git/wine.git/?a=commit;h=98fcf442dc3b476998cd5ed8e7...
Author: Andrew Eikum aeikum@codeweavers.com Date: Mon Sep 21 12:29:55 2009 -0500
mshtml: Reimplement IHTMLElement::{get, set}Attribute using IDispatchEx.
---
dlls/mshtml/htmlelem.c | 105 ++++++++++++---------------------------------- dlls/mshtml/tests/dom.c | 75 +++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 77 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index ad4f370..1fde2e9 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -96,44 +96,26 @@ static HRESULT WINAPI HTMLElement_setAttribute(IHTMLElement *iface, BSTR strAttr VARIANT AttributeValue, LONG lFlags) { HTMLElement *This = HTMLELEM_THIS(iface); - nsAString attr_str; - nsAString value_str; - nsresult nsres; HRESULT hres; - VARIANT AttributeValueChanged; - - WARN("(%p)->(%s . %08x)\n", This, debugstr_w(strAttributeName), lFlags); - - if(!This->nselem) { - FIXME("NULL nselem\n"); - return E_NOTIMPL; - } + DISPID dispid, dispidNamed = DISPID_PROPERTYPUT; + DISPPARAMS dispParams; + EXCEPINFO excep;
- VariantInit(&AttributeValueChanged); + TRACE("(%p)->(%s . %08x)\n", This, debugstr_w(strAttributeName), lFlags);
- hres = VariantChangeType(&AttributeValueChanged, &AttributeValue, 0, VT_BSTR); - if (FAILED(hres)) { - WARN("couldn't convert input attribute value %d to VT_BSTR\n", V_VT(&AttributeValue)); + hres = IDispatchEx_GetDispID(DISPATCHEX(&This->node.dispex), strAttributeName, + fdexNameCaseInsensitive | fdexNameEnsure, &dispid); + if(FAILED(hres)) return hres; - } - - nsAString_Init(&attr_str, strAttributeName); - nsAString_Init(&value_str, V_BSTR(&AttributeValueChanged)); - - TRACE("setting %s to %s\n", debugstr_w(strAttributeName), - debugstr_w(V_BSTR(&AttributeValueChanged))); - - nsres = nsIDOMHTMLElement_SetAttribute(This->nselem, &attr_str, &value_str); - nsAString_Finish(&attr_str); - nsAString_Finish(&value_str);
- if(NS_SUCCEEDED(nsres)) { - hres = S_OK; - }else { - ERR("SetAttribute failed: %08x\n", nsres); - hres = E_FAIL; - } + dispParams.cArgs = 1; + dispParams.cNamedArgs = 1; + dispParams.rgdispidNamedArgs = &dispidNamed; + dispParams.rgvarg = &AttributeValue;
+ hres = IDispatchEx_InvokeEx(DISPATCHEX(&This->node.dispex), dispid, + LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dispParams, + NULL, &excep, NULL); return hres; }
@@ -141,59 +123,28 @@ static HRESULT WINAPI HTMLElement_getAttribute(IHTMLElement *iface, BSTR strAttr LONG lFlags, VARIANT *AttributeValue) { HTMLElement *This = HTMLELEM_THIS(iface); - nsAString attr_str; - nsAString value_str; - const PRUnichar *value; - nsresult nsres; - HRESULT hres = S_OK; + DISPID dispid; + HRESULT hres; + DISPPARAMS dispParams = {NULL, NULL, 0, 0}; + EXCEPINFO excep;
- WARN("(%p)->(%s %08x %p)\n", This, debugstr_w(strAttributeName), lFlags, AttributeValue); + TRACE("(%p)->(%s %08x %p)\n", This, debugstr_w(strAttributeName), lFlags, AttributeValue);
- if(!This->nselem) { - FIXME("NULL nselem\n"); + hres = IDispatchEx_GetDispID(DISPATCHEX(&This->node.dispex), strAttributeName, + fdexNameCaseInsensitive, &dispid); + if(hres == DISP_E_UNKNOWNNAME) { V_VT(AttributeValue) = VT_NULL; return S_OK; }
- V_VT(AttributeValue) = VT_NULL; - - nsAString_Init(&attr_str, strAttributeName); - nsAString_Init(&value_str, NULL); - - nsres = nsIDOMHTMLElement_GetAttribute(This->nselem, &attr_str, &value_str); - nsAString_Finish(&attr_str); - - if(NS_SUCCEEDED(nsres)) { - static const WCHAR wszSRC[] = {'s','r','c',0}; - nsAString_GetData(&value_str, &value); - if(!strcmpiW(strAttributeName, wszSRC)) - { - WCHAR buffer[256]; - DWORD len; - BSTR bstrBaseUrl; - hres = IHTMLDocument2_get_URL(HTMLDOC(&This->node.doc->basedoc), &bstrBaseUrl); - if(SUCCEEDED(hres)) { - hres = CoInternetCombineUrl(bstrBaseUrl, value, - URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, - buffer, sizeof(buffer)/sizeof(WCHAR), &len, 0); - SysFreeString(bstrBaseUrl); - if(SUCCEEDED(hres)) { - V_VT(AttributeValue) = VT_BSTR; - V_BSTR(AttributeValue) = SysAllocString(buffer); - TRACE("attr_value=%s\n", debugstr_w(V_BSTR(AttributeValue))); - } - } - }else if(*value) { - V_VT(AttributeValue) = VT_BSTR; - V_BSTR(AttributeValue) = SysAllocString(value); - TRACE("attr_value=%s\n", debugstr_w(V_BSTR(AttributeValue))); - } - }else { - ERR("GetAttribute failed: %08x\n", nsres); - hres = E_FAIL; + if(FAILED(hres)) { + V_VT(AttributeValue) = VT_NULL; + return hres; }
- nsAString_Finish(&value_str); + hres = IDispatchEx_InvokeEx(DISPATCHEX(&This->node.dispex), dispid, + LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, + AttributeValue, &excep, NULL);
return hres; } diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 604ead5..b489ce0 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -804,6 +804,80 @@ static void test_doc_elem(IHTMLDocument2 *doc) IHTMLElement_Release(elem); }
+static void test_get_set_attr(IHTMLDocument2 *doc) +{ + IHTMLElement *elem; + IHTMLDocument3 *doc3; + HRESULT hres; + BSTR bstr; + VARIANT val; + + /* grab an element to test with */ + hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3); + ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument3) failed: %08x\n", hres); + + hres = IHTMLDocument3_get_documentElement(doc3, &elem); + IHTMLDocument3_Release(doc3); + ok(hres == S_OK, "get_documentElement failed: %08x\n", hres); + + /* get a non-present attribute */ + bstr = a2bstr("notAnAttribute"); + hres = IHTMLElement_getAttribute(elem, bstr, 0, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + ok(V_VT(&val) == VT_NULL, "variant type should have been VT_NULL (0x%x), was: 0x%x\n", VT_NULL, V_VT(&val)); + VariantClear(&val); + SysFreeString(bstr); + + /* get a present attribute */ + bstr = a2bstr("scrollHeight"); + hres = IHTMLElement_getAttribute(elem, bstr, 0, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + ok(V_VT(&val) == VT_I4, "variant type should have been VT_I4 (0x%x), was: 0x%x\n", VT_I4, V_VT(&val)); + VariantClear(&val); + SysFreeString(bstr); + + /* create a new BSTR attribute */ + bstr = a2bstr("newAttribute"); + + V_VT(&val) = VT_BSTR; + V_BSTR(&val) = a2bstr("the value"); + hres = IHTMLElement_setAttribute(elem, bstr, val, 0); + ok(hres == S_OK, "setAttribute failed: %08x\n", hres); + VariantClear(&val); + + hres = IHTMLElement_getAttribute(elem, bstr, 0, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + ok(V_VT(&val) == VT_BSTR, "variant type should have been VT_BSTR (0x%x), was: 0x%x\n", VT_BSTR, V_VT(&val)); + ok(strcmp_wa(V_BSTR(&val), "the value") == 0, "variant value should have been L"the value", was %s\n", wine_dbgstr_w(V_BSTR(&val))); + VariantClear(&val); + + /* overwrite the attribute with a BOOL */ + V_VT(&val) = VT_BOOL; + V_BOOL(&val) = VARIANT_TRUE; + hres = IHTMLElement_setAttribute(elem, bstr, val, 0); + ok(hres == S_OK, "setAttribute failed: %08x\n", hres); + VariantClear(&val); + + hres = IHTMLElement_getAttribute(elem, bstr, 0, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val)); + ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val)); + VariantClear(&val); + + SysFreeString(bstr); + + /* case-insensitive */ + bstr = a2bstr("newattribute"); + hres = IHTMLElement_getAttribute(elem, bstr, 0, &val); + ok(hres == S_OK, "getAttribute failed: %08x\n", hres); + todo_wine ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val)); + todo_wine ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val)); + VariantClear(&val); + SysFreeString(bstr); + + IHTMLElement_Release(elem); +} + #define get_doc_elem(d) _get_doc_elem(__LINE__,d) static IHTMLElement *_get_doc_elem(unsigned line, IHTMLDocument2 *doc) { @@ -5347,6 +5421,7 @@ START_TEST(dom) CoInitialize(NULL);
run_domtest(doc_str1, test_doc_elem); + run_domtest(doc_str1, test_get_set_attr); run_domtest(range_test_str, test_txtrange); run_domtest(range_test2_str, test_txtrange2); if (winetest_interactive || ! is_ie_hardened()) {