Close the collapsible menu after choosing a link
Same-page anchors kept the details menu open. scrolled.js closes it on any link click and loads only where a collapsible menu holds such links. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bb9d7c6b45
commit
dd5bc16413
4 files changed
+99
-3
No files matched your search
@@ -326,7 +326,14 @@ final class PageController extends AbstractController
|
||||
// Only the header changes with the scroll position; a scrolled value anywhere in it asks
|
||||
// for the small script that marks the page as scrolled.
|
||||
// Den Nach-oben-Knopf blendet dasselbe Skript ein; ohne es bleibt er dauerhaft sichtbar.
|
||||
$needsScrolled = (isset($areas['header']) && $this->hasScrolled($areas['header'])) || (bool) ($this->settings->load()['scrollTop'] ?? false);
|
||||
// Dasselbe Skript schließt das aufgeklappte Menü nach einer Wahl (ADR 119) - gebraucht nur,
|
||||
// wenn ein aufklappbares Menü auf ein Sprungziel dieser Seite zeigt: Ein Link auf eine
|
||||
// andere Seite lädt neu (die Seiten senden no-store, also stellt „Zurück“ kein offenes
|
||||
// Menü aus dem Seiten-Cache her). So bleibt eine Seite ohne solche Sprünge ohne Skript.
|
||||
$navigation = $this->navigation($path);
|
||||
$here = array_unique([rtrim($request->getPathInfo(), '/') ?: '/', $this->settings->publicPath($path, $this->settings->homePath())]);
|
||||
$needsScrolled = (isset($areas['header']) && $this->hasScrolled($areas['header'])) || (bool) ($this->settings->load()['scrollTop'] ?? false)
|
||||
|| [] !== array_filter($this->collapsibleMenuSlots($documents), fn (string $slot): bool => $this->jumpsWithin($navigation[$slot] ?? [], $here));
|
||||
$styles = $this->theme->css($theme).$this->menus->buttonCss($theme['buttons']).$this->scrollTopStyles($this->settings->load(), $theme).$this->consent->styles($theme).$this->styles->compileDocument($page['document']).$this->code->compileDocument($page['document']);
|
||||
foreach ([...array_values($areas), ...array_values($sections)] as $extra) {
|
||||
$styles .= $this->styles->compileDocument($extra).$this->code->compileDocument($extra);
|
||||
@@ -382,7 +389,7 @@ final class PageController extends AbstractController
|
||||
'canonical' => $canonical,
|
||||
'alternates' => $alternates,
|
||||
'pagination' => null === $blaettern || null === $adresse ? null : ['page' => $blaettern['page'], 'pages' => $blaettern['pages'], 'base' => $adresse],
|
||||
'navigation' => $this->navigation($path),
|
||||
'navigation' => $navigation,
|
||||
'postLists' => $postLists,
|
||||
// Ohne Beiträge gibt es keinen Feed, auf den der Kopf verweisen könnte.
|
||||
'hasPosts' => $this->posts->anyPublished(),
|
||||
@@ -774,6 +781,50 @@ final class PageController extends AbstractController
|
||||
}
|
||||
|
||||
/** Whether any block carries values for the scrolled page (see StyleSchema::scrollable). */
|
||||
/**
|
||||
* Die Menüplätze (header, footer …) der Menüs, die als Knopf aufklappen: Burger oder waagerecht
|
||||
* mit Zusammenklappen.
|
||||
*
|
||||
* @return list<string>
|
||||
*/
|
||||
private function collapsibleMenuSlots(array $documents): array
|
||||
{
|
||||
$slots = [];
|
||||
$walk = function (array $blocks) use (&$walk, &$slots): void {
|
||||
foreach ($blocks as $block) {
|
||||
if ('menu' === ($block['type'] ?? null)) {
|
||||
$layout = $block['props']['layout'] ?? 'horizontal';
|
||||
if ('burger' === $layout || ('horizontal' === $layout && 'never' !== ($block['props']['collapse'] ?? 'tablet'))) {
|
||||
$slots[] = (string) ($block['props']['slot'] ?? 'header');
|
||||
}
|
||||
}
|
||||
$walk($block['children'] ?? []);
|
||||
}
|
||||
};
|
||||
foreach ($documents as $document) {
|
||||
$walk($document['blocks'] ?? []);
|
||||
}
|
||||
|
||||
return array_values(array_unique($slots));
|
||||
}
|
||||
|
||||
/** Ob ein Link des Menüs zu einem Sprungziel auf dieser Seite führt (#kontakt, /#kontakt auf der Startseite). @param list<string> $here */
|
||||
private function jumpsWithin(array $links, array $here): bool
|
||||
{
|
||||
foreach ($links as $link) {
|
||||
$href = (string) ($link['href'] ?? '');
|
||||
$hash = strpos($href, '#');
|
||||
if (false !== $hash && (0 === $hash || \in_array(rtrim(substr($href, 0, $hash), '/') ?: '/', $here, true))) {
|
||||
return true;
|
||||
}
|
||||
if ($this->jumpsWithin($link['children'] ?? [], $here)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function hasScrolled(array $document): bool
|
||||
{
|
||||
$walk = function (array $blocks) use (&$walk): bool {
|
||||
|
||||
Reference in new issue
Block a user