diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c
index bd0f6a29d2..d5446c6a7b 100644
--- a/dlls/mshtml/htmlattr.c
+++ b/dlls/mshtml/htmlattr.c
@@ -80,7 +80,6 @@ static ULONG WINAPI HTMLDOMAttribute_Release(IHTMLDOMAttribute *iface)
if(!ref) {
assert(!This->elem);
- nsIDOMAttr_Release(This->nsattr);
release_dispex(&This->dispex);
heap_free(This);
}
@@ -136,27 +135,19 @@ static HRESULT WINAPI HTMLDOMAttribute_put_nodeName(IHTMLDOMAttribute *iface, VA
static HRESULT WINAPI HTMLDOMAttribute_get_nodeValue(IHTMLDOMAttribute *iface, VARIANT *p)
{
HTMLDOMAttribute *This = impl_from_IHTMLDOMAttribute(iface);
- const PRUnichar *val;
- nsAString val_str;
- HRESULT hres = S_OK;
+ DISPPARAMS dp = {NULL, NULL, 0, 0};
+ EXCEPINFO ei;
TRACE("(%p)->(%p)\n", This, p);
- nsAString_Init(&val_str, NULL);
- nsIDOMAttr_GetNodeValue(This->nsattr, &val_str);
- nsAString_GetData(&val_str, &val);
-
- V_VT(p) = VT_BSTR;
- if(*val) {
- V_BSTR(p) = SysAllocString(val);
- if(!V_BSTR(p))
- hres = E_OUTOFMEMORY;
- }else {
- V_BSTR(p) = NULL;
+ if(!This->elem) {
+ FIXME("NULL This->elem\n");
+ return E_UNEXPECTED;
}
- nsAString_Finish(&val_str);
- return hres;
+ memset(&ei, 0, sizeof(ei));
+ return IDispatchEx_InvokeEx(&This->elem->node.dispex.IDispatchEx_iface, This->dispid, LOCALE_SYSTEM_DEFAULT,
+ DISPATCH_PROPERTYGET, &dp, p, &ei, NULL);
}
static HRESULT WINAPI HTMLDOMAttribute_get_specified(IHTMLDOMAttribute *iface, VARIANT_BOOL *p)
@@ -191,7 +182,7 @@ static dispex_static_data_t HTMLDOMAttribute_dispex = {
HTMLDOMAttribute_iface_tids
};
-HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, nsIDOMAttr *nsattr, HTMLDOMAttribute **attr)
+HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, DISPID dispid, HTMLDOMAttribute **attr)
{
HTMLDOMAttribute *ret;
@@ -202,9 +193,7 @@ HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, nsIDOMAttr *nsattr, HTMLDOMAt
ret->IHTMLDOMAttribute_iface.lpVtbl = &HTMLDOMAttributeVtbl;
ret->ref = 1;
- nsIDOMAttr_AddRef(nsattr);
- ret->nsattr = nsattr;
-
+ ret->dispid = dispid;
ret->elem = elem;
list_add_tail(&elem->attrs, &ret->entry);
diff --git a/dlls/mshtml/htmlelem3.c b/dlls/mshtml/htmlelem3.c
index 02015e57a2..b23c5adfcc 100644
--- a/dlls/mshtml/htmlelem3.c
+++ b/dlls/mshtml/htmlelem3.c
@@ -557,43 +557,88 @@ static HRESULT WINAPI HTMLElement4_normalize(IHTMLElement4 *iface)
return E_NOTIMPL;
}
+/* FIXME: This should be done in IDispatchEx implementation layer */
+static BOOL get_attr_from_nselem(HTMLElement *This, BSTR name, DISPID *dispid)
+{
+ const PRUnichar *v;
+ nsIDOMAttr *nsattr;
+ nsAString nsstr;
+ BSTR val = NULL;
+ nsresult nsres;
+ HRESULT hres;
+
+ nsAString_InitDepend(&nsstr, name);
+ nsres = nsIDOMHTMLElement_GetAttributeNode(This->nselem, &nsstr, &nsattr);
+ nsAString_Finish(&nsstr);
+ if(NS_FAILED(nsres) || !nsattr)
+ return FALSE;
+
+ FIXME("HACK\n");
+
+ nsAString_Init(&nsstr, NULL);
+ nsres = nsIDOMAttr_GetNodeValue(nsattr, &nsstr);
+ if(NS_FAILED(nsres)) {
+ nsAString_Finish(&nsstr);
+ return FALSE;
+ }
+
+ nsAString_GetData(&nsstr, &v);
+ if(*v) {
+ val = SysAllocString(v);
+ if(!val) {
+ nsAString_Finish(&nsstr);
+ return FALSE;
+ }
+ }
+ nsAString_Finish(&nsstr);
+
+ hres = IDispatchEx_GetDispID(&This->node.dispex.IDispatchEx_iface, name, fdexNameEnsure, dispid);
+ if(SUCCEEDED(hres)) {
+ VARIANT arg;
+ DISPPARAMS dp = {&arg, NULL, 1, 0};
+ EXCEPINFO ei;
+
+ V_VT(&arg) = VT_BSTR;
+ V_BSTR(&arg) = val;
+ memset(&ei, 0, sizeof(ei));
+ hres = IDispatchEx_InvokeEx(&This->node.dispex.IDispatchEx_iface, *dispid,
+ LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
+ }
+
+ SysFreeString(val);
+ return SUCCEEDED(hres);
+}
+
static HRESULT WINAPI HTMLElement4_getAttributeNode(IHTMLElement4 *iface, BSTR bstrname, IHTMLDOMAttribute **ppAttribute)
{
HTMLElement *This = impl_from_IHTMLElement4(iface);
HTMLDOMAttribute *attr = NULL, *iter;
- nsAString name_str;
- nsIDOMAttr *nsattr;
- nsresult nsres;
+ DISPID dispid;
HRESULT hres;
TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrname), ppAttribute);
- nsAString_InitDepend(&name_str, bstrname);
- nsres = nsIDOMHTMLElement_GetAttributeNode(This->nselem, &name_str, &nsattr);
- nsAString_Finish(&name_str);
- if(NS_FAILED(nsres)) {
- ERR("GetAttributeNode failed: %08x\n", nsres);
- return E_FAIL;
- }
-
- if(!nsattr) {
- *ppAttribute = NULL;
- return S_OK;
+ hres = IDispatchEx_GetDispID(&This->node.dispex.IDispatchEx_iface, bstrname, fdexNameCaseInsensitive, &dispid);
+ if(hres == DISP_E_UNKNOWNNAME) {
+ if(!get_attr_from_nselem(This, bstrname, &dispid)) {
+ *ppAttribute = NULL;
+ return S_OK;
+ }
+ }else if(FAILED(hres)) {
+ return hres;
}
LIST_FOR_EACH_ENTRY(iter, &This->attrs, HTMLDOMAttribute, entry) {
- if(iter->nsattr == nsattr) {
+ if(iter->dispid == dispid) {
attr = iter;
break;
}
}
if(!attr) {
- hres = HTMLDOMAttribute_Create(This, nsattr, &attr);
- if(FAILED(hres)) {
- nsIDOMAttr_Release(nsattr);
+ hres = HTMLDOMAttribute_Create(This, dispid, &attr);
+ if(FAILED(hres))
return hres;
- }
}
IHTMLDOMAttribute_AddRef(&attr->IHTMLDOMAttribute_iface);
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index b39ad75ad2..11ab878844 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -749,13 +749,13 @@ typedef struct {
IHTMLDOMAttribute IHTMLDOMAttribute_iface;
LONG ref;
- nsIDOMAttr *nsattr;
+ DISPID dispid;
HTMLElement *elem;
struct list entry;
} HTMLDOMAttribute;
-HRESULT HTMLDOMAttribute_Create(HTMLElement*,nsIDOMAttr*,HTMLDOMAttribute**);
+HRESULT HTMLDOMAttribute_Create(HTMLElement*,DISPID,HTMLDOMAttribute**);
HRESULT HTMLElement_Create(HTMLDocumentNode*,nsIDOMNode*,BOOL,HTMLElement**);
HRESULT HTMLCommentElement_Create(HTMLDocumentNode*,nsIDOMNode*,HTMLElement**);