Browsertests wiederhergestellt; drei echte Fehler gefunden

Der Playwright-Editortest war durch den Editorumbau kaputt: er
steuerte die abgeschafften Auswahllisten. Umgeschrieben auf die
freien Bedienelemente - Einheitenfelder, Vererbung über drei Geräte,
einzelnes Zurücksetzen, Palettenfarbe, Abstand je Seite, Hover-Regel,
freie Rasterspalten und die weiter vorhandenen Bewegungseffekte.

Dabei kamen drei Fehler heraus, die ohne Browserlauf unsichtbar sind:

1. Die frei gestalteten Werte wirkten in der Editorvorschau gar
   nicht. Ein srcdoc-Iframe erbt die Richtlinie des einbettenden
   Dokuments, und die Verwaltung verbietet Inline-Styles - das
   erzeugte style-Element wurde stillschweigend verworfen.
   Ausgeliefert wurde es korrekt, nur die Vorschau log. Jetzt als
   inertes template plus adoptedStyleSheets.
2. Die Einrückung der Unterseiten in der Seitenliste hat nie
   funktioniert; sie lief über ein style-Attribut, das dieselbe
   Richtlinie verwirft. Jetzt über Klassen.
3. Das Theme setzte alle Links auf die Akzentfarbe und überschrieb
   die kontextabhängigen Farben: 3,08:1 auf dunklem Grund. Die Regel
   gilt jetzt nur für Links in Textblöcken, die voreingestellte
   Linkfarbe liegt auf allen hellen Tönen über 4,5:1.

Geprüft: 155 PHP-Tests / 579 Assertions unter PHP 8.2.12 und 8.4.22,
15 JavaScript-Modelltests, vollständiger Editortest mit axe (null
Verstöße) und Lighthouse 13.4.1 mit je drei Läufen mobil und Desktop,
alle fünf Kategorien 100.

Offen: npm run test:browser schlägt wegen eines Inhalts fehl -
/grundlagen trägt einen im Editor gesetzten Textblock mit 2,75:1.
Nicht verändert, weil es eine Nutzerentscheidung ist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
kantarciandClaude Opus 5 committed 2026-09-12 14:16:08 +02:00
1 parent 270cbda9ac
commit ba56add678
12 files changed
+169 -32

No files matched your search

+5 -2
View File
@@ -31,6 +31,9 @@ final class Theme
['key' => 'ink', 'name' => 'Tinte', 'value' => '#203b34'],
['key' => 'mint', 'name' => 'Mint', 'value' => '#e4efb9'],
['key' => 'accent', 'name' => 'Akzent', 'value' => '#b55b12'],
// Darker sibling of the accent: #b55b12 reaches only 4.37:1 on the light tones and
// would fail AA for normal text. This one passes on paper, mint and white.
['key' => 'link', 'name' => 'Links', 'value' => '#a4510f'],
],
'fonts' => [
['key' => 'body', 'name' => 'Fließtext', 'family' => '', 'source' => 'system', 'weights' => [400, 600], 'fallback' => 'system-ui'],
@@ -43,7 +46,7 @@ final class Theme
'lineHeight' => 1.6,
'color' => '@ink',
'backgroundColor' => '@paper',
'linkColor' => '@accent',
'linkColor' => '@link',
'containerWidth' => '1240px',
'headingScale' => 1.25,
],
@@ -264,7 +267,7 @@ final class Theme
return sprintf(
':root{%s;--k-size:%s}.kant{font-family:var(--kf-%s);font-size:var(--k-size);line-height:%s;color:%s;background:%s}'
.'.kant h1,.kant h2,.kant h3,.kant h4,.kant h5,.kant h6{font-family:var(--kf-%s)}'
.'.kant a{color:%s}.kant .shell{max-width:var(--k-container)}%s',
.'.kant .block-text a,.kant .post-excerpt a{color:%s}.kant .shell{max-width:var(--k-container)}%s',
implode(';', $variables),
$base['fontSize'],
$base['fontFamily'],
+3 -1
View File
@@ -84,6 +84,7 @@ final class EditorController extends AbstractController
'colors' => $theme['colors'],
'fonts' => $theme['fonts'],
'presets' => $theme['presets'],
'base' => $theme['base'],
'csrfToken' => $this->csrf->getToken('editor')->getValue(),
]);
}
@@ -218,12 +219,13 @@ final class EditorController extends AbstractController
}
$this->validator->validate($document);
$theme = $this->theme->load();
$navigation = [];
foreach ($this->menus->all() as $slot => $menu) {
$navigation[$slot] = $this->menus->resolve($menu['items'], (string) $page['path']);
}
return $this->render('page.html.twig', ['page' => [...$page, 'document' => $document], 'canonical' => '', 'editing' => true, 'navigation' => $navigation, 'needsTabs' => false, 'pageStyles' => $this->theme->css($this->theme->load()).$this->styles->compileDocument($document), 'googleFonts' => $this->theme->googleFontsUrl($this->theme->load())]);
return $this->render('page.html.twig', ['page' => [...$page, 'document' => $document], 'canonical' => '', 'editing' => true, 'navigation' => $navigation, 'needsTabs' => false, 'pageStyles' => $this->theme->css($theme).$this->styles->compileDocument($document), 'googleFonts' => $this->theme->googleFontsUrl($theme)]);
}
if (!isset($body['expectedVersion']) || !is_int($body['expectedVersion']) || $body['expectedVersion'] < 0) {
throw new \InvalidArgumentException();
@@ -23,6 +23,8 @@ final class AdminHeadersSubscriber implements EventSubscriberInterface
$headers->set('X-Robots-Tag', 'noindex, nofollow');
$headers->set('X-Content-Type-Options', 'nosniff');
$headers->set('Referrer-Policy', 'same-origin');
$headers->set('Content-Security-Policy', "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' https:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'");
// The preview must show the same typeface as the published page, so the font hosts are
// allowed here as well. Everything else stays as narrow as on the public side.
$headers->set('Content-Security-Policy', "default-src 'self'; script-src 'self'; style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' https:; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'");
}
}