Jacek Caban : mshtml: Added IHTMLWindow2::get_history implementation.

Alexandre Julliard julliard at winehq.org
Wed May 2 14:30:02 CDT 2012


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Wed May  2 10:28:09 2012 +0200

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 a0cf108..2f792f9 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 3376084..cdf34cd 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 2ae9811..ff64a63 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 fcc2654..f095cc2 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);
 }




More information about the wine-cvs mailing list