From ed050cbfa5299d100e3a90183ac677a6e187168d Mon Sep 17 00:00:00 2001 From: Jor Date: Tue, 15 Apr 2025 12:30:29 +0200 Subject: [PATCH 1/5] Sidebar improvements and small fixes. Sidebar status is now moved to sessionStorage. Fix: sidebar visibility was not correctly loaded from storage when the browser window was smaller than 1080 pixels wide. Sidebar width is now saved too. Remove too large try-catch block that would hide some errors. --- src/front-end/js/book.js | 62 +++++++++++++++----------- src/front-end/templates/index.hbs | 72 +++++++++++++++++-------------- 2 files changed, 76 insertions(+), 58 deletions(-) diff --git a/src/front-end/js/book.js b/src/front-end/js/book.js index 160ee93700..953f2ea4ac 100644 --- a/src/front-end/js/book.js +++ b/src/front-end/js/book.js @@ -514,6 +514,17 @@ aria-label="Show hidden lines">'; }); })(); +function setConfig(key, value, storage = localStorage) { + const fullKey = "mdbook-" + key; + try { + storage.setItem(fullKey, value); + } catch (e) { + // Ignore error. + // It can only be a security exception (if the user has disabled cookies/storage) + // TODO: maybe display some warning to the user that the setting they are trying to change will not be kept across page changes/reloads because they disabled storage for this site/origin? + } +} + (function sidebar() { const body = document.querySelector('body'); const sidebar = document.getElementById('sidebar'); @@ -523,34 +534,25 @@ aria-label="Show hidden lines">'; const sidebarResizeHandle = document.getElementById('sidebar-resize-handle'); let firstContact = null; - function showSidebar() { - body.classList.remove('sidebar-hidden'); - body.classList.add('sidebar-visible'); + function setSidebarVisibility(isVisible) { + body.classList.toggle('sidebar-hidden', !isVisible); + body.classList.toggle('sidebar-visible', isVisible); Array.from(sidebarLinks).forEach(function(link) { - link.setAttribute('tabIndex', 0); + link.setAttribute('tabIndex', isVisible ? 0 : -1); }); - sidebarToggleButton.setAttribute('aria-expanded', true); - sidebar.setAttribute('aria-hidden', false); - try { - localStorage.setItem('mdbook-sidebar', 'visible'); - } catch (e) { - // Ignore error. - } + sidebarToggleButton.setAttribute('aria-expanded', isVisible); + sidebar.setAttribute('aria-hidden', !isVisible); + + // We use sessionStorage for the sidebar visibility setting, as we want it to be specific to the browser window and tab (since different windows can have different sizes), unlike the theme which is a global preference (ie. if you want a dark theme, you probably want it on all your windows) + setConfig("sidebar", isVisible ? 'visible' : 'hidden', sessionStorage); + } + + function showSidebar() { + setSidebarVisibility(true); } function hideSidebar() { - body.classList.remove('sidebar-visible'); - body.classList.add('sidebar-hidden'); - Array.from(sidebarLinks).forEach(function(link) { - link.setAttribute('tabIndex', -1); - }); - sidebarToggleButton.setAttribute('aria-expanded', false); - sidebar.setAttribute('aria-hidden', true); - try { - localStorage.setItem('mdbook-sidebar', 'hidden'); - } catch (e) { - // Ignore error. - } + setSidebarVisibility(false); } // Toggle sidebar @@ -569,11 +571,18 @@ aria-label="Show hidden lines">'; sidebarResizeHandle.addEventListener('mousedown', initResize, false); - function initResize() { + let startClientX; + let startSidebarWidth; + function initResize(e) { window.addEventListener('mousemove', resize, false); window.addEventListener('mouseup', stopResize, false); + body.classList.add('sidebar-resizing'); + + startClientX = e.clientX; + startSidebarWidth = parseInt(getComputedStyle(document.body).getPropertyValue('--sidebar-width')?.replace(/px$/, ""), 10); } + function resize(e) { let pos = e.clientX - sidebar.offsetLeft; if (pos < 20) { @@ -582,8 +591,9 @@ aria-label="Show hidden lines">'; if (body.classList.contains('sidebar-hidden')) { showSidebar(); } - pos = Math.min(pos, window.innerWidth - 100); - document.documentElement.style.setProperty('--sidebar-width', pos + 'px'); + let sidebarWidth = startSidebarWidth + Math.min(e.clientX, window.innerWidth - 100) - startClientX; + setConfig("sidebarWidth", sidebarWidth, sessionStorage); + document.documentElement.style.setProperty('--sidebar-width', sidebarWidth + 'px'); } } //on mouseup remove windows functions mousemove & mouseup diff --git a/src/front-end/templates/index.hbs b/src/front-end/templates/index.hbs index 98f3b886c9..797585dcf4 100644 --- a/src/front-end/templates/index.hbs +++ b/src/front-end/templates/index.hbs @@ -64,50 +64,58 @@
- - + // Set the theme before any content is loaded, prevents flash - - - + // Hide / unhide sidebar before it is displayed, and restore its width if it was manually resized + + let sidebar = getConfig("sidebar", sessionStorage) ?? + ((document.body.clientWidth >= 1080) ? "visible" : "hidden"); - - + + // We need parseInt() because storage only stores strings + let sidebarWidth = parseInt(getConfig("sidebarWidth", sessionStorage), 10); + if(sidebarWidth && Number.isFinite(sidebarWidth)) { + document.documentElement.style.setProperty('--sidebar-width', Math.min(sidebarWidth, window.innerWidth - 100) + 'px'); + } + + })();