Jacek Caban : mshtml: Add IHTMLElement::getClientRects implementation.

Alexandre Julliard julliard at winehq.org
Wed Mar 27 17:27:37 CDT 2019


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed Mar 27 18:52:48 2019 +0100

mshtml: Add IHTMLElement::getClientRects implementation.

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

---

 dlls/mshtml/htmlelem.c       | 170 ++++++++++++++++++++++++++++++++++++++++++-
 dlls/mshtml/mshtml_private.h |   1 +
 dlls/mshtml/nsiface.idl      |  12 ++-
 dlls/mshtml/tests/dom.c      |   8 ++
 4 files changed, 188 insertions(+), 3 deletions(-)

diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index d490030..b14ecc1 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -553,6 +553,144 @@ static HRESULT create_html_rect(nsIDOMClientRect *nsrect, IHTMLRect **ret)
     return S_OK;
 }
 
+typedef struct {
+    DispatchEx dispex;
+    IHTMLRectCollection IHTMLRectCollection_iface;
+
+    LONG ref;
+
+    nsIDOMClientRectList *rect_list;
+} HTMLRectCollection;
+
+static inline HTMLRectCollection *impl_from_IHTMLRectCollection(IHTMLRectCollection *iface)
+{
+    return CONTAINING_RECORD(iface, HTMLRectCollection, IHTMLRectCollection_iface);
+}
+
+static HRESULT WINAPI HTMLRectCollection_QueryInterface(IHTMLRectCollection *iface, REFIID riid, void **ppv)
+{
+    HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
+
+    if(IsEqualGUID(&IID_IUnknown, riid)) {
+        *ppv = &This->IHTMLRectCollection_iface;
+    }else if(IsEqualGUID(&IID_IHTMLRectCollection, riid)) {
+        *ppv = &This->IHTMLRectCollection_iface;
+    }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
+        return *ppv ? S_OK : E_NOINTERFACE;
+    }else {
+        FIXME("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI HTMLRectCollection_AddRef(IHTMLRectCollection *iface)
+{
+    HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI HTMLRectCollection_Release(IHTMLRectCollection *iface)
+{
+    HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
+    LONG ref = InterlockedDecrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    if(!ref) {
+        if(This->rect_list)
+            nsIDOMClientRectList_Release(This->rect_list);
+        release_dispex(&This->dispex);
+        heap_free(This);
+    }
+
+    return ref;
+}
+
+static HRESULT WINAPI HTMLRectCollection_GetTypeInfoCount(IHTMLRectCollection *iface, UINT *pctinfo)
+{
+    HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
+    FIXME("(%p)->(%p)\n", This, pctinfo);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLRectCollection_GetTypeInfo(IHTMLRectCollection *iface, UINT iTInfo,
+        LCID lcid, ITypeInfo **ppTInfo)
+{
+    HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
+    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
+}
+
+static HRESULT WINAPI HTMLRectCollection_GetIDsOfNames(IHTMLRectCollection *iface, REFIID riid,
+        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+    HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
+    return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
+            lcid, rgDispId);
+}
+
+static HRESULT WINAPI HTMLRectCollection_Invoke(IHTMLRectCollection *iface, DISPID dispIdMember,
+        REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
+        VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
+    return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
+            pDispParams, pVarResult, pExcepInfo, puArgErr);
+}
+
+static HRESULT WINAPI HTMLRectCollection_get_length(IHTMLRectCollection *iface, LONG *p)
+{
+    HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
+    FIXME("(%p)->(%p)\n", This, p);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLRectCollection_get__newEnum(IHTMLRectCollection *iface, IUnknown **p)
+{
+    HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
+    FIXME("(%p)->(%p)\n", This, p);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI HTMLRectCollection_item(IHTMLRectCollection *iface, VARIANT *index, VARIANT *result)
+{
+    HTMLRectCollection *This = impl_from_IHTMLRectCollection(iface);
+    FIXME("(%p)->(%s %p)\n", This, debugstr_variant(index), result);
+    return E_NOTIMPL;
+}
+
+static const IHTMLRectCollectionVtbl HTMLRectCollectionVtbl = {
+    HTMLRectCollection_QueryInterface,
+    HTMLRectCollection_AddRef,
+    HTMLRectCollection_Release,
+    HTMLRectCollection_GetTypeInfoCount,
+    HTMLRectCollection_GetTypeInfo,
+    HTMLRectCollection_GetIDsOfNames,
+    HTMLRectCollection_Invoke,
+    HTMLRectCollection_get_length,
+    HTMLRectCollection_get__newEnum,
+    HTMLRectCollection_item
+};
+
+static const tid_t HTMLRectCollection_iface_tids[] = {
+    IHTMLRectCollection_tid,
+    0
+};
+static dispex_static_data_t HTMLRectCollection_dispex = {
+    NULL,
+    IHTMLRectCollection_tid,
+    HTMLRectCollection_iface_tids
+};
+
 static HRESULT WINAPI HTMLElement_QueryInterface(IHTMLElement *iface,
                                                  REFIID riid, void **ppv)
 {
@@ -2448,8 +2586,36 @@ static HRESULT WINAPI HTMLElement2_get_onpropertychange(IHTMLElement2 *iface, VA
 static HRESULT WINAPI HTMLElement2_getClientRects(IHTMLElement2 *iface, IHTMLRectCollection **pRectCol)
 {
     HTMLElement *This = impl_from_IHTMLElement2(iface);
-    FIXME("(%p)->(%p)\n", This, pRectCol);
-    return E_NOTIMPL;
+    nsIDOMClientRectList *rect_list;
+    HTMLRectCollection *rects;
+    nsresult nsres;
+
+    TRACE("(%p)->(%p)\n", This, pRectCol);
+
+    if(!This->dom_element) {
+        FIXME("comment element\n");
+        return E_NOTIMPL;
+    }
+
+    nsres = nsIDOMElement_GetClientRects(This->dom_element, &rect_list);
+    if(NS_FAILED(nsres)) {
+        WARN("GetClientRects failed: %08x\n", nsres);
+        return map_nsresult(nsres);
+    }
+
+    rects = heap_alloc_zero(sizeof(*rects));
+    if(!rects) {
+        nsIDOMClientRectList_Release(rect_list);
+        return E_OUTOFMEMORY;
+    }
+
+    rects->IHTMLRectCollection_iface.lpVtbl = &HTMLRectCollectionVtbl;
+    rects->ref = 1;
+    rects->rect_list = rect_list;
+    init_dispex(&rects->dispex, (IUnknown*)&rects->IHTMLRectCollection_iface, &HTMLRectCollection_dispex);
+
+    *pRectCol = &rects->IHTMLRectCollection_iface;
+    return S_OK;
 }
 
 static HRESULT WINAPI HTMLElement2_getBoundingClientRect(IHTMLElement2 *iface, IHTMLRect **pRect)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 967fda2..26037f0 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -210,6 +210,7 @@ typedef struct EventTarget EventTarget;
     XIID(IHTMLPerformanceTiming) \
     XIID(IHTMLPluginsCollection) \
     XIID(IHTMLRect) \
+    XIID(IHTMLRectCollection) \
     XIID(IHTMLScreen) \
     XIID(IHTMLScriptElement) \
     XIID(IHTMLSelectElement) \
diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index f9d8909..560fcd1 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -147,7 +147,6 @@ typedef nsISupports nsISupportsArray;
 typedef nsISupports nsIContentFilter;
 typedef nsISupports nsIDOMMediaList;
 typedef nsISupports nsIDOMHTMLTableSectionElement;
-typedef nsISupports nsIDOMClientRectList;
 typedef nsISupports nsINode;
 typedef nsISupports nsIDOMUserDataHandler;
 typedef nsISupports nsISHEntry;
@@ -1015,6 +1014,17 @@ interface nsIDOMClientRect : nsISupports
 
 [
     object,
+    uuid(f474c567-cbcb-458f-abad-ae42363da287),
+    local
+]
+interface nsIDOMClientRectList : nsISupports
+{
+    nsresult GetLength(uint32_t *aLength);
+    nsresult Item(UINT32 index, nsIDOMClientRect **_retval);
+}
+
+[
+    object,
     uuid(6289999b-1008-4269-b42a-413ec5a9d3f4),
     local
 ]
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index 7475c8f..19d7b11 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -5161,6 +5161,7 @@ static void _test_doc_set_title(unsigned line, IHTMLDocument2 *doc, const char *
 
 static void test_elem_bounding_client_rect(IUnknown *unk)
 {
+    IHTMLRectCollection *rects;
     IHTMLRect *rect, *rect2;
     IHTMLElement2 *elem2;
     LONG l;
@@ -5199,6 +5200,13 @@ static void test_elem_bounding_client_rect(IUnknown *unk)
     ok(l != 0xdeadbeef, "l = 0xdeadbeef\n");
 
     IHTMLRect_Release(rect);
+
+    hres = IHTMLElement2_getClientRects(elem2, &rects);
+    ok(hres == S_OK, "getClientRects failed: %08x\n", hres);
+
+    test_disp((IUnknown*)rects, &IID_IHTMLRectCollection, NULL, "[object]");
+
+    IHTMLRectCollection_Release(rects);
 }
 
 static void test_elem_col_item(IHTMLElementCollection *col, const char *n,




More information about the wine-cvs mailing list