From 1caf73be28dda1ad6fcc9ba3f2d0349686d300b7 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Wed, 26 Mar 2008 15:23:41 +0100 Subject: [PATCH] mshtml: Added IHTMLDocument2::get_location implementation. --- dlls/mshtml/Makefile.in | 1 + dlls/mshtml/htmldoc.c | 22 ++- dlls/mshtml/htmllocation.c | 311 +++++++++++++++++++++++++++++++++++ dlls/mshtml/mshtml_private.h | 11 ++ dlls/mshtml/tests/dom.c | 28 ++++ 5 files changed, 366 insertions(+), 7 deletions(-) create mode 100644 dlls/mshtml/htmllocation.c diff --git a/dlls/mshtml/Makefile.in b/dlls/mshtml/Makefile.in index 1ca2d1d4dba..0eee1897053 100644 --- a/dlls/mshtml/Makefile.in +++ b/dlls/mshtml/Makefile.in @@ -20,6 +20,7 @@ C_SRCS = \ htmlelem.c \ htmlelem2.c \ htmlinput.c \ + htmllocation.c \ htmlnode.c \ htmloption.c \ htmlscript.c \ diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 966dcf06e89..92a7f9aab78 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -183,6 +183,9 @@ static ULONG WINAPI HTMLDocument_Release(IHTMLDocument2 *iface) IHTMLOptionElementFactory_Release(HTMLOPTFACTORY(This->option_factory)); } + if(This->location) + This->location->doc = NULL; + if(This->window) IHTMLWindow2_Release(HTMLWINDOW2(This->window)); @@ -537,8 +540,17 @@ static HRESULT WINAPI HTMLDocument_get_referrer(IHTMLDocument2 *iface, BSTR *p) static HRESULT WINAPI HTMLDocument_get_location(IHTMLDocument2 *iface, IHTMLLocation **p) { - FIXME("(%p)->(%p)\n", iface, p); - return E_NOTIMPL; + HTMLDocument *This = HTMLDOC_THIS(iface); + + TRACE("(%p)->(%p)\n", This, p); + + if(This->location) + IHTMLLocation_AddRef(HTMLLOCATION(This->location)); + else + This->location = HTMLLocation_Create(This); + + *p = HTMLLOCATION(This->location); + return S_OK; } static HRESULT WINAPI HTMLDocument_get_lastModified(IHTMLDocument2 *iface, BSTR *p) @@ -1247,14 +1259,10 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject) TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppvObject); - ret = heap_alloc(sizeof(HTMLDocument)); + ret = heap_alloc_zero(sizeof(HTMLDocument)); ret->lpHTMLDocument2Vtbl = &HTMLDocumentVtbl; ret->ref = 0; - ret->nscontainer = NULL; - ret->nodes = NULL; ret->readystate = READYSTATE_UNINITIALIZED; - ret->window = NULL; - ret->option_factory = NULL; list_init(&ret->bindings); list_init(&ret->script_hosts); diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c new file mode 100644 index 00000000000..b05a2a9c83c --- /dev/null +++ b/dlls/mshtml/htmllocation.c @@ -0,0 +1,311 @@ +/* + * Copyright 2008 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winnls.h" +#include "ole2.h" + +#include "wine/debug.h" + +#include "mshtml_private.h" +#include "resource.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mshtml); + +#define HTMLLOCATION_THIS(iface) DEFINE_THIS(HTMLLocation, HTMLLocation, iface) + +static struct list window_list = LIST_INIT(window_list); + +static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID riid, void **ppv) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = HTMLLOCATION(This); + }else if(IsEqualGUID(&IID_IDispatch, riid)) { + TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv); + *ppv = HTMLLOCATION(This); + }else if(IsEqualGUID(&IID_IHTMLLocation, riid)) { + TRACE("(%p)->(IID_IHTMLLocation %p)\n", This, ppv); + *ppv = HTMLLOCATION(This); + } + + 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 HTMLLocation_AddRef(IHTMLLocation *iface) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + if(This->doc && This->doc->location == This) + This->doc->location = NULL; + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI HTMLLocation_GetTypeInfoCount(IHTMLLocation *iface, UINT *pctinfo) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_GetTypeInfo(IHTMLLocation *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_GetIDsOfNames(IHTMLLocation *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames, + lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_Invoke(IHTMLLocation *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_put_protocol(IHTMLLocation *iface, BSTR v) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_get_protocol(IHTMLLocation *iface, BSTR *p) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_put_host(IHTMLLocation *iface, BSTR v) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_get_host(IHTMLLocation *iface, BSTR *p) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_put_hostname(IHTMLLocation *iface, BSTR v) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_get_hostname(IHTMLLocation *iface, BSTR *p) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_put_port(IHTMLLocation *iface, BSTR v) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_get_port(IHTMLLocation *iface, BSTR *p) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_put_pathname(IHTMLLocation *iface, BSTR v) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_get_pathname(IHTMLLocation *iface, BSTR *p) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_put_search(IHTMLLocation *iface, BSTR v) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_get_search(IHTMLLocation *iface, BSTR *p) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_get_hash(IHTMLLocation *iface, BSTR *p) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL flag) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%x)\n", This, flag); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(bstr)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(bstr)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLLocation_toString(IHTMLLocation *iface, BSTR *String) +{ + HTMLLocation *This = HTMLLOCATION_THIS(iface); + FIXME("(%p)->(%p)\n", This, String); + return E_NOTIMPL; +} + +#undef HTMLLOCATION_THIS + +static const IHTMLLocationVtbl HTMLLocationVtbl = { + HTMLLocation_QueryInterface, + HTMLLocation_AddRef, + HTMLLocation_Release, + HTMLLocation_GetTypeInfoCount, + HTMLLocation_GetTypeInfo, + HTMLLocation_GetIDsOfNames, + HTMLLocation_Invoke, + HTMLLocation_put_href, + HTMLLocation_get_href, + HTMLLocation_put_protocol, + HTMLLocation_get_protocol, + HTMLLocation_put_host, + HTMLLocation_get_host, + HTMLLocation_put_hostname, + HTMLLocation_get_hostname, + HTMLLocation_put_port, + HTMLLocation_get_port, + HTMLLocation_put_pathname, + HTMLLocation_get_pathname, + HTMLLocation_put_search, + HTMLLocation_get_search, + HTMLLocation_put_hash, + HTMLLocation_get_hash, + HTMLLocation_reload, + HTMLLocation_replace, + HTMLLocation_assign, + HTMLLocation_toString +}; + +HTMLLocation *HTMLLocation_Create(HTMLDocument *doc) +{ + HTMLLocation *ret = heap_alloc(sizeof(*ret)); + + ret->lpHTMLLocationVtbl = &HTMLLocationVtbl; + ret->ref = 1; + ret->doc = doc; + + return ret; +} diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 569ab6c903b..4253a87894a 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -97,6 +97,14 @@ struct ConnectionPoint { ConnectionPoint *next; }; +typedef struct { + const IHTMLLocationVtbl *lpHTMLLocationVtbl; + + LONG ref; + + HTMLDocument *doc; +} HTMLLocation; + typedef struct { const IHTMLOptionElementFactoryVtbl *lpHTMLOptionElementFactoryVtbl; @@ -169,6 +177,7 @@ struct HTMLDocument { ConnectionPoint cp_propnotif; HTMLOptionElementFactory *option_factory; + HTMLLocation *location; struct list selection_list; struct list range_list; @@ -323,6 +332,7 @@ typedef struct { #define HTMLTEXTCONT(x) ((IHTMLTextContainer*) &(x)->lpHTMLTextContainerVtbl) #define HTMLOPTFACTORY(x) ((IHTMLOptionElementFactory*) &(x)->lpHTMLOptionElementFactoryVtbl) +#define HTMLLOCATION(x) ((IHTMLLocation*) &(x)->lpHTMLLocationVtbl) #define DEFINE_THIS2(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,ifc))) #define DEFINE_THIS(cls,ifc,iface) DEFINE_THIS2(cls,lp ## ifc ## Vtbl,iface) @@ -333,6 +343,7 @@ HRESULT HTMLLoadOptions_Create(IUnknown*,REFIID,void**); HTMLWindow *HTMLWindow_Create(HTMLDocument*); HTMLWindow *nswindow_to_window(const nsIDOMWindow*); HTMLOptionElementFactory *HTMLOptionElementFactory_Create(HTMLDocument*); +HTMLLocation *HTMLLocation_Create(HTMLDocument*); void setup_nswindow(HTMLWindow*); void HTMLDocument_HTMLDocument3_Init(HTMLDocument*); diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 68a213013b4..53e0a1f411d 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -163,6 +163,12 @@ static REFIID const script_iids[] = { NULL }; +static REFIID const location_iids[] = { + &IID_IDispatch, + &IID_IHTMLLocation, + NULL +}; + typedef struct { const char *tag; REFIID *iids; @@ -1002,6 +1008,27 @@ static void test_compatmode(IHTMLDocument2 *doc) SysFreeString(mode); } +static void test_location(IHTMLDocument2 *doc) +{ + IHTMLLocation *location, *location2; + ULONG ref; + HRESULT hres; + + hres = IHTMLDocument2_get_location(doc, &location); + ok(hres == S_OK, "get_location failed: %08x\n", hres); + + hres = IHTMLDocument2_get_location(doc, &location2); + ok(hres == S_OK, "get_location failed: %08x\n", hres); + + ok(location == location2, "location != location2\n"); + + test_ifaces((IUnknown*)location, location_iids); + + IHTMLLocation_Release(location2); + ref = IHTMLLocation_Release(location); + ok(!ref, "location chould be destroyed here\n"); +} + static void test_default_style(IHTMLStyle *style) { VARIANT_BOOL b; @@ -1114,6 +1141,7 @@ static void test_defaults(IHTMLDocument2 *doc) test_default_style(style); test_compatmode(doc); + test_location(doc); IHTMLStyle_Release(style);