From bea3154f48f97f866b1083e6f4421055244b8b83 Mon Sep 17 00:00:00 2001
From: Piotr Caban <piotr@codeweavers.com>
Date: Thu, 25 Aug 2011 15:23:35 +0200
Subject: [PATCH] mshtml: Added IHTMLAttributeCollection stub.

---
 dlls/mshtml/htmlanchor.c     |   1 +
 dlls/mshtml/htmlbody.c       |   1 +
 dlls/mshtml/htmlcomment.c    |   3 +-
 dlls/mshtml/htmlelem.c       | 190 ++++++++++++++++++++++++++++++++++-
 dlls/mshtml/htmlembed.c      |   3 +-
 dlls/mshtml/htmlform.c       |   1 +
 dlls/mshtml/htmlframe.c      |   1 +
 dlls/mshtml/htmlgeneric.c    |   3 +-
 dlls/mshtml/htmlhead.c       |   4 +-
 dlls/mshtml/htmliframe.c     |   1 +
 dlls/mshtml/htmlimg.c        |   1 +
 dlls/mshtml/htmlinput.c      |   1 +
 dlls/mshtml/htmlnode.c       |  18 +++-
 dlls/mshtml/htmlobject.c     |   1 +
 dlls/mshtml/htmloption.c     |   3 +-
 dlls/mshtml/htmlscript.c     |   1 +
 dlls/mshtml/htmlselect.c     |   1 +
 dlls/mshtml/htmlstyleelem.c  |   3 +-
 dlls/mshtml/htmltable.c      |   1 +
 dlls/mshtml/htmltablerow.c   |   3 +-
 dlls/mshtml/htmltextarea.c   |   1 +
 dlls/mshtml/mshtml_private.h |  21 ++++
 22 files changed, 253 insertions(+), 10 deletions(-)

