diff --git a/assets/css/compiled/main.css b/assets/css/compiled/main.css index 033ce358..1d49a548 100644 --- a/assets/css/compiled/main.css +++ b/assets/css/compiled/main.css @@ -174,6 +174,69 @@ body.zen-mode-enable { .chroma .gl { text-decoration-line: underline; } +.a11y-panel-enter-active { + animation: slideInFromTop 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards; +} +.a11y-panel-leave-active { + animation: slideOutToTop 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards; +} +.ios-toggle { + position: relative; + width: 42px; + height: 24px; + background: #e5e5e5; + border-radius: 12px; + cursor: pointer; + transition: background-color 0.3s ease; + pointer-events: auto; +} +.ios-toggle input { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + z-index: 1; +} +.ios-toggle::after { + content: ""; + position: absolute; + top: 2px; + left: 2px; + width: 20px; + height: 20px; + background: white; + border-radius: 50%; + transition: transform 0.3s ease, background-color 0.3s ease; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + z-index: 0; +} +.ios-toggle input:checked + .toggle-track::after { + transform: translateX(18px); +} +.ios-toggle input:checked + .toggle-track { + background: rgba(var(--color-primary-500), 1); +} +.ios-toggle input:checked ~ .ios-toggle-ball { + transform: translateX(18px); +} +.ios-toggle.is-checked { + background: rgba(var(--color-primary-500), 1); +} +.ios-toggle:has(input:checked) { + background: rgba(var(--color-primary-500), 1); +} +.ios-toggle:has(input:checked)::after { + transform: translateX(18px); +} +.dark .ios-toggle { + background: #404040; +} +.dark .ios-toggle::after { + background: #f5f5f5; +} @layer theme, base, components, utilities; @layer theme { :root, :host { @@ -428,6 +491,9 @@ body.zen-mode-enable { .top-0 { top: calc(var(--spacing) * 0); } + .top-1\/2 { + top: calc(1/2 * 100%); + } .top-20 { top: calc(var(--spacing) * 20); } @@ -446,6 +512,9 @@ body.zen-mode-enable { .left-0 { left: calc(var(--spacing) * 0); } + .left-1\/2 { + left: calc(1/2 * 100%); + } .left-\[calc\(max\(-50vw\,-800px\)\+50\%\)\] { left: calc(max(-50vw, -800px) + 50%); } @@ -1245,6 +1314,9 @@ body.zen-mode-enable { .h-3 { height: calc(var(--spacing) * 3); } + .h-5 { + height: calc(var(--spacing) * 5); + } .h-6 { height: calc(var(--spacing) * 6); } @@ -1320,6 +1392,9 @@ body.zen-mode-enable { .w-3 { width: calc(var(--spacing) * 3); } + .w-5 { + width: calc(var(--spacing) * 5); + } .w-6 { width: calc(var(--spacing) * 6); } @@ -1335,6 +1410,9 @@ body.zen-mode-enable { .w-36 { width: calc(var(--spacing) * 36); } + .w-80 { + width: calc(var(--spacing) * 80); + } .w-\[15\%\] { width: 15%; } @@ -1434,6 +1512,10 @@ body.zen-mode-enable { .border-collapse { border-collapse: collapse; } + .-translate-x-1\/2 { + --tw-translate-x: calc(calc(1/2 * 100%) * -1); + translate: var(--tw-translate-x) var(--tw-translate-y); + } .-translate-x-full { --tw-translate-x: -100%; translate: var(--tw-translate-x) var(--tw-translate-y); @@ -1442,6 +1524,10 @@ body.zen-mode-enable { --tw-translate-x: 100%; translate: var(--tw-translate-x) var(--tw-translate-y); } + .-translate-y-1\/2 { + --tw-translate-y: calc(calc(1/2 * 100%) * -1); + translate: var(--tw-translate-x) var(--tw-translate-y); + } .-translate-y-8 { --tw-translate-y: calc(var(--spacing) * -8); translate: var(--tw-translate-x) var(--tw-translate-y); @@ -1533,6 +1619,13 @@ body.zen-mode-enable { margin-block-end: calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse))); } } + .space-y-5 { + :where(& > :not(:last-child)) { + --tw-space-y-reverse: 0; + margin-block-start: calc(calc(var(--spacing) * 5) * var(--tw-space-y-reverse)); + margin-block-end: calc(calc(var(--spacing) * 5) * calc(1 - var(--tw-space-y-reverse))); + } + } .space-y-10 { :where(& > :not(:last-child)) { --tw-space-y-reverse: 0; @@ -1755,6 +1848,9 @@ body.zen-mode-enable { .bg-neutral { background-color: rgba(var(--color-neutral), 1); } + .bg-neutral-50 { + background-color: rgba(var(--color-neutral-50), 1); + } .bg-neutral-100 { background-color: rgba(var(--color-neutral-100), 1); } @@ -1956,6 +2052,9 @@ body.zen-mode-enable { .pr-0 { padding-right: calc(var(--spacing) * 0); } + .pr-8 { + padding-right: calc(var(--spacing) * 8); + } .pr-\[24px\] { padding-right: 24px; } @@ -2570,6 +2669,13 @@ body.zen-mode-enable { } } } + .hover\:text-neutral-700 { + &:hover { + @media (hover: hover) { + color: rgba(var(--color-neutral-700), 1); + } + } + } .hover\:text-primary-400 { &:hover { @media (hover: hover) { @@ -2668,6 +2774,11 @@ body.zen-mode-enable { translate: var(--tw-translate-x) var(--tw-translate-y); } } + .focus\:border-primary-500 { + &:focus { + border-color: rgba(var(--color-primary-500), 1); + } + } .focus\:bg-primary-100 { &:focus { background-color: rgba(var(--color-primary-100), 1); @@ -2683,6 +2794,11 @@ body.zen-mode-enable { opacity: 90%; } } + .focus\:ring-primary-500 { + &:focus { + --tw-ring-color: rgba(var(--color-primary-500), 1); + } + } .focus\:outline-2 { &:focus { outline-style: var(--tw-outline-style); @@ -3520,6 +3636,15 @@ body.zen-mode-enable { } } } + .dark\:hover\:text-neutral-200 { + &:is(.dark *) { + &:hover { + @media (hover: hover) { + color: rgba(var(--color-neutral-200), 1); + } + } + } + } .dark\:hover\:text-neutral-800 { &:is(.dark *) { &:hover { diff --git a/assets/css/components/a11y.css b/assets/css/components/a11y.css new file mode 100644 index 00000000..330561ed --- /dev/null +++ b/assets/css/components/a11y.css @@ -0,0 +1,77 @@ +.a11y-panel-enter-active { + animation: slideInFromTop 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards; +} + +.a11y-panel-leave-active { + animation: slideOutToTop 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards; +} + +.ios-toggle { + position: relative; + width: 42px; + height: 24px; + background: #e5e5e5; + border-radius: 12px; + cursor: pointer; + transition: background-color 0.3s ease; + pointer-events: auto; +} + +.ios-toggle input { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0; + cursor: pointer; + z-index: 1; +} + +.ios-toggle::after { + content: ""; + position: absolute; + top: 2px; + left: 2px; + width: 20px; + height: 20px; + background: white; + border-radius: 50%; + transition: + transform 0.3s ease, + background-color 0.3s ease; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + z-index: 0; +} + +.ios-toggle input:checked + .toggle-track::after { + transform: translateX(18px); +} + +.ios-toggle input:checked + .toggle-track { + background: rgba(var(--color-primary-500), 1); +} + +.ios-toggle input:checked ~ .ios-toggle-ball { + transform: translateX(18px); +} + +.ios-toggle.is-checked { + background: rgba(var(--color-primary-500), 1); +} + +.ios-toggle:has(input:checked) { + background: rgba(var(--color-primary-500), 1); +} + +.ios-toggle:has(input:checked)::after { + transform: translateX(18px); +} + +.dark .ios-toggle { + background: #404040; +} + +.dark .ios-toggle::after { + background: #f5f5f5; +} diff --git a/assets/css/main.css b/assets/css/main.css index a617b674..023eef06 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -2,6 +2,7 @@ @import "./components/zen-mode.css"; @import "./components/chroma.css"; +@import "./components/a11y.css"; @import "tailwindcss"; @config "../../tailwind.config.js"; diff --git a/assets/js/a11y.js b/assets/js/a11y.js new file mode 100644 index 00000000..6fb2e150 --- /dev/null +++ b/assets/js/a11y.js @@ -0,0 +1,172 @@ +const getA11ySettings = () => { + const settings = localStorage.getItem("a11ySettings"); + return settings + ? JSON.parse(settings) + : { + disableBlur: false, + disableImages: false, + fontSize: "default", + underlineLinks: false, + }; +}; + +const saveA11ySettings = (settings) => { + localStorage.setItem("a11ySettings", JSON.stringify(settings)); +}; + +const applyImageState = (imageElement, imageUrl, disableImages) => { + if (!imageElement) return; + if (disableImages) { + imageElement.style.display = "none"; + } else { + imageElement.style.display = ""; + if (imageUrl && !imageElement.getAttribute("src")) { + imageElement.setAttribute("src", imageUrl); + } + } +}; + +const applyFontSize = (fontSizePx) => { + const isDefaultSettings = localStorage.getItem("a11ySettings") === null; + if (!isDefaultSettings && fontSizePx !== "default") { + document.documentElement.style.fontSize = fontSizePx; + } +}; + +const applyUnderlineLinks = (enabled) => { + let styleElement = document.getElementById("a11y-underline-links"); + if (enabled) { + if (!styleElement) { + styleElement = document.createElement("style"); + styleElement.id = "a11y-underline-links"; + styleElement.textContent = "a { text-decoration: underline !important; }"; + document.head.appendChild(styleElement); + } + } else { + if (styleElement) { + styleElement.remove(); + } + } +}; + +const applyA11ySettings = () => { + const settings = getA11ySettings(); + document.querySelectorAll("script[data-target-id]").forEach((script) => { + const targetId = script.getAttribute("data-target-id"); + const scrollDivisor = Number(script.getAttribute("data-scroll-divisor") || 300); + const imageId = script.getAttribute("data-image-id"); + const imageUrl = script.getAttribute("data-image-url"); + const isMenuBlur = targetId === "menu-blur"; + setBackgroundBlur(targetId, scrollDivisor, settings.disableBlur, isMenuBlur); + applyImageState(document.getElementById(imageId), imageUrl, settings.disableImages); + }); + applyFontSize(settings.fontSize); + applyUnderlineLinks(settings.underlineLinks); +}; + +const updateA11ySetting = (key, value) => { + const settings = getA11ySettings(); + settings[key] = value; + saveA11ySettings(settings); + applyA11ySettings(); +}; + +const toggleA11yPanel = (prefix = "") => { + const panel = document.getElementById(`${prefix}a11y-panel`); + const overlay = document.getElementById(`${prefix}a11y-overlay`); + const button = document.getElementById(`${prefix}a11y-toggle`); + if (!panel || !overlay || !button) return; + if (overlay.classList.contains("hidden")) { + overlay.classList.remove("hidden"); + panel.classList.remove("hidden"); + button.setAttribute("aria-pressed", "true"); + button.setAttribute("aria-expanded", "true"); + } else { + overlay.classList.add("hidden"); + panel.classList.add("hidden"); + button.setAttribute("aria-pressed", "false"); + button.setAttribute("aria-expanded", "false"); + } +}; + +const initA11yPanel = (prefix = "") => { + const settings = getA11ySettings(); + const checkboxBlur = document.getElementById(`${prefix}disable-blur`); + const checkboxImages = document.getElementById(`${prefix}disable-images`); + const checkboxUnderline = document.getElementById(`${prefix}underline-links`); + const fontSizeSelect = document.getElementById(`${prefix}font-size-select`); + const toggleButton = document.getElementById(`${prefix}a11y-toggle`); + const closeButton = document.getElementById(`${prefix}a11y-close`); + const overlay = document.getElementById(`${prefix}a11y-overlay`); + + if ( + !checkboxBlur || + !checkboxImages || + !checkboxUnderline || + !fontSizeSelect || + !toggleButton || + !closeButton || + !overlay + ) { + console.warn(`One or more a11y elements not found for prefix: ${prefix}`); + return; + } + + checkboxBlur.checked = settings.disableBlur; + checkboxImages.checked = settings.disableImages; + fontSizeSelect.value = settings.fontSize; + checkboxUnderline.checked = settings.underlineLinks; + + 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)); + fontSizeSelect.addEventListener("change", (e) => { + // Remove fontSize from localStorage when default is selected + if (e.target.value === "default") { + const settings = getA11ySettings(); + delete settings.fontSize; + saveA11ySettings(settings); + document.documentElement.style.fontSize = ""; + } else { + updateA11ySetting("fontSize", e.target.value); + } + }); + + toggleButton.addEventListener("click", () => toggleA11yPanel(prefix)); + closeButton.addEventListener("click", () => toggleA11yPanel(prefix)); + overlay.addEventListener("click", (e) => { + if (e.target === overlay) { + toggleA11yPanel(prefix); + } + }); + + document.querySelectorAll(`.ios-toggle${prefix ? `[id^="${prefix}"]` : ""}`).forEach((toggle) => { + const checkbox = toggle.querySelector('input[type="checkbox"]'); + if (!checkbox) return; + const newToggle = toggle.cloneNode(true); + toggle.parentNode.replaceChild(newToggle, toggle); + newToggle.addEventListener("click", () => { + const newCheckbox = newToggle.querySelector('input[type="checkbox"]'); + if (newCheckbox) { + newCheckbox.checked = !newCheckbox.checked; + newCheckbox.dispatchEvent(new Event("change", { bubbles: true })); + } + }); + }); +}; + +document.querySelectorAll("script[data-target-id]").forEach((script) => { + const imageId = script.getAttribute("data-image-id"); + const imageUrl = script.getAttribute("data-image-url"); + const settings = getA11ySettings(); + applyImageState(document.getElementById(imageId), imageUrl, settings.disableImages); +}); + +document.addEventListener("DOMContentLoaded", () => { + applyA11ySettings(); + const allPanels = document.querySelectorAll('[id$="a11y-panel"]'); + allPanels.forEach((panel) => { + const prefix = panel.id.replace("a11y-panel", ""); + initA11yPanel(prefix); + }); +}); diff --git a/assets/js/background-blur.js b/assets/js/background-blur.js index dc8d491b..1d60793b 100644 --- a/assets/js/background-blur.js +++ b/assets/js/background-blur.js @@ -1,80 +1,52 @@ -(() => { - const scripts = document.querySelectorAll('script[data-target-id]'); - - const isA11yMode = () => { - return localStorage.getItem("a11yMode") === "true"; - }; - - const getScrollOpacity = (scrollDivisor) => { - const scrollY = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; - return scrollY / scrollDivisor; - }; - - const applyBlurState = (blurElement, scrollDivisor, targetId, imageElement, imageUrl) => { - if (!blurElement) return; - const isMenuBlur = targetId === "menu-blur"; - - if (isA11yMode()) { - blurElement.setAttribute("aria-hidden", "true"); - if (!isMenuBlur) { - blurElement.style.display = "none"; - blurElement.style.opacity = "0"; - } else { - blurElement.style.display = ""; - blurElement.style.opacity = getScrollOpacity(scrollDivisor); - } - // Hide image in a11y mode - if (imageElement) { - imageElement.style.display = "none"; - } +function setBackgroundBlur(targetId, scrollDivisor = 300, disableBlur = false, isMenuBlur = false) { + if (!targetId) { + console.error("data-target-id is null"); + return; + } + const blurElement = document.getElementById(targetId); + if (!blurElement) return; + if (disableBlur) { + blurElement.setAttribute("aria-hidden", "true"); + if (!isMenuBlur) { + blurElement.style.display = "none"; + blurElement.style.opacity = "0"; } else { blurElement.style.display = ""; - blurElement.style.opacity = getScrollOpacity(scrollDivisor); - blurElement.removeAttribute("aria-hidden"); - // Show image in normal mode - if (imageElement) { - imageElement.style.display = ""; - // Re-apply image source if it was removed - if (imageUrl && !imageElement.getAttribute('src')) { - imageElement.setAttribute('src', imageUrl); - } - } + } + } else { + blurElement.style.display = ""; + blurElement.removeAttribute("aria-hidden"); + } + const updateBlur = () => { + if (!disableBlur || isMenuBlur) { + const scroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0; + blurElement.style.opacity = scroll / scrollDivisor; } }; + blurElement.setAttribute("role", "presentation"); + blurElement.setAttribute("tabindex", "-1"); + window.addEventListener("scroll", updateBlur); + updateBlur(); +} - scripts.forEach(script => { - const targetId = script.getAttribute("data-target-id"); - const scrollDivisor = Number(script.getAttribute("data-scroll-divisor") || 300); - const imageId = script.getAttribute("data-image-id"); - const imageUrl = script.getAttribute("data-image-url"); // Get image URL from data attribute +document.querySelectorAll("script[data-target-id]").forEach((script) => { + const targetId = script.getAttribute("data-target-id"); + const scrollDivisor = Number(script.getAttribute("data-scroll-divisor") || 300); + const isMenuBlur = targetId === "menu-blur"; + const settings = JSON.parse(localStorage.getItem("a11ySettings") || "{}"); + const disableBlur = settings.disableBlur || false; + setBackgroundBlur(targetId, scrollDivisor, disableBlur, isMenuBlur); +}); - const blurElement = document.getElementById(targetId); - const imageElement = imageId ? document.getElementById(imageId) : null; - - if (blurElement) { - blurElement.setAttribute("role", "presentation"); - blurElement.setAttribute("tabindex", "-1"); - applyBlurState(blurElement, scrollDivisor, targetId, imageElement, imageUrl); - - window.addEventListener("scroll", () => { - if (!isA11yMode() || targetId === "menu-blur") { - blurElement.style.opacity = getScrollOpacity(scrollDivisor); - } - }); - } - }); - - window.toggleA11yMode = function() { - localStorage.setItem("a11yMode", String(!isA11yMode())); - scripts.forEach(script => { - const targetId = script.getAttribute("data-target-id"); - const scrollDivisor = Number(script.getAttribute("data-scroll-divisor") || 300); +// Prevent disableImages FOUC +// Note: I tried putting this in a11y.js but it did not work, and placing it here prevents FOUC +(() => { + const settings = JSON.parse(localStorage.getItem("a11ySettings") || "{}"); + if (settings.disableImages) { + document.querySelectorAll("script[data-image-id]").forEach((script) => { const imageId = script.getAttribute("data-image-id"); - const imageUrl = script.getAttribute("data-image-url"); // Get image URL from data attribute - - const blurElement = document.getElementById(targetId); - const imageElement = imageId ? document.getElementById(imageId) : null; - applyBlurState(blurElement, scrollDivisor, targetId, imageElement, imageUrl); + const image = imageId && document.getElementById(imageId); + if (image) image.style.display = "none"; }); - }; + } })(); diff --git a/i18n/ar.yaml b/i18n/ar.yaml index a97e7875..7bc969a0 100644 --- a/i18n/ar.yaml +++ b/i18n/ar.yaml @@ -25,6 +25,12 @@ article: part: "جزء" this_article: "هذه المقالة" +a11y: + disable_blur: "تعطيل التمويه" + disable_images: "تعطيل الصور" + show_link_underline: "إظهار خط تحت الروابط" + font_size: "حجم الخط" + author: byline_title: "الناشر" diff --git a/i18n/bg.yaml b/i18n/bg.yaml index 9f0dae2b..8f454f22 100644 --- a/i18n/bg.yaml +++ b/i18n/bg.yaml @@ -26,6 +26,12 @@ article: this_article: "Тази Статия" related_articles: "Подобни" +a11y: + disable_blur: "Изключване на замъгляването" + disable_images: "Изключване на изображенията" + show_link_underline: "Показване на подчертаване на връзките" + font_size: "Размер на шрифта" + author: byline_title: "Автор" diff --git a/i18n/ca.yaml b/i18n/ca.yaml index fe6b794a..d5cc0a4b 100644 --- a/i18n/ca.yaml +++ b/i18n/ca.yaml @@ -29,6 +29,12 @@ article: enable: "Activar mode zen" disable: "Desactivar mode zen" +a11y: + disable_blur: "Desactiva el desenfocament" + disable_images: "Desactiva les imatges" + show_link_underline: "Mostra el subratllat dels enllaços" + font_size: "Mida de la lletra" + author: byline_title: "Autor" diff --git a/i18n/cs.yaml b/i18n/cs.yaml index ab633a21..ddfe5891 100644 --- a/i18n/cs.yaml +++ b/i18n/cs.yaml @@ -26,6 +26,12 @@ article: this_article: "Tento článek" related_articles: "Related" +a11y: + disable_blur: "Zakázat rozmazání" + disable_images: "Zakázat obrázky" + show_link_underline: "Zobrazit podtržení odkazů" + font_size: "Velikost písma" + author: byline_title: "Autor" diff --git a/i18n/en.yaml b/i18n/en.yaml index 383a9d46..0b87e0c0 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -29,6 +29,12 @@ article: enable: "Enable zen mode" disable: "Disable zen mode" +a11y: + disable_blur: "Disable blur" + disable_images: "Disable images" + show_link_underline: "Show link underline" + font_size: "Font size" + author: byline_title: "Author" diff --git a/i18n/eo.yaml b/i18n/eo.yaml index a80aa480..79ebd137 100644 --- a/i18n/eo.yaml +++ b/i18n/eo.yaml @@ -29,6 +29,12 @@ article: enable: "Ŝalti zen-reĝimon" disable: "Malŝalti zen-reĝimon" +a11y: + disable_blur: "Malŝalti malklarigon" + disable_images: "Malŝalti bildojn" + show_link_underline: "Montri substrekojn de ligiloj" + font_size: "Tipara grandeco" + author: byline_title: "Aŭtoro" diff --git a/i18n/fa.yaml b/i18n/fa.yaml index 6eecd8ab..ecf11782 100644 --- a/i18n/fa.yaml +++ b/i18n/fa.yaml @@ -29,6 +29,12 @@ article: enable: "فعال کردن حالت تمام متن" disable: "غیر فعال کردن حالت تمام متن" +a11y: + disable_blur: "غیرفعال کردن تاری" + disable_images: "غیرفعال کردن تصاویر" + show_link_underline: "نمایش زیرخط لینک" + font_size: "اندازه فونت" + author: byline_title: "نویسنده" diff --git a/i18n/fi.yaml b/i18n/fi.yaml index 9a4d0b2d..dd4b206a 100644 --- a/i18n/fi.yaml +++ b/i18n/fi.yaml @@ -20,6 +20,12 @@ article: this_article: "This Article" related_articles: "Related" +a11y: + disable_blur: "Poista sumennus käytöstä" + disable_images: "Poista kuvat käytöstä" + show_link_underline: "Näytä linkkien alleviivaus" + font_size: "Fonttikoko" + author: byline_title: "Kirjoittaja" diff --git a/i18n/gl.yaml b/i18n/gl.yaml index ddc17a87..e3b0281a 100644 --- a/i18n/gl.yaml +++ b/i18n/gl.yaml @@ -29,6 +29,12 @@ article: enable: "Activar modo zen" disable: "Desactivar modo zen" +a11y: + disable_blur: "Desactivar o desenfoque" + disable_images: "Desactivar as imaxes" + show_link_underline: "Mostrar subliñado da ligazón" + font_size: "Tamaño de letra" + author: byline_title: "Autor" diff --git a/i18n/he.yaml b/i18n/he.yaml index f738d521..368bd71d 100644 --- a/i18n/he.yaml +++ b/i18n/he.yaml @@ -20,6 +20,12 @@ article: this_article: "This Article" related_articles: "Related" +a11y: + disable_blur: "השבת טשטוש" + disable_images: "השבת תמונות" + show_link_underline: "הצג קו תחתון לקישורים" + font_size: "גודל גופן" + author: byline_title: "מחבר" diff --git a/i18n/hu.yaml b/i18n/hu.yaml index 7c45457b..40f81724 100644 --- a/i18n/hu.yaml +++ b/i18n/hu.yaml @@ -20,6 +20,12 @@ article: this_article: "This Article" related_articles: "Related" +a11y: + disable_blur: "Elmosódás kikapcsolása" + disable_images: "Képek kikapcsolása" + show_link_underline: "Link aláhúzásának megjelenítése" + font_size: "Betűméret" + author: byline_title: "Szerző" diff --git a/i18n/id.yaml b/i18n/id.yaml index 70f8765d..33a0c8d3 100644 --- a/i18n/id.yaml +++ b/i18n/id.yaml @@ -26,6 +26,12 @@ article: this_article: "Artikel ini" related_articles: "Terkait" +a11y: + disable_blur: "Nonaktifkan blur" + disable_images: "Nonaktifkan gambar" + show_link_underline: "Tampilkan garis bawah tautan" + font_size: "Ukuran font" + author: byline_title: "Penulis" diff --git a/i18n/ja.yaml b/i18n/ja.yaml index 0574a68b..ca25ff42 100644 --- a/i18n/ja.yaml +++ b/i18n/ja.yaml @@ -29,6 +29,12 @@ article: enable: "Zenモードを有効にする" disable: "Zenモードを無効にする" +a11y: + disable_blur: "ぼかしを無効にする" + disable_images: "画像を無効にする" + show_link_underline: "リンクの下線を表示する" + font_size: "フォントサイズ" + author: byline_title: "著者" diff --git a/i18n/ko.yaml b/i18n/ko.yaml index 152e7b00..7c12f6cd 100644 --- a/i18n/ko.yaml +++ b/i18n/ko.yaml @@ -26,6 +26,12 @@ article: this_article: "이 글" related_articles: "관련 글" +a11y: + disable_blur: "흐림 효과 끄기" + disable_images: "이미지 끄기" + show_link_underline: "링크 밑줄 표시" + font_size: "글꼴 크기" + author: byline_title: "작성자" diff --git a/i18n/pl.yaml b/i18n/pl.yaml index ab3c947c..4fd77569 100644 --- a/i18n/pl.yaml +++ b/i18n/pl.yaml @@ -26,6 +26,12 @@ article: this_article: "This Article" related_articles: "Related" +a11y: + disable_blur: "Wyłącz rozmycie" + disable_images: "Wyłącz obrazy" + show_link_underline: "Pokaż podkreślenie linków" + font_size: "Rozmiar czcionki" + author: byline_title: "Autor" diff --git a/i18n/pt-BR.yaml b/i18n/pt-BR.yaml index 7a807d22..1a198bf7 100644 --- a/i18n/pt-BR.yaml +++ b/i18n/pt-BR.yaml @@ -23,6 +23,12 @@ article: this_article: "Esse Artigo" related_articles: "Relacionados" +a11y: + disable_blur: "Desativar desfoque" + disable_images: "Desativar imagens" + show_link_underline: "Mostrar sublinhado de links" + font_size: "Tamanho da fonte" + author: byline_title: "Autor" diff --git a/i18n/ro.yaml b/i18n/ro.yaml index eb77bd19..d8e98182 100644 --- a/i18n/ro.yaml +++ b/i18n/ro.yaml @@ -20,6 +20,12 @@ article: this_article: "This Article" related_articles: "Related" +a11y: + disable_blur: "Dezactivează estomparea" + disable_images: "Dezactivează imaginile" + show_link_underline: "Afișează sublinierea linkurilor" + font_size: "Dimensiunea fontului" + author: byline_title: "Autor" diff --git a/i18n/ru.yaml b/i18n/ru.yaml index db8b77cc..9aca26c2 100644 --- a/i18n/ru.yaml +++ b/i18n/ru.yaml @@ -26,6 +26,12 @@ article: this_article: "This Article" related_articles: "Related" +a11y: + disable_blur: "Отключить размытие" + disable_images: "Отключить изображения" + show_link_underline: "Показать подчеркивание ссылок" + font_size: "Размер шрифта" + author: byline_title: "Автор" diff --git a/i18n/sv.yaml b/i18n/sv.yaml index cec86546..139863f6 100644 --- a/i18n/sv.yaml +++ b/i18n/sv.yaml @@ -20,6 +20,12 @@ article: this_article: "Denna artikel" related_articles: "Relaterade" +a11y: + disable_blur: "Inaktivera suddighet" + disable_images: "Inaktivera bilder" + show_link_underline: "Visa länkunderstrykning" + font_size: "Teckenstorlek" + author: byline_title: "Författare" diff --git a/i18n/th.yaml b/i18n/th.yaml index 70796ecf..6a48aa3b 100644 --- a/i18n/th.yaml +++ b/i18n/th.yaml @@ -29,6 +29,12 @@ article: enable: "เปิดโหมดเซน" disable: "ปิดโหมดเซน" +a11y: + disable_blur: "ปิดการเบลอ" + disable_images: "ปิดการแสดงรูปภาพ" + show_link_underline: "แสดงเส้นใต้ลิงก์" + font_size: "ขนาดตัวอักษร" + author: byline_title: "ผู้เขียน" diff --git a/i18n/uk.yaml b/i18n/uk.yaml index c66e315b..8872b1bb 100644 --- a/i18n/uk.yaml +++ b/i18n/uk.yaml @@ -33,6 +33,12 @@ article: enable: "Enable zen mode" disable: "Disable zen mode" +a11y: + disable_blur: "Вимкнути розмиття" + disable_images: "Вимкнути зображення" + show_link_underline: "Показати підкреслення посилань" + font_size: "Розмір шрифту" + author: byline_title: "Автор" diff --git a/i18n/vi.yaml b/i18n/vi.yaml index b972303a..c65ec186 100644 --- a/i18n/vi.yaml +++ b/i18n/vi.yaml @@ -29,6 +29,12 @@ article: enable: "Bật zen mode" disable: "Tắt zen mode" +a11y: + disable_blur: "Tắt làm mờ" + disable_images: "Tắt hình ảnh" + show_link_underline: "Hiển thị gạch chân liên kết" + font_size: "Cỡ chữ" + author: byline_title: "Tác giả" diff --git a/i18n/zh-CN.yaml b/i18n/zh-CN.yaml index 020fac31..56722c7a 100644 --- a/i18n/zh-CN.yaml +++ b/i18n/zh-CN.yaml @@ -19,6 +19,12 @@ article: this_article: "本文" related_articles: "相关文章" +a11y: + disable_blur: "禁用模糊效果" + disable_images: "禁用图片" + show_link_underline: "显示链接下划线" + font_size: "字体大小" + author: byline_title: "作者" diff --git a/i18n/zh-TW.yaml b/i18n/zh-TW.yaml index 8dda2b4a..16803901 100644 --- a/i18n/zh-TW.yaml +++ b/i18n/zh-TW.yaml @@ -19,6 +19,12 @@ article: this_article: "本文" related_articles: "相關文章" +a11y: + disable_blur: "停用模糊效果" + disable_images: "停用圖片" + show_link_underline: "顯示連結底線" + font_size: "字體大小" + author: byline_title: "作者" diff --git a/layouts/partials/head.html b/layouts/partials/head.html index a1db6860..eb4b87ed 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -69,6 +69,13 @@ type="text/javascript" src="{{ $jsAppearance.RelPermalink }}" integrity="{{ $jsAppearance.Data.Integrity }}"> + {{ if .Site.Params.enableA11y | default false }} + {{ $jsA11y := resources.Get "js/a11y.js" }} + {{ $jsA11y = $jsA11y | resources.Minify | resources.Fingerprint (site.Params.fingerprintAlgorithm | default "sha512") }} + + {{ end }} {{ if .Site.Params.enableSearch | default false }} {{ $jsFuse := resources.Get "lib/fuse/fuse.min.js" }} {{ $jsSearch := resources.Get "js/search.js" }} diff --git a/layouts/partials/header/basic.html b/layouts/partials/header/basic.html index 80acaffc..4f9c132e 100644 --- a/layouts/partials/header/basic.html +++ b/layouts/partials/header/basic.html @@ -35,16 +35,7 @@ {{ partial "translations.html" . }} {{ if .Site.Params.enableA11y | default false }} - + {{ template "HeaderA11y" (dict "prefix" "desktop-" "Site" .Site) }} {{ end }} {{ if .Site.Params.enableSearch | default false }} @@ -82,18 +73,8 @@ {{ partial "translations.html" . }} - {{ if .Site.Params.enableA11y | default false }} - + {{ template "HeaderA11y" (dict "prefix" "mobile-" "Site" .Site) }} {{ end }} {{ if .Site.Params.enableSearch | default false }} @@ -178,6 +159,84 @@ {{ end }} +{{ define "HeaderA11y" }} + {{- $prefix := .prefix | default "" -}} +
+ + + + + +
+{{ end }} + {{/* ========== Render HTML ========== */}}