Skip to content

Commit

Permalink
Merge pull request #997 from ZeitOnline/WCM-423-beforeunload
Browse files Browse the repository at this point in the history
WCM-423: Ensure changed inlineforms are saved before leaving the page
  • Loading branch information
wosc authored Jan 27, 2025
2 parents 7176a47 + a2c9a22 commit 407f415
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 1 deletion.
1 change: 1 addition & 0 deletions core/docs/changelog/WCM-423.change
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
WCM-423: Ensure changed inlineforms are saved before leaving the page
5 changes: 4 additions & 1 deletion core/src/zeit/cms/browser/js/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,12 +307,15 @@ zeit.cms.follow_with_lock = function(element) {
window.open(element.href, element.target);
zeit.cms.request_lock.release();
} else {
window.location.href = element.href;
// Don't release the lock when replacing the current
// window. Opening the new page will implicitly reset
// everything. In fact it is necessary to keep the lock to
// prevent other requests to start until dispossing is
// properly finished.
// Store this, so window.beforeunload can release,
// see zeit.edit.inlineform
zeit.cms._follow_with_lock_called = true;
window.location.href = element.href;
}
});
});
Expand Down
1 change: 1 addition & 0 deletions core/src/zeit/cms/browser/resources/lightbox.css
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@
margin-top: -2em;
margin-right: 2em; /* Leave space for the close button */
background-color: transparent;
position: fixed;
}


Expand Down
52 changes: 52 additions & 0 deletions core/src/zeit/edit/browser/js/inlineform.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,55 @@ var wire_forms = function(parent) {
});
};

var save_dirty_before_leaving = function() {
if ($('.inline-form').length == 0) {
return;
}
window.addEventListener('beforeunload', function(event) {
var fields = $('.inline-form .field.dirty');
if (fields.length == 0) {
return;
}

// Causes browser to show dialog "do you really want to leave this page?"
event.preventDefault();

// That dialog is not customizeable though, so we show an overlay.
var forms = [];
var labels = [];
fields.each(function(i, field) {
field = $(field);
var form = field.closest('.inline-form')[0].form;
forms.push(form);
var label = field.find('label').text().trim();
labels.push(label);
});

var message = '<h1>Ungespeicherte Änderungen</h1>\n';
message += '<p>Die folgenden Änderungen werden erst jetzt gespeichert</p><ul>\n';
for (var label of labels) {
message += '<li>' + label + '</li>\n';
}
message += '</ul>\n';
var lightbox = new gocept.Lightbox(document.body, {use_ids: false});
lightbox.replace_content(message);

// Automatically save all the dirty forms
if (zeit.cms._follow_with_lock_called) {
// follow_with_lock intentionally keeps the lock, and the new
// page load will clear it. But since we want the user to abort,
// we have to release the lock ourselves.
zeit.cms.request_lock.release();
}
var requests = forms.map((x) => x.submit());
MochiKit.Async.gatherResults(requests).addCallback(function() {
message += '<p>Speichern abgeschlossen</p>';
lightbox.replace_content(message);
MochiKit.Async.callLater(1, function() { lightbox.close(); });
});
});
};

var evaluate_form_signals = function(event) {
// we don't get the usual MochiKit behaviour that additional arguments to
// signal() are passed along, since window is a DOM object and thus handles
Expand Down Expand Up @@ -64,6 +113,9 @@ var reload_inline_view = function(selector) {
MochiKit.Signal.connect(window, 'script-loading-finished', function() {
setup_views();
wire_forms();
if (window.feature_toggles && window.feature_toggles.inlineform_save_beforeunload) {
save_dirty_before_leaving();
}
});

MochiKit.Signal.connect(window, 'cp-editor-initialized', function() {
Expand Down

0 comments on commit 407f415

Please sign in to comment.