From d2e8d448113720a2f1f851f5fab3d0729a83c4f9 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 2 May 2012 10:28:09 +0200 Subject: [PATCH] mshtml: Added IHTMLWindow2::get_history implementation. --- dlls/mshtml/htmlwindow.c | 16 +++- dlls/mshtml/mshtml_private.h | 4 + dlls/mshtml/omnavigator.c | 169 ++++++++++++++++++++++++++++++++++- dlls/mshtml/tests/dom.c | 23 +++++ 4 files changed, 208 insertions(+), 4 deletions(-) diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index a0cf108cf36..2f792f99fed 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -690,8 +690,20 @@ static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocatio static HRESULT WINAPI HTMLWindow2_get_history(IHTMLWindow2 *iface, IOmHistory **p) { HTMLWindow *This = impl_from_IHTMLWindow2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + if(!This->history) { + HRESULT hres; + + hres = create_history(&This->history); + if(FAILED(hres)) + return hres; + } + + IOmHistory_AddRef(This->history); + *p = This->history; + return S_OK; } static HRESULT WINAPI HTMLWindow2_close(IHTMLWindow2 *iface) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 3376084d807..cdf34cd06ea 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -88,6 +88,7 @@ typedef struct event_target_t event_target_t; XDIID(DispHTMLGenericElement) \ XDIID(DispHTMLFrameElement) \ XDIID(DispHTMLHeadElement) \ + XDIID(DispHTMLHistory) \ XDIID(DispHTMLIFrame) \ XDIID(DispHTMLImg) \ XDIID(DispHTMLInputElement) \ @@ -180,6 +181,7 @@ typedef struct event_target_t event_target_t; XIID(IHTMLWindow3) \ XIID(IHTMLWindow4) \ XIID(IHTMLWindow6) \ + XIID(IOmHistory) \ XIID(IOmNavigator) typedef enum { @@ -333,6 +335,7 @@ struct HTMLWindow { HTMLImageElementFactory *image_factory; HTMLLocation *location; IHTMLScreen *screen; + IOmHistory *history; global_prop_t *global_props; DWORD global_prop_cnt; @@ -641,6 +644,7 @@ HTMLImageElementFactory *HTMLImageElementFactory_Create(HTMLWindow*) DECLSPEC_HI HRESULT HTMLLocation_Create(HTMLWindow*,HTMLLocation**) DECLSPEC_HIDDEN; IOmNavigator *OmNavigator_Create(void) DECLSPEC_HIDDEN; HRESULT HTMLScreen_Create(IHTMLScreen**) DECLSPEC_HIDDEN; +HRESULT create_history(IOmHistory**) DECLSPEC_HIDDEN; void HTMLDocument_HTMLDocument3_Init(HTMLDocument*) DECLSPEC_HIDDEN; void HTMLDocument_HTMLDocument5_Init(HTMLDocument*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 2ae98114a7d..ff64a63473d 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -44,9 +44,169 @@ typedef struct { HTMLMimeTypesCollection *mime_types; } OmNavigator; -static inline OmNavigator *impl_from_IOmNavigator(IOmNavigator *iface) +typedef struct { + DispatchEx dispex; + IOmHistory IOmHistory_iface; + + LONG ref; +} OmHistory; + +static inline OmHistory *impl_from_IOmHistory(IOmHistory *iface) { - return CONTAINING_RECORD(iface, OmNavigator, IOmNavigator_iface); + return CONTAINING_RECORD(iface, OmHistory, IOmHistory_iface); +} + +static HRESULT WINAPI OmHistory_QueryInterface(IOmHistory *iface, REFIID riid, void **ppv) +{ + OmHistory *This = impl_from_IOmHistory(iface); + + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = &This->IOmHistory_iface; + }else if(IsEqualGUID(&IID_IOmHistory, riid)) { + TRACE("(%p)->(IID_IOmHistory %p)\n", This, ppv); + *ppv = &This->IOmHistory_iface; + }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 OmHistory_AddRef(IOmHistory *iface) +{ + OmHistory *This = impl_from_IOmHistory(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI OmHistory_Release(IOmHistory *iface) +{ + OmHistory *This = impl_from_IOmHistory(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 OmHistory_GetTypeInfoCount(IOmHistory *iface, UINT *pctinfo) +{ + OmHistory *This = impl_from_IOmHistory(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI OmHistory_GetTypeInfo(IOmHistory *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + OmHistory *This = impl_from_IOmHistory(iface); + + return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI OmHistory_GetIDsOfNames(IOmHistory *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + OmHistory *This = impl_from_IOmHistory(iface); + + return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames, + lcid, rgDispId); +} + +static HRESULT WINAPI OmHistory_Invoke(IOmHistory *iface, DISPID dispIdMember, REFIID riid, LCID lcid, + WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + OmHistory *This = impl_from_IOmHistory(iface); + + return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI OmHistory_get_length(IOmHistory *iface, short *p) +{ + OmHistory *This = impl_from_IOmHistory(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI OmHistory_back(IOmHistory *iface, VARIANT *pvargdistance) +{ + OmHistory *This = impl_from_IOmHistory(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(pvargdistance)); + return E_NOTIMPL; +} + +static HRESULT WINAPI OmHistory_forward(IOmHistory *iface, VARIANT *pvargdistance) +{ + OmHistory *This = impl_from_IOmHistory(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(pvargdistance)); + return E_NOTIMPL; +} + +static HRESULT WINAPI OmHistory_go(IOmHistory *iface, VARIANT *pvargdistance) +{ + OmHistory *This = impl_from_IOmHistory(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(pvargdistance)); + return E_NOTIMPL; +} + +static const IOmHistoryVtbl OmHistoryVtbl = { + OmHistory_QueryInterface, + OmHistory_AddRef, + OmHistory_Release, + OmHistory_GetTypeInfoCount, + OmHistory_GetTypeInfo, + OmHistory_GetIDsOfNames, + OmHistory_Invoke, + OmHistory_get_length, + OmHistory_back, + OmHistory_forward, + OmHistory_go +}; + +static const tid_t OmHistory_iface_tids[] = { + IOmHistory_tid, + 0 +}; +static dispex_static_data_t OmHistory_dispex = { + NULL, + DispHTMLHistory_tid, + NULL, + OmHistory_iface_tids +}; + + +HRESULT create_history(IOmHistory **ret) +{ + OmHistory *history; + + history = heap_alloc_zero(sizeof(*history)); + if(!history) + return E_OUTOFMEMORY; + + init_dispex(&history->dispex, (IUnknown*)&history->IOmHistory_iface, &OmHistory_dispex); + history->IOmHistory_iface.lpVtbl = &OmHistoryVtbl; + history->ref = 1; + + *ret = &history->IOmHistory_iface; + return S_OK; } struct HTMLPluginsCollection { @@ -347,6 +507,11 @@ static HRESULT create_mime_types_collection(OmNavigator *navigator, HTMLMimeType return S_OK; } +static inline OmNavigator *impl_from_IOmNavigator(IOmNavigator *iface) +{ + return CONTAINING_RECORD(iface, OmNavigator, IOmNavigator_iface); +} + static HRESULT WINAPI OmNavigator_QueryInterface(IOmNavigator *iface, REFIID riid, void **ppv) { OmNavigator *This = impl_from_IOmNavigator(iface); diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index fcc2654fa81..f095cc2f23b 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -4477,6 +4477,28 @@ static void test_body_funs(IHTMLBodyElement *body) VariantClear(&vDefaultbg); } +static void test_history(IHTMLWindow2 *window) +{ + IOmHistory *history, *history2; + HRESULT hres; + + history = NULL; + hres = IHTMLWindow2_get_history(window, &history); + ok(hres == S_OK, "get_history failed: %08x\n", hres); + ok(history != NULL, "history = NULL\n"); + + test_disp((IUnknown*)history, &DIID_DispHTMLHistory, "[object]"); + + history2 = NULL; + hres = IHTMLWindow2_get_history(window, &history2); + ok(hres == S_OK, "get_history failed: %08x\n", hres); + ok(history2 != NULL, "history2 = NULL\n"); + ok(iface_cmp((IUnknown*)history, (IUnknown*)history2), "history != history2\n"); + + IOmHistory_Release(history2); + IOmHistory_Release(history); +} + static void test_window(IHTMLDocument2 *doc) { IHTMLWindow2 *window, *window2, *self, *parent; @@ -4564,6 +4586,7 @@ static void test_window(IHTMLDocument2 *doc) test_screen(window); test_window_status(window); set_window_status(window, "Test!"); + test_history(window); IHTMLWindow2_Release(window); }