Files
Shaarli_bm_theme/shaarli-pro/js/modules/a11y.js
T
bruno f753b27542
CI / build (push) Failing after 6m2s
Add asset pipeline and professionalize theme
Introduce a Node build system for minified CSS/JS with content hashes,
add PWA support, i18n helpers, accessibility improvements, and more
translatable strings. Move theme configuration from bookmarks to
localStorage, add Playwright tests, and set up CI workflows.
2026-08-09 09:25:03 -04:00

67 lines
2.0 KiB
JavaScript

// =====================================================================
// Accessibility helpers for Shaarli Pro modals and overlays.
// =====================================================================
(function (root) {
'use strict';
const FOCUSABLE_SELECTORS = [
'a[href]',
'button:not([disabled])',
'input:not([disabled])',
'select:not([disabled])',
'textarea:not([disabled])',
'[tabindex]:not([tabindex="-1"])'
].join(', ');
/**
* Return a focusable element inside a container.
*/
function getFocusable(container, first) {
if (!container) return null;
const elements = Array.prototype.slice.call(container.querySelectorAll(FOCUSABLE_SELECTORS));
return first ? elements[0] : elements[elements.length - 1];
}
/**
* Move focus to the first focusable element inside a container.
*/
function focusFirst(container) {
const el = getFocusable(container, true);
if (el) el.focus();
}
/**
* Keep keyboard focus inside a container while it is open.
* Returns a cleanup function that removes the listener.
*/
function trapFocus(container) {
if (!container) return function () {};
function handleKey(e) {
if (e.key !== 'Tab') return;
const first = getFocusable(container, true);
const last = getFocusable(container, false);
if (!first || !last) return;
if (e.shiftKey && document.activeElement === first) {
e.preventDefault();
last.focus();
} else if (!e.shiftKey && document.activeElement === last) {
e.preventDefault();
first.focus();
}
}
container.addEventListener('keydown', handleKey);
return function () {
container.removeEventListener('keydown', handleKey);
};
}
root.ShaarliProA11y = {
focusFirst: focusFirst,
trapFocus: trapFocus,
getFocusable: getFocusable
};
}(window));