Commit 9a8e628d authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Embed the HTMLLocation into the outer window.

Gets rid of the issues with the cyclic dependency or detached location. Signed-off-by: 's avatarGabriel Ivăncescu <gabrielopcode@gmail.com>
parent 7b084e9f
......@@ -36,28 +36,19 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
static HRESULT get_url(HTMLLocation *This, const WCHAR **ret)
static inline HTMLOuterWindow *get_window(HTMLLocation *This)
{
if(!This->window || !This->window->url)
*ret = L"about:blank";
else
*ret = This->window->url;
return S_OK;
return CONTAINING_RECORD(This, HTMLOuterWindow, location);
}
static IUri *get_uri(HTMLLocation *This)
{
return This->window ? This->window->uri : NULL;
return get_window(This)->uri;
}
static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url)
{
const WCHAR *doc_url;
HRESULT hres;
hres = get_url(This, &doc_url);
if(FAILED(hres))
return hres;
const WCHAR *doc_url = get_window(This)->url ? get_window(This)->url : L"about:blank";
if(!InternetCrackUrlW(doc_url, 0, 0, url)) {
FIXME("InternetCrackUrlW failed: 0x%08lx\n", GetLastError());
......@@ -102,28 +93,13 @@ static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID r
static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface)
{
HTMLLocation *This = impl_from_IHTMLLocation(iface);
LONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p) ref=%ld\n", This, ref);
return ref;
return IHTMLWindow2_AddRef(&get_window(This)->base.IHTMLWindow2_iface);
}
static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface)
{
HTMLLocation *This = impl_from_IHTMLLocation(iface);
LONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) ref=%ld\n", This, ref);
if(!ref) {
if(This->window)
This->window->location = NULL;
release_dispex(&This->dispex);
free(This);
}
return ref;
return IHTMLWindow2_Release(&get_window(This)->base.IHTMLWindow2_iface);
}
static HRESULT WINAPI HTMLLocation_GetTypeInfoCount(IHTMLLocation *iface, UINT *pctinfo)
......@@ -163,12 +139,7 @@ static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
if(!This->window) {
FIXME("No window available\n");
return E_FAIL;
}
return navigate_url(This->window, v, This->window->uri, BINDING_NAVIGATED);
return navigate_url(get_window(This), v, get_uri(This), BINDING_NAVIGATED);
}
static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p)
......@@ -521,11 +492,6 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
if(!This->window) {
FIXME("No window available\n");
return E_FAIL;
}
if(hash[0] != '#') {
unsigned size = (1 /* # */ + wcslen(v) + 1) * sizeof(WCHAR);
if(!(hash = malloc(size)))
......@@ -534,7 +500,7 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v)
memcpy(hash + 1, v, size - sizeof(WCHAR));
}
hres = navigate_url(This->window, hash, This->window->uri, BINDING_NAVIGATED);
hres = navigate_url(get_window(This), hash, get_uri(This), BINDING_NAVIGATED);
if(hash != v)
free(hash);
......@@ -577,18 +543,13 @@ static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL fla
TRACE("(%p)->(%x)\n", This, flag);
if(!This->window) {
FIXME("No window available\n");
return E_FAIL;
}
/* reload is supposed to fail if called from a script with different origin, but IE doesn't care */
if(!is_main_content_window(This->window)) {
if(!is_main_content_window(get_window(This))) {
FIXME("Unsupported on iframe\n");
return E_NOTIMPL;
}
return reload_page(This->window);
return reload_page(get_window(This));
}
static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
......@@ -597,12 +558,7 @@ static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
TRACE("(%p)->(%s)\n", This, debugstr_w(bstr));
if(!This->window) {
FIXME("No window available\n");
return E_FAIL;
}
return navigate_url(This->window, bstr, This->window->uri, BINDING_NAVIGATED | BINDING_REPLACE);
return navigate_url(get_window(This), bstr, get_uri(This), BINDING_NAVIGATED | BINDING_REPLACE);
}
static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr)
......@@ -662,22 +618,10 @@ static dispex_static_data_t HTMLLocation_dispex = {
HTMLLocation_iface_tids
};
HRESULT HTMLLocation_Create(HTMLOuterWindow *window, HTMLLocation **ret)
void HTMLLocation_Init(HTMLLocation *location)
{
HTMLLocation *location;
location = malloc(sizeof(*location));
if(!location)
return E_OUTOFMEMORY;
location->IHTMLLocation_iface.lpVtbl = &HTMLLocationVtbl;
location->ref = 1;
location->window = window;
init_dispatch(&location->dispex, (IUnknown*)&location->IHTMLLocation_iface, &HTMLLocation_dispex,
COMPAT_MODE_QUIRKS);
*ret = location;
return S_OK;
}
......@@ -67,19 +67,13 @@ static inline BOOL is_outer_window(HTMLWindow *window)
return &window->outer_window->base == window;
}
static HRESULT get_location(HTMLOuterWindow *This, HTMLLocation **ret)
static void get_location(HTMLOuterWindow *This, HTMLLocation **ret)
{
if(!This->location) {
HRESULT hres;
if(!This->location.dispex.outer)
HTMLLocation_Init(&This->location);
hres = HTMLLocation_Create(This, &This->location);
if(FAILED(hres))
return hres;
}
IHTMLLocation_AddRef(&This->location->IHTMLLocation_iface);
*ret = This->location;
return S_OK;
IHTMLLocation_AddRef(&This->location.IHTMLLocation_iface);
*ret = &This->location;
}
void get_top_window(HTMLOuterWindow *window, HTMLOuterWindow **ret)
......@@ -133,8 +127,8 @@ static void detach_inner_window(HTMLInnerWindow *window)
if(doc)
detach_document_node(doc);
if(outer_window && outer_window->location)
dispex_unlink(&outer_window->location->dispex);
if(outer_window && outer_window->location.dispex.outer)
dispex_unlink(&outer_window->location.dispex);
abort_window_bindings(window);
remove_target_tasks(window->task_magic);
......@@ -240,10 +234,8 @@ static void release_outer_window(HTMLOuterWindow *This)
if(This->base.inner_window)
detach_inner_window(This->base.inner_window);
if(This->location) {
This->location->window = NULL;
IHTMLLocation_Release(&This->location->IHTMLLocation_iface);
}
if(This->location.dispex.outer)
release_dispex(&This->location.dispex);
if(This->frame_element)
This->frame_element->content_window = NULL;
......@@ -808,14 +800,10 @@ static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocatio
{
HTMLWindow *This = impl_from_IHTMLWindow2(iface);
HTMLLocation *location;
HRESULT hres;
TRACE("(%p)->(%p)\n", This, p);
hres = get_location(This->outer_window, &location);
if(FAILED(hres))
return hres;
get_location(This->outer_window, &location);
*p = &location->IHTMLLocation_iface;
return S_OK;
}
......@@ -3925,9 +3913,7 @@ static HRESULT IHTMLWindow2_location_hook(DispatchEx *dispex, WORD flags, DISPPA
TRACE("forwarding to location.href\n");
hres = get_location(This->base.outer_window, &location);
if(FAILED(hres))
return hres;
get_location(This->base.outer_window, &location);
hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, 0, flags, dp, res, ei, caller);
IHTMLLocation_Release(&location->IHTMLLocation_iface);
......
......@@ -490,10 +490,6 @@ typedef struct {
struct HTMLLocation {
DispatchEx dispex;
IHTMLLocation IHTMLLocation_iface;
LONG ref;
HTMLOuterWindow *window;
};
typedef struct {
......@@ -576,7 +572,7 @@ struct HTMLOuterWindow {
unsigned readystate_pending;
HTMLInnerWindow *pending_window;
HTMLLocation *location;
HTMLLocation location;
IMoniker *mon;
IUri *uri;
IUri *uri_nofrag;
......@@ -993,7 +989,7 @@ void get_top_window(HTMLOuterWindow*,HTMLOuterWindow**) DECLSPEC_HIDDEN;
HRESULT HTMLOptionElementFactory_Create(HTMLInnerWindow*,HTMLOptionElementFactory**) DECLSPEC_HIDDEN;
HRESULT HTMLImageElementFactory_Create(HTMLInnerWindow*,HTMLImageElementFactory**) DECLSPEC_HIDDEN;
HRESULT HTMLXMLHttpRequestFactory_Create(HTMLInnerWindow*,HTMLXMLHttpRequestFactory**) DECLSPEC_HIDDEN;
HRESULT HTMLLocation_Create(HTMLOuterWindow*,HTMLLocation**) DECLSPEC_HIDDEN;
void HTMLLocation_Init(HTMLLocation*) DECLSPEC_HIDDEN;
HRESULT create_navigator(compat_mode_t,IOmNavigator**) DECLSPEC_HIDDEN;
HRESULT create_html_screen(compat_mode_t,IHTMLScreen**) DECLSPEC_HIDDEN;
HRESULT create_performance(HTMLInnerWindow*,IHTMLPerformance**) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment