From 83f845dfa1bb4a6ec6e8b7f65e9469dc9a8a7787 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 14 Jun 2018 17:35:14 +0200 Subject: [PATCH] mshtml: Added IHTMLWindow7::performance property implementation. Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- dlls/mshtml/htmlwindow.c | 35 ++++++-- dlls/mshtml/mshtml_private.h | 5 ++ dlls/mshtml/omnavigator.c | 164 +++++++++++++++++++++++++++++++++++ dlls/mshtml/tests/dom.c | 13 ++- 4 files changed, 210 insertions(+), 7 deletions(-) diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index 364dae87f12..401d19de168 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -2315,16 +2315,39 @@ static HRESULT WINAPI HTMLWindow7_get_styleMedia(IHTMLWindow7 *iface, IHTMLStyle static HRESULT WINAPI HTMLWindow7_put_performance(IHTMLWindow7 *iface, VARIANT v) { - HTMLWindow *This = impl_from_IHTMLWindow7(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; + HTMLInnerWindow *This = impl_from_IHTMLWindow7(iface)->inner_window; + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + if(!This->performance_initialized) { + V_VT(&This->performance) = VT_EMPTY; + This->performance_initialized = TRUE; + } + + return VariantCopy(&This->performance, &v); } static HRESULT WINAPI HTMLWindow7_get_performance(IHTMLWindow7 *iface, VARIANT *p) { - HTMLWindow *This = impl_from_IHTMLWindow7(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + HTMLInnerWindow *This = impl_from_IHTMLWindow7(iface)->inner_window; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + if(!This->performance_initialized) { + IHTMLPerformance *performance; + + hres = create_performance(&performance); + if(FAILED(hres)) + return hres; + + V_VT(&This->performance) = VT_DISPATCH; + V_DISPATCH(&This->performance) = (IDispatch*)performance; + This->performance_initialized = TRUE; + } + + V_VT(p) = VT_NULL; + return VariantCopy(p, &This->performance); } static HRESULT WINAPI HTMLWindow7_get_innerWidth(IHTMLWindow7 *iface, LONG *p) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 62879e06180..e28ecbc6e0c 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -199,6 +199,7 @@ typedef struct EventTarget EventTarget; XIID(IHTMLObjectElement2) \ XIID(IHTMLOptionElement) \ XIID(IHTMLOptionElementFactory) \ + XIID(IHTMLPerformance) \ XIID(IHTMLPluginsCollection) \ XIID(IHTMLRect) \ XIID(IHTMLScreen) \ @@ -522,6 +523,9 @@ struct HTMLInnerWindow { OmHistory *history; IHTMLStorage *session_storage; + BOOL performance_initialized; + VARIANT performance; + unsigned parser_callback_cnt; struct list script_queue; @@ -870,6 +874,7 @@ HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,HTMLXMLHttpRequestFact HRESULT HTMLLocation_Create(HTMLInnerWindow*,HTMLLocation**) DECLSPEC_HIDDEN; IOmNavigator *OmNavigator_Create(void) DECLSPEC_HIDDEN; HRESULT HTMLScreen_Create(IHTMLScreen**) DECLSPEC_HIDDEN; +HRESULT create_performance(IHTMLPerformance**) DECLSPEC_HIDDEN; HRESULT create_history(HTMLInnerWindow*,OmHistory**) DECLSPEC_HIDDEN; HRESULT create_dom_implementation(IHTMLDOMImplementation**) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 406e7f564bf..faf15f046ad 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -1320,3 +1320,167 @@ IOmNavigator *OmNavigator_Create(void) return &ret->IOmNavigator_iface; } + +typedef struct { + DispatchEx dispex; + IHTMLPerformance IHTMLPerformance_iface; + LONG ref; +} HTMLPerformance; + +static inline HTMLPerformance *impl_from_IHTMLPerformance(IHTMLPerformance *iface) +{ + return CONTAINING_RECORD(iface, HTMLPerformance, IHTMLPerformance_iface); +} + +static HRESULT WINAPI HTMLPerformance_QueryInterface(IHTMLPerformance *iface, REFIID riid, void **ppv) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); + + if(IsEqualGUID(&IID_IUnknown, riid)) { + *ppv = &This->IHTMLPerformance_iface; + }else if(IsEqualGUID(&IID_IHTMLPerformance, riid)) { + *ppv = &This->IHTMLPerformance_iface; + }else if(dispex_query_interface(&This->dispex, riid, ppv)) { + return *ppv ? S_OK : E_NOINTERFACE; + }else { + WARN("Unsupported interface %s\n", debugstr_mshtml_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI HTMLPerformance_AddRef(IHTMLPerformance *iface) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI HTMLPerformance_Release(IHTMLPerformance *iface) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + release_dispex(&This->dispex); + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI HTMLPerformance_GetTypeInfoCount(IHTMLPerformance *iface, UINT *pctinfo) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLPerformance_GetTypeInfo(IHTMLPerformance *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + + return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLPerformance_GetIDsOfNames(IHTMLPerformance *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + + return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI HTMLPerformance_Invoke(IHTMLPerformance *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + + return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLPerformance_get_navigation(IHTMLPerformance *iface, + IHTMLPerformanceNavigation **p) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLPerformance_get_timing(IHTMLPerformance *iface, IHTMLPerformanceTiming **p) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLPerformance_toString(IHTMLPerformance *iface, BSTR *string) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + FIXME("(%p)->(%p)\n", This, string); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLPerformance_toJSON(IHTMLPerformance *iface, VARIANT *var) +{ + HTMLPerformance *This = impl_from_IHTMLPerformance(iface); + FIXME("(%p)->(%p)\n", This, var); + return E_NOTIMPL; +} + +static const IHTMLPerformanceVtbl HTMLPerformanceVtbl = { + HTMLPerformance_QueryInterface, + HTMLPerformance_AddRef, + HTMLPerformance_Release, + HTMLPerformance_GetTypeInfoCount, + HTMLPerformance_GetTypeInfo, + HTMLPerformance_GetIDsOfNames, + HTMLPerformance_Invoke, + HTMLPerformance_get_navigation, + HTMLPerformance_get_timing, + HTMLPerformance_toString, + HTMLPerformance_toJSON +}; + +static const tid_t HTMLPerformance_iface_tids[] = { + IHTMLPerformance_tid, + 0 +}; +static dispex_static_data_t HTMLPerformance_dispex = { + NULL, + IHTMLPerformance_tid, + HTMLPerformance_iface_tids +}; + +HRESULT create_performance(IHTMLPerformance **ret) +{ + HTMLPerformance *performance; + + performance = heap_alloc_zero(sizeof(*performance)); + if(!performance) + return E_OUTOFMEMORY; + + performance->IHTMLPerformance_iface.lpVtbl = &HTMLPerformanceVtbl; + performance->ref = 1; + + init_dispex(&performance->dispex, (IUnknown*)&performance->IHTMLPerformance_iface, + &HTMLPerformance_dispex); + + *ret = &performance->IHTMLPerformance_iface; + return S_OK; +} diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 3f08a230b96..69b62069f3e 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -6851,7 +6851,6 @@ static void test_window(IHTMLDocument2 *doc) ok(window7 != NULL, "window7 == NULL\n"); hres = IHTMLWindow7_get_performance(window7, &v); - todo_wine ok(hres == S_OK, "get_performance failed: %08x\n", hres); if(SUCCEEDED(hres)) { ok(V_VT(&v) == VT_DISPATCH, "V_VT(performance) = %u\n", V_VT(&v)); @@ -6861,6 +6860,18 @@ static void test_window(IHTMLDocument2 *doc) ok(hres == S_OK, "Could not get IHTMLPerformance iface: %08x\n", hres); IHTMLPerformance_Release(performance); + + V_VT(&v) = VT_I2; + V_I2(&v) = 2; + hres = IHTMLWindow7_put_performance(window7, v); + ok(hres == S_OK, "put_performance failed: %08x\n", hres); + + V_VT(&v) = VT_ERROR; + hres = IHTMLWindow7_get_performance(window7, &v); + ok(hres == S_OK, "get_performance failed: %08x\n", hres); + ok(V_VT(&v) == VT_I2, "V_VT(performance) = %u\n", V_VT(&v)); + ok(V_I2(&v) == 2, "V_I2(performance) = %d\n", V_I2(&v)); + IHTMLWindow7_Release(window7); } }else {