Andrew Eikum : mshtml: Reimplement IHTMLElement::{get, set}Attribute using IDispatchEx.
Alexandre Julliard
julliard at winehq.org
Tue Sep 22 13:56:37 CDT 2009
Module: wine
Branch: master
Commit: 98fcf442dc3b476998cd5ed8e7489e580161b661
URL: http://source.winehq.org/git/wine.git/?a=commit;h=98fcf442dc3b476998cd5ed8e7489e580161b661
Author: Andrew Eikum <aeikum at 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()) {
More information about the wine-cvs
mailing list