diff --git a/dlls/mshtml/htmlanchor.c b/dlls/mshtml/htmlanchor.c
index 7422de7847a..a1dc8c35ff6 100644
--- a/dlls/mshtml/htmlanchor.c
+++ b/dlls/mshtml/htmlanchor.c
@@ -598,6 +598,7 @@ static const NodeImplVtbl HTMLAnchorElementImplVtbl = {
     HTMLAnchorElement_QI,
     HTMLAnchorElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     NULL,
     NULL,
     HTMLAnchorElement_handle_event
diff --git a/dlls/mshtml/htmlbody.c b/dlls/mshtml/htmlbody.c
index cbc9abf24dc..bb3e85bd108 100644
--- a/dlls/mshtml/htmlbody.c
+++ b/dlls/mshtml/htmlbody.c
@@ -786,6 +786,7 @@ static const NodeImplVtbl HTMLBodyElementImplVtbl = {
     HTMLBodyElement_QI,
     HTMLBodyElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     HTMLBodyElement_get_event_target
 };
 
diff --git a/dlls/mshtml/htmlcomment.c b/dlls/mshtml/htmlcomment.c
index e97127e71a0..525f0dbf7f7 100644
--- a/dlls/mshtml/htmlcomment.c
+++ b/dlls/mshtml/htmlcomment.c
@@ -172,7 +172,8 @@ static void HTMLCommentElement_destructor(HTMLDOMNode *iface)
 static const NodeImplVtbl HTMLCommentElementImplVtbl = {
     HTMLCommentElement_QI,
     HTMLCommentElement_destructor,
-    HTMLElement_clone
+    HTMLElement_clone,
+    HTMLElement_get_attr_col
 };
 
 static const tid_t HTMLCommentElement_iface_tids[] = {
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index bb0ac99adc2..5f77e6804e8 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -1731,7 +1731,8 @@ HRESULT HTMLElement_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode **
 static const NodeImplVtbl HTMLElementImplVtbl = {
     HTMLElement_QI,
     HTMLElement_destructor,
-    HTMLElement_clone
+    HTMLElement_clone,
+    HTMLElement_get_attr_col
 };
 
 static inline HTMLElement *impl_from_DispatchEx(DispatchEx *iface)
@@ -2113,3 +2114,190 @@ static IHTMLFiltersCollection *HTMLFiltersCollection_Create(void)
 
     return &ret->IHTMLFiltersCollection_iface;
 }
+
+/* interface IHTMLAttributeCollection */
+static inline HTMLAttributeCollection *impl_from_IHTMLAttributeCollection(IHTMLAttributeCollection *iface)
+{
+    return CONTAINING_RECORD(iface, HTMLAttributeCollection, IHTMLAttributeCollection_iface);
+}
+
+static HRESULT WINAPI HTMLAttributeCollection_QueryInterface(IHTMLAttributeCollection *iface, REFIID riid, void **ppv)
+{
+    HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
+
+    *ppv = NULL;
+
+    if(IsEqualGUID(&IID_IUnknown, riid)) {
+        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
+        *ppv = &This->IHTMLAttributeCollection_iface;
+    }else if(IsEqualGUID(&IID_IHTMLAttributeCollection, riid)) {
+        TRACE("(%p)->(IID_IHTMLAttributeCollection %p)\n", This, ppv);
+        *ppv = &This->IHTMLAttributeCollection_iface;
+    }else if(IsEqualGUID(&IID_IHTMLAttributeCollection2, riid)) {
+        FIXME("(%p)->(IID_IHTMLAttributeCollection2 %p)\n", This, ppv);
+    }else if(IsEqualGUID(&IID_IHTMLAttributeCollection3, riid)) {
+        FIXME("(%p)->(IID_IHTMLAttributeCollection3 %p)\n", This, ppv);
+    }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
+        return *ppv ? S_OK : E_NOINTERFACE;
+    }
+
+    if(*ppv) {
+        IUnknown_AddRef((IUnknown*)*ppv);
+        return S_OK;
+    }
+
+    WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI HTMLAttributeCollection_AddRef(IHTMLAttributeCollection *iface)
+{
+    HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI HTMLAttributeCollection_Release(IHTMLAttributeCollection *iface)
+{
+    HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(!ref) {
+        IHTMLElement_Release(&This->elem->IHTMLElement_iface);
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI HTMLAttributeCollection_GetTypeInfoCount(IHTMLAttributeCollection *iface, UINT *pctinfo)
+{
+    HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
+    return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
+}
+
+static HRESULT WINAPI HTMLAttributeCollection_GetTypeInfo(IHTMLAttributeCollection *iface, UINT iTInfo,
+        LCID lcid, ITypeInfo **ppTInfo)
+{
+    HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
+    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
+}
+
+static HRESULT WINAPI HTMLAttributeCollection_GetIDsOfNames(IHTMLAttributeCollection *iface, REFIID riid,
+        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+    HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
+    return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
+            lcid, rgDispId);
+}
+
+static HRESULT WINAPI HTMLAttributeCollection_Invoke(IHTMLAttributeCollection *iface, DISPID dispIdMember,
+        REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
+        VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
+    return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
+            wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+}
+
+static HRESULT WINAPI HTMLAttributeCollection_get_length(IHTMLAttributeCollection *iface, LONG *p)
+{
+    HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
+    FIXME("(%p)->(%p)\n", This, p);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLAttributeCollection__newEnum(IHTMLAttributeCollection *iface, IUnknown **p)
+{
+    HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
+    FIXME("(%p)->(%p)\n", This, p);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLAttributeCollection_item(IHTMLAttributeCollection *iface, VARIANT *name, IDispatch **ppItem)
+{
+    HTMLAttributeCollection *This = impl_from_IHTMLAttributeCollection(iface);
+    FIXME("(%p)->(%s, %p)\n", This, debugstr_variant(name), ppItem);
+    return E_NOTIMPL;
+}
+
+static const IHTMLAttributeCollectionVtbl HTMLAttributeCollectionVtbl = {
+    HTMLAttributeCollection_QueryInterface,
+    HTMLAttributeCollection_AddRef,
+    HTMLAttributeCollection_Release,
+    HTMLAttributeCollection_GetTypeInfoCount,
+    HTMLAttributeCollection_GetTypeInfo,
+    HTMLAttributeCollection_GetIDsOfNames,
+    HTMLAttributeCollection_Invoke,
+    HTMLAttributeCollection_get_length,
+    HTMLAttributeCollection__newEnum,
+    HTMLAttributeCollection_item
+};
+
+static inline HTMLAttributeCollection *HTMLAttributeCollection_from_DispatchEx(DispatchEx *iface)
+{
+    return CONTAINING_RECORD(iface, HTMLAttributeCollection, dispex);
+}
+
+static HRESULT HTMLAttributeCollection_get_dispid(DispatchEx *dispex, BSTR name, DWORD flags, DISPID *dispid)
+{
+    HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex);
+    FIXME("(%p)->(%s %x %p)\n", This, debugstr_w(name), flags, dispid);
+    return E_NOTIMPL;
+}
+
+static HRESULT HTMLAttributeCollection_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
+        VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
+{
+    HTMLAttributeCollection *This = HTMLAttributeCollection_from_DispatchEx(dispex);
+    FIXME("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, flags, params, res, ei, caller);
+    return E_NOTIMPL;
+}
+
+static const dispex_static_data_vtbl_t HTMLAttributeCollection_dispex_vtbl = {
+    NULL,
+    HTMLAttributeCollection_get_dispid,
+    HTMLAttributeCollection_invoke,
+    NULL
+};
+
+static const tid_t HTMLAttributeCollection_iface_tids[] = {
+    IHTMLAttributeCollection_tid,
+    IHTMLAttributeCollection2_tid,
+    IHTMLAttributeCollection3_tid,
+    0
+};
+
+static dispex_static_data_t HTMLAttributeCollection_dispex = {
+    &HTMLAttributeCollection_dispex_vtbl,
+    DispHTMLAttributeCollection_tid,
+    NULL,
+    HTMLAttributeCollection_iface_tids
+};
+
+HRESULT HTMLElement_get_attr_col(HTMLDOMNode *iface, HTMLAttributeCollection **ac)
+{
+    HTMLElement *This = impl_from_HTMLDOMNode(iface);
+    HTMLAttributeCollection *ret;
+
+    ret = heap_alloc_zero(sizeof(*ret));
+    if(!ret)
+        return E_OUTOFMEMORY;
+
+    ret->IHTMLAttributeCollection_iface.lpVtbl = &HTMLAttributeCollectionVtbl;
+    ret->ref = 1;
+
+    IHTMLElement_AddRef(&This->IHTMLElement_iface);
+    ret->elem = This;
+
+    init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLAttributeCollection_iface,
+            &HTMLAttributeCollection_dispex);
+
+    *ac = ret;
+    return S_OK;
+}
diff --git a/dlls/mshtml/htmlembed.c b/dlls/mshtml/htmlembed.c
index aa1d2493ac6..50586901628 100644
--- a/dlls/mshtml/htmlembed.c
+++ b/dlls/mshtml/htmlembed.c
@@ -254,7 +254,8 @@ static void HTMLEmbedElement_destructor(HTMLDOMNode *iface)
 static const NodeImplVtbl HTMLEmbedElementImplVtbl = {
     HTMLEmbedElement_QI,
     HTMLEmbedElement_destructor,
-    HTMLElement_clone
+    HTMLElement_clone,
+    HTMLElement_get_attr_col
 };
 
 static const tid_t HTMLEmbedElement_iface_tids[] = {
diff --git a/dlls/mshtml/htmlform.c b/dlls/mshtml/htmlform.c
index ae84ac3a4c9..8905208153b 100644
--- a/dlls/mshtml/htmlform.c
+++ b/dlls/mshtml/htmlform.c
@@ -633,6 +633,7 @@ static const NodeImplVtbl HTMLFormElementImplVtbl = {
     HTMLFormElement_QI,
     HTMLFormElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     NULL,
     NULL,
     NULL,
diff --git a/dlls/mshtml/htmlframe.c b/dlls/mshtml/htmlframe.c
index 3b4126b664b..2663616d86b 100644
--- a/dlls/mshtml/htmlframe.c
+++ b/dlls/mshtml/htmlframe.c
@@ -270,6 +270,7 @@ static const NodeImplVtbl HTMLFrameElementImplVtbl = {
     HTMLFrameElement_QI,
     HTMLFrameElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     NULL,
     NULL,
     NULL,
diff --git a/dlls/mshtml/htmlgeneric.c b/dlls/mshtml/htmlgeneric.c
index ffa9c4122fc..703349d4fca 100644
--- a/dlls/mshtml/htmlgeneric.c
+++ b/dlls/mshtml/htmlgeneric.c
@@ -154,7 +154,8 @@ static void HTMLGenericElement_destructor(HTMLDOMNode *iface)
 static const NodeImplVtbl HTMLGenericElementImplVtbl = {
     HTMLGenericElement_QI,
     HTMLGenericElement_destructor,
-    HTMLElement_clone
+    HTMLElement_clone,
+    HTMLElement_get_attr_col
 };
 
 static const tid_t HTMLGenericElement_iface_tids[] = {
diff --git a/dlls/mshtml/htmlhead.c b/dlls/mshtml/htmlhead.c
index 69e4edfae8d..80c5e4c04ac 100644
--- a/dlls/mshtml/htmlhead.c
+++ b/dlls/mshtml/htmlhead.c
@@ -156,6 +156,7 @@ static const NodeImplVtbl HTMLTitleElementImplVtbl = {
     HTMLTitleElement_QI,
     HTMLTitleElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col
 };
 
 static const tid_t HTMLTitleElement_iface_tids[] = {
@@ -312,7 +313,8 @@ static void HTMLHeadElement_destructor(HTMLDOMNode *iface)
 static const NodeImplVtbl HTMLHeadElementImplVtbl = {
     HTMLHeadElement_QI,
     HTMLHeadElement_destructor,
-    HTMLElement_clone
+    HTMLElement_clone,
+    HTMLElement_get_attr_col
 };
 
 static const tid_t HTMLHeadElement_iface_tids[] = {
diff --git a/dlls/mshtml/htmliframe.c b/dlls/mshtml/htmliframe.c
index 8a293464b5c..3acab1eaa29 100644
--- a/dlls/mshtml/htmliframe.c
+++ b/dlls/mshtml/htmliframe.c
@@ -248,6 +248,7 @@ static const NodeImplVtbl HTMLIFrameImplVtbl = {
     HTMLIFrame_QI,
     HTMLIFrame_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     NULL,
     NULL,
     NULL,
diff --git a/dlls/mshtml/htmlimg.c b/dlls/mshtml/htmlimg.c
index c984fbd63be..0e8a6047823 100644
--- a/dlls/mshtml/htmlimg.c
+++ b/dlls/mshtml/htmlimg.c
@@ -658,6 +658,7 @@ static const NodeImplVtbl HTMLImgElementImplVtbl = {
     HTMLImgElement_QI,
     HTMLImgElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     NULL,
     NULL,
     NULL,
diff --git a/dlls/mshtml/htmlinput.c b/dlls/mshtml/htmlinput.c
index 9d197618695..65cbeab8803 100644
--- a/dlls/mshtml/htmlinput.c
+++ b/dlls/mshtml/htmlinput.c
@@ -1185,6 +1185,7 @@ static const NodeImplVtbl HTMLInputElementImplVtbl = {
     HTMLInputElement_QI,
     HTMLInputElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     NULL,
     HTMLInputElementImpl_fire_event,
     NULL,
diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c
index 7afccd6f08b..e8d6f95667f 100644
--- a/dlls/mshtml/htmlnode.c
+++ b/dlls/mshtml/htmlnode.c
@@ -472,8 +472,22 @@ static HRESULT WINAPI HTMLDOMNode_get_childNodes(IHTMLDOMNode *iface, IDispatch
 static HRESULT WINAPI HTMLDOMNode_get_attributes(IHTMLDOMNode *iface, IDispatch **p)
 {
     HTMLDOMNode *This = impl_from_IHTMLDOMNode(iface);
-    FIXME("(%p)->(%p)\n", This, p);
-    return E_NOTIMPL;
+    HTMLAttributeCollection *col;
+    HRESULT hres;
+
+    TRACE("(%p)->(%p)\n", This, p);
+
+    if(This->vtbl->get_attr_col) {
+        hres = This->vtbl->get_attr_col(This, &col);
+        if(FAILED(hres))
+            return hres;
+
+        *p = (IDispatch*)&col->IHTMLAttributeCollection_iface;
+        return S_OK;
+    }
+
+    *p = NULL;
+    return S_OK;
 }
 
 static HRESULT WINAPI HTMLDOMNode_insertBefore(IHTMLDOMNode *iface, IHTMLDOMNode *newChild,
diff --git a/dlls/mshtml/htmlobject.c b/dlls/mshtml/htmlobject.c
index 50e04a916d9..40a0de080d5 100644
--- a/dlls/mshtml/htmlobject.c
+++ b/dlls/mshtml/htmlobject.c
@@ -470,6 +470,7 @@ static const NodeImplVtbl HTMLObjectElementImplVtbl = {
     HTMLObjectElement_QI,
     HTMLObjectElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     NULL,
     NULL,
     NULL,
diff --git a/dlls/mshtml/htmloption.c b/dlls/mshtml/htmloption.c
index 9137765136e..533a914901f 100644
--- a/dlls/mshtml/htmloption.c
+++ b/dlls/mshtml/htmloption.c
@@ -343,7 +343,8 @@ static void HTMLOptionElement_destructor(HTMLDOMNode *iface)
 static const NodeImplVtbl HTMLOptionElementImplVtbl = {
     HTMLOptionElement_QI,
     HTMLOptionElement_destructor,
-    HTMLElement_clone
+    HTMLElement_clone,
+    HTMLElement_get_attr_col
 };
 
 static const tid_t HTMLOptionElement_iface_tids[] = {
diff --git a/dlls/mshtml/htmlscript.c b/dlls/mshtml/htmlscript.c
index ca0524fecdc..3418fcc379c 100644
--- a/dlls/mshtml/htmlscript.c
+++ b/dlls/mshtml/htmlscript.c
@@ -330,6 +330,7 @@ static const NodeImplVtbl HTMLScriptElementImplVtbl = {
     HTMLScriptElement_QI,
     HTMLScriptElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     NULL,
     NULL,
     NULL,
diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c
index 6d2e3935a6e..0d454486894 100644
--- a/dlls/mshtml/htmlselect.c
+++ b/dlls/mshtml/htmlselect.c
@@ -615,6 +615,7 @@ static const NodeImplVtbl HTMLSelectElementImplVtbl = {
     HTMLSelectElement_QI,
     HTMLSelectElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     NULL,
     NULL,
     NULL,
diff --git a/dlls/mshtml/htmlstyleelem.c b/dlls/mshtml/htmlstyleelem.c
index 942f422bbeb..d866db279a6 100644
--- a/dlls/mshtml/htmlstyleelem.c
+++ b/dlls/mshtml/htmlstyleelem.c
@@ -295,7 +295,8 @@ static void HTMLStyleElement_destructor(HTMLDOMNode *iface)
 static const NodeImplVtbl HTMLStyleElementImplVtbl = {
     HTMLStyleElement_QI,
     HTMLStyleElement_destructor,
-    HTMLElement_clone
+    HTMLElement_clone,
+    HTMLElement_get_attr_col
 };
 
 static const tid_t HTMLStyleElement_iface_tids[] = {
diff --git a/dlls/mshtml/htmltable.c b/dlls/mshtml/htmltable.c
index 5e25373fee4..61cde8070c9 100644
--- a/dlls/mshtml/htmltable.c
+++ b/dlls/mshtml/htmltable.c
@@ -559,6 +559,7 @@ static const NodeImplVtbl HTMLTableImplVtbl = {
     HTMLTable_QI,
     HTMLTable_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col
 };
 
 static const tid_t HTMLTable_iface_tids[] = {
diff --git a/dlls/mshtml/htmltablerow.c b/dlls/mshtml/htmltablerow.c
index ee2c29548c6..c9b21eca0be 100644
--- a/dlls/mshtml/htmltablerow.c
+++ b/dlls/mshtml/htmltablerow.c
@@ -300,7 +300,8 @@ static void HTMLTableRow_destructor(HTMLDOMNode *iface)
 static const NodeImplVtbl HTMLTableRowImplVtbl = {
     HTMLTableRow_QI,
     HTMLTableRow_destructor,
-    HTMLElement_clone
+    HTMLElement_clone,
+    HTMLElement_get_attr_col
 };
 
 static const tid_t HTMLTableRow_iface_tids[] = {
diff --git a/dlls/mshtml/htmltextarea.c b/dlls/mshtml/htmltextarea.c
index ae2fd6a8aa8..fc833e35229 100644
--- a/dlls/mshtml/htmltextarea.c
+++ b/dlls/mshtml/htmltextarea.c
@@ -447,6 +447,7 @@ static const NodeImplVtbl HTMLTextAreaElementImplVtbl = {
     HTMLTextAreaElement_QI,
     HTMLTextAreaElement_destructor,
     HTMLElement_clone,
+    HTMLElement_get_attr_col,
     NULL,
     NULL,
     NULL,
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 9bb37e482a5..8bbedd509ca 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -73,6 +73,7 @@ typedef struct event_target_t event_target_t;
     XDIID(DispCPlugins) \
     XDIID(DispDOMChildrenCollection) \
     XDIID(DispHTMLAnchorElement) \
+    XDIID(DispHTMLAttributeCollection) \
     XDIID(DispHTMLBody) \
     XDIID(DispHTMLCommentElement) \
     XDIID(DispHTMLCurrentStyle) \
@@ -106,6 +107,9 @@ typedef struct event_target_t event_target_t;
     XDIID(DispHTMLWindow2) \
     XDIID(HTMLDocumentEvents) \
     XIID(IHTMLAnchorElement) \
+    XIID(IHTMLAttributeCollection) \
+    XIID(IHTMLAttributeCollection2) \
+    XIID(IHTMLAttributeCollection3) \
     XIID(IHTMLBodyElement) \
     XIID(IHTMLBodyElement2) \
     XIID(IHTMLCommentElement) \
@@ -223,6 +227,7 @@ typedef struct HTMLDocumentNode HTMLDocumentNode;
 typedef struct HTMLDocumentObj HTMLDocumentObj;
 typedef struct HTMLFrameBase HTMLFrameBase;
 typedef struct NSContainer NSContainer;
+typedef struct HTMLAttributeCollection HTMLAttributeCollection;
 
 typedef enum {
     SCRIPTMODE_GECKO,
@@ -498,6 +503,7 @@ typedef struct {
     HRESULT (*qi)(HTMLDOMNode*,REFIID,void**);
     void (*destructor)(HTMLDOMNode*);
     HRESULT (*clone)(HTMLDOMNode*,nsIDOMNode*,HTMLDOMNode**);
+    HRESULT (*get_attr_col)(HTMLDOMNode*,HTMLAttributeCollection**);
     event_target_t **(*get_event_target)(HTMLDOMNode*);
     HRESULT (*fire_event)(HTMLDOMNode*,DWORD,BOOL*);
     HRESULT (*handle_event)(HTMLDOMNode*,DWORD,BOOL*);
@@ -712,6 +718,20 @@ HRESULT create_nselem(HTMLDocumentNode*,const WCHAR*,nsIDOMHTMLElement**) DECLSP
 
 HRESULT HTMLDOMTextNode_Create(HTMLDocumentNode*,nsIDOMNode*,HTMLDOMNode**) DECLSPEC_HIDDEN;
 
+struct HTMLAttributeCollection {
+    DispatchEx dispex;
+    IHTMLAttributeCollection IHTMLAttributeCollection_iface;
+    IHTMLAttributeCollection2 IHTMLAttributeCollection2_iface;
+    IHTMLAttributeCollection3 IHTMLAttributeCollection3_iface;
+
+    LONG ref;
+
+    HTMLElement *elem;
+    LONG size;
+    DISPID *collection;
+    struct list attrs;
+};
+
 typedef struct {
     DispatchEx dispex;
     IHTMLDOMAttribute IHTMLDOMAttribute_iface;
@@ -760,6 +780,7 @@ void HTMLDOMNode_destructor(HTMLDOMNode*) DECLSPEC_HIDDEN;
 HRESULT HTMLElement_QI(HTMLDOMNode*,REFIID,void**) DECLSPEC_HIDDEN;
 void HTMLElement_destructor(HTMLDOMNode*) DECLSPEC_HIDDEN;
 HRESULT HTMLElement_clone(HTMLDOMNode*,nsIDOMNode*,HTMLDOMNode**) DECLSPEC_HIDDEN;
+HRESULT HTMLElement_get_attr_col(HTMLDOMNode*,HTMLAttributeCollection**) DECLSPEC_HIDDEN;
 
 HRESULT HTMLFrameBase_QI(HTMLFrameBase*,REFIID,void**) DECLSPEC_HIDDEN;
 void HTMLFrameBase_destructor(HTMLFrameBase*) DECLSPEC_HIDDEN;
-- 
GitLab