Build Hüfner Gartenbau as a ninth installation, let buttons call and write, colour the button arrow like its text

- Website of Garten- und Landschaftsbau Hüfner GmbH rebuilt from the delivered design with
  imprint, privacy, 404 and the enquiry form (scripts/reset-huefner.sh, ports 8102/8103),
  Barlow and Barlow Condensed served locally with their licence.
- Buttons, icon cards, calls to action, icons and linked images accept tel: and mailto:
  links, the same targets menus and rich text already allowed (ADR 107).
- The arrow inside a button takes the button's text colour instead of the accent colour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kantarciandClaude Opus 5.5 committed 2026-10-06 19:47:06 +02:00
1 parent 0ba82b7d33
commit 5bfe1f3c6e
24 files changed
+1576 -11

No files matched your search

+34 -1
View File
@@ -187,7 +187,10 @@ final class CmsTest extends TestCase
$bad = $base;
$bad['blocks'][] = $base['blocks'][0];
yield 'duplicate IDs' => [$bad];
foreach (['javascript:alert(1)', 'data:text/html,hi', '//evil.test', '/\\evil.test', "https://example.test/\nfoo"] as $url) {
// tel: und mailto: sind Linkziele, aber nur in sauberer Form: keine Buchstaben in der
// Nummer, eine echte Adresse, kein Weg aus dem Attribut.
foreach (['javascript:alert(1)', 'data:text/html,hi', '//evil.test', '/\\evil.test', "https://example.test/\nfoo",
'tel:ruf-mich-an', 'tel:+49 7229 6992826', 'mailto:keine-adresse', 'mailto:a@b.de?subject="x"', 'mailto:a@b.de?subject=<script>'] as $url) {
$bad = $base;
$bad['blocks'][0]['children'][3]['props']['href'] = $url;
yield $url => [$bad];
@@ -243,6 +246,36 @@ final class CmsTest extends TestCase
yield 'missing meaningful alt' => [$bad];
}
/**
* Ein Knopf darf anrufen oder eine E-Mail öffnen - wie ein Menüeintrag oder ein Link im Text.
* Vorher war „Jetzt anrufen“ nur als Textlink im Knopf-Aussehen zu bauen. Eine Bildquelle
* bleibt dagegen bei Pfad und HTTPS.
*/
public function testButtonsAndLinkedBlocksMayCallOrWrite(): void
{
$document = DemoContent::pages()['home'];
$ziele = ['tel:+4972296992826', 'mailto:info@huefner-gartenbau.de', 'mailto:info@huefner-gartenbau.de?subject=Bewerbung%3A%20Helfer'];
foreach ($ziele as $i => $ziel) {
$document['blocks'][0]['children'][3]['props']['href'] = $ziel;
$this->pages->saveDraft('page-1', $document, $i);
}
$id = $this->pages->saveDraft('page-1', $document, 3);
$this->pages->publish('page-1', $id, 4);
$html = $this->request('/')->getContent();
self::assertStringContainsString('href="mailto:info@huefner-gartenbau.de?subject=Bewerbung%3A%20Helfer"', (string) $html);
$bild = DemoContent::pages()['home'];
$bild['blocks'][0]['children'][] = ['id' => 'bild-tel', 'type' => 'image', 'props' => ['src' => 'tel:+4972296992826', 'alt' => 'x', 'decorative' => false, 'width' => 10, 'height' => 10]];
$this->expectException(InvalidDocument::class);
$this->pages->saveDraft('page-1', $bild, 5);
}
public function testTheButtonArrowTakesTheColourOfTheButtonText(): void
{
// Der Pfeil ist ein Symbol (block-icon) und bekam die Akzentfarbe: grün auf einem roten Knopf.
self::assertStringContainsString('.button-arrow .block-icon{color:inherit}', (string) file_get_contents(__DIR__.'/../public/assets/site.css'));
}
#[DataProvider('invalidDocuments')]
public function testRejectsInvalidDocumentsBeforeWriting(array $document): void
{