Vorschau zeigt nie eine Seite ohne ihre Gestaltung
CMS quality / php (8.2) (push) Canceled after 0s
CMS quality / php (8.4) (push) Canceled after 0s
CMS quality / browser (push) Canceled after 0s
CMS quality / mysql (push) Canceled after 0s

Gemessen: die Farben in der Vorschau und auf der veroeffentlichten
Seite waren immer identisch. Der Aufbau war das Problem - die
erzeugten Stile wurden im load-Ereignis des Rahmens angewandt, und das
feuert erst, wenn das letzte Bild geladen ist. Auf der nachgebauten
Startseite stand die Vorschau dadurch 1440 ms lang ohne eine einzige
Farbe da.

Jetzt wird angewandt, sobald das Dokument geparst ist; der Rahmen
bleibt bis dahin verdeckt; und gestaltet wird nur das neue Dokument -
der erste Anlauf gestaltete das alte und schaltete zu frueh sichtbar.

Die Editorkontrolle prueft dagegen das Verhalten statt der Zeit: der
Rahmen muss beim Aufbau verdeckt werden und danach wieder sichtbar.
Eine Zeitmessung haette auf der kleinen Testseite nichts gefunden.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
kantarciandClaude Opus 5 committed 2026-09-13 16:08:12 +02:00
1 parent e0d06ac44c
commit 6c477a52be
4 files changed
+88 -2

No files matched your search

+35 -2
View File
@@ -563,9 +563,20 @@ async function updatePreview() {
if (sequence !== previewSequence) return;
const frame = $('#preview');
const top = frame.contentWindow?.scrollY || 0;
frame.onload = () => {
if (sequence !== previewSequence) return;
let angewandt = false;
// Die Gestaltung muss sitzen, sobald der Kopf des Dokuments geparst ist. Vorher hing das an
// frame.onload - und das feuert erst, wenn das letzte Bild geladen ist. Auf einer Seite mit
// sechzehn Bildern stand die Vorschau dadurch sekundenlang ohne jede Gestaltung da: schwarze
// Knöpfe statt roter, kein Hero, keine Farben. Genau das hat Umut im Bild gesehen.
// Welches Dokument gerade im Rahmen steht. Ohne diesen Vergleich wird beim Warten auf das
// neue Dokument das alte gestaltet - es hat dieselben Kennzeichen -, der Rahmen wird sichtbar
// geschaltet, und gleich darauf ersetzt srcdoc den Inhalt durch den ungestalteten neuen.
const altesDokument = frame.contentDocument;
const anwenden = () => {
if (angewandt || sequence !== previewSequence) return;
const doc = frame.contentDocument;
if (!doc || doc === altesDokument || !doc.getElementById('kant-styles')) return;
angewandt = true;
const style = doc.createElement('link'); style.rel = 'stylesheet'; style.href = '/assets/preview.css'; doc.head.append(style);
// The preview delivers the generated stylesheet as inert template text (see page.html.twig).
// Applying it as a constructed stylesheet is not a source in the sense of the policy, so the
@@ -590,9 +601,31 @@ async function updatePreview() {
});
doc.addEventListener('submit', event => event.preventDefault());
frame.contentWindow.scrollTo(0, top); highlight();
// Erst jetzt ansehen lassen: bis hierher zeigte das Fenster eine Seite ohne Gestaltung.
frame.style.visibility = '';
$('#preview-status').textContent = 'Entwurf · Zum Auswählen direkt auf ein Element klicken.';
};
// Solange die Gestaltung fehlt, bleibt die Fläche leer statt falsch.
frame.style.visibility = 'hidden';
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.
const warten = () => {
if (angewandt || sequence !== previewSequence) return;
anwenden();
if (!angewandt) requestAnimationFrame(warten);
};
requestAnimationFrame(warten);
// Das Netz darunter ist das Ladeereignis - und zwar ohne Uhr: bringt auch das fertig geladene
// Dokument keine Gestaltung mit, stimmt etwas anderes nicht, und dann ist eine unfertige
// Vorschau immer noch besser als eine unsichtbare.
frame.onload = () => {
anwenden();
if (!angewandt) {
frame.style.visibility = '';
$('#preview-status').textContent = 'Vorschau ohne Gestaltung - bitte die Seite neu laden.';
}
};
} catch (error) {
if (error.name === 'AbortError' || sequence !== previewSequence) return;
$('#preview-status').textContent = `Letzte gültige Vorschau: ${error.message}`;