Fassung 1.7.0: verlässliche Installation, übersichtliche Verwaltung und bedienbare Bewegung
This commit is contained in:
1 parent
b164c4edfe
commit
495b26896e
55 files changed
+1632
-423
No files matched your search
+26
-5
@@ -5,6 +5,8 @@ import { createRichText } from './rich-text.js';
|
||||
import { createCanvasOverlay } from './canvas-overlay.js';
|
||||
import { preview, rowPreview } from './library-previews.js';
|
||||
import { decorateContainers } from './preview-containers.js';
|
||||
import { initMotion } from './motion.js';
|
||||
import { initSliders } from './slider.js';
|
||||
|
||||
// Mirrors DocumentValidator::ICONS; the server rejects anything outside this list.
|
||||
const ICONS = ['app', 'web', 'design', 'network', 'hardware', 'shop', 'support', 'shield', 'clock', 'star', 'phone', 'mail', 'pin', 'check'];
|
||||
@@ -16,6 +18,7 @@ const $ = selector => document.querySelector(selector);
|
||||
// same document, draft and preview endpoints, so this file does not care which one it drives.
|
||||
const api = root.dataset.api;
|
||||
const editingArea = 'page' !== root.dataset.kind;
|
||||
const adminBase = document.querySelector('meta[name="admin-base"]').content;
|
||||
const mayScript = 'true' === root.dataset.canScript;
|
||||
let history, selected = null, version, revisionId, publishedRevisionId, csrfToken;
|
||||
let busy = false, conflict = false, previewTimer, previewController, previewSequence = 0;
|
||||
@@ -26,6 +29,21 @@ let previewScale = 1, overlay = null, pendingInsert = null;
|
||||
const collapsed = new Set();
|
||||
let renderedProperties = null;
|
||||
let revealAfterPreview = null;
|
||||
let previewPlayback = false, stopPlayback = () => {};
|
||||
|
||||
function playPreview() {
|
||||
stopPlayback(); stopPlayback = () => {};
|
||||
const button = $('#preview-motion');
|
||||
button.setAttribute('aria-pressed', String(previewPlayback));
|
||||
button.textContent = previewPlayback ? 'Bewegung stoppen' : 'Bewegung testen';
|
||||
const doc = $('#preview').contentDocument;
|
||||
if (previewPlayback && doc?.body) {
|
||||
const stopMotion = initMotion(doc), stopSliders = initSliders(doc);
|
||||
stopPlayback = () => { stopMotion(); stopSliders(); };
|
||||
}
|
||||
}
|
||||
|
||||
$('#preview-motion').addEventListener('click', () => { previewPlayback = !previewPlayback; playPreview(); });
|
||||
|
||||
function notify(message = '', recover = false) {
|
||||
$('#message').textContent = message;
|
||||
@@ -56,7 +74,7 @@ async function request(path, body, signal) {
|
||||
|
||||
function controls() {
|
||||
const ready = Boolean(history);
|
||||
$('#save-status').textContent = busy ? 'Wird gespeichert …' : conflict ? 'Speicherkonflikt' : !ready ? 'Wird geladen …' : history.dirty ? 'Ungespeicherte Änderungen' : revisionId === publishedRevisionId ? 'Veröffentlicht' : 'Entwurf gespeichert';
|
||||
$('#save-status').textContent = busy ? 'Wird gespeichert …' : conflict ? 'Speicherkonflikt' : !ready ? 'Wird geladen …' : history.dirty ? 'Ungespeicherte Änderungen' : editingArea ? 'Bereich gespeichert' : revisionId === publishedRevisionId ? 'Veröffentlicht' : 'Entwurf gespeichert';
|
||||
$('#save').disabled = !ready || busy || conflict || !history.dirty;
|
||||
if ($('#publish')) $('#publish').disabled = !ready || busy || conflict || history.dirty || revisionId === publishedRevisionId;
|
||||
$('#undo').disabled = !ready || busy || !history.past.length;
|
||||
@@ -77,6 +95,7 @@ function controls() {
|
||||
$('#select-page').disabled = !ready || busy;
|
||||
$('#add-root-section').disabled = !ready || busy;
|
||||
$('#open-media-library').disabled = !ready || busy;
|
||||
$('#preview-motion').disabled = !ready || busy;
|
||||
}
|
||||
|
||||
function renderTree() {
|
||||
@@ -440,7 +459,7 @@ function renderLegacyEffects(block, panel) {
|
||||
none: 'Keiner', lift: 'Leicht anheben', sink: 'Leicht absenken', zoom: 'Bild vergrößern',
|
||||
glow: 'Leuchten', tilt: 'Leicht kippen', 'grow-border': 'Rahmen einfahren',
|
||||
}],
|
||||
['entrance', 'Einblendung beim Laden', {
|
||||
['entrance', 'Einblendung beim Erscheinen', {
|
||||
none: 'Keine', fade: 'Sanft einblenden', rise: 'Von unten', sink: 'Von oben', left: 'Von links',
|
||||
right: 'Von rechts', zoom: 'Heranzoomen', flip: 'Kippen', blur: 'Aus der Unschärfe',
|
||||
}],
|
||||
@@ -453,7 +472,7 @@ function renderLegacyEffects(block, panel) {
|
||||
select.addEventListener('change', () => { history.change(doc => setEffect(doc, selected, key, select.value)); controls(); schedulePreview(); });
|
||||
panel.append(labelEl, select);
|
||||
}
|
||||
const note = document.createElement('p'); note.className = 'field-help'; note.textContent = 'Bewegungseffekte werden bei „Bewegung reduzieren“ ausgeschaltet. Zoom wirkt auf enthaltene Bilder. Einblendungen laufen beim Laden der Seite, nicht beim Scrollen: eine öffentliche Seite führt kein JavaScript aus.'; panel.append(note);
|
||||
const note = document.createElement('p'); note.className = 'field-help'; note.textContent = 'Einblendungen starten, sobald das Element im Bildschirm erscheint. Mit „Bewegung testen“ lässt sich das in der Vorschau prüfen. Die Einstellung „Bewegung reduzieren“ wird berücksichtigt.'; panel.append(note);
|
||||
}
|
||||
|
||||
function chooseMedia(multiple) {
|
||||
@@ -654,6 +673,7 @@ async function updatePreview() {
|
||||
highlight(revealAfterPreview === selected); revealAfterPreview = null;
|
||||
markInsertTarget();
|
||||
frame.style.visibility = '';
|
||||
playPreview();
|
||||
$('#preview-status').textContent = loaded
|
||||
? 'Entwurf · Klicken wählt aus, Doppelklick bearbeitet Text, Elemente lassen sich hierher ziehen.'
|
||||
: 'Editor-Hilfsflächen konnten nicht geladen werden. Bitte den Editor neu laden.';
|
||||
@@ -663,6 +683,7 @@ async function updatePreview() {
|
||||
};
|
||||
// Solange die Gestaltung fehlt, bleibt die Fläche leer statt falsch.
|
||||
frame.style.visibility = 'hidden';
|
||||
stopPlayback();
|
||||
frame.srcdoc = html;
|
||||
// Sobald der Kopf da ist, wird gestaltet - geprüft Bild für Bild statt auf ein Ereignis zu
|
||||
// warten, das es für srcdoc nicht zuverlässig gibt.
|
||||
@@ -696,7 +717,7 @@ function changed() {
|
||||
|
||||
async function loadDesignSchema() {
|
||||
try {
|
||||
const response = await fetch('/admin/api/design', { credentials: 'same-origin' });
|
||||
const response = await fetch(adminBase + '/api/design', { credentials: 'same-origin' });
|
||||
if (!response.ok) return;
|
||||
designSchema = await response.json();
|
||||
designPanel = createDesignPanel({
|
||||
@@ -1024,7 +1045,7 @@ $('#confirm-preset').addEventListener('click', async () => {
|
||||
const name = $('#preset-name').value.trim();
|
||||
const error = $('#preset-error');
|
||||
try {
|
||||
const response = await fetch('/admin/api/style-presets', {
|
||||
const response = await fetch(adminBase + '/api/style-presets', {
|
||||
method: 'POST', credentials: 'same-origin',
|
||||
headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': designSchema.csrfToken },
|
||||
body: JSON.stringify({ name, style: pendingPreset }),
|
||||
|
||||
Reference in new issue
Block a user