Sorry for the lengthy post but this needs some context.
Context
I'm building an app for academic papers publishing. The stack is Laravel + vanilla JS and I use Etherpad to edit the papers. It is embedded in the last step of a two-part form. Because of this configuration (that I cannot change), here's the process :
- the data given in the first part of the form is stored through laravel
- Etherpad is prepared to show an empty pad in the second part of the form and creates its own stuff in its own database
- the second part is submitted : Etherpad updates its stuff, I populate a mapping table in my database, and then I do other stuff relevant to my app only.
Issue
The first part of the form is submitted via ajax for various usability reasons; thus, if the user is on the second part and reloads the page, they return to the first step and part of my work is lost - it creates inconsistencies in my database and lets unnecessary stuff created in Etherpad's.
Need
Therefore I need to catch any and all ways to reload the page and show a custom confirmation modal. This allows me to clean up the data properly.
Approach 1
I've tried a manual approach : catch keydown events (F5, CTRL+R, CTRL+SHIFT+R), catch links click (such as a go back link), catch back/forward mouse buttons, ... I realized I can't catch the browser's reload button which is unfortunate.
Approach 2
I switched to an approach using performanceNavigationTiming, with the beforeunload event :
window.addEventListener('beforeunload', (event) => {
event.preventDefault();
if (performance.getEntries()[0].type == "reload") {
Shared.cancelForm(false);
window.addEventListener('unload', (event) => {
Shared.cancelForm(false);
});
}
});
It works like a charm but the browser keeps showing me its own confirm modal, which I can't customize or remove, as far as I know. When the user click "Stay on the page", it shows my own cancelForm modal. I added the unload listener to try and catch the fact that the user might click "Leave the page" in the browser's modal, but it doesn't seem to work either.
Next possible approach
I was wondering if a PerformanceObserver could help, but I'm not sure how to use it properly, nor if it will be of any use in my case. My understanding is quite limited on this point.
Any help in the use of PerformanceObserver (for my purpose or more generally), or regarding the feature I'm trying to implement, is happily welcome !!