From d2c86cc8da9cd5d6d17316c7ad7647adf5d0b511 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B6ren=20Weber?= <mail@soeren-weber.de>
Date: Sun, 8 Sep 2024 13:14:34 +0200
Subject: [PATCH] menu: optimize performance #685

---
 layouts/partials/_relearn/pageIsHidden.gotmpl |  2 +-
 layouts/partials/menu.html                    | 88 +++++++++----------
 layouts/partials/relearn-meta.gotmpl          |  7 +-
 3 files changed, 48 insertions(+), 49 deletions(-)

diff --git a/layouts/partials/_relearn/pageIsHidden.gotmpl b/layouts/partials/_relearn/pageIsHidden.gotmpl
index b73f750a0f..32892f7a15 100644
--- a/layouts/partials/_relearn/pageIsHidden.gotmpl
+++ b/layouts/partials/_relearn/pageIsHidden.gotmpl
@@ -1 +1 @@
-{{- return .Scratch.Get "relearnIsHiddenNode" }}
\ No newline at end of file
+{{- return or (.Params.hidden) (eq .Title "") }}
\ No newline at end of file
diff --git a/layouts/partials/menu.html b/layouts/partials/menu.html
index 37f80ce2eb..5afa07749d 100644
--- a/layouts/partials/menu.html
+++ b/layouts/partials/menu.html
@@ -26,7 +26,7 @@
             {{- $pages := partialCached "_relearn/pages.gotmpl" (dict "page" .Site.Home) .Site.Home.Path }}
             {{- $defaultAlwaysopen := .Site.Params.alwaysopen | default false }}
             {{- range $pages }}
-              {{- template "section-tree-nav" dict "sect" . "currentnode" $currentNode "showvisitedlinks" $showvisitedlinks "alwaysopen" $defaultAlwaysopen }}
+              {{- partial "inline/menu-walker" (dict "sect" . "currentnode" $currentNode "showvisitedlinks" $showvisitedlinks "alwaysopen" $defaultAlwaysopen) }}
             {{- end }}
           </ul>
         </div>
@@ -113,49 +113,47 @@
         </div>
       </div>
     </aside>
