mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 04:34:48 +00:00
mshtml: Dispatch beforeunload event to the window.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
parent
e2bb4c1b88
commit
00dbd769b9
|
@ -58,6 +58,7 @@ static nsresult NSAPI handle_focus(nsIDOMEventListener*,nsIDOMEvent*);
|
|||
static nsresult NSAPI handle_keypress(nsIDOMEventListener*,nsIDOMEvent*);
|
||||
static nsresult NSAPI handle_pageshow(nsIDOMEventListener*,nsIDOMEvent*);
|
||||
static nsresult NSAPI handle_load(nsIDOMEventListener*,nsIDOMEvent*);
|
||||
static nsresult NSAPI handle_beforeunload(nsIDOMEventListener*,nsIDOMEvent*);
|
||||
|
||||
enum doc_event_listener_flags {
|
||||
BUBBLES = 0x0001,
|
||||
|
@ -74,6 +75,7 @@ static const struct {
|
|||
{ EVENTID_KEYPRESS, BUBBLES, EVENTLISTENER_VTBL(handle_keypress) },
|
||||
{ EVENTID_PAGESHOW, OVERRIDE, EVENTLISTENER_VTBL(handle_pageshow), },
|
||||
{ EVENTID_LOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_load), },
|
||||
{ EVENTID_BEFOREUNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_beforeunload), },
|
||||
};
|
||||
|
||||
struct nsDocumentEventListener {
|
||||
|
@ -333,6 +335,27 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult NSAPI handle_beforeunload(nsIDOMEventListener *iface, nsIDOMEvent *nsevent)
|
||||
{
|
||||
nsEventListener *This = impl_from_nsIDOMEventListener(iface);
|
||||
HTMLDocumentNode *doc = This->This->doc;
|
||||
HTMLInnerWindow *window;
|
||||
DOMEvent *event;
|
||||
HRESULT hres;
|
||||
|
||||
if(!doc || !(window = doc->window))
|
||||
return NS_OK;
|
||||
|
||||
/* Gecko dispatches this to the document, but IE dispatches it to the window */
|
||||
hres = create_event_from_nsevent(nsevent, dispex_compat_mode(&doc->node.event_target.dispex), &event);
|
||||
if(SUCCEEDED(hres)) {
|
||||
dispatch_event(&window->event_target, event);
|
||||
IDOMEvent_Release(&event->IDOMEvent_iface);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent *nsevent)
|
||||
{
|
||||
nsEventListener *This = impl_from_nsIDOMEventListener(iface);
|
||||
|
|
|
@ -20,6 +20,8 @@ var compat_version;
|
|||
var tests = [];
|
||||
|
||||
var pageshow_fired = false;
|
||||
window.onbeforeunload = function() { ok(false, "beforeunload fired"); };
|
||||
|
||||
if(window.addEventListener) {
|
||||
window.addEventListener("pageshow", function(e) {
|
||||
pageshow_fired = true;
|
||||
|
@ -32,6 +34,9 @@ if(window.addEventListener) {
|
|||
}, true);
|
||||
|
||||
document.addEventListener("visibilitychange", function() { ok(false, "visibilitychange fired"); });
|
||||
document.addEventListener("beforeunload", function() { ok(false, "beforeunload fired on document"); });
|
||||
}else {
|
||||
document.attachEvent("onbeforeunload", function() { ok(false, "beforeunload fired on document"); });
|
||||
}
|
||||
|
||||
sync_test("page transition events", function() {
|
||||
|
|
|
@ -98,6 +98,8 @@ DEFINE_EXPECT(submit_onclick_setret);
|
|||
DEFINE_EXPECT(elem2_cp_onclick);
|
||||
DEFINE_EXPECT(iframe_onload);
|
||||
DEFINE_EXPECT(visibilitychange);
|
||||
DEFINE_EXPECT(onbeforeunload);
|
||||
DEFINE_EXPECT(iframe_onbeforeunload);
|
||||
DEFINE_EXPECT(doc1_onstorage);
|
||||
DEFINE_EXPECT(doc1_onstoragecommit);
|
||||
DEFINE_EXPECT(window1_onstorage);
|
||||
|
@ -1431,6 +1433,27 @@ static HRESULT WINAPI onvisibilitychange(IDispatchEx *iface, DISPID id, LCID lci
|
|||
|
||||
EVENT_HANDLER_FUNC_OBJ(onvisibilitychange);
|
||||
|
||||
static HRESULT WINAPI onbeforeunload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
CHECK_EXPECT(onbeforeunload);
|
||||
test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
EVENT_HANDLER_FUNC_OBJ(onbeforeunload);
|
||||
|
||||
static HRESULT WINAPI iframe_onbeforeunload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
CHECK_EXPECT(iframe_onbeforeunload);
|
||||
ok(called_onbeforeunload, "beforeunload not fired on parent window before iframe\n");
|
||||
test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
EVENT_HANDLER_FUNC_OBJ(iframe_onbeforeunload);
|
||||
|
||||
static HRESULT WINAPI nocall(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
|
||||
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
|
@ -2460,6 +2483,85 @@ static void test_visibilitychange(IHTMLDocument2 *doc)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_unload_event(IHTMLDocument2 *doc)
|
||||
{
|
||||
IHTMLDocument2 *child_doc;
|
||||
IHTMLFrameBase2 *iframe;
|
||||
IHTMLDocument6 *doc6;
|
||||
IHTMLElement2 *elem;
|
||||
IHTMLWindow2 *child;
|
||||
HRESULT hres;
|
||||
VARIANT v;
|
||||
BSTR bstr;
|
||||
|
||||
V_VT(&v) = VT_DISPATCH;
|
||||
V_DISPATCH(&v) = (IDispatch*)&onbeforeunload_obj;
|
||||
hres = IHTMLWindow2_put_onbeforeunload(window, v);
|
||||
ok(hres == S_OK, "put_onbeforeunload failed: %08lx\n", hres);
|
||||
|
||||
V_VT(&v) = VT_EMPTY;
|
||||
hres = IHTMLWindow2_get_onbeforeunload(window, &v);
|
||||
ok(hres == S_OK, "get_onbeforeunload failed: %08lx\n", hres);
|
||||
ok(V_VT(&v) == VT_DISPATCH, "V_VT(onbeforeunload) = %d\n", V_VT(&v));
|
||||
ok(V_DISPATCH(&v) == (IDispatch*)&onbeforeunload_obj, "V_DISPATCH(onbeforeunload) = %p\n", V_DISPATCH(&v));
|
||||
|
||||
hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument6, (void**)&doc6);
|
||||
ok(hres == S_OK, "Could not get IHTMLDocument6 iface: %08lx\n", hres);
|
||||
bstr = SysAllocString(L"ifr");
|
||||
hres = IHTMLDocument6_getElementById(doc6, bstr, &elem);
|
||||
ok(hres == S_OK, "getElementById failed: %08lx\n", hres);
|
||||
IHTMLDocument6_Release(doc6);
|
||||
SysFreeString(bstr);
|
||||
|
||||
hres = IHTMLElement2_QueryInterface(elem, &IID_IHTMLFrameBase2, (void**)&iframe);
|
||||
ok(hres == S_OK, "Could not get IHTMLFrameBase2 iface: %08lx\n", hres);
|
||||
IHTMLElement2_Release(elem);
|
||||
hres = IHTMLFrameBase2_get_contentWindow(iframe, &child);
|
||||
ok(hres == S_OK, "get_contentWindow failed: %08lx\n", hres);
|
||||
IHTMLFrameBase2_Release(iframe);
|
||||
|
||||
hres = IHTMLWindow2_get_document(child, &child_doc);
|
||||
ok(hres == S_OK, "get_document failed: %08lx\n", hres);
|
||||
|
||||
V_VT(&v) = VT_DISPATCH;
|
||||
V_DISPATCH(&v) = (IDispatch*)&iframe_onbeforeunload_obj;
|
||||
hres = IHTMLWindow2_put_onbeforeunload(child, v);
|
||||
ok(hres == S_OK, "put_onbeforeunload failed: %08lx\n", hres);
|
||||
|
||||
V_VT(&v) = VT_EMPTY;
|
||||
hres = IHTMLWindow2_get_onbeforeunload(child, &v);
|
||||
ok(hres == S_OK, "get_onbeforeunload failed: %08lx\n", hres);
|
||||
ok(V_VT(&v) == VT_DISPATCH, "V_VT(onbeforeunload) = %d\n", V_VT(&v));
|
||||
ok(V_DISPATCH(&v) == (IDispatch*)&iframe_onbeforeunload_obj, "V_DISPATCH(onbeforeunload) = %p\n", V_DISPATCH(&v));
|
||||
|
||||
add_event_listener((IUnknown*)doc, L"beforeunload", (IDispatch*)&nocall_obj, VARIANT_TRUE);
|
||||
add_event_listener((IUnknown*)child_doc, L"beforeunload", (IDispatch*)&nocall_obj, VARIANT_TRUE);
|
||||
IHTMLDocument2_Release(child_doc);
|
||||
IHTMLWindow2_Release(child);
|
||||
|
||||
SET_EXPECT(onbeforeunload);
|
||||
SET_EXPECT(iframe_onbeforeunload);
|
||||
navigate(doc, L"blank.html");
|
||||
CHECK_CALLED(iframe_onbeforeunload);
|
||||
CHECK_CALLED(onbeforeunload);
|
||||
|
||||
V_VT(&v) = VT_EMPTY;
|
||||
hres = IHTMLWindow2_get_onbeforeunload(window, &v);
|
||||
ok(hres == S_OK, "get_onbeforeunload failed: %08lx\n", hres);
|
||||
ok(V_VT(&v) == VT_NULL, "V_VT(onbeforeunload) = %d\n", V_VT(&v));
|
||||
|
||||
V_VT(&v) = VT_DISPATCH;
|
||||
V_DISPATCH(&v) = (IDispatch*)&onbeforeunload_obj;
|
||||
hres = IHTMLWindow2_put_onbeforeunload(window, v);
|
||||
ok(hres == S_OK, "put_onbeforeunload failed: %08lx\n", hres);
|
||||
|
||||
V_VT(&v) = VT_EMPTY;
|
||||
hres = IHTMLWindow2_get_onbeforeunload(window, &v);
|
||||
ok(hres == S_OK, "get_onbeforeunload failed: %08lx\n", hres);
|
||||
ok(V_VT(&v) == VT_DISPATCH, "V_VT(onbeforeunload) = %d\n", V_VT(&v));
|
||||
ok(V_DISPATCH(&v) == (IDispatch*)&onbeforeunload_obj, "V_DISPATCH(onbeforeunload) = %p\n", V_DISPATCH(&v));
|
||||
}
|
||||
|
||||
static void test_submit(IHTMLDocument2 *doc)
|
||||
{
|
||||
IHTMLElement *elem, *submit;
|
||||
|
@ -5571,6 +5673,7 @@ START_TEST(events)
|
|||
run_test_from_res(L"doc_with_prop_ie9.html", test_doc_obj);
|
||||
run_test_from_res(L"doc_with_prop_ie9.html", test_visibilitychange);
|
||||
run_test_from_res(L"blank_ie10.html", test_visibilitychange);
|
||||
run_test_from_res(L"iframe.html", test_unload_event);
|
||||
run_test(empty_doc_ie9_str, test_create_event);
|
||||
}
|
||||
|
||||
|
|
4
dlls/mshtml/tests/iframe.html
Normal file
4
dlls/mshtml/tests/iframe.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
<html>
|
||||
<head><meta http-equiv="x-ua-compatible" content="IE=11" /></head>
|
||||
<body><iframe src="about:blank" id="ifr"></iframe></body>
|
||||
</html>
|
|
@ -82,6 +82,9 @@ doc_with_prop.html HTML "doc_with_prop.html"
|
|||
/* @makedep: doc_with_prop_ie9.html */
|
||||
doc_with_prop_ie9.html HTML "doc_with_prop_ie9.html"
|
||||
|
||||
/* @makedep: iframe.html */
|
||||
iframe.html HTML "iframe.html"
|
||||
|
||||
/* For res: protocol test: */
|
||||
|
||||
/* @makedep: jstest.html */
|
||||
|
|
Loading…
Reference in a new issue