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