@@ -179,6 +179,103 @@ jobs:
179179 if (-not (Test-Path -Path '../../_site')) {
180180 throw "Expected Zensical output at ../../_site but it was not created."
181181 }
182+
183+ $navStateScript = @'
184+ (() => {
185+ const storageKey = "zensical-nav-state-v1";
186+ let lastSignature = "";
187+
188+ const getToggles = () =>
189+ Array.from(document.querySelectorAll("input.md-nav__toggle.md-toggle[id]"));
190+
191+ const getPrimaryList = () =>
192+ document.querySelector("nav.md-nav--primary > ul.md-nav__list");
193+
194+ const applyDefaultTopLevelState = (toggles) => {
195+ const primaryList = getPrimaryList();
196+ if (!primaryList) {
197+ return;
198+ }
199+
200+ const topLevelToggles = Array.from(
201+ primaryList.querySelectorAll(
202+ " :scope > li > input.md-nav__toggle.md-toggle[id]"
203+ )
204+ );
205+ const topLevelIds = new Set(topLevelToggles.map((toggle) => toggle.id));
206+
207+ for (const toggle of toggles) {
208+ toggle.checked = topLevelIds.has(toggle.id);
209+ }
210+ };
211+
212+ const restoreState = (toggles) => {
213+ const raw = localStorage.getItem(storageKey);
214+ if (!raw) {
215+ applyDefaultTopLevelState(toggles);
216+ return;
217+ }
218+
219+ try {
220+ const state = JSON.parse(raw);
221+ for (const toggle of toggles) {
222+ if (Object.prototype.hasOwnProperty.call(state, toggle.id)) {
223+ toggle.checked = !!state[toggle.id];
224+ }
225+ }
226+ } catch {
227+ applyDefaultTopLevelState(toggles);
228+ }
229+ };
230+
231+ const persistState = (toggles) => {
232+ const state = {};
233+ for (const toggle of toggles) {
234+ state[toggle.id] = !!toggle.checked;
235+ }
236+ localStorage.setItem(storageKey, JSON.stringify(state));
237+ };
238+
239+ const initialize = () => {
240+ const toggles = getToggles();
241+ if (toggles.length === 0) {
242+ return;
243+ }
244+
245+ const signature = toggles.map((toggle) => toggle.id).join("|");
246+ if (signature === lastSignature) {
247+ return;
248+ }
249+
250+ lastSignature = signature;
251+ restoreState(toggles);
252+ for (const toggle of toggles) {
253+ if (toggle.dataset.navStateBound === "true") {
254+ continue;
255+ }
256+
257+ toggle.dataset.navStateBound = "true";
258+ toggle.addEventListener("change", () => persistState(getToggles()));
259+ }
260+ };
261+
262+ if (document.readyState === "loading") {
263+ document.addEventListener("DOMContentLoaded", initialize, { once : true });
264+ } else {
265+ initialize();
266+ }
267+
268+ setInterval(initialize, 500);
269+ })();
270+ ' @
271+
272+ Get-ChildItem -Path ' ../../_site' -Filter '*.html' -Recurse | ForEach-Object {
273+ $html = Get-Content -Path $_.FullName -Raw
274+ if ($html -notmatch 'zensical-nav-state-v1') {
275+ $html = $html -replace '</body>', "<script>$navStateScript</script>`n</body>"
276+ Set-Content -Path $_.FullName -Value $html -NoNewline
277+ }
278+ }
182279 }
183280
184281 - uses : actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
0 commit comments