From 352130c6a82a25fba19ba57d29fa80df1bf18eb1 Mon Sep 17 00:00:00 2001 From: ZhenShuo Leo <98386542+ZhenShuo2021@users.noreply.github.com> Date: Tue, 22 Jul 2025 01:59:04 +0800 Subject: [PATCH 1/2] feat: add zen mode toggle into a11y panel --- assets/js/a11y.js | 20 +++++++++++++++++++- assets/js/zen-mode.js | 12 ++++++++---- layouts/partials/header/basic.html | 1 + 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/assets/js/a11y.js b/assets/js/a11y.js index 6fb2e150..a1ed58eb 100644 --- a/assets/js/a11y.js +++ b/assets/js/a11y.js @@ -7,6 +7,7 @@ const getA11ySettings = () => { disableImages: false, fontSize: "default", underlineLinks: false, + zenMode: false, }; }; @@ -49,6 +50,15 @@ const applyUnderlineLinks = (enabled) => { } }; +const applyZenMode = (enabled) => { + if (enabled && typeof _toggleZenMode === 'function') { + const zenModeCheckbox = document.querySelector('[id$="zen-mode"]'); + if (zenModeCheckbox) { + _toggleZenMode(zenModeCheckbox, { scrollToHeader: false }); + } + } +}; + const applyA11ySettings = () => { const settings = getA11ySettings(); document.querySelectorAll("script[data-target-id]").forEach((script) => { @@ -62,6 +72,7 @@ const applyA11ySettings = () => { }); applyFontSize(settings.fontSize); applyUnderlineLinks(settings.underlineLinks); + applyZenMode(settings.zenMode); }; const updateA11ySetting = (key, value) => { @@ -94,6 +105,7 @@ const initA11yPanel = (prefix = "") => { const checkboxBlur = document.getElementById(`${prefix}disable-blur`); const checkboxImages = document.getElementById(`${prefix}disable-images`); const checkboxUnderline = document.getElementById(`${prefix}underline-links`); + const checkboxZenMode = document.getElementById(`${prefix}zen-mode`); const fontSizeSelect = document.getElementById(`${prefix}font-size-select`); const toggleButton = document.getElementById(`${prefix}a11y-toggle`); const closeButton = document.getElementById(`${prefix}a11y-close`); @@ -103,6 +115,7 @@ const initA11yPanel = (prefix = "") => { !checkboxBlur || !checkboxImages || !checkboxUnderline || + !checkboxZenMode || !fontSizeSelect || !toggleButton || !closeButton || @@ -114,12 +127,17 @@ const initA11yPanel = (prefix = "") => { checkboxBlur.checked = settings.disableBlur; checkboxImages.checked = settings.disableImages; - fontSizeSelect.value = settings.fontSize; checkboxUnderline.checked = settings.underlineLinks; + checkboxZenMode.checked = settings.zenMode; + fontSizeSelect.value = settings.fontSize; checkboxBlur.addEventListener("change", (e) => updateA11ySetting("disableBlur", e.target.checked)); checkboxImages.addEventListener("change", (e) => updateA11ySetting("disableImages", e.target.checked)); checkboxUnderline.addEventListener("change", (e) => updateA11ySetting("underlineLinks", e.target.checked)); + checkboxZenMode.addEventListener("change", (e) => { + updateA11ySetting("zenMode", e.target.checked) + _toggleZenMode(checkboxZenMode, { scrollToHeader: false }) + }) fontSizeSelect.addEventListener("change", (e) => { // Remove fontSize from localStorage when default is selected if (e.target.value === "default") { diff --git a/assets/js/zen-mode.js b/assets/js/zen-mode.js index 995eb7d7..16d5cc02 100644 --- a/assets/js/zen-mode.js +++ b/assets/js/zen-mode.js @@ -1,4 +1,4 @@ -function _toogleZenMode(zendModeButton) { +function _toggleZenMode(zendModeButton, options = { scrollToHeader: true }) { // Nodes selection const body = document.querySelector("body"); const footer = document.querySelector("footer"); @@ -35,11 +35,15 @@ function _toogleZenMode(zendModeButton) { // Change title to enable zendModeButton.setAttribute("title", titleI18nEnable); // Auto-scroll to title article - window.scrollTo(window.scrollX, header.getBoundingClientRect().top - 90); + if (options.scrollToHeader) { + window.scrollTo(window.scrollX, header.getBoundingClientRect().top - 90); + } } else { //localStorage.setItem('blowfish-zen-mode-enabled', 'false'); zendModeButton.setAttribute("title", titleI18nDisable); - document.querySelector("body").scrollIntoView(); + if (options.scrollToHeader) { + document.querySelector("body").scrollIntoView(); + } } } @@ -48,7 +52,7 @@ function _registerZendModeButtonClick(zendModeButton) { event.preventDefault(); // Toggle zen-mode - _toogleZenMode(zendModeButton); + _toggleZenMode(zendModeButton); }); } diff --git a/layouts/partials/header/basic.html b/layouts/partials/header/basic.html index 4f9c132e..18aab05e 100644 --- a/layouts/partials/header/basic.html +++ b/layouts/partials/header/basic.html @@ -202,6 +202,7 @@ (dict "id" (print $prefix "disable-blur") "label" (i18n "a11y.disable_blur")) (dict "id" (print $prefix "disable-images") "label" (i18n "a11y.disable_images")) (dict "id" (print $prefix "underline-links") "label" (i18n "a11y.show_link_underline")) + (dict "id" (print $prefix "zen-mode") "label" (i18n "article.zen_mode_title.enable")) -}} From 7f4e4dab405e3513e8ba530cc60a6c2eac4ef5e9 Mon Sep 17 00:00:00 2001 From: ZhenShuo Leo <98386542+ZhenShuo2021@users.noreply.github.com> Date: Wed, 23 Jul 2025 04:25:22 +0800 Subject: [PATCH 2/2] fix(a11y): prevent zen mode toggle requiring double-click Add state comparison in applyZenMode to only toggle when current state differs from desired state --- assets/js/a11y.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/assets/js/a11y.js b/assets/js/a11y.js index a1ed58eb..3117ae72 100644 --- a/assets/js/a11y.js +++ b/assets/js/a11y.js @@ -51,9 +51,13 @@ const applyUnderlineLinks = (enabled) => { }; const applyZenMode = (enabled) => { - if (enabled && typeof _toggleZenMode === 'function') { + const body = document.querySelector("body"); + const isZenModeActive = body && body.classList.contains("zen-mode-enable"); + + // Toggle only if current state doesn't match desired state + if (enabled !== isZenModeActive) { const zenModeCheckbox = document.querySelector('[id$="zen-mode"]'); - if (zenModeCheckbox) { + if (zenModeCheckbox && typeof _toggleZenMode === "function") { _toggleZenMode(zenModeCheckbox, { scrollToHeader: false }); } } @@ -135,9 +139,9 @@ const initA11yPanel = (prefix = "") => { checkboxImages.addEventListener("change", (e) => updateA11ySetting("disableImages", e.target.checked)); checkboxUnderline.addEventListener("change", (e) => updateA11ySetting("underlineLinks", e.target.checked)); checkboxZenMode.addEventListener("change", (e) => { - updateA11ySetting("zenMode", e.target.checked) - _toggleZenMode(checkboxZenMode, { scrollToHeader: false }) - }) + // Only save setting, let applyZenMode handle the toggle logic + updateA11ySetting("zenMode", e.target.checked); + }); fontSizeSelect.addEventListener("change", (e) => { // Remove fontSize from localStorage when default is selected if (e.target.value === "default") {