diff --git a/TEST_SCENARIOS.md b/TEST_SCENARIOS.md index e4c66e2..e0b2bd8 100644 --- a/TEST_SCENARIOS.md +++ b/TEST_SCENARIOS.md @@ -195,6 +195,8 @@ plus bas. - **ATTENDU** : rien ne se passe. Aucun bouton derrière l'overlay ne prend le focus ni ne s'active. Tout redevient normal ensuite, focus compris. - **Historique** : l'overlay ne bloque que la **souris** — il couvre la page. Le clavier passait au travers : `Tab` entrait dans les contrôles derrière et `Espace` les activait. Corrigé avec l'attribut natif `inert` (retire un sous-arbre du focus, du hit-testing et de l'arbre d'accessibilité), posé sur chaque enfant de `` **sauf** l'overlay. - **Point de vigilance** : `hideBusy()` retire l'inertie **inconditionnellement**. Une opération qui échouerait sans le rétablir laisserait une application qui semble gelée. +- **`inert` ne suffit pas seul** : il retire les contrôles du focus, mais **pas** le défilement. `Espace`, `Page haut/bas`, `Début/Fin` et les flèches font défiler le document **sans aucun élément focalisé** — la page bougeait encore sous l'overlay. Ces touches sont donc avalées en phase de capture tant que l'opération tourne. +- **Vérifier aussi le défilement** : pendant l'overlay, `Espace` et `Page bas` ne doivent rien bouger ; après, le défilement clavier doit refonctionner. ### B14 · dialogues natifs ouverts par un clic programmatique - **ACTION** : `A` ouverte + **dirty** → (a) Settings → *Import vault* ; (b) télécharger une pièce jointe (fallback web) ; (c) *Upload icon* ; (d) joindre un fichier. diff --git a/js/app.js b/js/app.js index 8f5c124..d74cefe 100644 --- a/js/app.js +++ b/js/app.js @@ -7410,6 +7410,18 @@ async function init() { // BEFORE any input-level handler that might call stopPropagation, and // before the browser swallows the keystroke for things like clearing // an active form-autocomplete popup on a focused field. + // `inert` takes the controls out of reach but does NOT stop the browser's + // own scrolling keys — Space, PageUp/Down, Home/End and the arrows scroll + // the document without needing a focused element. Swallow them while a + // blocking operation is running; everything else (Esc, shortcuts) is + // already handled by the guards on each feature. + document.addEventListener('keydown', e => { + if (!isBusy()) return; + const scrolls = [' ', 'Spacebar', 'PageUp', 'PageDown', 'Home', 'End', + 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight']; + if (scrolls.indexOf(e.key) !== -1) e.preventDefault(); + }, true); + document.addEventListener('keydown', e => { if (e.key !== 'Escape') return; if (!$('#slideover').classList.contains('is-open')) return;