mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 18:34:02 +00:00
Choosing a language in the picker now applies it at once. The choice is stored and ?lang is kept in step through replaceState, and the picker keeps focus. Code that writes translated text itself re-presents it on a switch: onLocaleChange() lets an owner listen, removed at teardown, and status writers hand over a function of the locale (voice cards, scene director, SDR, draw hints, imagery split, map sources, Bhote Koshi media) so the words are rebuilt rather than re-sent. The HUD, cockpit, radio, CCTV, launch, awareness and credit texts follow the same hook, and applyDocumentTranslations can be applied again without undoing text code wrote since. The unsaved-work registry and persistLocaleAndReload existed only to guard the reload, so they go, with their catalog entries.
85 lines
3.1 KiB
JavaScript
85 lines
3.1 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;
|
|
|
|
// Cesium writes these two texts in English once, when it builds the credit
|
|
// display, and never rewrites them; English is Cesium's own text. Called
|
|
// again after a locale change, this words them again.
|
|
expand.textContent = t('Data attribution');
|
|
const title = lightbox.querySelector?.('.cesium-credit-lightbox-title');
|
|
if (title) title.textContent = t('Data provided by:');
|
|
|
|
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);
|
|
if (!expand.hasAttribute?.('aria-expanded'))
|
|
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;
|
|
}
|