Navigation : un retour en cours retient l'adresse suivante ; test des adresses

history.go est asynchrone : une adresse demandée pendant un retour attend
son arrivée. Le test dans le navigateur ouvre chaque adresse du tableau de
l'ADR 0013 dans un nouvel onglet, vérifie le retour, le rôle link des liens
et l'aller-retour d'un lien de position, et range ses captures dans
browser-shots/adresses/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Pierre MARTIN
2026-11-09 13:45:17 +01:00
co-authored by Claude Opus 5.5
parent f4914b30ab
commit 97a098e98f
3 changed files with 318 additions and 12 deletions
+1 -1
View File
@@ -1007,7 +1007,7 @@ export function startApp(options: AppOptions): void {
// Le menu a son adresse : l'ouvrir, c'est aller à #/menu (comme son
// lien) ; le refermer, revenir à l'écran d'avant.
menu: () => {
if (navigation.route.screen === "menu") {
if (!ui.menuVeil.hidden) {
closeOverlays();
} else {
closeTransient();
+33 -7
View File
@@ -50,6 +50,10 @@ function currentHash(): string {
*/
export function startNavigation(onChange: (route: Route) => void): Navigation {
let trail: readonly string[] = [];
// Un retour dans l'historique est en cours (history.go est asynchrone) :
// une adresse demandée entre-temps attend son arrivée.
let leaving: ReturnType<typeof setTimeout> | null = null;
let queued: string | null = null;
const remember = (next: readonly string[]) => {
trail = next.slice(-TRAIL_MAX);
@@ -76,8 +80,25 @@ export function startNavigation(onChange: (route: Route) => void): Navigation {
remember([...trail, hash]);
}
onChange(parseRoute(hash));
if (leaving !== null) {
clearTimeout(leaving);
leaving = null;
const next = queued;
queued = null;
if (next !== null) {
go(next);
}
}
});
function go(hash: string): void {
if (leaving !== null) {
queued = hash;
} else if (hash !== currentHash()) {
location.hash = hash;
}
}
function replace(hash: string): void {
if (hash === currentHash()) {
return;
@@ -100,19 +121,24 @@ export function startNavigation(onChange: (route: Route) => void): Navigation {
get route() {
return parseRoute(currentHash());
},
go(hash) {
if (hash !== currentHash()) {
location.hash = hash;
}
},
go,
replace,
leave(stay) {
if (leaving !== null) {
return; // déjà en route
}
const steps = stepsBack(trail, stay);
if (steps === null) {
replace("#/");
} else {
history.go(steps);
return;
}
// Au cas où le navigateur ne reviendrait pas (historique
// indisponible), on n'attend pas plus d'une seconde.
leaving = setTimeout(() => {
leaving = null;
queued = null;
}, 1000);
history.go(steps);
},
};
}