mshtml: Implement pagehide event.

Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com>
This commit is contained in:
Gabriel Ivăncescu 2022-11-18 17:20:28 +02:00 committed by Alexandre Julliard
parent 570e6b2087
commit f8d4dbd703
6 changed files with 87 additions and 2 deletions

View file

@ -184,6 +184,8 @@ static const event_info_t event_info[] = {
EVENT_FIXME},
{L"msthumbnailclick", EVENT_TYPE_MOUSE, DISPID_EVPROP_ONMSTHUMBNAILCLICK,
EVENT_FIXME},
{L"pagehide", EVENT_TYPE_PAGETRANSITION, DISPID_EVPROP_ONPAGEHIDE,
0},
{L"pageshow", EVENT_TYPE_PAGETRANSITION, DISPID_EVPROP_ONPAGESHOW,
0},
{L"paste", EVENT_TYPE_CLIPBOARD, DISPID_EVMETH_ONPASTE,

View file

@ -51,6 +51,7 @@ typedef enum {
EVENTID_MOUSEUP,
EVENTID_MOUSEWHEEL,
EVENTID_MSTHUMBNAILCLICK,
EVENTID_PAGEHIDE,
EVENTID_PAGESHOW,
EVENTID_PASTE,
EVENTID_PROGRESS,

View file

@ -57,6 +57,7 @@ static nsresult NSAPI handle_blur(nsIDOMEventListener*,nsIDOMEvent*);
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_pagehide(nsIDOMEventListener*,nsIDOMEvent*);
static nsresult NSAPI handle_load(nsIDOMEventListener*,nsIDOMEvent*);
static nsresult NSAPI handle_beforeunload(nsIDOMEventListener*,nsIDOMEvent*);
static nsresult NSAPI handle_unload(nsIDOMEventListener*,nsIDOMEvent*);
@ -75,6 +76,7 @@ static const struct {
{ EVENTID_FOCUS, 0, EVENTLISTENER_VTBL(handle_focus) },
{ EVENTID_KEYPRESS, BUBBLES, EVENTLISTENER_VTBL(handle_keypress) },
{ EVENTID_PAGESHOW, OVERRIDE, EVENTLISTENER_VTBL(handle_pageshow), },
{ EVENTID_PAGEHIDE, OVERRIDE, EVENTLISTENER_VTBL(handle_pagehide), },
{ EVENTID_LOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_load), },
{ EVENTID_BEFOREUNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_beforeunload), },
{ EVENTID_UNLOAD, OVERRIDE, EVENTLISTENER_VTBL(handle_unload) },
@ -234,6 +236,26 @@ static nsresult NSAPI handle_pageshow(nsIDOMEventListener *iface, nsIDOMEvent *n
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)
{
IOleCommandTarget *olecmd = NULL;

View file

@ -19,12 +19,16 @@
var compat_version;
var tests = [];
var pageshow_fired = false;
var pageshow_fired = false, pagehide_fired = false;
document.doc_unload_events_called = false;
window.onbeforeunload = function() { ok(false, "beforeunload fired"); };
window.onunload = function() {
document.doc_unload_events_called = true;
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) {
@ -38,6 +42,16 @@ if(window.addEventListener) {
ok(document.readyState === "complete", "pageshow readyState = " + document.readyState);
}, 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("beforeunload", function() { ok(false, "beforeunload fired on document"); });
document.addEventListener("unload", function() { ok(false, "unload fired on document"); });
@ -51,6 +65,7 @@ sync_test("page transition events", function() {
ok(pageshow_fired === false, "pageshow fired");
else
ok(pageshow_fired === true, "pageshow not fired");
ok(pagehide_fired === false, "pagehide fired");
if(document.body.addEventListener)
document.body.addEventListener("unload", function() { ok(false, "unload fired on document.body"); });

View file

@ -101,7 +101,9 @@ DEFINE_EXPECT(visibilitychange);
DEFINE_EXPECT(onbeforeunload);
DEFINE_EXPECT(iframe_onbeforeunload);
DEFINE_EXPECT(onunload);
DEFINE_EXPECT(pagehide);
DEFINE_EXPECT(iframe_onunload);
DEFINE_EXPECT(iframe_pagehide);
DEFINE_EXPECT(doc1_onstorage);
DEFINE_EXPECT(doc1_onstoragecommit);
DEFINE_EXPECT(window1_onstorage);
@ -1458,6 +1460,17 @@ static HRESULT WINAPI iframe_onbeforeunload(IDispatchEx *iface, DISPID id, LCID
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,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
@ -1465,18 +1478,34 @@ static HRESULT WINAPI onunload(IDispatchEx *iface, DISPID id, LCID lcid, WORD wF
if(expect_iframe_onunload) {
ok(called_onbeforeunload, "beforeunload not fired 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);
return S_OK;
}
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,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
CHECK_EXPECT(iframe_onunload);
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);
return S_OK;
}
@ -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_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*)child_doc, L"beforeunload", (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)
SET_EXPECT(onbeforeunload);
SET_EXPECT(iframe_onbeforeunload);
SET_EXPECT(onunload);
SET_EXPECT(pagehide);
SET_EXPECT(iframe_onunload);
SET_EXPECT(iframe_pagehide);
navigate(doc, L"blank.html");
CHECK_CALLED(iframe_pagehide);
CHECK_CALLED(iframe_onunload);
CHECK_CALLED(pagehide);
CHECK_CALLED(onunload);
CHECK_CALLED(iframe_onbeforeunload);
CHECK_CALLED(onbeforeunload);

View file

@ -420,6 +420,16 @@ static void send_unload_events_impl(HTMLInnerWindow *window)
if(window->doc && !window->doc->unload_sent) {
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);
if(SUCCEEDED(hres)) {
dispatch_event(&window->event_target, event);