Paul Gofman : mshtml: Add stub object for HTMLElement classList.

Alexandre Julliard julliard at winehq.org
Mon Jul 19 15:59:16 CDT 2021


Module: wine
Branch: master
Commit: a08d13ddb0365c13265635f8b06e38b3d62135cc
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a08d13ddb0365c13265635f8b06e38b3d62135cc

Author: Paul Gofman <pgofman at codeweavers.com>
Date:   Mon Jul 19 15:53:16 2021 +0300

mshtml: Add stub object for HTMLElement classList.

Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mshtml/htmlelem.c               | 143 ++++++++++++++++++++++++++++++++++-
 dlls/mshtml/mshtml_private.h         |   1 +
 dlls/mshtml/mshtml_private_iface.idl |  11 +++
 dlls/mshtml/tests/dom.js             |   5 ++
 4 files changed, 157 insertions(+), 3 deletions(-)

diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index 961e4e79e08..5bb3f1eaf15 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -6395,6 +6395,142 @@ static event_target_vtbl_t HTMLElement_event_target_vtbl = {
     HTMLElement_set_current_event
 };
 
+struct token_list {
+    DispatchEx dispex;
+    IWineDOMTokenList IWineDOMTokenList_iface;
+    IHTMLElement *element;
+
+    LONG ref;
+};
+
+static inline struct token_list *impl_from_IWineDOMTokenList(IWineDOMTokenList *iface)
+{
+    return CONTAINING_RECORD(iface, struct token_list, IWineDOMTokenList_iface);
+}
+
+static HRESULT WINAPI token_list_QueryInterface(IWineDOMTokenList *iface, REFIID riid, void **ppv)
+{
+    struct token_list *token_list = impl_from_IWineDOMTokenList(iface);
+
+    TRACE("(%p)->(%s %p)\n", token_list, debugstr_mshtml_guid(riid), ppv);
+
+    if(IsEqualGUID(&IID_IUnknown, riid)) {
+        *ppv = &token_list->IWineDOMTokenList_iface;
+    }else if(IsEqualGUID(&IID_IWineDOMTokenList, riid)) {
+        *ppv = &token_list->IWineDOMTokenList_iface;
+    }else if(dispex_query_interface(&token_list->dispex, riid, ppv)) {
+        return *ppv ? S_OK : E_NOINTERFACE;
+    }else {
+        WARN("(%p)->(%s %p)\n", token_list, debugstr_mshtml_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI token_list_AddRef(IWineDOMTokenList *iface)
+{
+    struct token_list *token_list = impl_from_IWineDOMTokenList(iface);
+    LONG ref = InterlockedIncrement(&token_list->ref);
+
+    TRACE("(%p) ref=%d\n", token_list, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI token_list_Release(IWineDOMTokenList *iface)
+{
+    struct token_list *token_list = impl_from_IWineDOMTokenList(iface);
+    LONG ref = InterlockedDecrement(&token_list->ref);
+
+    TRACE("(%p) ref=%d\n", token_list, ref);
+
+    if(!ref) {
+        IHTMLElement_Release(token_list->element);
+        release_dispex(&token_list->dispex);
+        heap_free(token_list);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI token_list_GetTypeInfoCount(IWineDOMTokenList *iface, UINT *pctinfo)
+{
+    struct token_list *token_list = impl_from_IWineDOMTokenList(iface);
+    FIXME("(%p)->(%p)\n", token_list, pctinfo);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI token_list_GetTypeInfo(IWineDOMTokenList *iface, UINT iTInfo,
+        LCID lcid, ITypeInfo **ppTInfo)
+{
+    struct token_list *token_list = impl_from_IWineDOMTokenList(iface);
+
+    return IDispatchEx_GetTypeInfo(&token_list->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
+}
+
+static HRESULT WINAPI token_list_GetIDsOfNames(IWineDOMTokenList *iface, REFIID riid,
+        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+    struct token_list *token_list = impl_from_IWineDOMTokenList(iface);
+
+    return IDispatchEx_GetIDsOfNames(&token_list->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
+            lcid, rgDispId);
+}
+
+static HRESULT WINAPI token_list_Invoke(IWineDOMTokenList *iface, DISPID dispIdMember,
+        REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
+        VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    struct token_list *token_list = impl_from_IWineDOMTokenList(iface);
+
+    return IDispatchEx_Invoke(&token_list->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
+            pDispParams, pVarResult, pExcepInfo, puArgErr);
+}
+
+static const IWineDOMTokenListVtbl WineDOMTokenListVtbl = {
+    token_list_QueryInterface,
+    token_list_AddRef,
+    token_list_Release,
+    token_list_GetTypeInfoCount,
+    token_list_GetTypeInfo,
+    token_list_GetIDsOfNames,
+    token_list_Invoke,
+};
+
+static const tid_t token_list_iface_tids[] = {
+    IWineDOMTokenList_tid,
+    0
+};
+static dispex_static_data_t token_list_dispex = {
+    NULL,
+    IWineDOMTokenList_tid,
+    token_list_iface_tids
+};
+
+static HRESULT create_token_list(compat_mode_t compat_mode, IHTMLElement *element, IWineDOMTokenList **ret)
+{
+    struct token_list *obj;
+
+    obj = heap_alloc_zero(sizeof(*obj));
+    if(!obj)
+    {
+        ERR("No memory.\n");
+        return E_OUTOFMEMORY;
+    }
+
+    obj->IWineDOMTokenList_iface.lpVtbl = &WineDOMTokenListVtbl;
+    obj->ref = 1;
+    init_dispatch(&obj->dispex, (IUnknown*)&obj->IWineDOMTokenList_iface, &token_list_dispex, compat_mode);
+    IHTMLElement_AddRef(element);
+    obj->element = element;
+
+    *ret = &obj->IWineDOMTokenList_iface;
+    return S_OK;
+}
+
 static inline HTMLElement *impl_from_IWineHTMLElementPrivateVtbl(IWineHTMLElementPrivate *iface)
 {
     return CONTAINING_RECORD(iface, HTMLElement, IWineHTMLElementPrivate_iface);
@@ -6459,11 +6595,12 @@ static HRESULT WINAPI htmlelement_private_Invoke(IWineHTMLElementPrivate *iface,
 
 static HRESULT WINAPI htmlelement_private_get_classList(IWineHTMLElementPrivate *iface, IDispatch **class_list)
 {
-    FIXME("iface %p, class_list %p stub.\n", iface, class_list);
+    HTMLElement *This = impl_from_IWineHTMLElementPrivateVtbl(iface);
 
-    *class_list = NULL;
+    TRACE("iface %p, class_list %p.\n", iface, class_list);
 
-    return S_OK;
+    return create_token_list(dispex_compat_mode(&This->node.event_target.dispex), &This->IHTMLElement_iface,
+            (IWineDOMTokenList **)class_list);
 }
 
 static const IWineHTMLElementPrivateVtbl WineHTMLElementPrivateVtbl = {
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 56bef40b4d0..c1e7e78253d 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -273,6 +273,7 @@ typedef struct EventTarget EventTarget;
     XIID(ISVGTextContentElement)
 
 #define PRIVATE_TID_LIST \
+    XIID(IWineDOMTokenList) \
     XIID(IWineHTMLElementPrivate) \
     XIID(IWineHTMLWindowPrivate) \
     XIID(IWineMSHTMLConsole)
diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl
index 9ca7e0d7421..1764b0a8c9d 100644
--- a/dlls/mshtml/mshtml_private_iface.idl
+++ b/dlls/mshtml/mshtml_private_iface.idl
@@ -102,4 +102,15 @@ interface IWineHTMLElementPrivate : IDispatch
     HRESULT classList([retval, out] IDispatch **class_list);
 }
 
+[
+    odl,
+    oleautomation,
+    dual,
+    hidden,
+    uuid(08ef0edd-5fb8-4178-a2f0-9f686e00441b)
+]
+interface IWineDOMTokenList : IDispatch
+{
+}
+
 } /* library MSHTML_private */
diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js
index a2c70540eba..f54cb0f7088 100644
--- a/dlls/mshtml/tests/dom.js
+++ b/dlls/mshtml/tests/dom.js
@@ -508,3 +508,8 @@ sync_test("hasAttribute", function() {
     r = elem.hasAttribute("attr");
     ok(r === false, "hasAttribute(attr) returned " + r);
 });
+
+sync_test("classList", function() {
+    var elem = document.createElement("div");
+    var classList = elem.classList;
+});




More information about the wine-cvs mailing list