From e7de2f8955fc79f4a49e9ca2b95bbd27bb853eaa Mon Sep 17 00:00:00 2001 From: Shubham Date: Fri, 19 Jul 2024 14:26:17 +0530 Subject: [PATCH] Refactor UnsavedController to use event.preventDefault() to trigger browser confirmation dialog Per https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event "best practice is to trigger the dialog by invoking `preventDefault()` on the event object, while also setting `returnValue` to support legacy cases." We don't need to support legacy cases, as our supported browsers all support the `preventDefault()` approach. See also: https://caniuse.com/mdn-api_window_beforeunload_event_preventdefault_activation Fixes #12132 From PR #12139 --- CHANGELOG.txt | 1 + CONTRIBUTORS.md | 1 + .../src/controllers/ActionController.test.js | 18 ++---- .../src/controllers/UnsavedController.test.js | 39 +++++++++---- client/src/controllers/UnsavedController.ts | 55 +++++++++++-------- docs/releases/6.3.md | 1 + .../templates/wagtailadmin/pages/create.html | 2 +- .../templates/wagtailadmin/pages/edit.html | 2 +- 8 files changed, 70 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 7b4cdbe779..11de853659 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -281,6 +281,7 @@ Changelog * Maintenance: Remove jQuery usage in telepath widget classes (Matt Westcott) * Maintenance: Remove `xregexp` (IE11 polyfill) along with `window.XRegExp` global util (LB (Ben) Johnston) * Maintenance: Refactor the Django port of `urlify` to use TypeScript, officially deprecate `window.URLify` global util (LB (Ben) Johnston) + * Maintenance: Adopt the modern best practice for `beforeunload` usage in `UnsavedController` to trigger a leave page warning when edits have been made (Shubham Mukati, Sage Abdullah) 6.0.6 (11.07.2024) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index ef54e855d8..f2217ab39a 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -833,6 +833,7 @@ * Daniel Black * Atif Khan * Sanjeev Holla S +* Shubham Mukati ## Translators diff --git a/client/src/controllers/ActionController.test.js b/client/src/controllers/ActionController.test.js index 30f5fa3ad9..fbb84333db 100644 --- a/client/src/controllers/ActionController.test.js +++ b/client/src/controllers/ActionController.test.js @@ -27,11 +27,7 @@ describe('ActionController', () => { reload: { configurable: true, value: jest.fn().mockImplementation(() => { - const event = new Event('beforeunload'); - Object.defineProperty(event, 'returnValue', { - value: null, - writable: true, - }); + const event = new Event('beforeunload', { cancelable: true }); window.dispatchEvent(event); }), }, @@ -156,9 +152,8 @@ describe('ActionController', () => { expect(beforeUnloadHandler).toHaveBeenCalledTimes(1); const event = beforeUnloadHandler.mock.lastCall[0]; - // These mean the browser confirmation dialog was not shown + // This means the browser confirmation dialog was not shown expect(event.defaultPrevented).toBe(false); - expect(event.returnValue).toBeNull(); window.removeEventListener('beforeunload', beforeUnloadHandler); }); @@ -168,7 +163,7 @@ describe('ActionController', () => {