mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 10:24:02 +00:00
Replace the semantic keys with the English source text, so code reads as the
UI does and English needs no catalog: t('Save keys'), tn(count, one, other)
for plurals, msg() for text stored in data, and bare data-i18n* markup that
translates the element's own English. Other languages are one flat JSON each.
- Simplify src/i18n: drop namespaces, the configurable locale pair
(GEV_DEFAULT_LOCALE / GEV_SECONDARY_LOCALE) and its build defines. Locale
comes from ?lang=, the stored choice, then browser languages.
- Add scripts/i18n.mjs (npm run i18n): extracts every message from t/tn/msg
and markup, and fails on missing, unused, placeholder-mismatched or
wrongly-shaped plural entries. npm test runs it via catalog.test.mjs.
- Add Russian (src/i18n/locales/ru.json, 833 messages), started from the
community catalog in #312 and reviewed against the current English.
- Fix data-i18n placed on parents that would wipe their children (cockpit
LEVEL and local weather cells, first-run EXPLORE MANUALLY tile), and a
doubled degree sign in the TRACK ACQUIRED signal.
- Rewrite docs/TRANSLATORS.md for the new workflow; drop sections the earlier
merge resurrected in docs/CURRENT-STATE.md.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
77 lines
2.7 KiB
JavaScript
77 lines
2.7 KiB
JavaScript
/**
|
|
* Adds the keyboard semantics omitted by Cesium's href-less attribution links.
|
|
* Cesium retains ownership of showing and hiding its required credit lightbox.
|
|
*/
|
|
import { t } from './i18n/index.js';
|
|
|
|
export function configureCreditKeyboardAccess(root = document) {
|
|
const expand = root?.querySelector?.(
|
|
'#cesium-credits .cesium-credit-expand-link',
|
|
);
|
|
const lightbox = root?.querySelector?.('.cesium-credit-lightbox');
|
|
const close = lightbox?.querySelector?.('.cesium-credit-lightbox-close');
|
|
if (!expand || !lightbox || !close) return false;
|
|
const overlay = lightbox.parentElement;
|
|
|
|
if (!lightbox.id) lightbox.id = 'cesium-credit-lightbox';
|
|
expand.setAttribute('role', 'button');
|
|
expand.setAttribute('tabindex', '0');
|
|
expand.setAttribute('aria-haspopup', 'dialog');
|
|
expand.setAttribute('aria-controls', lightbox.id);
|
|
expand.setAttribute('aria-expanded', 'false');
|
|
close.setAttribute('role', 'button');
|
|
close.setAttribute('tabindex', '0');
|
|
close.setAttribute('aria-label', t('Close data attribution'));
|
|
|
|
if (expand.dataset.gevKeyboardReady === 'true') return true;
|
|
expand.dataset.gevKeyboardReady = 'true';
|
|
|
|
const installKeyboardActivation = (control) => {
|
|
let spacePressed = false;
|
|
control.addEventListener('keydown', (event) => {
|
|
if (event.key === 'Enter') {
|
|
event.preventDefault();
|
|
if (!event.repeat) control.click();
|
|
return;
|
|
}
|
|
if (event.key !== ' ') return;
|
|
event.preventDefault();
|
|
if (!event.repeat) spacePressed = true;
|
|
});
|
|
control.addEventListener('keyup', (event) => {
|
|
if (event.key !== ' ') return;
|
|
event.preventDefault();
|
|
if (!spacePressed) return;
|
|
spacePressed = false;
|
|
control.click();
|
|
});
|
|
// A long Space hold may hand control to push-to-talk and move focus away.
|
|
// Cancelling the armed release prevents that eventual keyup from also
|
|
// activating the attribution control.
|
|
control.addEventListener('blur', () => {
|
|
spacePressed = false;
|
|
});
|
|
};
|
|
const closeAndRestoreFocus = () => {
|
|
expand.setAttribute('aria-expanded', 'false');
|
|
expand.focus();
|
|
};
|
|
installKeyboardActivation(expand);
|
|
installKeyboardActivation(close);
|
|
lightbox.addEventListener('keydown', (event) => {
|
|
if (event.key !== 'Escape' || event.defaultPrevented) return;
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
close.click();
|
|
});
|
|
expand.addEventListener('click', () => {
|
|
expand.setAttribute('aria-expanded', 'true');
|
|
close.focus();
|
|
});
|
|
close.addEventListener('click', closeAndRestoreFocus);
|
|
overlay?.addEventListener?.('click', (event) => {
|
|
if (!lightbox.contains(event.target)) closeAndRestoreFocus();
|
|
});
|
|
return true;
|
|
}
|