-    {{- define "section-tree-nav" }}
-      {{- $currentNode := .currentnode }}
-      {{- $showvisitedlinks := .showvisitedlinks }}
-      {{- $alwaysopen := .alwaysopen }}
-      {{- $currentFileRelPermalink := .currentnode.RelPermalink }}
-      {{- with .sect }}
-        {{- $isSelf := eq .RelPermalink $currentFileRelPermalink }}
-        {{- $isAncestor := and (not $isSelf) (.IsAncestor $currentNode) }}
-        {{- $isActive := $isSelf }}
-        {{- $pages := partialCached "_relearn/pages.gotmpl" (dict "page" .) .Path }}
-        {{- $isHidden := or (.Params.hidden) (eq .Title "") }}
-        {{- $relearnIsHiddenFrom := index ($currentNode.Scratch.Get "relearnIsHiddenFrom") .RelPermalink }}
-        {{- $hidden := and $relearnIsHiddenFrom (not $.showhidden) (not $isSelf) (not $isAncestor) }}
-        {{- if $hidden }}
-        {{- else }}
-          {{- $numberOfVisibleChildren := 0 }}
-          {{- range $pages }}
-            {{- $isSelfSub := eq .RelPermalink $currentFileRelPermalink }}
-            {{- $isAncestorSub := and (not $isSelf) (.IsAncestor $currentNode) }}
-            {{- $relearnIsSubHiddenFrom := index ($currentNode.Scratch.Get "relearnIsHiddenFrom") .RelPermalink }}
-            {{- $subHidden := and $relearnIsSubHiddenFrom (not $.showhidden) (not $isSelfSub) (not $isAncestorSub) }}
-            {{- $numberOfVisibleChildren = add $numberOfVisibleChildren (int (not $subHidden)) }}
-          {{- end }}
-          {{- $title := partial "title.gotmpl" (dict "page" . "linkTitle" true) }}
-          {{- $url := partial "permalink.gotmpl" (dict "to" .) }}
-          {{- safeHTML .Params.head }}
-          {{- if $numberOfVisibleChildren }}
-            {{- $isCollapsible := or (.Params.collapsibleMenu | default .Site.Params.collapsibleMenu) (not $url) }}
-            {{- $currentAlwaysopen := .Params.alwaysopen | default $alwaysopen }}
-            {{- $pageHash := md5 .Page }}
-            {{- $isOpen := or $currentAlwaysopen $isSelf $isAncestor }}
-            <li class="{{if $isHidden }}hidden {{end}}{{if $isActive }}active {{end}}{{if (or $isSelf $isAncestor) }}parent {{end}}{{if $currentAlwaysopen}}alwaysopen {{end}}" data-nav-id="{{ $url }}">{{ if $isCollapsible }}<input type="checkbox" id="R-section-{{ $pageHash }}" aria-controls="R-subsections-{{ $pageHash }}"{{ if $isOpen }} checked{{ end }}><label for="R-section-{{ $pageHash }}"><i class="fa-fw fas fa-chevron-down"></i><i class="fa-fw fas fa-chevron-right"></i><span class="a11y-only">{{ T "Submenu" $title }}</span></label>{{ end }}{{ if $url }}<a class="padding" href="{{ $url }}">{{ else }}<span class="padding">{{ end }}
-            {{- partial "menu-pre.html" . }}{{ $title }}{{ partial "menu-post.html" . }}
-            {{- if $url }}{{ if $showvisitedlinks }}<i class="fa-fw fas fa-check read-icon"></i>{{ end }}</a>{{ else }}</span>{{ end }}<ul id="R-subsections-{{ $pageHash }}" class="collapsible-menu">
-            {{- $defaultAlwaysopen := .Site.Params.alwaysopen | default true }}
-            {{- range $pages }}
-              {{- template "section-tree-nav" dict "sect" . "currentnode" $currentNode "showvisitedlinks" $showvisitedlinks "alwaysopen" $defaultAlwaysopen }}
-            {{- end }}</ul></li>
-          {{- else }}
-            <li class="{{if $isHidden }}hidden {{end}}{{if $isActive }}active {{end}}" data-nav-id="{{ $url }}">{{ if $url }}<a class="padding" href="{{ $url }}">{{ else }}<span class="padding">{{ end }}
-              {{- partial "menu-pre.html" . }}{{ $title }}{{ partial "menu-post.html" . }}
-              {{- if $url }}{{ if $showvisitedlinks }}<i class="fa-fw fas fa-check read-icon"></i>{{ end }}</a>{{ else }}</span>{{ end }}</li>
-          {{- end }}
+{{- define "partials/inline/menu-walker" }}
+  {{- $currentNode := .currentnode }}
+  {{- $showvisitedlinks := .showvisitedlinks }}
+  {{- $alwaysopen := .alwaysopen }}
+  {{- $currentFileRelPermalink := .currentnode.RelPermalink }}
+  {{- with .sect }}
+    {{- $isSelf := eq .RelPermalink $currentFileRelPermalink }}
+    {{- $isAncestor := and (not $isSelf) (.IsAncestor $currentNode) }}
+    {{- $isHidden := or (.Params.hidden) (eq .Title "") }}
+    {{- if or $isAncestor $isSelf (not $isHidden) }}
+      {{- $isActive := $isSelf }}
+      {{- $pages := partialCached "_relearn/pages.gotmpl" (dict "page" .) .Path }}
+      {{- $hasVisibleChildren := false }}
+      {{- range $pages }}
+        {{- $isSubSelf := eq . $currentNode }}
+        {{- $isSubAncestor := and (not $isSubSelf) (.IsAncestor $currentNode) }}
+        {{- $isSubHidden := or (.Params.hidden) (eq .Title "") }}
+        {{- if or $isSubAncestor $isSubSelf (not $isSubHidden) }}
+          {{- $hasVisibleChildren = true }}
+          {{- break }}
         {{- end }}
       {{- end }}
