Ajustement de l’accessibilité

This commit is contained in:
JonathanMM 2025-04-21 17:25:42 +02:00
commit 336cb39849
2 changed files with 117 additions and 27 deletions

View file

@ -13,7 +13,12 @@ export default class Grille {
private _indice: Array<string | undefined>;
private _motActuel: number;
public constructor(longueurMot: number, maxPropositions: number, indice: string, audioPanel: AudioPanel) {
public constructor(
longueurMot: number,
maxPropositions: number,
indice: string,
audioPanel: AudioPanel
) {
this._grille = document.getElementById("grille") as HTMLElement;
this._audioPanel = audioPanel;
@ -30,17 +35,23 @@ export default class Grille {
private afficherGrille() {
let table = document.createElement("table");
table.setAttribute("aria-live", "polite");
table.setAttribute("aria-label", "Grille de jeu");
for (let nbMot = 0; nbMot < this._maxPropositions; nbMot++) {
let ligne = document.createElement("tr");
let mot = this._propositions.length <= nbMot ? "" : this._propositions[nbMot];
let mot =
this._propositions.length <= nbMot ? "" : this._propositions[nbMot];
if (mot.length > 0) {
ligne.setAttribute("role", "group");
ligne.setAttribute("aria-label", `Mot ${nbMot + 1} sur 6`);
ligne.setAttribute("aria-label", `Mot ${nbMot + 1} sur 6, ${mot}`);
}
for (let nbLettre = 0; nbLettre < this._longueurMot; nbLettre++) {
let cellule = document.createElement("td");
let contenuCellule: string = "";
if (nbMot < this._motActuel || (nbMot === this._motActuel && mot.length !== 0)) {
if (
nbMot < this._motActuel ||
(nbMot === this._motActuel && mot.length !== 0)
) {
if (mot.length <= nbLettre) {
contenuCellule = ".";
cellule.classList.add("cellule-lettre-pas-curseur");
@ -58,24 +69,36 @@ export default class Grille {
cellule.classList.add("cellule-lettre-pas-curseur");
}
}
if (this._resultats.length > nbMot && this._resultats[nbMot][nbLettre]) {
if (
this._resultats.length > nbMot &&
this._resultats[nbMot][nbLettre]
) {
let resultat = this._resultats[nbMot][nbLettre];
let emoji: string = "🟦";
switch (resultat.statut) {
case LettreStatut.BienPlace:
emoji = "🟥";
cellule.classList.add("bien-place", "resultat");
cellule.setAttribute("aria-label", `Lettre ${resultat.lettre} bien placée`);
cellule.setAttribute(
"aria-label",
`Lettre ${resultat.lettre} bien placée`
);
break;
case LettreStatut.MalPlace:
emoji = "🟡";
cellule.classList.add("mal-place", "resultat");
cellule.setAttribute("aria-label", `Lettre ${resultat.lettre} mal placée`);
cellule.setAttribute(
"aria-label",
`Lettre ${resultat.lettre} mal placée`
);
break;
default:
emoji = "🟦";
cellule.classList.add("non-trouve", "resultat");
cellule.setAttribute("aria-label", `Lettre ${resultat.lettre} non présente`);
cellule.setAttribute(
"aria-label",
`Lettre ${resultat.lettre} non présente`
);
}
// console.log(resultat.lettre + " => " + emoji);
}
@ -95,7 +118,13 @@ export default class Grille {
this.afficherGrille();
}
public validerMot(mot: string, resultats: Array<LettreResultat>, isBonneReponse: boolean, skipAnimation: boolean = false, endCallback?: () => void): void {
public validerMot(
mot: string,
resultats: Array<LettreResultat>,
isBonneReponse: boolean,
skipAnimation: boolean = false,
endCallback?: () => void
): void {
this.saisirMot(this._motActuel, mot);
this.mettreAJourIndice(resultats);
this._resultats.push(resultats);
@ -114,7 +143,10 @@ export default class Grille {
}
}
private animerResultats(resultats: Array<LettreResultat>, endCallback?: () => void): void {
private animerResultats(
resultats: Array<LettreResultat>,
endCallback?: () => void
): void {
let table = this._grille.getElementsByTagName("table").item(0);
if (table === null) {
this.afficherGrille();
@ -133,7 +165,12 @@ export default class Grille {
this.animerLettre(td, resultats, 0, endCallback);
}
private animerLettre(td: HTMLCollectionOf<HTMLTableCellElement>, resultats: Array<LettreResultat>, numLettre: number, endCallback?: () => void): void {
private animerLettre(
td: HTMLCollectionOf<HTMLTableCellElement>,
resultats: Array<LettreResultat>,
numLettre: number,
endCallback?: () => void
): void {
if (numLettre >= td.length) {
this.afficherGrille();
if (endCallback) endCallback();
@ -142,21 +179,31 @@ export default class Grille {
let cellule = td[numLettre];
let resultat = resultats[numLettre];
cellule.innerHTML = resultat.lettre;
let callback = (() => this.animerLettre(td, resultats, numLettre + 1, endCallback)).bind(this);
let callback = (() =>
this.animerLettre(td, resultats, numLettre + 1, endCallback)).bind(this);
switch (resultat.statut) {
case LettreStatut.BienPlace:
cellule.classList.add("bien-place", "resultat");
cellule.setAttribute("aria-label", `Lettre ${resultat.lettre} bien placée`);
cellule.setAttribute(
"aria-label",
`Lettre ${resultat.lettre} bien placée`
);
this._audioPanel.jouerSonLettreBienPlace(callback);
break;
case LettreStatut.MalPlace:
cellule.classList.add("mal-place", "resultat");
cellule.setAttribute("aria-label", `Lettre ${resultat.lettre} mal placée`);
cellule.setAttribute(
"aria-label",
`Lettre ${resultat.lettre} mal placée`
);
this._audioPanel.jouerSonLettreMalPlace(callback);
break;
default:
cellule.classList.add("non-trouve", "resultat");
cellule.setAttribute("aria-label", `Lettre ${resultat.lettre} non présente`);
cellule.setAttribute(
"aria-label",
`Lettre ${resultat.lettre} non présente`
);
this._audioPanel.jouerSonLettreNonTrouve(callback);
}
}
@ -164,7 +211,10 @@ export default class Grille {
private mettreAJourIndice(resultats: Array<LettreResultat>): void {
for (let i = 0; i < this._indice.length; i++) {
if (!this._indice[i]) {
this._indice[i] = resultats[i].statut === LettreStatut.BienPlace ? resultats[i].lettre : undefined;
this._indice[i] =
resultats[i].statut === LettreStatut.BienPlace
? resultats[i].lettre
: undefined;
}
}
}

View file

@ -23,7 +23,12 @@ export default class Input {
private _resultats: Array<Array<LettreResultat>>;
private _haptiqueActive: boolean;
public constructor(gestionnaire: Gestionnaire, configuration: Configuration, longueurMot: number, premiereLettre: string) {
public constructor(
gestionnaire: Gestionnaire,
configuration: Configuration,
longueurMot: number,
premiereLettre: string
) {
this._grille = document.getElementById("grille") as HTMLElement;
this._inputArea = document.getElementById("input-area") as HTMLElement;
this._premiereLettre = premiereLettre;
@ -32,11 +37,14 @@ export default class Input {
this._motSaisi = "";
this._estBloque = new Array<ContexteBloquage>();
this._resultats = new Array<Array<LettreResultat>>();
this._haptiqueActive = configuration.haptique ?? Configuration.Default.haptique;
this._haptiqueActive =
configuration.haptique ?? Configuration.Default.haptique;
this.ajouterEvenementClavierPhysique();
this.dessinerClavier(configuration.disposition ?? Configuration.Default.disposition);
this.dessinerClavier(
configuration.disposition ?? Configuration.Default.disposition
);
}
public dessinerClavier(disposition: ClavierDisposition): void {
@ -55,12 +63,14 @@ export default class Input {
lettreDiv.dataset["lettre"] = lettre;
lettreDiv.innerText = "⌫";
lettreDiv.classList.add("input-lettre-effacer");
lettreDiv.setAttribute("aria-label", "Effacer la dernière lettre");
this.ajouterFocus(lettreDiv);
break;
case "_entree":
lettreDiv.innerText = "↲";
lettreDiv.dataset["lettre"] = lettre;
lettreDiv.classList.add("input-lettre-entree");
lettreDiv.setAttribute("aria-label", "Valider le mot");
this.ajouterFocus(lettreDiv);
break;
case "_vide":
@ -73,6 +83,11 @@ export default class Input {
default:
lettreDiv.dataset["lettre"] = lettre;
lettreDiv.innerText = lettre;
if (lettre === ".") {
lettreDiv.setAttribute("aria-label", "Mettre un blanc");
} else {
lettreDiv.setAttribute("aria-label", `Lettre ${lettre}`);
}
this.ajouterFocus(lettreDiv);
}
ligneDiv.appendChild(lettreDiv);
@ -80,7 +95,8 @@ export default class Input {
this._inputArea.appendChild(ligneDiv);
}
this._haptiqueActive = Sauvegardeur.chargerConfig()?.haptique ?? Configuration.Default.haptique;
this._haptiqueActive =
Sauvegardeur.chargerConfig()?.haptique ?? Configuration.Default.haptique;
this.ajouterEvenementClavierVirtuel();
this.remettrePropositions();
}
@ -125,7 +141,8 @@ export default class Input {
event.stopPropagation();
let div = event.currentTarget;
if (!div) return;
if (this._haptiqueActive && window.navigator.vibrate) window.navigator.vibrate(75);
if (this._haptiqueActive && window.navigator.vibrate)
window.navigator.vibrate(75);
let lettre = (div as HTMLElement).dataset["lettre"];
if (lettre === undefined) {
return;
@ -217,17 +234,25 @@ export default class Input {
private siPreremplissageEstReponse(): { preRempli: boolean; mot?: string } {
let lettrePrerempli = new Array<{ preRempli: boolean; lettre?: string }>();
for (let i = 0; i < this._longueurMot; i++) lettrePrerempli.push({ preRempli: false });
for (let i = 0; i < this._longueurMot; i++)
lettrePrerempli.push({ preRempli: false });
for (let resultat of this._resultats) {
for (let positionResultat in resultat) {
let lettreResultat = resultat[positionResultat];
if (lettreResultat.statut === LettreStatut.BienPlace) lettrePrerempli[positionResultat] = { preRempli: true, lettre: lettreResultat.lettre };
if (lettreResultat.statut === LettreStatut.BienPlace)
lettrePrerempli[positionResultat] = {
preRempli: true,
lettre: lettreResultat.lettre,
};
}
}
if (lettrePrerempli.every((lettre) => lettre.preRempli)) {
return { preRempli: true, mot: lettrePrerempli.reduce((mot, lettre) => mot + lettre.lettre, "") };
return {
preRempli: true,
mot: lettrePrerempli.reduce((mot, lettre) => mot + lettre.lettre, ""),
};
}
return { preRempli: false };
@ -236,7 +261,11 @@ export default class Input {
private saisirLettre(lettre: string): void {
if (this.estBloque()) return;
if (this._motSaisi.length >= this._longueurMot) return;
if (this._motSaisi.length === 0 && lettre.toUpperCase() !== this._premiereLettre) this._motSaisi += this._premiereLettre;
if (
this._motSaisi.length === 0 &&
lettre.toUpperCase() !== this._premiereLettre
)
this._motSaisi += this._premiereLettre;
this._motSaisi += lettre;
this._gestionnaire.actualiserAffichage(this._motSaisi);
}
@ -246,7 +275,8 @@ export default class Input {
}
public debloquer(contexte: ContexteBloquage): void {
if (this._estBloque.includes(contexte)) this._estBloque.splice(this._estBloque.indexOf(contexte), 1);
if (this._estBloque.includes(contexte))
this._estBloque.splice(this._estBloque.indexOf(contexte), 1);
}
private estBloque(): boolean {
@ -268,7 +298,8 @@ export default class Input {
let statutLettres: { [lettre: string]: LettreStatut } = {};
// console.log(statutLettres);
for (let resultat of resultats) {
if (!statutLettres[resultat.lettre]) statutLettres[resultat.lettre] = resultat.statut;
if (!statutLettres[resultat.lettre])
statutLettres[resultat.lettre] = resultat.statut;
else {
switch (resultat.statut) {
case LettreStatut.BienPlace:
@ -300,12 +331,17 @@ export default class Input {
touche.className = "";
touche.classList.add("input-lettre");
touche.classList.add("lettre-bien-place");
touche.setAttribute(
"aria-label",
`Lettre ${lettre}, bien placée`
);
break;
case LettreStatut.MalPlace:
if (touche.classList.contains("lettre-bien-place")) break;
touche.className = "";
touche.classList.add("input-lettre");
touche.classList.add("lettre-mal-place");
touche.setAttribute("aria-label", `Lettre ${lettre}, mal placée`);
break;
default:
if (touche.classList.contains("lettre-bien-place")) break;
@ -313,6 +349,10 @@ export default class Input {
touche.className = "";
touche.classList.add("input-lettre");
touche.classList.add("lettre-non-trouve");
touche.setAttribute(
"aria-label",
`Lettre ${lettre}, non présente`
);
break;
}
}