Bilder in vier Breiten, Releasearchiv fuer Hosting ohne Composer
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

Uploads werden weiterhin nach WebP umgewandelt, jetzt in vier statt drei
Breiten (480/960/1600/2400) und ohne Hochskalieren. Hintergrundbilder
waehlen ihre Variante je Geraet, weil CSS kein srcset kennt.

Dabei kam ein Fehler heraus, den erst der Browsertest zeigte: der
Dokumentpruefer erlaubte drei sources je Bild, also war mit der vierten
Variante jedes Dokument mit einem Bild ungueltig - ohne sichtbare Meldung.
Die Grenze haengt jetzt an MediaLibrary::WIDTHS.

Geteiltes Hosting hat meistens keinen Composer. scripts/build-release.php
baut deshalb auf einem Build-Rechner ein Archiv mit fertigem vendor/ ohne
Entwicklungspakete, samt SHA-256. Der Updater bricht ab, wenn ein Update
composer.lock aendert und Composer auf dem Server nicht aufrufbar ist,
statt mit einem unpassenden vendor/ weiterzulaufen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
kantarciandClaude Opus 5 committed 2026-09-12 22:39:08 +02:00
1 parent c046681302
commit c3bff7d936
17 files changed
+414 -26

No files matched your search

+28 -7
View File
@@ -107,17 +107,17 @@ final class StyleCompiler
continue;
}
$rules = '';
$base = $this->declarations($values);
$base = $this->declarations($values, 'self', $device);
if ('' !== $base) {
$rules .= sprintf('#%s{%s}', $id, $base);
}
// Some properties belong on the images inside the block, not on the block: object-fit
// on a figure does nothing, and a radius on the figure leaves the image square.
$images = $this->declarations($values, 'img');
$images = $this->declarations($values, 'img', $device);
if ('' !== $images) {
$rules .= sprintf('#%s img{%s}', $id, $images);
}
$hover = is_array($values['hover'] ?? null) ? $this->declarations($values['hover']) : '';
$hover = is_array($values['hover'] ?? null) ? $this->declarations($values['hover'], 'self', $device) : '';
if ('' !== $hover) {
$rules .= sprintf('#%s:hover,#%s:focus-within{%s}', $id, $id, $hover);
}
@@ -138,7 +138,7 @@ final class StyleCompiler
*
* @param string $target 'self' for the block, 'img' for the images inside it
*/
private function declarations(array $values, string $target = 'self'): string
private function declarations(array $values, string $target = 'self', string $device = 'desktop'): string
{
$properties = StyleSchema::properties();
$out = [];
@@ -173,7 +173,7 @@ final class StyleCompiler
// The composed declarations describe the block itself; none of them has an image variant.
if ('self' === $target) {
foreach ([
$this->background($values),
$this->background($values, $device),
$this->shadow($values),
$this->textShadow($values),
$this->filter($values),
@@ -203,7 +203,7 @@ final class StyleCompiler
}
/** Overlay, gradient and image share one background-image declaration, layered in that order. */
private function background(array $values): string
private function background(array $values, string $device = 'desktop'): string
{
$layers = [];
$overlay = $values['overlayColor'] ?? null;
@@ -223,7 +223,9 @@ final class StyleCompiler
if (isset($values['backgroundImage']) && null !== $this->media) {
$item = $this->media->find((string) $values['backgroundImage']);
if (null !== $item && [] !== $item['variants']) {
$largest = end($item['variants']);
// A phone should not download the 2400 pixel variant of a background. CSS has no
// srcset, but the rules are already written per device, so the device decides.
$largest = $this->variantFor($item['variants'], $device);
// The URL comes from the media library, never from the document.
$layers[] = sprintf('url("%s")', $largest['src']);
}
@@ -314,6 +316,25 @@ final class StyleCompiler
return [] === $parts ? '' : 'transform:'.implode(' ', $parts);
}
/**
* The variant a device should load for a background.
*
* Mobile takes the smallest that is at least 960 wide, tablet the one around 1600, desktop the
* largest. A picture that only has small variants simply gives what it has.
*/
private function variantFor(array $variants, string $device): array
{
$wanted = ['mobile' => 960, 'tablet' => 1600, 'desktop' => 4000][$device] ?? 4000;
$chosen = $variants[0];
foreach ($variants as $variant) {
if ($variant['width'] <= $wanted || $chosen['width'] < $wanted) {
$chosen = $variant;
}
}
return $chosen;
}
private function grid(array $values): string
{
return isset($values['gridColumns'])