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