Delay dirty form check data snapshot to avoid race conditions. Fix #4978 (#5469)

User interaction with the form within the 10s delay also won’t trigger the confirmation message. There will still be race condition issues if form widgets like rich text take 10+ seconds to initialise – but that doesn’t seem likely.
pull/5479/head
Thibaud Colas 2019-07-28 02:42:44 -04:00 zatwierdzone przez Matt Westcott
rodzic b818eeab5d
commit db9b582912
3 zmienionych plików z 11 dodań i 2 usunięć

Wyświetl plik

@ -78,6 +78,7 @@ Changelog
* Fix: Added missing `is_stored_locally` method to `AbstractDocument` (jonny5532)
* Fix: Query model no longer removes punctuation as part of string normalisation (William Blackie)
* Fix: Make login test helper work with user models with non-default username fields (Andrew Miller)
* Fix: Delay dirty form check to prevent "unsaved changes" warning from being wrongly triggered (Thibaud Colas)
2.5.1 (07.05.2019)

Wyświetl plik

@ -99,6 +99,7 @@ Bug fixes
* Added missing ``is_stored_locally`` method to ``AbstractDocument`` (jonny5532)
* Query model no longer removes punctuation as part of string normalisation (William Blackie)
* Make login test helper work with user models with non-default username fields (Andrew Miller)
* Delay dirty form check to prevent "unsaved changes" warning from being wrongly triggered (Thibaud Colas)
Upgrade considerations

Wyświetl plik

@ -57,16 +57,23 @@ function enableDirtyFormCheck(formSelector, options) {
var $form = $(formSelector);
var confirmationMessage = options.confirmationMessage || ' ';
var alwaysDirty = options.alwaysDirty || false;
var initialData = $form.serialize();
var initialData = null;
var formSubmitted = false;
$form.on('submit', function() {
formSubmitted = true;
});
// Delay snapshotting the forms data to avoid race conditions with form widgets that might process the values.
// User interaction with the form within that delay also wont trigger the confirmation message.
setTimeout(function() {
initialData = $form.serialize();
}, 1000 * 10);
window.addEventListener('beforeunload', function(event) {
var isDirty = initialData && $form.serialize() != initialData;
var displayConfirmation = (
!formSubmitted && (alwaysDirty || $form.serialize() != initialData)
!formSubmitted && (alwaysDirty || isDirty)
);
if (displayConfirmation) {