Commit 7b084e9f authored by Gabriel Ivăncescu's avatar Gabriel Ivăncescu Committed by Alexandre Julliard

mshtml: Tie window.location to the outer window.

Even in IE9+ modes, it's still a non-JS object. Signed-off-by: 's avatarGabriel Ivăncescu <gabrielopcode@gmail.com>
parent e495c256
......@@ -2025,6 +2025,7 @@ void dispex_unlink(DispatchEx *This)
for(prop = This->dynamic_data->props; prop < This->dynamic_data->props + This->dynamic_data->prop_cnt; prop++) {
VariantClear(&prop->var);
prop->flags |= DYNPROP_DELETED;
}
if(This->dynamic_data->func_disps) {
......
......@@ -38,18 +38,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
static HRESULT get_url(HTMLLocation *This, const WCHAR **ret)
{
if(!This->window || !This->window->base.outer_window || !This->window->base.outer_window->url)
if(!This->window || !This->window->url)
*ret = L"about:blank";
else
*ret = This->window->base.outer_window->url;
*ret = This->window->url;
return S_OK;
}
static IUri *get_uri(HTMLLocation *This)
{
if(!This->window || !This->window->base.outer_window)
return NULL;
return This->window->base.outer_window->uri;
return This->window ? This->window->uri : NULL;
}
static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url)
......@@ -165,12 +163,12 @@ static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
if(!This->window || !This->window->base.outer_window) {
if(!This->window) {
FIXME("No window available\n");
return E_FAIL;
}
return navigate_url(This->window->base.outer_window, v, This->window->base.outer_window->uri, BINDING_NAVIGATED);
return navigate_url(This->window, v, This->window->uri, BINDING_NAVIGATED);
}
static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p)
......@@ -523,7 +521,7 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v)
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
if(!This->window || !This->window->base.outer_window) {
if(!This->window) {
FIXME("No window available\n");
return E_FAIL;
}
......@@ -536,7 +534,7 @@ static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v)
memcpy(hash + 1, v, size - sizeof(WCHAR));
}
hres = navigate_url(This->window->base.outer_window, hash, This->window->base.outer_window->uri, BINDING_NAVIGATED);
hres = navigate_url(This->window, hash, This->window->uri, BINDING_NAVIGATED);
if(hash != v)
free(hash);
......@@ -585,12 +583,12 @@ static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL fla
}
/* 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->base.outer_window)) {
if(!is_main_content_window(This->window)) {
FIXME("Unsupported on iframe\n");
return E_NOTIMPL;
}
return reload_page(This->window->base.outer_window);
return reload_page(This->window);
}
static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
......@@ -599,13 +597,12 @@ static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
TRACE("(%p)->(%s)\n", This, debugstr_w(bstr));
if(!This->window || !This->window->base.outer_window) {
if(!This->window) {
FIXME("No window available\n");
return E_FAIL;
}
return navigate_url(This->window->base.outer_window, bstr, This->window->base.outer_window->uri,
BINDING_NAVIGATED|BINDING_REPLACE);
return navigate_url(This->window, bstr, This->window->uri, BINDING_NAVIGATED | BINDING_REPLACE);
}
static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr)
......@@ -659,14 +656,14 @@ static const tid_t HTMLLocation_iface_tids[] = {
0
};
static dispex_static_data_t HTMLLocation_dispex = {
L"Object",
L"Location",
NULL,
DispHTMLLocation_tid,
HTMLLocation_iface_tids
};
HRESULT HTMLLocation_Create(HTMLInnerWindow *window, HTMLLocation **ret)
HRESULT HTMLLocation_Create(HTMLOuterWindow *window, HTMLLocation **ret)
{
HTMLLocation *location;
......@@ -679,7 +676,7 @@ HRESULT HTMLLocation_Create(HTMLInnerWindow *window, HTMLLocation **ret)
location->window = window;
init_dispatch(&location->dispex, (IUnknown*)&location->IHTMLLocation_iface, &HTMLLocation_dispex,
dispex_compat_mode(&window->event_target.dispex));
COMPAT_MODE_QUIRKS);
*ret = location;
return S_OK;
......
......@@ -67,7 +67,7 @@ static inline BOOL is_outer_window(HTMLWindow *window)
return &window->outer_window->base == window;
}
static HRESULT get_location(HTMLInnerWindow *This, HTMLLocation **ret)
static HRESULT get_location(HTMLOuterWindow *This, HTMLLocation **ret)
{
if(!This->location) {
HRESULT hres;
......@@ -133,6 +133,9 @@ 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);
abort_window_bindings(window);
remove_target_tasks(window->task_magic);
release_script_hosts(window);
......@@ -237,6 +240,11 @@ 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->frame_element)
This->frame_element->content_window = NULL;
......@@ -269,11 +277,6 @@ static void release_inner_window(HTMLInnerWindow *This)
free(This->global_props[i].name);
free(This->global_props);
if(This->location) {
This->location->window = NULL;
IHTMLLocation_Release(&This->location->IHTMLLocation_iface);
}
if(This->image_factory) {
This->image_factory->window = NULL;
IHTMLImageElementFactory_Release(&This->image_factory->IHTMLImageElementFactory_iface);
......@@ -809,7 +812,7 @@ static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocatio
TRACE("(%p)->(%p)\n", This, p);
hres = get_location(This->inner_window, &location);
hres = get_location(This->outer_window, &location);
if(FAILED(hres))
return hres;
......@@ -3922,7 +3925,7 @@ static HRESULT IHTMLWindow2_location_hook(DispatchEx *dispex, WORD flags, DISPPA
TRACE("forwarding to location.href\n");
hres = get_location(This, &location);
hres = get_location(This->base.outer_window, &location);
if(FAILED(hres))
return hres;
......
......@@ -493,7 +493,7 @@ struct HTMLLocation {
LONG ref;
HTMLInnerWindow *window;
HTMLOuterWindow *window;
};
typedef struct {
......@@ -576,6 +576,7 @@ struct HTMLOuterWindow {
unsigned readystate_pending;
HTMLInnerWindow *pending_window;
HTMLLocation *location;
IMoniker *mon;
IUri *uri;
IUri *uri_nofrag;
......@@ -619,8 +620,6 @@ struct HTMLInnerWindow {
LONG task_magic;
HTMLLocation *location;
IMoniker *mon;
nsChannelBSC *bscallback;
struct list bindings;
......@@ -994,7 +993,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(HTMLInnerWindow*,HTMLLocation**) DECLSPEC_HIDDEN;
HRESULT HTMLLocation_Create(HTMLOuterWindow*,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;
......
......@@ -11813,11 +11813,14 @@ static void test_document_mode_lock(void)
IHTMLWindow7 *window7;
IHTMLWindow5 *window5;
IHTMLWindow2 *window;
IDispatchEx *dispex;
IStream *stream;
DISPID dispid;
HRESULT hres;
HGLOBAL mem;
VARIANT var;
SIZE_T len;
BSTR bstr;
MSG msg;
notif_doc = doc = create_document();
......@@ -11872,6 +11875,14 @@ static void test_document_mode_lock(void)
IHTMLWindow2_Release(window);
VariantClear(&var);
bstr = SysAllocString(L"wineTestProp");
hres = IHTMLLocation_QueryInterface(location, &IID_IDispatchEx, (void**)&dispex);
ok(hres == S_OK, "Could not get IDispatchEx: %08lx\n", hres);
hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameEnsure, &dispid);
ok(hres == S_OK, "GetDispID(wineTestProp) returned: %08lx\n", hres);
IDispatchEx_Release(dispex);
SysFreeString(bstr);
len = strlen(doc_blank_ie9);
mem = GlobalAlloc(0, len);
memcpy(mem, doc_blank_ie9, len);
......@@ -11909,10 +11920,14 @@ static void test_document_mode_lock(void)
hres = IHTMLWindow2_get_location(window, &location2);
ok(hres == S_OK, "get_location failed: %08lx\n", hres);
todo_wine
ok(location == location2, "location != location2\n");
bstr = SysAllocString(L"wineTestProp");
hres = IHTMLLocation_GetIDsOfNames(location2, &IID_NULL, &bstr, 1, 0, &dispid);
ok(hres == DISP_E_UNKNOWNNAME, "GetIDsOfNames(wineTestProp) returned: %08lx\n", hres);
IHTMLLocation_Release(location2);
IHTMLLocation_Release(location);
SysFreeString(bstr);
hres = IHTMLWindow2_get_navigator(window, &navigator2);
ok(hres == S_OK, "get_navigator failed: %08lx\n", hres);
......
......@@ -3134,6 +3134,7 @@ static void test_iframe_connections(IHTMLDocument2 *doc)
static void test_doc_obj(IHTMLDocument2 *doc)
{
static DISPID propput_dispid = DISPID_PROPERTYPUT;
DISPID dispid, import_node_id, has_own_prop_id;
IHTMLOptionElementFactory *option, *option2;
IHTMLImageElementFactory *image, *image2;
......@@ -3307,6 +3308,28 @@ static void test_doc_obj(IHTMLDocument2 *doc)
IHTMLWindow7_Release(window7);
VariantClear(&res);
/* Add props to location, since it gets lost on navigation, despite being same object */
bstr = SysAllocString(L"wineTestProp");
hres = IHTMLLocation_QueryInterface(location, &IID_IDispatchEx, (void**)&dispex);
ok(hres == S_OK, "Could not get IDispatchEx: %08lx\n", hres);
hres = IDispatchEx_GetDispID(dispex, bstr, fdexNameEnsure, &dispid);
ok(hres == S_OK, "GetDispID(wineTestProp) returned: %08lx\n", hres);
SysFreeString(bstr);
dp.cArgs = dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &propput_dispid;
dp.rgvarg = &arg;
V_VT(&arg) = VT_I4;
V_I4(&arg) = 42;
bstr = SysAllocString(L"reload");
hres = IDispatchEx_GetDispID(dispex, bstr, 0, &dispid);
ok(hres == S_OK, "GetDispID(reload) returned: %08lx\n", hres);
hres = IDispatchEx_InvokeEx(dispex, dispid, 0, DISPATCH_PROPERTYPUT, &dp, NULL, NULL, NULL);
todo_wine_if(document_mode < 9)
ok(hres == (document_mode < 9 ? E_NOTIMPL : S_OK), "InvokeEx returned: %08lx\n", hres);
IDispatchEx_Release(dispex);
SysFreeString(bstr);
/* Navigate to a different document mode page, checking using the same doc obj.
Test that it breaks COM rules, since IEventTarget is conditionally exposed.
All the events registered on the old doc node are also removed.
......@@ -3356,10 +3379,24 @@ static void test_doc_obj(IHTMLDocument2 *doc)
hres = IHTMLWindow2_get_location(window, &location2);
ok(hres == S_OK, "get_location failed: %08lx\n", hres);
todo_wine
ok(location == location2, "location != location2\n");
bstr = SysAllocString(L"wineTestProp");
hres = IHTMLLocation_GetIDsOfNames(location2, &IID_NULL, &bstr, 1, 0, &dispid);
ok(hres == DISP_E_UNKNOWNNAME, "GetIDsOfNames(wineTestProp) returned: %08lx\n", hres);
SysFreeString(bstr);
memset(&dp, 0, sizeof(dp));
bstr = SysAllocString(L"reload");
hres = IHTMLLocation_GetIDsOfNames(location2, &IID_NULL, &bstr, 1, 0, &dispid);
ok(hres == S_OK, "GetIDsOfNames(reload) returned: %08lx\n", hres);
hres = IHTMLLocation_Invoke(location2, dispid, &IID_NULL, 0, DISPATCH_PROPERTYGET, &dp, &res, NULL, NULL);
ok(hres == S_OK, "Invoke failed: %08lx\n", hres);
ok(V_VT(&res) == VT_DISPATCH, "VT = %d\n", V_VT(&res));
IHTMLLocation_Release(location2);
IHTMLLocation_Release(location);
SysFreeString(bstr);
VariantClear(&res);
hres = IHTMLWindow2_get_navigator(window, &navigator2);
ok(hres == S_OK, "get_navigator failed: %08lx\n", hres);
......
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