From: Gabriel Ivăncescu gabrielopcode@gmail.com
Even in IE9+ modes, it's still a non-JS object.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/dispex.c | 1 + dlls/mshtml/htmllocation.c | 31 +++++++++++++--------------- dlls/mshtml/htmlwindow.c | 19 ++++++++++-------- dlls/mshtml/mshtml_private.h | 7 +++---- dlls/mshtml/tests/dom.c | 17 +++++++++++++++- dlls/mshtml/tests/events.c | 39 +++++++++++++++++++++++++++++++++++- 6 files changed, 83 insertions(+), 31 deletions(-)
diff --git a/dlls/mshtml/dispex.c b/dlls/mshtml/dispex.c index 2f9453918c1..817d77dda7d 100644 --- a/dlls/mshtml/dispex.c +++ b/dlls/mshtml/dispex.c @@ -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) { diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index 066ebb4f5e6..5c31ee02e04 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -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; diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c index c4c6a99f5f3..e678c9f99e0 100644 --- a/dlls/mshtml/htmlwindow.c +++ b/dlls/mshtml/htmlwindow.c @@ -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;
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 870ba14c8b4..1ce25d5c862 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -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; diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 2efbbbf513c..39af8faa8d5 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -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); diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index 196ab3160a7..ecc3bfb3bc1 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -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);