Keep old pages readable, detect stale settings writes, make backups honest
- Own CSS is parsed on write only. A page whose stored CSS no longer passes a stricter rule answers 200 and opens in the editor; that one block loses its CSS. A document read several times in one request is validated once. - Settings and theme refuse a write from an outdated form. - A backup fails when a media file does not arrive completely and leaves no half directory behind; rotation counts intact backups only. - The archive update takes its backup behind the maintenance page. - A package import puts all media in place before removing the old ones, reports honestly when that fails and keeps a maintenance state that was already on. - Restoring replaces the SQLite file in one move and points at pending migrations. - Six irreversible actions ask first, in a dialog of the admin's own. - Ctrl+S in the editor takes the field being typed in along; Delete no longer removes a block while a dialog is open. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
This commit is contained in:
1 parent
0d61aa0f22
commit
ead47cc924
25 files changed
+437
-72
No files matched your search
+14
-2
@@ -1920,7 +1920,15 @@ function onKey(event) {
|
||||
if (!history || busy) return;
|
||||
const key = event.key.toLowerCase();
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
if (key === 's') { event.preventDefault(); save(); }
|
||||
if (key === 's') {
|
||||
event.preventDefault();
|
||||
// Viele Felder schreiben erst beim Verlassen ins Dokument (eigenes CSS, Zahlen im Design).
|
||||
// Ohne diesen Schritt sicherte Strg+S den Stand ohne das, was gerade getippt wurde - und
|
||||
// meldete trotzdem „gespeichert“.
|
||||
const field = document.activeElement;
|
||||
if (field && field.ownerDocument === document && inField(field) && !field.isContentEditable) field.blur();
|
||||
save();
|
||||
}
|
||||
// Keep native text-field undo intact; the toolbar always undoes the complete document.
|
||||
if (inField(event.target)) return;
|
||||
if (key === 'z' || key === 'y') { event.preventDefault(); (event.shiftKey || key === 'y') ? history.redo() : history.undo(); changed(); }
|
||||
@@ -1935,7 +1943,11 @@ function onKey(event) {
|
||||
}
|
||||
// Delete removes the selected element - but never while a field or the preview text is
|
||||
// being typed in, and never something the sidebar buttons would refuse.
|
||||
if ((event.key === 'Delete' || event.key === 'Backspace') && selected && !inField(event.target) && !inlineEdit && !$('#delete').disabled) {
|
||||
// Auch nicht, während ein Dialog offen ist oder der Fokus auf einem Bedienelement der
|
||||
// Seitenleiste liegt: Entf auf einer Kachel der Mediathek löschte sonst den gewählten Baustein.
|
||||
const where = event.target;
|
||||
const onStage = !where?.closest || where.ownerDocument !== document || where === document.body || Boolean(where.closest('#structure, .canvas-scroll'));
|
||||
if ((event.key === 'Delete' || event.key === 'Backspace') && selected && onStage && !document.querySelector('dialog[open]') && !inField(event.target) && !inlineEdit && !$('#delete').disabled) {
|
||||
event.preventDefault(); actions.delete(selected);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user