mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 09:17:14 +00:00
mshtml: Embed the HTMLLocation into the outer window.
Gets rid of the issues with the cyclic dependency or detached location. Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
7b084e9f23
commit
9a8e628d70
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue