From fbe02eb74c03acb815effd29b423a268616f1413 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Fri, 22 Aug 2014 14:48:37 +0200 Subject: [PATCH] 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 6992c93b5ac..4837a89ee8f 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 1e7d992ab36..8e11ce968d3 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 5424a19ed95..19e424f4288 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 5b564a1c782..932d1c1c2e4 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 05f58a3ec5e..577d2220983 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)