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

mshtml: Implement pagehide event.

parent 570e6b20
...@@ -184,6 +184,8 @@ static const event_info_t event_info[] = { ...@@ -184,6 +184,8 @@ static const event_info_t event_info[] = {
EVENT_FIXME}, EVENT_FIXME},
{L"msthumbnailclick", EVENT_TYPE_MOUSE, DISPID_EVPROP_ONMSTHUMBNAILCLICK, {L"msthumbnailclick", EVENT_TYPE_MOUSE, DISPID_EVPROP_ONMSTHUMBNAILCLICK,
EVENT_FIXME}, EVENT_FIXME},
{L"pagehide", EVENT_TYPE_PAGETRANSITION, DISPID_EVPROP_ONPAGEHIDE,
0},
{L"pageshow", EVENT_TYPE_PAGETRANSITION, DISPID_EVPROP_ONPAGESHOW, {L"pageshow", EVENT_TYPE_PAGETRANSITION, DISPID_EVPROP_ONPAGESHOW,
0}, 0},
{L"paste", EVENT_TYPE_CLIPBOARD, DISPID_EVMETH_ONPASTE, {L"paste", EVENT_TYPE_CLIPBOARD, DISPID_EVMETH_ONPASTE,
......
...@@ -51,6 +51,7 @@ typedef enum { ...@@ -51,6 +51,7 @@ typedef enum {
EVENTID_MOUSEUP, EVENTID_MOUSEUP,
EVENTID_MOUSEWHEEL, EVENTID_MOUSEWHEEL,
EVENTID_MSTHUMBNAILCLICK, EVENTID_MSTHUMBNAILCLICK,
EVENTID_PAGEHIDE,
EVENTID_PAGESHOW, EVENTID_PAGESHOW,
EVENTID_PASTE, EVENTID_PASTE,
EVENTID_PROGRESS, EVENTID_PROGRESS,
......
...@@ -57,6 +57,7 @@ static nsresult NSAPI handle_blur(nsIDOMEventListener*,nsIDOMEvent*); ...@@ -57,6 +57,7 @@ static nsresult NSAPI handle_blur(nsIDOMEventListener*,nsIDOMEvent*);
static nsresult NSAPI handle_focus(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_focus(nsIDOMEventListener*,nsIDOMEvent*);
static nsresult NSAPI handle_keypress(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_keypress(nsIDOMEventListener*,nsIDOMEvent*);
static nsresult NSAPI handle_pageshow(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_pageshow(nsIDOMEventListener*,nsIDOMEvent*);
static nsresult NSAPI handle_pagehide(nsIDOMEventListener*,nsIDOMEvent*);
static nsresult NSAPI handle_load(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_load(nsIDOMEventListener*,nsIDOMEvent*);
static nsresult NSAPI handle_beforeunload(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_beforeunload(nsIDOMEventListener*,nsIDOMEvent*);
static nsresult NSAPI handle_unload(nsIDOMEventListener*,nsIDOMEvent*); static nsresult NSAPI handle_unload(nsIDOMEventListener*,nsIDOMEvent*);
...@@ -75,6 +76,7 @@ static const struct { ...@@ -75,6 +76,7 @@ static const struct {
{ EVENTID_FOCUS, 0, EVENTLISTENER_VTBL(handle_focus) }, { EVENTID_FOCUS, 0, EVENTLISTENER_VTBL(handle_focus) },
{ EVENTID_KEYPRESS, BUBBLES, EVENTLISTENER_VTBL(handle_keypress) }, { EVENTID_KEYPRESS, BUBBLES, EVENTLISTENER_VTBL(handle_keypress) },
{ EVENTID_PAGESHOW, OVERRIDE, EVENTLISTENER_VTBL(handle_pageshow), }, { EVENTID_PAGESHOW, OVERRIDE, EVENTLISTENER_VTBL(handle_pageshow), },
{ EVENTID_PAGEHIDE, OVERRIDE, EVENTLISTENER_VTBL(handle_pagehide), },
{ EVENTID_LOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_load), }, { EVENTID_LOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_load), },
{ EVENTID_BEFOREUNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_beforeunload), }, { EVENTID_BEFOREUNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_beforeunload), },
{ EVENTID_UNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_unload) }, { EVENTID_UNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_unload) },
...@@ -234,6 +236,26 @@ static nsresult NSAPI handle_pageshow(nsIDOMEventListener *iface, nsIDOMEvent *n ...@@ -234,6 +236,26 @@ static nsresult NSAPI handle_pageshow(nsIDOMEventListener *iface, nsIDOMEvent *n
return NS_OK; return NS_OK;
} }
static nsresult NSAPI handle_pagehide(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) || !doc->dom_document || doc->document_mode < COMPAT_MODE_IE11 || doc->unload_sent)
return NS_OK;
hres = create_document_event(doc, EVENTID_PAGEHIDE, &event);
if(SUCCEEDED(hres)) {
dispatch_event(&window->event_target, event);
IDOMEvent_Release(&event->IDOMEvent_iface);
}
return NS_OK;
}
static void handle_docobj_load(HTMLDocumentObj *doc) static void handle_docobj_load(HTMLDocumentObj *doc)
{ {
IOleCommandTarget *olecmd = NULL; IOleCommandTarget *olecmd = NULL;
......
...@@ -19,12 +19,16 @@ ...@@ -19,12 +19,16 @@
var compat_version; var compat_version;
var tests = []; var tests = [];
var pageshow_fired = false; var pageshow_fired = false, pagehide_fired = false;
document.doc_unload_events_called = false; document.doc_unload_events_called = false;
window.onbeforeunload = function() { ok(false, "beforeunload fired"); }; window.onbeforeunload = function() { ok(false, "beforeunload fired"); };
window.onunload = function() { window.onunload = function() {
document.doc_unload_events_called = true; document.doc_unload_events_called = true;
ok(document.readyState === "complete", "unload readyState = " + document.readyState); ok(document.readyState === "complete", "unload readyState = " + document.readyState);
if(document.documentMode < 11)
ok(pagehide_fired === false, "pagehide fired before unload");
else
ok(pagehide_fired === true, "pagehide not fired before unload");
}; };
if(window.addEventListener) { if(window.addEventListener) {
...@@ -38,6 +42,16 @@ if(window.addEventListener) { ...@@ -38,6 +42,16 @@ if(window.addEventListener) {
ok(document.readyState === "complete", "pageshow readyState = " + document.readyState); ok(document.readyState === "complete", "pageshow readyState = " + document.readyState);
}, true); }, true);
window.addEventListener("pagehide", function(e) {
pagehide_fired = true;
ok(document.documentMode >= 11, "pagehide fired");
var r = Object.prototype.toString.call(e);
todo_wine.
ok(r === "[object PageTransitionEvent]", "pagehide toString = " + r);
ok("persisted" in e, "'persisted' not in pagehide event");
}, true);
document.addEventListener("visibilitychange", function() { ok(false, "visibilitychange fired"); }); document.addEventListener("visibilitychange", function() { ok(false, "visibilitychange fired"); });
document.addEventListener("beforeunload", function() { ok(false, "beforeunload fired on document"); }); document.addEventListener("beforeunload", function() { ok(false, "beforeunload fired on document"); });
document.addEventListener("unload", function() { ok(false, "unload fired on document"); }); document.addEventListener("unload", function() { ok(false, "unload fired on document"); });
...@@ -51,6 +65,7 @@ sync_test("page transition events", function() { ...@@ -51,6 +65,7 @@ sync_test("page transition events", function() {
ok(pageshow_fired === false, "pageshow fired"); ok(pageshow_fired === false, "pageshow fired");
else else
ok(pageshow_fired === true, "pageshow not fired"); ok(pageshow_fired === true, "pageshow not fired");
ok(pagehide_fired === false, "pagehide fired");
if(document.body.addEventListener) if(document.body.addEventListener)
document.body.addEventListener("unload", function() { ok(false, "unload fired on document.body"); }); document.body.addEventListener("unload", function() { ok(false, "unload fired on document.body"); });
......
...@@ -101,7 +101,9 @@ DEFINE_EXPECT(visibilitychange); ...@@ -101,7 +101,9 @@ DEFINE_EXPECT(visibilitychange);
DEFINE_EXPECT(onbeforeunload); DEFINE_EXPECT(onbeforeunload);
DEFINE_EXPECT(iframe_onbeforeunload); DEFINE_EXPECT(iframe_onbeforeunload);
DEFINE_EXPECT(onunload); DEFINE_EXPECT(onunload);
DEFINE_EXPECT(pagehide);
DEFINE_EXPECT(iframe_onunload); DEFINE_EXPECT(iframe_onunload);
DEFINE_EXPECT(iframe_pagehide);
DEFINE_EXPECT(doc1_onstorage); DEFINE_EXPECT(doc1_onstorage);
DEFINE_EXPECT(doc1_onstoragecommit); DEFINE_EXPECT(doc1_onstoragecommit);
DEFINE_EXPECT(window1_onstorage); DEFINE_EXPECT(window1_onstorage);
...@@ -1458,6 +1460,17 @@ static HRESULT WINAPI iframe_onbeforeunload(IDispatchEx *iface, DISPID id, LCID ...@@ -1458,6 +1460,17 @@ static HRESULT WINAPI iframe_onbeforeunload(IDispatchEx *iface, DISPID id, LCID
EVENT_HANDLER_FUNC_OBJ(iframe_onbeforeunload); EVENT_HANDLER_FUNC_OBJ(iframe_onbeforeunload);
static HRESULT WINAPI pagehide(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
CHECK_EXPECT(pagehide);
ok(!called_onunload, "unload fired before pagehide\n");
test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
return S_OK;
}
EVENT_HANDLER_FUNC_OBJ(pagehide);
static HRESULT WINAPI onunload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, static HRESULT WINAPI onunload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{ {
...@@ -1465,18 +1478,34 @@ static HRESULT WINAPI onunload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wF ...@@ -1465,18 +1478,34 @@ static HRESULT WINAPI onunload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wF
if(expect_iframe_onunload) { if(expect_iframe_onunload) {
ok(called_onbeforeunload, "beforeunload not fired before unload\n"); ok(called_onbeforeunload, "beforeunload not fired before unload\n");
ok(called_iframe_onbeforeunload, "beforeunload not fired on iframe before unload\n"); ok(called_iframe_onbeforeunload, "beforeunload not fired on iframe before unload\n");
} ok(called_pagehide, "pagehide not fired before unload\n");
}else
ok(!called_pagehide, "pagehide fired before unload in quirks mode\n");
test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller); test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
return S_OK; return S_OK;
} }
EVENT_HANDLER_FUNC_OBJ(onunload); EVENT_HANDLER_FUNC_OBJ(onunload);
static HRESULT WINAPI iframe_pagehide(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
CHECK_EXPECT(iframe_pagehide);
ok(called_pagehide, "pagehide not fired on parent window before iframe\n");
ok(called_onunload, "unload not fired on parent window before pagehide on iframe\n");
ok(!called_iframe_onunload, "unload fired before pagehide on iframe\n");
test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
return S_OK;
}
EVENT_HANDLER_FUNC_OBJ(iframe_pagehide);
static HRESULT WINAPI iframe_onunload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, static HRESULT WINAPI iframe_onunload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller) VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{ {
CHECK_EXPECT(iframe_onunload); CHECK_EXPECT(iframe_onunload);
ok(called_onunload, "unload not fired on parent window before iframe\n"); ok(called_onunload, "unload not fired on parent window before iframe\n");
ok(called_iframe_pagehide, "pagehide not fired before unload on iframe\n");
test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller); test_event_args(NULL, id, wFlags, pdp, pvarRes, pei, pspCaller);
return S_OK; return S_OK;
} }
...@@ -2585,6 +2614,8 @@ static void test_unload_event(IHTMLDocument2 *doc) ...@@ -2585,6 +2614,8 @@ static void test_unload_event(IHTMLDocument2 *doc)
ok(V_VT(&v) == VT_DISPATCH, "V_VT(onbeforeunload) = %d\n", V_VT(&v)); 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)); ok(V_DISPATCH(&v) == (IDispatch*)&iframe_onbeforeunload_obj, "V_DISPATCH(onbeforeunload) = %p\n", V_DISPATCH(&v));
add_event_listener((IUnknown*)window, L"pagehide", (IDispatch*)&pagehide_obj, VARIANT_TRUE);
add_event_listener((IUnknown*)child, L"pagehide", (IDispatch*)&iframe_pagehide_obj, VARIANT_TRUE);
add_event_listener((IUnknown*)doc, L"beforeunload", (IDispatch*)&nocall_obj, VARIANT_TRUE); 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); add_event_listener((IUnknown*)child_doc, L"beforeunload", (IDispatch*)&nocall_obj, VARIANT_TRUE);
add_event_listener((IUnknown*)doc, L"unload", (IDispatch*)&nocall_obj, VARIANT_TRUE); add_event_listener((IUnknown*)doc, L"unload", (IDispatch*)&nocall_obj, VARIANT_TRUE);
...@@ -2595,9 +2626,13 @@ static void test_unload_event(IHTMLDocument2 *doc) ...@@ -2595,9 +2626,13 @@ static void test_unload_event(IHTMLDocument2 *doc)
SET_EXPECT(onbeforeunload); SET_EXPECT(onbeforeunload);
SET_EXPECT(iframe_onbeforeunload); SET_EXPECT(iframe_onbeforeunload);
SET_EXPECT(onunload); SET_EXPECT(onunload);
SET_EXPECT(pagehide);
SET_EXPECT(iframe_onunload); SET_EXPECT(iframe_onunload);
SET_EXPECT(iframe_pagehide);
navigate(doc, L"blank.html"); navigate(doc, L"blank.html");
CHECK_CALLED(iframe_pagehide);
CHECK_CALLED(iframe_onunload); CHECK_CALLED(iframe_onunload);
CHECK_CALLED(pagehide);
CHECK_CALLED(onunload); CHECK_CALLED(onunload);
CHECK_CALLED(iframe_onbeforeunload); CHECK_CALLED(iframe_onbeforeunload);
CHECK_CALLED(onbeforeunload); CHECK_CALLED(onbeforeunload);
......
...@@ -420,6 +420,16 @@ static void send_unload_events_impl(HTMLInnerWindow *window) ...@@ -420,6 +420,16 @@ static void send_unload_events_impl(HTMLInnerWindow *window)
if(window->doc && !window->doc->unload_sent) { if(window->doc && !window->doc->unload_sent) {
window->doc->unload_sent = TRUE; window->doc->unload_sent = TRUE;
/* Native sends pagehide events prior to unload on the same window
before it moves on to the next window, so they're interleaved. */
if(window->doc->document_mode >= COMPAT_MODE_IE11) {
hres = create_document_event(window->doc, EVENTID_PAGEHIDE, &event);
if(SUCCEEDED(hres)) {
dispatch_event(&window->event_target, event);
IDOMEvent_Release(&event->IDOMEvent_iface);
}
}
hres = create_document_event(window->doc, EVENTID_UNLOAD, &event); hres = create_document_event(window->doc, EVENTID_UNLOAD, &event);
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
dispatch_event(&window->event_target, event); dispatch_event(&window->event_target, event);
......
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