diff --git a/dlls/mshtml/htmlattr.c b/dlls/mshtml/htmlattr.c
index 5d4c2b46dea..4c4d8a456a0 100644
--- a/dlls/mshtml/htmlattr.c
+++ b/dlls/mshtml/htmlattr.c
@@ -81,6 +81,7 @@ static ULONG WINAPI HTMLDOMAttribute_Release(IHTMLDOMAttribute *iface)
if(!ref) {
assert(!This->elem);
release_dispex(&This->dispex);
+ heap_free(This->name);
heap_free(This);
}
@@ -124,6 +125,11 @@ static HRESULT WINAPI HTMLDOMAttribute_get_nodeName(IHTMLDOMAttribute *iface, BS
TRACE("(%p)->(%p)\n", This, p);
+ if(!This->elem) {
+ FIXME("NULL This->elem\n");
+ return E_UNEXPECTED;
+ }
+
return IDispatchEx_GetMemberName(&This->elem->node.dispex.IDispatchEx_iface, This->dispid, p);
}
@@ -163,16 +169,16 @@ static HRESULT WINAPI HTMLDOMAttribute_get_specified(IHTMLDOMAttribute *iface, V
TRACE("(%p)->(%p)\n", This, p);
- if(get_dispid_type(This->dispid) != DISPEXPROP_BUILTIN) {
- *p = VARIANT_TRUE;
- return S_OK;
- }
-
if(!This->elem || !This->elem->nselem) {
FIXME("NULL This->elem\n");
return E_UNEXPECTED;
}
+ if(get_dispid_type(This->dispid) != DISPEXPROP_BUILTIN) {
+ *p = VARIANT_TRUE;
+ return S_OK;
+ }
+
hres = IDispatchEx_GetMemberName(&This->elem->node.dispex.IDispatchEx_iface, This->dispid, &name);
if(FAILED(hres))
return hres;
@@ -221,7 +227,7 @@ static dispex_static_data_t HTMLDOMAttribute_dispex = {
HTMLDOMAttribute_iface_tids
};
-HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, DISPID dispid, HTMLDOMAttribute **attr)
+HRESULT HTMLDOMAttribute_Create(const WCHAR *name, HTMLElement *elem, DISPID dispid, HTMLDOMAttribute **attr)
{
HTMLAttributeCollection *col;
HTMLDOMAttribute *ret;
@@ -231,23 +237,35 @@ HRESULT HTMLDOMAttribute_Create(HTMLElement *elem, DISPID dispid, HTMLDOMAttribu
if(!ret)
return E_OUTOFMEMORY;
- hres = HTMLElement_get_attr_col(&elem->node, &col);
- if(FAILED(hres)) {
- heap_free(ret);
- return hres;
- }
- IHTMLAttributeCollection_Release(&col->IHTMLAttributeCollection_iface);
-
ret->IHTMLDOMAttribute_iface.lpVtbl = &HTMLDOMAttributeVtbl;
ret->ref = 1;
-
ret->dispid = dispid;
ret->elem = elem;
- list_add_tail(&elem->attrs->attrs, &ret->entry);
init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLDOMAttribute_iface,
&HTMLDOMAttribute_dispex);
+ /* For attributes attached to an element, (elem,dispid) pair should be valid used for its operation. */
+ if(elem) {
+ hres = HTMLElement_get_attr_col(&elem->node, &col);
+ if(FAILED(hres)) {
+ IHTMLDOMAttribute_Release(&ret->IHTMLDOMAttribute_iface);
+ return hres;
+ }
+ IHTMLAttributeCollection_Release(&col->IHTMLAttributeCollection_iface);
+
+ list_add_tail(&elem->attrs->attrs, &ret->entry);
+ }
+
+ /* For detached attributes we may still do most operations if we have its name available. */
+ if(name) {
+ ret->name = heap_strdupW(name);
+ if(!ret->name) {
+ IHTMLDOMAttribute_Release(&ret->IHTMLDOMAttribute_iface);
+ return E_OUTOFMEMORY;
+ }
+ }
+
*attr = ret;
return S_OK;
}
diff --git a/dlls/mshtml/htmldoc5.c b/dlls/mshtml/htmldoc5.c
index edf81090924..8871934309a 100644
--- a/dlls/mshtml/htmldoc5.c
+++ b/dlls/mshtml/htmldoc5.c
@@ -120,8 +120,17 @@ static HRESULT WINAPI HTMLDocument5_createAttribute(IHTMLDocument5 *iface, BSTR
IHTMLDOMAttribute **ppattribute)
{
HTMLDocument *This = impl_from_IHTMLDocument5(iface);
- FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrattrName), ppattribute);
- return E_NOTIMPL;
+ HTMLDOMAttribute *attr;
+ HRESULT hres;
+
+ TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrattrName), ppattribute);
+
+ hres = HTMLDOMAttribute_Create(bstrattrName, NULL, 0, &attr);
+ if(FAILED(hres))
+ return hres;
+
+ *ppattribute = &attr->IHTMLDOMAttribute_iface;
+ return S_OK;
}
static HRESULT WINAPI HTMLDocument5_createComment(IHTMLDocument5 *iface, BSTR bstrdata,
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index 6867a1733ad..82399738b31 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -2246,7 +2246,7 @@ static inline HRESULT get_domattr(HTMLAttributeCollection *This, DISPID id, LONG
return E_UNEXPECTED;
}
- hres = HTMLDOMAttribute_Create(This->elem, id, attr);
+ hres = HTMLDOMAttribute_Create(NULL, This->elem, id, attr);
if(FAILED(hres))
return hres;
}
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 75200c445e3..38aaa242ae3 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -852,12 +852,14 @@ typedef struct {
LONG ref;
- DISPID dispid;
+ WCHAR *name;
+
HTMLElement *elem;
+ DISPID dispid;
struct list entry;
} HTMLDOMAttribute;
-HRESULT HTMLDOMAttribute_Create(HTMLElement*,DISPID,HTMLDOMAttribute**) DECLSPEC_HIDDEN;
+HRESULT HTMLDOMAttribute_Create(const WCHAR*,HTMLElement*,DISPID,HTMLDOMAttribute**) DECLSPEC_HIDDEN;
HRESULT HTMLElement_Create(HTMLDocumentNode*,nsIDOMNode*,BOOL,HTMLElement**) DECLSPEC_HIDDEN;
HRESULT HTMLCommentElement_Create(HTMLDocumentNode*,nsIDOMNode*,HTMLElement**) DECLSPEC_HIDDEN;