-    {{- end }}
\ No newline at end of file
+      {{- $title := partial "title.gotmpl" (dict "page" . "linkTitle" true) }}
+      {{- $url := partial "permalink.gotmpl" (dict "to" .) }}
+      {{- if $hasVisibleChildren }}
+        {{- $isCollapsible := or (.Params.collapsibleMenu | default .Site.Params.collapsibleMenu) (not $url) }}
+        {{- $currentAlwaysopen := .Params.alwaysopen | default $alwaysopen }}
+        {{- $pageId := md5 .Page }}
+        {{- $isOpen := or $currentAlwaysopen $isSelf $isAncestor }}
+            <li class="{{if $isHidden }}hidden {{end}}{{if $isActive }}active {{end}}{{if (or $isSelf $isAncestor) }}parent {{end}}{{if $currentAlwaysopen}}alwaysopen {{end}}" data-nav-id="{{ $url }}">{{ if $isCollapsible }}<input type="checkbox" id="R-section-{{ $pageId }}" aria-controls="R-subsections-{{ $pageId }}"{{ if $isOpen }} checked{{ end }}><label for="R-section-{{ $pageId }}"><i class="fa-fw fas fa-chevron-down"></i><i class="fa-fw fas fa-chevron-right"></i><span class="a11y-only">{{ T "Submenu" $title }}</span></label>{{ end }}{{ if $url }}<a class="padding" href="{{ $url }}">{{ else }}<span class="padding">{{ end }}
+        {{- partial "menu-pre.html" . }}{{ $title }}{{ partial "menu-post.html" . }}
+        {{- if $url }}{{ if $showvisitedlinks }}<i class="fa-fw fas fa-check read-icon"></i>{{ end }}</a>{{ else }}</span>{{ end }}<ul id="R-subsections-{{ $pageId }}" class="collapsible-menu">
+        {{- $defaultAlwaysopen := .Site.Params.alwaysopen | default true }}
+        {{- range $pages }}
+          {{- partial "inline/menu-walker" (dict "sect" . "currentnode" $currentNode "showvisitedlinks" $showvisitedlinks "alwaysopen" $defaultAlwaysopen) }}
+        {{- end }}</ul></li>
+      {{- else }}
+            <li class="{{if $isHidden }}hidden {{end}}{{if $isActive }}active {{end}}" data-nav-id="{{ $url }}">{{ if $url }}<a class="padding" href="{{ $url }}">{{ else }}<span class="padding">{{ end }}
+        {{- partial "menu-pre.html" . }}{{ $title }}{{ partial "menu-post.html" . }}
+        {{- if $url }}{{ if $showvisitedlinks }}<i class="fa-fw fas fa-check read-icon"></i>{{ end }}</a>{{ else }}</span>{{ end }}</li>
+      {{- end }}
+    {{- end }}
+  {{- end }}
+{{- end }}
\ No newline at end of file
diff --git a/layouts/partials/relearn-meta.gotmpl b/layouts/partials/relearn-meta.gotmpl
index 94f7b8b637..3824aebb5e 100644
--- a/layouts/partials/relearn-meta.gotmpl
+++ b/layouts/partials/relearn-meta.gotmpl
@@ -15,7 +15,6 @@ section: {{- .Section }}
 {{- $currentNode.Scratch.Delete "relearnNextPage"     }}
 {{- $currentNode.Scratch.Delete "relearnIsHiddenNode" }}{{/* the node itself is flagged as hidden */}}
 {{- $currentNode.Scratch.Delete "relearnIsHiddenStem" }}{{/* the node or one of its parents is flagged as hidden */}}
-{{- $currentNode.Scratch.Delete "relearnIsHiddenFrom" }}{{/* the node is hidden from the current page */}}
 {{- template "relearn-structure" dict "node" .Site.Home "currentnode" $currentNode "hiddenstem" false "hiddencurrent" false }}
 {{- if not ($currentNode.Scratch.Get "relearnIsSelfFound") }}
 	{{- if not $currentNode.IsHome }}
@@ -39,13 +38,11 @@ section: {{- .Section }}
 
 	{{- $hidden_node := or (.node.Params.hidden) (eq .node.Title "") }}
 	{{- $hidden_stem := or $hidden_node .hiddenstem }}
-	{{- $hidden_current_stem := or $hidden_node .hiddencurrent }}
 	{{- $hidden_from_current := or (and $hidden_node (not $isAncestor) (not $isSelf) ) (and .hiddencurrent (or $isPreSelf $isPostSelf $isDescendant) ) }}
 	{{- if $isSelf }}
 		{{- $currentNode.Scratch.Set "relearnIsHiddenNode" $hidden_node }}
 		{{- $currentNode.Scratch.Set "relearnIsHiddenStem" $hidden_stem }}
 	{{- end }}
-	{{- $currentNode.Scratch.SetInMap "relearnIsHiddenFrom" .node.RelPermalink $hidden_current_stem }}
 
 	{{- if or (eq $currentNode.Kind "home") (eq $currentNode.Kind "section") (eq $currentNode.Kind "page") }}
 		{{- if not $hidden_from_current }}
@@ -53,6 +50,7 @@ section: {{- .Section }}
 				{{- $currentNode.Scratch.Set "relearnPrevPage" .node }}
 			{{- else if and $isPostSelf .node.RelPermalink (eq ($currentNode.Scratch.Get "relearnNextPage") nil) }}
 				{{- $currentNode.Scratch.Set "relearnNextPage" .node }}
+				{{- return }}
 			{{- end }}
 		{{- end }}
 	{{- end }}
@@ -60,5 +58,8 @@ section: {{- .Section }}
 	{{- $pages := partialCached "_relearn/pages.gotmpl" (dict "page" .node) .node.Path }}
 	{{- range $pages }}
 		{{- template "relearn-structure" dict "node" . "currentnode" $currentNode "hiddenstem" $hidden_stem "hiddencurrent" $hidden_from_current }}
+		{{- if $currentNode.Scratch.Get "relearnNextPage" }}
+			{{- return }}
+		{{- end }}
 	{{- end }}
 {{- end }}
\ No newline at end of file