Jacek Caban : mshtml: Added IHTMLDocument5:: get_implementation implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Aug 22 13:48:40 CDT 2014


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Aug 22 14:48:37 2014 +0200

mshtml: Added IHTMLDocument5::get_implementation implementation.

---

 dlls/mshtml/htmldoc.c        |  17 +++++-
 dlls/mshtml/main.c           |   1 +
 dlls/mshtml/mshtml_private.h |   4 ++
 dlls/mshtml/omnavigator.c    | 142 +++++++++++++++++++++++++++++++++++++++++++
 dlls/mshtml/tests/dom.c      |  28 +++++++++
 5 files changed, 190 insertions(+), 2 deletions(-)

diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index 6992c93..4837a89 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -2617,8 +2617,21 @@ static HRESULT WINAPI HTMLDocument5_get_doctype(IHTMLDocument5 *iface, IHTMLDOMN
 static HRESULT WINAPI HTMLDocument5_get_implementation(IHTMLDocument5 *iface, IHTMLDOMImplementation **p)
 {
     HTMLDocument *This = impl_from_IHTMLDocument5(iface);
-    FIXME("(%p)->(%p)\n", This, p);
-    return E_NOTIMPL;
+    HTMLDocumentNode *doc_node = This->doc_node;
+
+    TRACE("(%p)->(%p)\n", This, p);
+
+    if(!doc_node->dom_implementation) {
+        HRESULT hres;
+
+        hres = create_dom_implementation(&doc_node->dom_implementation);
+        if(FAILED(hres))
+            return hres;
+    }
+
+    IHTMLDOMImplementation_AddRef(doc_node->dom_implementation);
+    *p = doc_node->dom_implementation;
+    return S_OK;
 }
 
 static HRESULT WINAPI HTMLDocument5_createAttribute(IHTMLDocument5 *iface, BSTR bstrattrName,
diff --git a/dlls/mshtml/main.c b/dlls/mshtml/main.c
index 1e7d992..8e11ce9 100644
--- a/dlls/mshtml/main.c
+++ b/dlls/mshtml/main.c
@@ -533,6 +533,7 @@ const char *debugstr_mshtml_guid(const GUID *iid)
     X(IID_IHTMLDocument7);
     X(IID_IHTMLDOMAttribute);
     X(IID_IHTMLDOMChildrenCollection);
+    X(IID_IHTMLDOMImplementation);
     X(IID_IHTMLDOMNode);
     X(IID_IHTMLDOMNode2);
     X(IID_IHTMLElement);
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 5424a19..19e424f 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -136,6 +136,7 @@ typedef struct event_target_t event_target_t;
     XIID(IHTMLDocument5) \
     XIID(IHTMLDOMAttribute) \
     XIID(IHTMLDOMChildrenCollection) \
+    XIID(IHTMLDOMImplementation) \
     XIID(IHTMLDOMNode) \
     XIID(IHTMLDOMNode2) \
     XIID(IHTMLDOMTextNode) \
@@ -732,6 +733,8 @@ struct HTMLDocumentNode {
     BOOL content_ready;
     event_target_t *body_event_target;
 
+    IHTMLDOMImplementation *dom_implementation;
+
     ICatInformation *catmgr;
     nsDocumentEventListener *nsevent_listener;
     BOOL *event_vector;
@@ -762,6 +765,7 @@ HRESULT HTMLLocation_Create(HTMLInnerWindow*,HTMLLocation**) DECLSPEC_HIDDEN;
 IOmNavigator *OmNavigator_Create(void) DECLSPEC_HIDDEN;
 HRESULT HTMLScreen_Create(IHTMLScreen**) DECLSPEC_HIDDEN;
 HRESULT create_history(HTMLInnerWindow*,OmHistory**) DECLSPEC_HIDDEN;
+HRESULT create_dom_implementation(IHTMLDOMImplementation**) DECLSPEC_HIDDEN;
 
 HRESULT create_storage(IHTMLStorage**) DECLSPEC_HIDDEN;
 
diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c
index 5b564a1..932d1c1 100644
--- a/dlls/mshtml/omnavigator.c
+++ b/dlls/mshtml/omnavigator.c
@@ -44,6 +44,148 @@ typedef struct {
     HTMLMimeTypesCollection *mime_types;
 } OmNavigator;
 
+typedef struct {
+    DispatchEx dispex;
+    IHTMLDOMImplementation IHTMLDOMImplementation_iface;
+
+    LONG ref;
+} HTMLDOMImplementation;
+
+static inline HTMLDOMImplementation *impl_from_IHTMLDOMImplementation(IHTMLDOMImplementation *iface)
+{
+    return CONTAINING_RECORD(iface, HTMLDOMImplementation, IHTMLDOMImplementation_iface);
+}
+
+static HRESULT WINAPI HTMLDOMImplementation_QueryInterface(IHTMLDOMImplementation *iface, REFIID riid, void **ppv)
+{
+    HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation(iface);
+
+    TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
+
+    if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IHTMLDOMImplementation, riid)) {
+        *ppv = &This->IHTMLDOMImplementation_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 HTMLDOMImplementation_AddRef(IHTMLDOMImplementation *iface)
+{
+    HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation(iface);
+    LONG ref = InterlockedIncrement(&This->ref);
+
+    TRACE("(%p) ref=%d\n", This, ref);
+
+    return ref;
+}
+
+static ULONG WINAPI HTMLDOMImplementation_Release(IHTMLDOMImplementation *iface)
+{
+    HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation(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 HTMLDOMImplementation_GetTypeInfoCount(IHTMLDOMImplementation *iface, UINT *pctinfo)
+{
+    HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation(iface);
+
+    return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
+}
+
+static HRESULT WINAPI HTMLDOMImplementation_GetTypeInfo(IHTMLDOMImplementation *iface, UINT iTInfo,
+        LCID lcid, ITypeInfo **ppTInfo)
+{
+    HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation(iface);
+
+    return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
+}
+
+static HRESULT WINAPI HTMLDOMImplementation_GetIDsOfNames(IHTMLDOMImplementation *iface, REFIID riid,
+        LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
+{
+    HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation(iface);
+
+    return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames,
+            cNames, lcid, rgDispId);
+}
+
+static HRESULT WINAPI HTMLDOMImplementation_Invoke(IHTMLDOMImplementation *iface, DISPID dispIdMember,
+        REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
+        EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+    HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation(iface);
+
+    return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid,
+            lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
+}
+
+static HRESULT WINAPI HTMLDOMImplementation_hasFeature(IHTMLDOMImplementation *iface, BSTR feature,
+        VARIANT version, VARIANT_BOOL *pfHasFeature)
+{
+    HTMLDOMImplementation *This = impl_from_IHTMLDOMImplementation(iface);
+
+    FIXME("(%p)->(%s %s %p) returning false\n", This, debugstr_w(feature), debugstr_variant(&version), pfHasFeature);
+
+    *pfHasFeature = VARIANT_FALSE;
+    return S_OK;
+}
+
+static const IHTMLDOMImplementationVtbl HTMLDOMImplementationVtbl = {
+    HTMLDOMImplementation_QueryInterface,
+    HTMLDOMImplementation_AddRef,
+    HTMLDOMImplementation_Release,
+    HTMLDOMImplementation_GetTypeInfoCount,
+    HTMLDOMImplementation_GetTypeInfo,
+    HTMLDOMImplementation_GetIDsOfNames,
+    HTMLDOMImplementation_Invoke,
+    HTMLDOMImplementation_hasFeature
+};
+
+static const tid_t HTMLDOMImplementation_iface_tids[] = {
+    IHTMLDOMImplementation_tid,
+    0
+};
+static dispex_static_data_t HTMLDOMImplementation_dispex = {
+    NULL,
+    IHTMLDOMImplementation_tid,
+    NULL,
+    HTMLDOMImplementation_iface_tids
+};
+
+HRESULT create_dom_implementation(IHTMLDOMImplementation **ret)
+{
+    HTMLDOMImplementation *dom_implementation;
+
+    dom_implementation = heap_alloc_zero(sizeof(*dom_implementation));
+    if(!dom_implementation)
+        return E_OUTOFMEMORY;
+
+    dom_implementation->IHTMLDOMImplementation_iface.lpVtbl = &HTMLDOMImplementationVtbl;
+    dom_implementation->ref = 1;
+
+    init_dispex(&dom_implementation->dispex, (IUnknown*)&dom_implementation->IHTMLDOMImplementation_iface,
+            &HTMLDOMImplementation_dispex);
+
+    *ret = &dom_implementation->IHTMLDOMImplementation_iface;
+    return S_OK;
+}
+
 static inline OmHistory *impl_from_IOmHistory(IOmHistory *iface)
 {
     return CONTAINING_RECORD(iface, OmHistory, IOmHistory_iface);
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index 05f58a3..577d222 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -5697,6 +5697,33 @@ static void test_window(IHTMLDocument2 *doc)
     IHTMLWindow2_Release(window);
 }
 
+static void test_dom_implementation(IHTMLDocument2 *doc)
+{
+    IHTMLDocument5 *doc5 = get_htmldoc5_iface((IUnknown*)doc);
+    IHTMLDOMImplementation *dom_implementation;
+    VARIANT_BOOL b;
+    VARIANT v;
+    BSTR str;
+    HRESULT hres;
+
+    hres = IHTMLDocument5_get_implementation(doc5, &dom_implementation);
+    IHTMLDocument5_Release(doc5);
+    ok(hres == S_OK, "get_implementation failed: %08x\n", hres);
+    ok(dom_implementation != NULL, "dom_implementation == NULL\n");
+
+    str = a2bstr("test");
+    V_VT(&v) = VT_BSTR;
+    V_BSTR(&v) = a2bstr("1.0");
+    b = 100;
+    hres = IHTMLDOMImplementation_hasFeature(dom_implementation, str, v, &b);
+    SysFreeString(str);
+    VariantClear(&v);
+    ok(hres == S_OK, "hasFeature failed: %08x\n", hres);
+    ok(!b, "hasFeature returned %x\n", b);
+
+    IHTMLDOMImplementation_Release(dom_implementation);
+}
+
 static void test_defaults(IHTMLDocument2 *doc)
 {
     IHTMLStyleSheetsCollection *stylesheetcol;
@@ -5831,6 +5858,7 @@ static void test_defaults(IHTMLDocument2 *doc)
 
     test_default_selection(doc);
     test_doc_title(doc, "");
+    test_dom_implementation(doc);
 }
 
 #define test_button_name(a,b) _test_button_name(__LINE__,a,b)




More information about the wine-cvs mailing list