[REF] event screen: no frame names, list summaries trimmed to use
The event list shows only the retained plan's redundancy gap and the id of the best proposal, yet its summaries still carried cumulative collisions and redundancy totals. They now carry what the list reads. The mode frame is gone from the screen, so its names go too: the mode surface component, the mode colour tokens and the bar's mode label are named for what they are. Values, pixels and captures are unchanged. Checked: node 4039, navigateur 884 with the walkthrough, node-long 105. --- FR --- [REF] écran d'événement : sans noms de cadre, résumés de liste réduits La liste des événements ne montre que l'écart de redondance du retenu et l'identifiant de la meilleure proposition, mais ses résumés portaient encore les collisions cumulées et les totaux de redondance. Ils portent désormais ce que la liste lit. Le cadre de mode a quitté l'écran, ses noms aussi : le composant de surface, les jetons de couleur du mode et le libellé de mode de la barre portent le nom de ce qu'ils sont. Valeurs, pixels et captures inchangés. Vérifié : node 4039, navigateur 884 avec le parcours, node-long 105. Assisted-by: Claude Opus 5.5
This commit is contained in:
parent
824f9214f6
commit
91c844725b
25 changed files with 127 additions and 141 deletions
|
|
@ -21,13 +21,14 @@
|
||||||
// rencontres répétées imposées dépendent du plan, et chaque ligne les lit
|
// rencontres répétées imposées dépendent du plan, et chaque ligne les lit
|
||||||
// dans ses mesures, à part des choisies.
|
// dans ses mesures, à part des choisies.
|
||||||
//
|
//
|
||||||
// resumeDuRetenu donne à la liste des événements deux nombres du retenu,
|
// resumeDuRetenu donne à la liste des événements la différence à la cible
|
||||||
// lus dans la même mesure que sa ligne du tableau, sans le diagnostic ni
|
// du retenu, lue dans la même mesure que sa ligne du tableau, sans le
|
||||||
// les plafonds : la liste en résume chaque événement du dossier.
|
// diagnostic ni les plafonds : la liste en résume chaque événement du
|
||||||
// premiereDuClassement est la seule définition de la proposition au rang 1
|
// dossier. premiereDuClassement est la seule définition de la proposition
|
||||||
// : la section de la génération la lit dans sa table, resumeDuMeilleur la
|
// au rang 1 : la section de la génération la lit dans sa table,
|
||||||
// donne à la liste, sur la même table d'évaluation, diagnostic compris — le
|
// resumeDuMeilleur en donne l'identifiant à la liste, sur la même table
|
||||||
// premier critère du classement lit le plafond a priori.
|
// d'évaluation, diagnostic compris — le premier critère du classement lit
|
||||||
|
// le plafond a priori.
|
||||||
import { classer } from '../moteur/classement.js';
|
import { classer } from '../moteur/classement.js';
|
||||||
import { indexerPlan, normaliser } from '../moteur/configuration.js';
|
import { indexerPlan, normaliser } from '../moteur/configuration.js';
|
||||||
import { diagnostiquer } from '../moteur/diagnostic.js';
|
import { diagnostiquer } from '../moteur/diagnostic.js';
|
||||||
|
|
@ -162,16 +163,15 @@ export function evaluer(charge, { plafondsAPriori = 'calcul' } = {}) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Le résumé du retenu que montre la liste des événements (§ 5.4, § 8.1,
|
* Le résumé du retenu que montre la liste des événements (§ 5.4, § 8.1,
|
||||||
* § 8.9) : ses collisions cumulées et sa somme de redondance Σ r(p), celles
|
* § 8.9) : diffRedondance, la valeur absolue de la cible de l'événement
|
||||||
* de mesurer, que la ligne du retenu d'evaluer porte aussi ; la cible de
|
* (cibleRedondance) moins la somme de redondance Σ r(p) du retenu, celle de
|
||||||
* l'événement (cibleRedondance) ; et diffRedondance, la valeur absolue de la
|
* mesurer, que la ligne du retenu d'evaluer porte aussi. null sans retenu,
|
||||||
* cible moins Σ r(p). null sans retenu, pour un retenu fautif ou en dérive,
|
* pour un retenu fautif ou en dérive, et quand la configuration ne se
|
||||||
* et quand la configuration ne se normalise pas : rien ne s'y mesure, et
|
* normalise pas : rien ne s'y mesure, et la liste écrit « — ». Ne modifie
|
||||||
* la liste écrit « — ». Ne modifie pas la charge.
|
* pas la charge.
|
||||||
*
|
*
|
||||||
* @param {import('../stockage/types.js').Charge} charge
|
* @param {import('../stockage/types.js').Charge} charge
|
||||||
* @returns {{collisionsCumulees: number, totalRedondance: number,
|
* @returns {{diffRedondance: number}|null}
|
||||||
* cibleRedondance: number, diffRedondance: number}|null}
|
|
||||||
*/
|
*/
|
||||||
export function resumeDuRetenu(charge) {
|
export function resumeDuRetenu(charge) {
|
||||||
const { retenu } = charge;
|
const { retenu } = charge;
|
||||||
|
|
@ -183,9 +183,8 @@ export function resumeDuRetenu(charge) {
|
||||||
if (erreur instanceof ErreurConfiguration) return null;
|
if (erreur instanceof ErreurConfiguration) return null;
|
||||||
throw erreur;
|
throw erreur;
|
||||||
}
|
}
|
||||||
const { collisionsCumulees, totalRedondance } = mesurer(instance, indexerPlan(instance, planDepuisFichier(retenu)));
|
const { totalRedondance } = mesurer(instance, indexerPlan(instance, planDepuisFichier(retenu)));
|
||||||
const cible = cibleRedondance(charge);
|
return { diffRedondance: Math.abs(cibleRedondance(charge) - totalRedondance) };
|
||||||
return { collisionsCumulees, totalRedondance, cibleRedondance: cible, diffRedondance: Math.abs(cible - totalRedondance) };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -204,15 +203,14 @@ export function premiereDuClassement(table) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* La meilleure proposition du classement que montre la liste des
|
* La meilleure proposition du classement que montre la liste des
|
||||||
* événements (§ 5.4, § 5.7, § 8.1) : l'identifiant de la proposition au
|
* événements (§ 5.4, § 5.7, § 8.1) : id, l'identifiant de la proposition au
|
||||||
* rang 1 (premiereDuClassement) et ses collisions cumulées, celles de sa
|
* rang 1 (premiereDuClassement). null sans proposition, quand aucune ne se
|
||||||
* ligne d'evaluer. null sans proposition, quand aucune ne se compare —
|
* compare — toutes fautives ou en dérive —, et quand la configuration ne se
|
||||||
* toutes fautives ou en dérive —, et quand la configuration ne se normalise
|
* normalise pas : la liste écrit alors « — ». Le retenu n'y entre pas. Ne
|
||||||
* pas : la liste écrit alors « — ». Le retenu n'y entre pas. Ne modifie pas
|
* modifie pas la charge.
|
||||||
* la charge.
|
|
||||||
*
|
*
|
||||||
* @param {import('../stockage/types.js').Charge} charge
|
* @param {import('../stockage/types.js').Charge} charge
|
||||||
* @returns {{id: number, collisionsCumulees: number}|null}
|
* @returns {{id: number}|null}
|
||||||
*/
|
*/
|
||||||
export function resumeDuMeilleur(charge) {
|
export function resumeDuMeilleur(charge) {
|
||||||
if (charge.propositions.length === 0) return null;
|
if (charge.propositions.length === 0) return null;
|
||||||
|
|
@ -224,5 +222,5 @@ export function resumeDuMeilleur(charge) {
|
||||||
throw erreur;
|
throw erreur;
|
||||||
}
|
}
|
||||||
const premiere = premiereDuClassement(table);
|
const premiere = premiereDuClassement(table);
|
||||||
return premiere === null ? null : { id: premiere.id, collisionsCumulees: premiere.mesures.collisionsCumulees };
|
return premiere === null ? null : { id: premiere.id };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -441,41 +441,33 @@ describe("évaluation : une configuration qui ne se tient pas", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('resumeDuRetenu : les mesures du retenu que lit la liste des événements (§ 5.4, § 8.1, § 8.9)', () => {
|
describe('resumeDuRetenu : la différence à la cible que lit la liste des événements (§ 5.4, § 8.1, § 8.9)', () => {
|
||||||
// La petite démonstration, trois propositions générées, la deuxième retenue.
|
// La petite démonstration, trois propositions générées, la deuxième retenue.
|
||||||
function retenue() {
|
function retenue() {
|
||||||
const generees = generee(chargeDemo('petite-conflit'), { graine: 3, nombre: 3, arret: 300 });
|
const generees = generee(chargeDemo('petite-conflit'), { graine: 3, nombre: 3, arret: 300 });
|
||||||
return executer(generees, 'retenirProposition', { id: generees.propositions[1].id });
|
return executer(generees, 'retenirProposition', { id: generees.propositions[1].id });
|
||||||
}
|
}
|
||||||
|
|
||||||
test("les collisions cumulées et Σ r(p) du retenu, celles de la ligne du retenu d'evaluer, et la cible, 1000 par défaut", () => {
|
test("la seule différence à la cible, 1000 par défaut, contre le Σ r(p) de la ligne du retenu d'evaluer", () => {
|
||||||
const charge = figer(retenue());
|
const charge = figer(retenue());
|
||||||
const resume = resumeDuRetenu(charge);
|
const resume = resumeDuRetenu(charge);
|
||||||
const { mesures } = evaluer(charge).retenu;
|
const { mesures } = evaluer(charge).retenu;
|
||||||
assert.ok(mesures.collisionsCumulees > 0, 'la petite démonstration en conflit compte des collisions');
|
assert.ok(mesures.totalRedondance !== 1000, 'la différence se distingue de zéro');
|
||||||
assert.deepEqual(resume, {
|
assert.deepEqual(resume, { diffRedondance: Math.abs(1000 - mesures.totalRedondance) });
|
||||||
collisionsCumulees: mesures.collisionsCumulees,
|
|
||||||
totalRedondance: mesures.totalRedondance,
|
|
||||||
cibleRedondance: 1000,
|
|
||||||
diffRedondance: Math.abs(1000 - mesures.totalRedondance),
|
|
||||||
});
|
|
||||||
const instance = normaliser(configurationDepuisCharge(charge));
|
const instance = normaliser(configurationDepuisCharge(charge));
|
||||||
const attendues = mesurer(instance, indexerPlan(instance, planDepuisFichier(charge.retenu)));
|
const attendues = mesurer(instance, indexerPlan(instance, planDepuisFichier(charge.retenu)));
|
||||||
assert.equal(resume.totalRedondance, attendues.totalRedondance);
|
assert.equal(attendues.totalRedondance, mesures.totalRedondance);
|
||||||
assert.equal(resume.collisionsCumulees, attendues.collisionsCumulees);
|
|
||||||
assert.equal(CIBLE_REDONDANCE_PAR_DEFAUT, 1000);
|
assert.equal(CIBLE_REDONDANCE_PAR_DEFAUT, 1000);
|
||||||
assert.equal(cibleRedondance(charge), 1000);
|
assert.equal(cibleRedondance(charge), 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("une cible propre à l'événement : la différence se lit contre elle, en valeur absolue, des deux côtés", () => {
|
test("une cible propre à l'événement : la différence se lit contre elle, en valeur absolue, des deux côtés", () => {
|
||||||
const charge = retenue();
|
const charge = retenue();
|
||||||
const total = resumeDuRetenu(charge).totalRedondance;
|
const total = evaluer(charge).retenu.mesures.totalRedondance;
|
||||||
for (const cible of [0, total, total + 7, 5_000]) {
|
for (const cible of [0, total, total + 7, 5_000]) {
|
||||||
const avecCible = executer(charge, 'changerCibleRedondance', { cible: String(cible) });
|
const avecCible = executer(charge, 'changerCibleRedondance', { cible: String(cible) });
|
||||||
assert.equal(cibleRedondance(avecCible), cible);
|
assert.equal(cibleRedondance(avecCible), cible);
|
||||||
const resume = resumeDuRetenu(avecCible);
|
assert.deepEqual(resumeDuRetenu(avecCible), { diffRedondance: Math.abs(cible - total) }, String(cible));
|
||||||
assert.equal(resume.cibleRedondance, cible);
|
|
||||||
assert.equal(resume.diffRedondance, Math.abs(cible - total), String(cible));
|
|
||||||
}
|
}
|
||||||
const dessous = executer(charge, 'changerCibleRedondance', { cible: '0' });
|
const dessous = executer(charge, 'changerCibleRedondance', { cible: '0' });
|
||||||
assert.equal(resumeDuRetenu(dessous).diffRedondance, total);
|
assert.equal(resumeDuRetenu(dessous).diffRedondance, total);
|
||||||
|
|
@ -507,7 +499,7 @@ describe('resumeDuRetenu : les mesures du retenu que lit la liste des événemen
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('resumeDuMeilleur : la proposition au rang 1 que lit la liste des événements (§ 5.4, § 5.7, § 8.1)', () => {
|
describe('resumeDuMeilleur : la proposition au rang 1 que lit la liste des événements (§ 5.4, § 5.7, § 8.1)', () => {
|
||||||
test("le rang 1 du classement, ni le plus petit identifiant ni le moins de collisions : son identifiant et ses collisions cumulées", () => {
|
test('le rang 1 du classement, ni le plus petit identifiant ni le moins de collisions : son seul identifiant', () => {
|
||||||
// Le classement range les plans écrits à la main 3, 2, 1, 4 : la 3 vient
|
// Le classement range les plans écrits à la main 3, 2, 1, 4 : la 3 vient
|
||||||
// en tête avec 6 collisions cumulées, quand la 1 n'en porte que 4.
|
// en tête avec 6 collisions cumulées, quand la 1 n'en porte que 4.
|
||||||
const charge = structuredClone(chargeDemo('petite-conflit'));
|
const charge = structuredClone(chargeDemo('petite-conflit'));
|
||||||
|
|
@ -516,9 +508,10 @@ describe('resumeDuMeilleur : la proposition au rang 1 que lit la liste des évé
|
||||||
figer(charge);
|
figer(charge);
|
||||||
const table = evaluer(charge);
|
const table = evaluer(charge);
|
||||||
assert.deepEqual(table.classement.ordre, [3, 2, 1, 4]);
|
assert.deepEqual(table.classement.ordre, [3, 2, 1, 4]);
|
||||||
assert.deepEqual(resumeDuMeilleur(charge), { id: 3, collisionsCumulees: 6 });
|
assert.deepEqual(resumeDuMeilleur(charge), { id: 3 });
|
||||||
assert.equal(premiereDuClassement(table), table.propositions[0]);
|
assert.equal(premiereDuClassement(table), table.propositions[0]);
|
||||||
assert.equal(premiereDuClassement(table).mesures.collisionsCumulees, 6);
|
assert.equal(premiereDuClassement(table).mesures.collisionsCumulees, 6);
|
||||||
|
assert.equal(table.propositions.find(({ id }) => id === 1).mesures.collisionsCumulees, 4);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("après des générations : la première ligne d'evaluer, comparable, et le retenu n'y change rien", () => {
|
test("après des générations : la première ligne d'evaluer, comparable, et le retenu n'y change rien", () => {
|
||||||
|
|
@ -526,7 +519,7 @@ describe('resumeDuMeilleur : la proposition au rang 1 que lit la liste des évé
|
||||||
charge = generee(charge, { graine: 9, nombre: 2, arret: 300 });
|
charge = generee(charge, { graine: 9, nombre: 2, arret: 300 });
|
||||||
const [premiere] = evaluer(charge).propositions;
|
const [premiere] = evaluer(charge).propositions;
|
||||||
assert.equal(premiere.statut, 'comparable');
|
assert.equal(premiere.statut, 'comparable');
|
||||||
const attendu = { id: premiere.id, collisionsCumulees: premiere.mesures.collisionsCumulees };
|
const attendu = { id: premiere.id };
|
||||||
assert.deepEqual(resumeDuMeilleur(figer(charge)), attendu);
|
assert.deepEqual(resumeDuMeilleur(figer(charge)), attendu);
|
||||||
const derniere = charge.propositions.at(-1).id;
|
const derniere = charge.propositions.at(-1).id;
|
||||||
const retenue = executer(charge, 'retenirProposition', { id: derniere });
|
const retenue = executer(charge, 'retenirProposition', { id: derniere });
|
||||||
|
|
|
||||||
|
|
@ -147,9 +147,9 @@ const AUCUN_RESUME = Object.freeze({ mesuresDuRetenu: null, meilleureDuClassemen
|
||||||
// rattrape en mémoire, par la règle de rattraper, et examiner (§ 8.9, point
|
// rattrape en mémoire, par la règle de rattraper, et examiner (§ 8.9, point
|
||||||
// 3) en écarte une proposition fautive, dont l'identifiant se répète ou
|
// 3) en écarte une proposition fautive, dont l'identifiant se répète ou
|
||||||
// atteint le compteur — le classement lève sur un identifiant répété. La
|
// atteint le compteur — le classement lève sur un identifiant répété. La
|
||||||
// liste nomme ainsi la proposition au rang 1, et son nombre, que le bloc de
|
// liste nomme ainsi la proposition au rang 1 que le bloc de génération de
|
||||||
// génération de l'événement ouvert nomme (§ 8.1). null pour un état absent
|
// l'événement ouvert nomme (§ 8.1). null pour un état absent ou qui ne
|
||||||
// ou qui ne s'ouvre pas.
|
// s'ouvre pas.
|
||||||
async function chargeExaminee(fs, racine, base) {
|
async function chargeExaminee(fs, racine, base) {
|
||||||
try {
|
try {
|
||||||
return (await ouvrirDepot(fs, racine, base)).charge;
|
return (await ouvrirDepot(fs, racine, base)).charge;
|
||||||
|
|
|
||||||
|
|
@ -639,7 +639,7 @@ describe('lister (§ 8.1, § 19.4)', () => {
|
||||||
return serialiser(modifier(charge), { revision: 3, produitVersion: V1 });
|
return serialiser(modifier(charge), { revision: 3, produitVersion: V1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
test('les mesures du retenu : collisions cumulées, Σ r(p), la cible et la différence, celles de resumeDuRetenu ; null sans retenu ; rien d’écrit', async () => {
|
test('les mesures du retenu : la seule différence à la cible, celle de resumeDuRetenu ; null sans retenu ; rien d’écrit', async () => {
|
||||||
const { fs, facade } = await deuxEvenements();
|
const { fs, facade } = await deuxEvenements();
|
||||||
fs.deposer('portable', `retenue${SUFFIXES.etat}`, texteRetenu());
|
fs.deposer('portable', `retenue${SUFFIXES.etat}`, texteRetenu());
|
||||||
const avant = ecritures(fs);
|
const avant = ecritures(fs);
|
||||||
|
|
@ -648,12 +648,7 @@ describe('lister (§ 8.1, § 19.4)', () => {
|
||||||
const par = Object.fromEntries(lignes.map((ligne) => [ligne.base, ligne]));
|
const par = Object.fromEntries(lignes.map((ligne) => [ligne.base, ligne]));
|
||||||
const charge = analyser(texteRetenu()).charge;
|
const charge = analyser(texteRetenu()).charge;
|
||||||
const { mesures } = evaluer(charge).retenu;
|
const { mesures } = evaluer(charge).retenu;
|
||||||
assert.deepEqual(par.retenue.mesuresDuRetenu, {
|
assert.deepEqual(par.retenue.mesuresDuRetenu, { diffRedondance: Math.abs(1000 - mesures.totalRedondance) });
|
||||||
collisionsCumulees: mesures.collisionsCumulees,
|
|
||||||
totalRedondance: mesures.totalRedondance,
|
|
||||||
cibleRedondance: 1000,
|
|
||||||
diffRedondance: Math.abs(1000 - mesures.totalRedondance),
|
|
||||||
});
|
|
||||||
assert.deepEqual(par.retenue.mesuresDuRetenu, resumeDuRetenu(charge));
|
assert.deepEqual(par.retenue.mesuresDuRetenu, resumeDuRetenu(charge));
|
||||||
assert.equal(par['soiree-a'].mesuresDuRetenu, null);
|
assert.equal(par['soiree-a'].mesuresDuRetenu, null);
|
||||||
assert.equal(par.petite.mesuresDuRetenu, null);
|
assert.equal(par.petite.mesuresDuRetenu, null);
|
||||||
|
|
@ -665,8 +660,8 @@ describe('lister (§ 8.1, § 19.4)', () => {
|
||||||
fs.deposer('portable', `retenue${SUFFIXES.etat}`, texte);
|
fs.deposer('portable', `retenue${SUFFIXES.etat}`, texte);
|
||||||
const ligne = (await listerResume(facade)).find(({ base }) => base === 'retenue');
|
const ligne = (await listerResume(facade)).find(({ base }) => base === 'retenue');
|
||||||
const { totalRedondance } = evaluer(analyser(texte).charge).retenu.mesures;
|
const { totalRedondance } = evaluer(analyser(texte).charge).retenu.mesures;
|
||||||
assert.equal(ligne.mesuresDuRetenu.cibleRedondance, 25);
|
assert.notEqual(Math.abs(25 - totalRedondance), Math.abs(1000 - totalRedondance));
|
||||||
assert.equal(ligne.mesuresDuRetenu.diffRedondance, Math.abs(25 - totalRedondance));
|
assert.deepEqual(ligne.mesuresDuRetenu, { diffRedondance: Math.abs(25 - totalRedondance) });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('un retenu fautif, ou en dérive, et un état illisible : null, la liste entière rendue, rien d’écrit', async () => {
|
test('un retenu fautif, ou en dérive, et un état illisible : null, la liste entière rendue, rien d’écrit', async () => {
|
||||||
|
|
@ -716,7 +711,7 @@ describe('lister (§ 8.1, § 19.4)', () => {
|
||||||
const charge = analyser(texte).charge;
|
const charge = analyser(texte).charge;
|
||||||
const [premiere] = evaluer(charge).propositions;
|
const [premiere] = evaluer(charge).propositions;
|
||||||
assert.equal(premiere.statut, 'comparable', base);
|
assert.equal(premiere.statut, 'comparable', base);
|
||||||
assert.deepEqual(par[base].meilleureDuClassement, { id: premiere.id, collisionsCumulees: premiere.mesures.collisionsCumulees }, base);
|
assert.deepEqual(par[base].meilleureDuClassement, { id: premiere.id }, base);
|
||||||
assert.deepEqual(par[base].meilleureDuClassement, resumeDuMeilleur(charge), base);
|
assert.deepEqual(par[base].meilleureDuClassement, resumeDuMeilleur(charge), base);
|
||||||
}
|
}
|
||||||
assert.equal(par.proposee.mesuresDuRetenu, null);
|
assert.equal(par.proposee.mesuresDuRetenu, null);
|
||||||
|
|
@ -724,7 +719,7 @@ describe('lister (§ 8.1, § 19.4)', () => {
|
||||||
assert.equal(par.petite.meilleureDuClassement, null);
|
assert.equal(par.petite.meilleureDuClassement, null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("un journal en avance d'une entrée : la ligne porte la proposition et le nombre que montre le bloc après ouverture, sans rien écrire", async () => {
|
test("un journal en avance d'une entrée : la ligne porte la proposition que montre le bloc après ouverture, sans rien écrire", async () => {
|
||||||
const montage = await deuxEvenements();
|
const montage = await deuxEvenements();
|
||||||
const { fs, facade } = montage;
|
const { fs, facade } = montage;
|
||||||
// L'état d'une soirée sans proposition ; le journal porte en plus la
|
// L'état d'une soirée sans proposition ; le journal porte en plus la
|
||||||
|
|
@ -905,7 +900,9 @@ describe('lister (§ 8.1, § 19.4)', () => {
|
||||||
fs.deposer('portable', `retenue${SUFFIXES.etat}`, plusTard);
|
fs.deposer('portable', `retenue${SUFFIXES.etat}`, plusTard);
|
||||||
for (let pas = 0; pas < lignes.length; pas += 1) await unPas(horloge);
|
for (let pas = 0; pas < lignes.length; pas += 1) await unPas(horloge);
|
||||||
await flux.fin;
|
await flux.fin;
|
||||||
assert.equal(recus.get('retenue').mesuresDuRetenu.cibleRedondance, 25);
|
const { totalRedondance } = evaluer(analyser(plusTard).charge).retenu.mesures;
|
||||||
|
assert.notEqual(Math.abs(25 - totalRedondance), Math.abs(1000 - totalRedondance));
|
||||||
|
assert.equal(recus.get('retenue').mesuresDuRetenu.diffRedondance, Math.abs(25 - totalRedondance));
|
||||||
assert.deepEqual(recus.get('retenue'), resumesAttendus(plusTard));
|
assert.deepEqual(recus.get('retenue'), resumesAttendus(plusTard));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,8 @@ export function signalementsDe(ligne) {
|
||||||
*
|
*
|
||||||
* @param {Object} ligne LigneListe (evenements.js)
|
* @param {Object} ligne LigneListe (evenements.js)
|
||||||
* @param {ReturnType<import('../../application/format.js').creerFormat>} format
|
* @param {ReturnType<import('../../application/format.js').creerFormat>} format
|
||||||
* @param {{mesuresDuRetenu: Object|null, meilleureDuClassement: Object|null}} [resume]
|
* @param {{mesuresDuRetenu: {diffRedondance: number}|null,
|
||||||
|
* meilleureDuClassement: {id: number}|null}} [resume]
|
||||||
* @returns {{nom: string, date: string, etat: string, participants: string,
|
* @returns {{nom: string, date: string, etat: string, participants: string,
|
||||||
* modification: string, chemin: string, enAttente: boolean,
|
* modification: string, chemin: string, enAttente: boolean,
|
||||||
* diffRedondance: string, meilleure: {id: string},
|
* diffRedondance: string, meilleure: {id: string},
|
||||||
|
|
|
||||||
|
|
@ -335,15 +335,11 @@ describe('saisieDe : la saisie d’un nom pour copier ou renommer (§ 8.7)', ()
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('ligneAffichee : les mesures du retenu (§ 5.4, § 8.1, § 8.9)', () => {
|
describe('ligneAffichee : les mesures du retenu (§ 5.4, § 8.1, § 8.9)', () => {
|
||||||
test('la différence à la cible, celle de la façade, mise en forme, sans calcul ici ; les collisions cumulées du retenu ne se montrent pas', () => {
|
test('la différence à la cible, celle de la façade, mise en forme, sans calcul ici', () => {
|
||||||
const mesuresDuRetenu = { collisionsCumulees: 8765, totalRedondance: 1500, cibleRedondance: 1000, diffRedondance: 500 };
|
for (const diffRedondance of [500, 7, 0]) {
|
||||||
const affichee = ligneAffichee(ligne(), format, { ...AUCUN, mesuresDuRetenu });
|
const affichee = ligneAffichee(ligne(), format, { ...AUCUN, mesuresDuRetenu: { diffRedondance } });
|
||||||
assert.equal(affichee.diffRedondance, format.nombre(500));
|
assert.equal(affichee.diffRedondance, format.nombre(diffRedondance), String(diffRedondance));
|
||||||
assert.ok(!Object.values(affichee).includes(format.nombre(8765)));
|
}
|
||||||
// La différence se lit telle que la façade la rend, jamais refaite
|
|
||||||
// depuis la cible et la somme.
|
|
||||||
const telleQuelle = ligneAffichee(ligne(), format, { ...AUCUN, mesuresDuRetenu: { ...mesuresDuRetenu, diffRedondance: 7 } });
|
|
||||||
assert.equal(telleQuelle.diffRedondance, format.nombre(7));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('sans retenu mesurable, et pour une ligne illisible, la différence vaut « — »', () => {
|
test('sans retenu mesurable, et pour une ligne illisible, la différence vaut « — »', () => {
|
||||||
|
|
@ -378,8 +374,8 @@ describe('ligneAffichee : les résumés en attente (§ 8.1)', () => {
|
||||||
assert.deepEqual(attente.meilleure, { id: VIDE });
|
assert.deepEqual(attente.meilleure, { id: VIDE });
|
||||||
assert.equal(ligneAffichee(ligne(), format, AUCUN).enAttente, false);
|
assert.equal(ligneAffichee(ligne(), format, AUCUN).enAttente, false);
|
||||||
const recu = ligneAffichee(ligne(), format, {
|
const recu = ligneAffichee(ligne(), format, {
|
||||||
mesuresDuRetenu: { collisionsCumulees: 12, totalRedondance: 990, cibleRedondance: 1000, diffRedondance: 10 },
|
mesuresDuRetenu: { diffRedondance: 10 },
|
||||||
meilleureDuClassement: { id: 3, collisionsCumulees: 9 },
|
meilleureDuClassement: { id: 3 },
|
||||||
});
|
});
|
||||||
assert.equal(recu.enAttente, false);
|
assert.equal(recu.enAttente, false);
|
||||||
assert.equal(recu.diffRedondance, format.nombre(10));
|
assert.equal(recu.diffRedondance, format.nombre(10));
|
||||||
|
|
@ -401,8 +397,8 @@ describe('ligneAffichee : la meilleure proposition du classement (§ 5.4, § 5.7
|
||||||
return executer(charge, 'enregistrerGeneration', { propositions, configuration, produitVersion: VERSION.affichee });
|
return executer(charge, 'enregistrerGeneration', { propositions, configuration, produitVersion: VERSION.affichee });
|
||||||
}
|
}
|
||||||
|
|
||||||
test("l'identifiant que rend la façade, mis en forme, sans calcul ici ; ses collisions cumulées ne se montrent pas", () => {
|
test("l'identifiant que rend la façade, mis en forme, sans calcul ici", () => {
|
||||||
const affichee = ligneAffichee(ligne(), format, { ...AUCUN, meilleureDuClassement: { id: 1234, collisionsCumulees: 5678 } });
|
const affichee = ligneAffichee(ligne(), format, { ...AUCUN, meilleureDuClassement: { id: 1234 } });
|
||||||
assert.deepEqual(affichee.meilleure, { id: format.nombre(1234) });
|
assert.deepEqual(affichee.meilleure, { id: format.nombre(1234) });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
// écartées, placements en dérive — vient dessous, sur toute la largeur du
|
// écartées, placements en dérive — vient dessous, sur toute la largeur du
|
||||||
// message : l'action n'étroitise que la première phrase. La zone des
|
// message : l'action n'étroitise que la première phrase. La zone des
|
||||||
// annonces qui les porte prend la hauteur d'un avertissement ordinaire,
|
// annonces qui les porte prend la hauteur d'un avertissement ordinaire,
|
||||||
// action comprise, et défile au-delà (CadreMode.svelte).
|
// action comprise, et défile au-delà (SurfaceEvenement.svelte).
|
||||||
import { getContext } from 'svelte';
|
import { getContext } from 'svelte';
|
||||||
import Commande from '../primitives/Commande.svelte';
|
import Commande from '../primitives/Commande.svelte';
|
||||||
import Icone from '../primitives/Icone.svelte';
|
import Icone from '../primitives/Icone.svelte';
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@
|
||||||
// libellés, elle porte seule le mode : aucun trait n'entoure la surface de
|
// libellés, elle porte seule le mode : aucun trait n'entoure la surface de
|
||||||
// travail.
|
// travail.
|
||||||
//
|
//
|
||||||
// Son fond et son filet sont ceux du mode, son icône de la teinte du mode
|
// Son fond et son filet sont ceux du mode (--couleur-mode-…-fond et
|
||||||
// (--couleur-cadre-…), son texte de l'encre de la page (marques.js :
|
// -filet), son icône de la teinte du mode (--couleur-mode-lecture,
|
||||||
|
// -ecriture, -bloque), son texte de l'encre de la page (marques.js :
|
||||||
// bandeMode et les signes bandeLecture, bandeEcriture, bandeBloque).
|
// bandeMode et les signes bandeLecture, bandeEcriture, bandeBloque).
|
||||||
// Région d'état, elle annonce le mode quand il change.
|
// Région d'état, elle annonce le mode quand il change.
|
||||||
//
|
//
|
||||||
|
|
@ -68,14 +69,14 @@
|
||||||
|
|
||||||
.signe {
|
.signe {
|
||||||
display: flex;
|
display: flex;
|
||||||
color: var(--couleur-cadre-lecture);
|
color: var(--couleur-mode-lecture);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ecriture .signe {
|
.ecriture .signe {
|
||||||
color: var(--couleur-cadre-ecriture);
|
color: var(--couleur-mode-ecriture);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bloque .signe {
|
.bloque .signe {
|
||||||
color: var(--couleur-cadre-bloque);
|
color: var(--couleur-mode-bloque);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@
|
||||||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -->
|
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// L'en-tête de l'événement ouvert, en tête de la tête (CadreMode.svelte) :
|
// L'en-tête de l'événement ouvert, en tête de la tête
|
||||||
// son nom, puis, sur la même ligne tant qu'elle a la place, son résumé — la date
|
// (SurfaceEvenement.svelte) : son nom, puis, sur la même ligne tant qu'elle
|
||||||
// quand il en a une, les participants, les tables et leurs sièges, les
|
// a la place, son résumé — la date quand il en a une, les participants, les
|
||||||
// tours (resumeEvenement, modele.js) —, d'encre secondaire. Le nom se
|
// tables et leurs sièges, les tours (resumeEvenement, modele.js) —, d'encre
|
||||||
// coupe où il le faut, même sans espace : un nom long de glyphes larges
|
// secondaire. Le nom se coupe où il le faut, même sans espace : un nom
|
||||||
// passe à la ligne au lieu d'élargir la page. Le résumé passe à la ligne
|
// long de glyphes larges passe à la ligne au lieu d'élargir la page. Le
|
||||||
// entre ses éléments, jamais dans l'un d'eux.
|
// résumé passe à la ligne entre ses éléments, jamais dans l'un d'eux.
|
||||||
import { getContext } from 'svelte';
|
import { getContext } from 'svelte';
|
||||||
import { resumeEvenement } from './modele.js';
|
import { resumeEvenement } from './modele.js';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ afterEach(() => {
|
||||||
const dans = (m, selecteur) => m.racine.querySelector(selecteur);
|
const dans = (m, selecteur) => m.racine.querySelector(selecteur);
|
||||||
const tous = (m, selecteur) => [...m.racine.querySelectorAll(selecteur)];
|
const tous = (m, selecteur) => [...m.racine.querySelectorAll(selecteur)];
|
||||||
const ecran = (m) => dans(m, '[data-ecran="evenement"]');
|
const ecran = (m) => dans(m, '[data-ecran="evenement"]');
|
||||||
const cadre = (m) => dans(m, '[data-mode]');
|
const surface = (m) => dans(m, '[data-mode]');
|
||||||
const bande = (m) => ecran(m).querySelector(':scope > [role="status"]');
|
const bande = (m) => ecran(m).querySelector(':scope > [role="status"]');
|
||||||
const fixe = (m, nom) => dans(m, `[data-place-fixe] [data-commande="${nom}"]`);
|
const fixe = (m, nom) => dans(m, `[data-place-fixe] [data-commande="${nom}"]`);
|
||||||
const etats = (m) => dans(m, `[role="group"][aria-label="${t('evenement.etat.titre')}"]`);
|
const etats = (m) => dans(m, `[role="group"][aria-label="${t('evenement.etat.titre')}"]`);
|
||||||
|
|
@ -162,24 +162,24 @@ describe('la bande de mode et la pleine fenêtre (§ 8.4)', () => {
|
||||||
expect(Math.abs(b.top - boite(dans(m, '[data-bandeau]')).bottom), mode).toBeLessThanOrEqual(1);
|
expect(Math.abs(b.top - boite(dans(m, '[data-bandeau]')).bottom), mode).toBeLessThanOrEqual(1);
|
||||||
expect([b.left, b.right], mode).toEqual([0, innerWidth]);
|
expect([b.left, b.right], mode).toEqual([0, innerWidth]);
|
||||||
expect(document.documentElement.scrollWidth, mode).toBeLessThanOrEqual(innerWidth);
|
expect(document.documentElement.scrollWidth, mode).toBeLessThanOrEqual(innerWidth);
|
||||||
expect(b.bottom, mode).toBeLessThanOrEqual(boite(cadre(m)).top);
|
expect(b.bottom, mode).toBeLessThanOrEqual(boite(surface(m)).top);
|
||||||
// L'écran va d'un bord à l'autre de la fenêtre, au retrait de
|
// L'écran va d'un bord à l'autre de la fenêtre, au retrait de
|
||||||
// l'écran près, et la barre, la tête et la surface avec lui, sans
|
// l'écran près, et la barre, la tête et la surface avec lui, sans
|
||||||
// trait autour d'elles.
|
// trait autour d'elles.
|
||||||
const retrait = Number.parseFloat(style(ecran(m).parentElement).paddingLeft);
|
const retrait = Number.parseFloat(style(ecran(m).parentElement).paddingLeft);
|
||||||
expect(retrait, mode).toBeGreaterThan(0);
|
expect(retrait, mode).toBeGreaterThan(0);
|
||||||
expect(retrait, mode).toBeLessThanOrEqual(32);
|
expect(retrait, mode).toBeLessThanOrEqual(32);
|
||||||
for (const element of [ecran(m), cadre(m)]) {
|
for (const element of [ecran(m), surface(m)]) {
|
||||||
const e = boite(element);
|
const e = boite(element);
|
||||||
expect(e.left, mode).toBeCloseTo(retrait, 0);
|
expect(e.left, mode).toBeCloseTo(retrait, 0);
|
||||||
expect(e.right, mode).toBeCloseTo(innerWidth - retrait, 0);
|
expect(e.right, mode).toBeCloseTo(innerWidth - retrait, 0);
|
||||||
}
|
}
|
||||||
for (const cote of ['Top', 'Right', 'Bottom', 'Left']) {
|
for (const cote of ['Top', 'Right', 'Bottom', 'Left']) {
|
||||||
expect(Number.parseFloat(style(cadre(m))[`border${cote}Width`]), `${mode} ${cote}`).toBe(0);
|
expect(Number.parseFloat(style(surface(m))[`border${cote}Width`]), `${mode} ${cote}`).toBe(0);
|
||||||
}
|
}
|
||||||
expect(region.textContent, mode).toContain(t(cle));
|
expect(region.textContent, mode).toContain(t(cle));
|
||||||
expect(region.textContent, mode).toContain(t(explication));
|
expect(region.textContent, mode).toContain(t(explication));
|
||||||
expect(region.textContent, mode).toContain(dans(m, '[data-mode-libelle="cadre"]').textContent);
|
expect(region.textContent, mode).toContain(dans(m, '[data-mode-libelle="barre"]').textContent);
|
||||||
expect(visible(region), mode).toBe(true);
|
expect(visible(region), mode).toBe(true);
|
||||||
hauteurs.push(b.height);
|
hauteurs.push(b.height);
|
||||||
const icones = region.querySelectorAll('svg');
|
const icones = region.querySelectorAll('svg');
|
||||||
|
|
@ -190,7 +190,7 @@ describe('la bande de mode et la pleine fenêtre (§ 8.4)', () => {
|
||||||
const lieu = `${theme} ${mode}`;
|
const lieu = `${theme} ${mode}`;
|
||||||
expect(fond(region), lieu).toEqual(jeton(`--couleur-mode-${mode}-fond`));
|
expect(fond(region), lieu).toEqual(jeton(`--couleur-mode-${mode}-fond`));
|
||||||
expect(composantes(style(region).borderBottomColor), lieu).toEqual(jeton(`--couleur-mode-${mode}-filet`));
|
expect(composantes(style(region).borderBottomColor), lieu).toEqual(jeton(`--couleur-mode-${mode}-filet`));
|
||||||
expect(trait(icones[0]), lieu).toEqual(jeton(`--couleur-cadre-${mode}`));
|
expect(trait(icones[0]), lieu).toEqual(jeton(`--couleur-mode-${mode}`));
|
||||||
exigerSigneVisible(icones[0], lieu);
|
exigerSigneVisible(icones[0], lieu);
|
||||||
exigerTextesLisibles(region, lieu);
|
exigerTextesLisibles(region, lieu);
|
||||||
});
|
});
|
||||||
|
|
@ -235,7 +235,7 @@ describe('la carte d’en-tête', () => {
|
||||||
expect(imprimer.textContent).toBe(t('impression.commande.ouvrir'));
|
expect(imprimer.textContent).toBe(t('impression.commande.ouvrir'));
|
||||||
expect(entete.contains(imprimer)).toBe(false);
|
expect(entete.contains(imprimer)).toBe(false);
|
||||||
const place = boite(fixe(m, 'lecture'));
|
const place = boite(fixe(m, 'lecture'));
|
||||||
const [i, e, c] = [boite(imprimer), boite(etats(m)), boite(cadre(m))];
|
const [i, e, c] = [boite(imprimer), boite(etats(m)), boite(surface(m))];
|
||||||
expect(i.top).toBe(place.top);
|
expect(i.top).toBe(place.top);
|
||||||
expect(i.height).toBeGreaterThanOrEqual(44);
|
expect(i.height).toBeGreaterThanOrEqual(44);
|
||||||
expect(c.right - i.right).toBeLessThanOrEqual(24);
|
expect(c.right - i.right).toBeLessThanOrEqual(24);
|
||||||
|
|
@ -459,10 +459,10 @@ describe('les avertissements, en messages d’avis', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Le texte de l'avertissement et son action ne sont jamais rognés : ni
|
// Le texte de l'avertissement et son action ne sont jamais rognés : ni
|
||||||
// le texte, ni le message, ni aucune boîte qui les porte jusqu'au cadre
|
// le texte, ni le message, ni aucune boîte qui les porte jusqu'à la
|
||||||
// ne déborde de sa hauteur, et chacun tient dans la boîte visible de
|
// surface de l'événement (SurfaceEvenement.svelte) ne déborde de sa
|
||||||
// chaque ascendant qui coupe ce qui le dépasse, la zone des annonces la
|
// hauteur, et chacun tient dans la boîte visible de chaque ascendant qui
|
||||||
// première. Le manque d'une place, de quatre et de treize : le nombre et
|
// coupe ce qui le dépasse, la zone des annonces la première. Le manque d'une place, de quatre et de treize : le nombre et
|
||||||
// l'accord allongent la phrase.
|
// l'accord allongent la phrase.
|
||||||
for (const largeur of [1366, 1024]) {
|
for (const largeur of [1366, 1024]) {
|
||||||
for (const manque of [1, 4, 13]) {
|
for (const manque of [1, 4, 13]) {
|
||||||
|
|
@ -489,7 +489,7 @@ describe('les avertissements, en messages d’avis', () => {
|
||||||
const a = boite(action);
|
const a = boite(action);
|
||||||
expect(a.top, 'bouton sous le haut de la zone').toBeGreaterThanOrEqual(z.top + zone.clientTop - 0.5);
|
expect(a.top, 'bouton sous le haut de la zone').toBeGreaterThanOrEqual(z.top + zone.clientTop - 0.5);
|
||||||
expect(a.bottom, 'bouton au-dessus du bas visible de la zone').toBeLessThanOrEqual(z.top + zone.clientTop + zone.clientHeight + 0.5);
|
expect(a.bottom, 'bouton au-dessus du bas visible de la zone').toBeLessThanOrEqual(z.top + zone.clientTop + zone.clientHeight + 0.5);
|
||||||
const borne = cadre(m);
|
const borne = surface(m);
|
||||||
for (let element = texte; element !== borne.parentElement; element = element.parentElement) {
|
for (let element = texte; element !== borne.parentElement; element = element.parentElement) {
|
||||||
const nom = `${element.tagName.toLowerCase()}${element.hasAttribute('data-annonces') ? '[data-annonces]' : ''}`;
|
const nom = `${element.tagName.toLowerCase()}${element.hasAttribute('data-annonces') ? '[data-annonces]' : ''}`;
|
||||||
expect(element.scrollHeight, `${nom} : hauteur du contenu`).toBeLessThanOrEqual(element.clientHeight + 1);
|
expect(element.scrollHeight, `${nom} : hauteur du contenu`).toBeLessThanOrEqual(element.clientHeight + 1);
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,8 @@
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dans une barre étroite (CadreMode.svelte), l'intertitre s'efface : le
|
/* Dans une barre étroite (SurfaceEvenement.svelte), l'intertitre
|
||||||
groupe garde son nom, et les quatre étapes leur ligne. */
|
s'efface : le groupe garde son nom, et les quatre étapes leur ligne. */
|
||||||
@container barre (max-width: 80rem) {
|
@container barre (max-width: 80rem) {
|
||||||
.intertitre {
|
.intertitre {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ const bande = (m) => dans(m, '[data-ecran="evenement"] > [role="status"]');
|
||||||
const fixe = (m, nom) => dans(m, `[data-place-fixe] [data-commande="${nom}"]`);
|
const fixe = (m, nom) => dans(m, `[data-place-fixe] [data-commande="${nom}"]`);
|
||||||
const historique = (m, nom) => dans(m, `[data-mode] [data-historique] [data-commande="${nom}"]`);
|
const historique = (m, nom) => dans(m, `[data-mode] [data-historique] [data-commande="${nom}"]`);
|
||||||
const boutonEtat = (m, etat) => dans(m, `[data-etat="${etat}"] [data-commande="etat"]`);
|
const boutonEtat = (m, etat) => dans(m, `[data-etat="${etat}"] [data-commande="etat"]`);
|
||||||
const libelleCadre = (m) => dans(m, '[data-mode-libelle="cadre"]');
|
const libelleBarre = (m) => dans(m, '[data-mode-libelle="barre"]');
|
||||||
const libelleBandeau = (m) => dans(m, '[data-mode-libelle="bandeau"]');
|
const libelleBandeau = (m) => dans(m, '[data-mode-libelle="bandeau"]');
|
||||||
const avertissement = (m, code) => dans(m, `[data-avertissement="${code}"]`);
|
const avertissement = (m, code) => dans(m, `[data-avertissement="${code}"]`);
|
||||||
const ecran = (m) => dans(m, '[data-ecran]');
|
const ecran = (m) => dans(m, '[data-ecran]');
|
||||||
|
|
@ -347,7 +347,7 @@ describe('le mode sans cadre (§ 8.4, § 14.5)', () => {
|
||||||
for (const cote of ['Top', 'Right', 'Bottom', 'Left']) {
|
for (const cote of ['Top', 'Right', 'Bottom', 'Left']) {
|
||||||
expect(Number.parseFloat(style[`border${cote}Width`]), `${mode} ${cote}`).toBe(0);
|
expect(Number.parseFloat(style[`border${cote}Width`]), `${mode} ${cote}`).toBe(0);
|
||||||
}
|
}
|
||||||
const libelle = libelleCadre(m);
|
const libelle = libelleBarre(m);
|
||||||
expect(libelle.checkVisibility()).toBe(true);
|
expect(libelle.checkVisibility()).toBe(true);
|
||||||
expect(visible(libelle)).toBe(true);
|
expect(visible(libelle)).toBe(true);
|
||||||
expect(libelle.contains(auCentre(libelle))).toBe(true);
|
expect(libelle.contains(auCentre(libelle))).toBe(true);
|
||||||
|
|
@ -364,7 +364,7 @@ describe('le mode sans cadre (§ 8.4, § 14.5)', () => {
|
||||||
expect(releves).toEqual([t('coquille.mode.lecture'), t('coquille.mode.ecriture'), t('coquille.mode.bloque')]);
|
expect(releves).toEqual([t('coquille.mode.lecture'), t('coquille.mode.ecriture'), t('coquille.mode.bloque')]);
|
||||||
// Une surface plus haute que la fenêtre : la page et la surface
|
// Une surface plus haute que la fenêtre : la page et la surface
|
||||||
// défilées jusqu'en bas, le libellé garde sa boîte.
|
// défilées jusqu'en bas, le libellé garde sa boîte.
|
||||||
const avant = libelleCadre(m).getBoundingClientRect().toJSON();
|
const avant = libelleBarre(m).getBoundingClientRect().toJSON();
|
||||||
const haut = document.createElement('div');
|
const haut = document.createElement('div');
|
||||||
haut.style.height = '3000px';
|
haut.style.height = '3000px';
|
||||||
dans(m, '[data-section]').append(haut);
|
dans(m, '[data-section]').append(haut);
|
||||||
|
|
@ -372,8 +372,8 @@ describe('le mode sans cadre (§ 8.4, § 14.5)', () => {
|
||||||
for (let porteur = dans(m, '[data-section]'); porteur !== null; porteur = porteur.parentElement) {
|
for (let porteur = dans(m, '[data-section]'); porteur !== null; porteur = porteur.parentElement) {
|
||||||
porteur.scrollTop = porteur.scrollHeight;
|
porteur.scrollTop = porteur.scrollHeight;
|
||||||
}
|
}
|
||||||
expect(libelleCadre(m).getBoundingClientRect().toJSON()).toEqual(avant);
|
expect(libelleBarre(m).getBoundingClientRect().toJSON()).toEqual(avant);
|
||||||
expect(visible(libelleCadre(m))).toBe(true);
|
expect(visible(libelleBarre(m))).toBe(true);
|
||||||
expect(visible(fixe(m, 'debloquer'))).toBe(true);
|
expect(visible(fixe(m, 'debloquer'))).toBe(true);
|
||||||
haut.remove();
|
haut.remove();
|
||||||
});
|
});
|
||||||
|
|
@ -396,7 +396,7 @@ describe('l’inactivité (§ 8.4, § 19.4)', () => {
|
||||||
m.horloge.avancer(INACTIVITE_MS);
|
m.horloge.avancer(INACTIVITE_MS);
|
||||||
await attendre(() => expect(m.seance.etat().mode).toBe('lecture'));
|
await attendre(() => expect(m.seance.etat().mode).toBe('lecture'));
|
||||||
expect(fichier(m, SUFFIXES.verrou)).toBeNull();
|
expect(fichier(m, SUFFIXES.verrou)).toBeNull();
|
||||||
expect(libelleCadre(m).textContent).toBe(t('coquille.mode.lecture'));
|
expect(libelleBarre(m).textContent).toBe(t('coquille.mode.lecture'));
|
||||||
expect(libelleBandeau(m).textContent).toBe(t('coquille.mode.lecture'));
|
expect(libelleBandeau(m).textContent).toBe(t('coquille.mode.lecture'));
|
||||||
const annonce = avertissement(m, 'RETOUR_AUTOMATIQUE');
|
const annonce = avertissement(m, 'RETOUR_AUTOMATIQUE');
|
||||||
expect(annonce.textContent).toContain(t('RETOUR_AUTOMATIQUE', {}));
|
expect(annonce.textContent).toContain(t('RETOUR_AUTOMATIQUE', {}));
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@
|
||||||
<script>
|
<script>
|
||||||
// L'événement ouvert (§ 2.1, § 8.4) : la bande de mode, sous le bandeau,
|
// L'événement ouvert (§ 2.1, § 8.4) : la bande de mode, sous le bandeau,
|
||||||
// puis la barre, la tête et la surface de travail de toute section
|
// puis la barre, la tête et la surface de travail de toute section
|
||||||
// (CadreMode.svelte), sans trait autour d'elles. La barre porte la place
|
// (SurfaceEvenement.svelte), sans trait autour d'elles. La barre porte la
|
||||||
// fixe, le libellé de mode, Défaire et Refaire, puis les outils — la
|
// place fixe, le libellé de mode, Défaire et Refaire, puis les outils — la
|
||||||
// suite des états du plan — et les actions — « Imprimer… », l'action
|
// suite des états du plan — et les actions — « Imprimer… », l'action
|
||||||
// principale de l'en-tête. Sous la barre, la tête de l'événement : son
|
// principale de l'en-tête. Sous la barre, la tête de l'événement : son
|
||||||
// en-tête — nom et résumé — et la navigation des sections, dans l'ordre
|
// en-tête — nom et résumé — et la navigation des sections, dans l'ordre
|
||||||
|
|
@ -43,7 +43,7 @@
|
||||||
// son plafond, et non au-dessus de la section : la section ne cède à la
|
// son plafond, et non au-dessus de la section : la section ne cède à la
|
||||||
// zone que ce dont elle dépasse la tête, quel que soit le nombre des
|
// zone que ce dont elle dépasse la tête, quel que soit le nombre des
|
||||||
// avertissements, et le support rompu, en tête de la zone, garde ses
|
// avertissements, et le support rompu, en tête de la zone, garde ses
|
||||||
// issues en vue (CadreMode.svelte).
|
// issues en vue (SurfaceEvenement.svelte).
|
||||||
import { getContext } from 'svelte';
|
import { getContext } from 'svelte';
|
||||||
import SectionBadges from '../badges/SectionBadges.svelte';
|
import SectionBadges from '../badges/SectionBadges.svelte';
|
||||||
import Diagnostic from '../diagnostic/Diagnostic.svelte';
|
import Diagnostic from '../diagnostic/Diagnostic.svelte';
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
import Avertissements from './Avertissements.svelte';
|
import Avertissements from './Avertissements.svelte';
|
||||||
import BandeMode from './BandeMode.svelte';
|
import BandeMode from './BandeMode.svelte';
|
||||||
import Commande from '../primitives/Commande.svelte';
|
import Commande from '../primitives/Commande.svelte';
|
||||||
import CadreMode from './CadreMode.svelte';
|
import SurfaceEvenement from './SurfaceEvenement.svelte';
|
||||||
import EnteteEvenement from './EnteteEvenement.svelte';
|
import EnteteEvenement from './EnteteEvenement.svelte';
|
||||||
import EtatsPlan from './EtatsPlan.svelte';
|
import EtatsPlan from './EtatsPlan.svelte';
|
||||||
import SupportRompu from './SupportRompu.svelte';
|
import SupportRompu from './SupportRompu.svelte';
|
||||||
|
|
@ -138,9 +138,9 @@
|
||||||
|
|
||||||
<div class="evenement" data-ecran="evenement">
|
<div class="evenement" data-ecran="evenement">
|
||||||
<BandeMode />
|
<BandeMode />
|
||||||
<CadreMode outils={$ui.pleinEcran ? null : outils} actions={$ui.pleinEcran ? null : actions} tete={$ui.pleinEcran ? null : tete} annonces={annoncer ? annonces : null}>
|
<SurfaceEvenement outils={$ui.pleinEcran ? null : outils} actions={$ui.pleinEcran ? null : actions} tete={$ui.pleinEcran ? null : tete} annonces={annoncer ? annonces : null}>
|
||||||
<Section />
|
<Section />
|
||||||
</CadreMode>
|
</SurfaceEvenement>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
@ -176,7 +176,7 @@
|
||||||
|
|
||||||
/* Les phases côte à côte, séparées d'un blanc : les huit onglets tiennent
|
/* Les phases côte à côte, séparées d'un blanc : les huit onglets tiennent
|
||||||
sur une ligne à côté de la place des annonces dans une fenêtre de
|
sur une ligne à côté de la place des annonces dans une fenêtre de
|
||||||
1 366 px (CadreMode.svelte). */
|
1 366 px (SurfaceEvenement.svelte). */
|
||||||
nav {
|
nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="corps" data-mode={mode}>
|
<div class="corps" data-mode={mode}>
|
||||||
<div class="barre" role="group" aria-label={t('evenement.cadre.commandes')}>
|
<div class="barre" role="group" aria-label={t('evenement.barre.commandes')}>
|
||||||
<div class="ligne">
|
<div class="ligne">
|
||||||
<div class="fixe" data-place-fixe>
|
<div class="fixe" data-place-fixe>
|
||||||
{#if commande === 'format'}
|
{#if commande === 'format'}
|
||||||
|
|
@ -115,7 +115,7 @@
|
||||||
</div>
|
</div>
|
||||||
{#if libelle !== null}
|
{#if libelle !== null}
|
||||||
<span class="porte-libelle">
|
<span class="porte-libelle">
|
||||||
<span class="libelle" class:ecriture={mode === 'ecriture'} class:bloque={mode === 'bloque'} data-mode-libelle="cadre"
|
<span class="libelle" class:ecriture={mode === 'ecriture'} class:bloque={mode === 'bloque'} data-mode-libelle="barre"
|
||||||
>{t(libelle.cle)}</span
|
>{t(libelle.cle)}</span
|
||||||
>
|
>
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -114,7 +114,7 @@
|
||||||
<div class="tete">
|
<div class="tete">
|
||||||
<h2>{t('impression.titre')}</h2>
|
<h2>{t('impression.titre')}</h2>
|
||||||
{#if cleMode !== null}
|
{#if cleMode !== null}
|
||||||
<span class="mode" data-mode-libelle="cadre">{t(cleMode)}</span>
|
<span class="mode" data-mode-libelle="barre">{t(cleMode)}</span>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<div class="groupe vues" role="group" aria-label={t('impression.vue.titre')}>
|
<div class="groupe vues" role="group" aria-label={t('impression.vue.titre')}>
|
||||||
|
|
|
||||||
|
|
@ -205,9 +205,9 @@ textarea {
|
||||||
|
|
||||||
/* Bande de mode (§ 8.4) : la teinte de chaque mode, que porte son icône,
|
/* Bande de mode (§ 8.4) : la teinte de chaque mode, que porte son icône,
|
||||||
puis son fond et son filet. */
|
puis son fond et son filet. */
|
||||||
--couleur-cadre-lecture: #5c6878;
|
--couleur-mode-lecture: #5c6878;
|
||||||
--couleur-cadre-ecriture: #2e7d32;
|
--couleur-mode-ecriture: #2e7d32;
|
||||||
--couleur-cadre-bloque: #7b3fa0;
|
--couleur-mode-bloque: #7b3fa0;
|
||||||
--couleur-mode-lecture-fond: #e9edf3;
|
--couleur-mode-lecture-fond: #e9edf3;
|
||||||
--couleur-mode-lecture-filet: #c3cbd6;
|
--couleur-mode-lecture-filet: #c3cbd6;
|
||||||
--couleur-mode-ecriture-fond: #e3f4e8;
|
--couleur-mode-ecriture-fond: #e3f4e8;
|
||||||
|
|
@ -311,9 +311,9 @@ textarea {
|
||||||
--couleur-appartenance-6-fond: #152826;
|
--couleur-appartenance-6-fond: #152826;
|
||||||
--couleur-appartenance-6-marque: #298e88;
|
--couleur-appartenance-6-marque: #298e88;
|
||||||
|
|
||||||
--couleur-cadre-lecture: #9aa5b4;
|
--couleur-mode-lecture: #9aa5b4;
|
||||||
--couleur-cadre-ecriture: #81c784;
|
--couleur-mode-ecriture: #81c784;
|
||||||
--couleur-cadre-bloque: #ce93d8;
|
--couleur-mode-bloque: #ce93d8;
|
||||||
--couleur-mode-lecture-fond: #1f252d;
|
--couleur-mode-lecture-fond: #1f252d;
|
||||||
--couleur-mode-lecture-filet: #3a434f;
|
--couleur-mode-lecture-filet: #3a434f;
|
||||||
--couleur-mode-ecriture-fond: #16291c;
|
--couleur-mode-ecriture-fond: #16291c;
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ export const TABLE = new Map([
|
||||||
['evenement.phase.produire', 'Produire'],
|
['evenement.phase.produire', 'Produire'],
|
||||||
|
|
||||||
// --- La barre de l'événement et sa place fixe (§ 8.3, § 8.4, § 8.5) ------
|
// --- La barre de l'événement et sa place fixe (§ 8.3, § 8.4, § 8.5) ------
|
||||||
['evenement.cadre.commandes', 'Commandes de l\u{2019}événement'],
|
['evenement.barre.commandes', 'Commandes de l\u{2019}événement'],
|
||||||
['evenement.commande.defaire', 'Défaire'],
|
['evenement.commande.defaire', 'Défaire'],
|
||||||
['evenement.commande.refaire', 'Refaire'],
|
['evenement.commande.refaire', 'Refaire'],
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,9 +102,9 @@ export const SIGNES = Object.freeze([
|
||||||
marque('signeAvis', 'avis-marque', ['avis-fond']),
|
marque('signeAvis', 'avis-marque', ['avis-fond']),
|
||||||
marque('signeRefus', 'refus-marque', ['refus-fond']),
|
marque('signeRefus', 'refus-marque', ['refus-fond']),
|
||||||
marque('signeInformation', 'information-marque', ['information-fond']),
|
marque('signeInformation', 'information-marque', ['information-fond']),
|
||||||
marque('bandeEcriture', 'cadre-ecriture', ['mode-ecriture-fond']),
|
marque('bandeEcriture', 'mode-ecriture', ['mode-ecriture-fond']),
|
||||||
marque('bandeLecture', 'cadre-lecture', ['mode-lecture-fond']),
|
marque('bandeLecture', 'mode-lecture', ['mode-lecture-fond']),
|
||||||
marque('bandeBloque', 'cadre-bloque', ['mode-bloque-fond']),
|
marque('bandeBloque', 'mode-bloque', ['mode-bloque-fond']),
|
||||||
marque('actionPrincipale', 'action-fond', SURFACES),
|
marque('actionPrincipale', 'action-fond', SURFACES),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@ describe('les signes des pastilles, des messages, de la bande de mode et de l’
|
||||||
// la bande.
|
// la bande.
|
||||||
for (const mode of ['Ecriture', 'Lecture', 'Bloque']) {
|
for (const mode of ['Ecriture', 'Lecture', 'Bloque']) {
|
||||||
const signe = parNom(SIGNES, `bande${mode}`);
|
const signe = parNom(SIGNES, `bande${mode}`);
|
||||||
assert.deepEqual([signe.jeton, ...signe.fonds], [`--couleur-cadre-${mode.toLowerCase()}`, `--couleur-mode-${mode.toLowerCase()}-fond`]);
|
assert.deepEqual([signe.jeton, ...signe.fonds], [`--couleur-mode-${mode.toLowerCase()}`, `--couleur-mode-${mode.toLowerCase()}-fond`]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ function exigerModeSansCadre(mode) {
|
||||||
const style = getComputedStyle(surface);
|
const style = getComputedStyle(surface);
|
||||||
for (const cote of ['Top', 'Right', 'Bottom', 'Left']) expect(Number.parseFloat(style[`border${cote}Width`]), cote).toBe(0);
|
for (const cote of ['Top', 'Right', 'Bottom', 'Left']) expect(Number.parseFloat(style[`border${cote}Width`]), cote).toBe(0);
|
||||||
const bande = dans('[data-ecran="evenement"] > [role="status"]');
|
const bande = dans('[data-ecran="evenement"] > [role="status"]');
|
||||||
const libelle = dans('[data-mode-libelle="cadre"]');
|
const libelle = dans('[data-mode-libelle="barre"]');
|
||||||
expect(visible(bande)).toBe(true);
|
expect(visible(bande)).toBe(true);
|
||||||
expect(visible(libelle)).toBe(true);
|
expect(visible(libelle)).toBe(true);
|
||||||
expect(texteDe(libelle).length).toBeGreaterThan(0);
|
expect(texteDe(libelle).length).toBeGreaterThan(0);
|
||||||
|
|
@ -860,7 +860,7 @@ describe('le parcours par gestes, depuis un répertoire neuf', { timeout: DUREE
|
||||||
await rienEcrit(avant, 'créer une table en lecture');
|
await rienEcrit(avant, 'créer une table en lecture');
|
||||||
expect(charge().tables).toHaveLength(0);
|
expect(charge().tables).toHaveLength(0);
|
||||||
await photographier(m, '01b-passer-en-ecriture', {
|
await photographier(m, '01b-passer-en-ecriture', {
|
||||||
condition: ['[data-place-fixe] [data-commande="modifier"]', '[data-refus="MODE_LECTURE"]', '[data-mode-libelle="cadre"]'],
|
condition: ['[data-place-fixe] [data-commande="modifier"]', '[data-refus="MODE_LECTURE"]', '[data-mode-libelle="barre"]'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -1446,7 +1446,7 @@ describe('le parcours par gestes, depuis un répertoire neuf', { timeout: DUREE
|
||||||
await rienEcrit(avant, 'les quatre gestes en lecture');
|
await rienEcrit(avant, 'les quatre gestes en lecture');
|
||||||
expect(dans(`[data-table="${t2}"]`).getAttribute('transform')).toBeNull();
|
expect(dans(`[data-table="${t2}"]`).getAttribute('transform')).toBeNull();
|
||||||
for (const t of etatMontre().tables) expect(tous(`[data-siege^="${t.id}:"]`), `table ${t.numero}`).toHaveLength(t.capacite);
|
for (const t of etatMontre().tables) expect(tous(`[data-siege^="${t.id}:"]`), `table ${t.numero}`).toHaveLength(t.capacite);
|
||||||
await photographier(m, '20-mode-lecture', { condition: ['[data-mode-libelle="cadre"]', '[data-mode-libelle="bandeau"]'], graine: GRAINE });
|
await photographier(m, '20-mode-lecture', { condition: ['[data-mode-libelle="barre"]', '[data-mode-libelle="bandeau"]'], graine: GRAINE });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('20 « Défaire » en lecture : refusé avec « Modifier » ; en écriture, rend l’état d’avant 19', async () => {
|
test('20 « Défaire » en lecture : refusé avec « Modifier » ; en écriture, rend l’état d’avant 19', async () => {
|
||||||
|
|
|
||||||
|
|
@ -149,9 +149,9 @@
|
||||||
font-size: var(--taille-texte);
|
font-size: var(--taille-texte);
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
/* Jamais plus haute que la surface qui la porte (CadreMode) : ouverte
|
/* Jamais plus haute que la surface qui la porte
|
||||||
sous la grille, dans une fenêtre étroite, elle se montre en entier,
|
(SurfaceEvenement.svelte) : ouverte sous la grille, dans une fenêtre
|
||||||
et son contenu défile en elle. */
|
étroite, elle se montre en entier, et son contenu défile en elle. */
|
||||||
max-height: 100cqb;
|
max-height: 100cqb;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -270,9 +270,9 @@ async function cliquerPoint({ x, y }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Un clic réel au centre d'une chaise. Quand elle est hors du cadre du
|
// Un clic réel au centre d'une chaise. Quand elle est hors du cadre du
|
||||||
// plan — les annonces du cadre de mode, avertissements compris, prennent
|
// plan — les annonces de l'écran de l'événement, avertissements compris,
|
||||||
// leur hauteur à la surface —, la vue se déplace d'abord, par le cadrage de
|
// prennent leur hauteur à la surface —, la vue se déplace d'abord, par le
|
||||||
// la séance, pour poser la chaise au centre du cadre, au même k.
|
// cadrage de la séance, pour poser la chaise au centre du cadre, au même k.
|
||||||
async function cliquerChaise(m, table, siege) {
|
async function cliquerChaise(m, table, siege) {
|
||||||
const atteinte = () => {
|
const atteinte = () => {
|
||||||
const { x, y } = pointChaise(m, table, siege);
|
const { x, y } = pointChaise(m, table, siege);
|
||||||
|
|
|
||||||
|
|
@ -808,7 +808,7 @@ describe('les commandes de vue n’écrivent rien et restent vivantes (§ 8.2,
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('le plein écran (§ 8.4, § 18.6)', () => {
|
describe('le plein écran (§ 8.4, § 18.6)', () => {
|
||||||
test('la surface s’agrandit ; le cadre de mode, son libellé et le bandeau restent visibles ; ressorti, la surface retrouve sa boîte', async () => {
|
test('la surface s’agrandit ; la barre, la tête et la surface de l’événement, ses deux libellés de mode et le bandeau restent visibles ; ressorti, la surface retrouve sa boîte', async () => {
|
||||||
const m = await petite();
|
const m = await petite();
|
||||||
await deuxImages();
|
await deuxImages();
|
||||||
const avant = boite(surface(m));
|
const avant = boite(surface(m));
|
||||||
|
|
@ -818,7 +818,7 @@ describe('le plein écran (§ 8.4, § 18.6)', () => {
|
||||||
expect(plein.width * plein.height).toBeGreaterThan(avant.width * avant.height);
|
expect(plein.width * plein.height).toBeGreaterThan(avant.width * avant.height);
|
||||||
expect(plein.height).toBeGreaterThan(avant.height);
|
expect(plein.height).toBeGreaterThan(avant.height);
|
||||||
expect(plein.width).toBeGreaterThan(avant.width);
|
expect(plein.width).toBeGreaterThan(avant.width);
|
||||||
const temoins = [dans(m, '[data-mode]'), dans(m, '[data-mode-libelle="cadre"]'), dans(m, '[data-mode-libelle="bandeau"]'), dans(m, '[data-bandeau]')];
|
const temoins = [dans(m, '[data-mode]'), dans(m, '[data-mode-libelle="barre"]'), dans(m, '[data-mode-libelle="bandeau"]'), dans(m, '[data-bandeau]')];
|
||||||
for (const temoin of temoins) {
|
for (const temoin of temoins) {
|
||||||
expect(temoin).not.toBeNull();
|
expect(temoin).not.toBeNull();
|
||||||
expect(visible(temoin)).toBe(true);
|
expect(visible(temoin)).toBe(true);
|
||||||
|
|
|
||||||
|
|
@ -466,7 +466,7 @@ function releverEtats(m) {
|
||||||
function signatureMode(racine) {
|
function signatureMode(racine) {
|
||||||
const surface = racine.querySelector('[data-mode]');
|
const surface = racine.querySelector('[data-mode]');
|
||||||
const bande = racine.querySelector('[data-ecran="evenement"] > [role="status"]');
|
const bande = racine.querySelector('[data-ecran="evenement"] > [role="status"]');
|
||||||
const libelle = racine.querySelector('[data-mode-libelle="cadre"]');
|
const libelle = racine.querySelector('[data-mode-libelle="barre"]');
|
||||||
if (surface === null || bande === null || libelle === null) return null;
|
if (surface === null || bande === null || libelle === null) return null;
|
||||||
const s = getComputedStyle(surface);
|
const s = getComputedStyle(surface);
|
||||||
const trait = ['Top', 'Right', 'Bottom', 'Left'].reduce((somme, cote) => somme + Number.parseFloat(s[`border${cote}Width`]), 0);
|
const trait = ['Top', 'Right', 'Bottom', 'Left'].reduce((somme, cote) => somme + Number.parseFloat(s[`border${cote}Width`]), 0);
|
||||||
|
|
@ -517,7 +517,7 @@ export function fautesBandeau(racine, mode, { version = VERSION.affichee, proven
|
||||||
if (libelle !== null) fautes.push(`libellé de mode « ${libelle.textContent.trim()} » sans événement ouvert`);
|
if (libelle !== null) fautes.push(`libellé de mode « ${libelle.textContent.trim()} » sans événement ouvert`);
|
||||||
return fautes;
|
return fautes;
|
||||||
}
|
}
|
||||||
const barre = racine.querySelector('[data-mode-libelle="cadre"]');
|
const barre = racine.querySelector('[data-mode-libelle="barre"]');
|
||||||
if (libelle === null) fautes.push(`libellé de mode absent du bandeau (${mode})`);
|
if (libelle === null) fautes.push(`libellé de mode absent du bandeau (${mode})`);
|
||||||
else if (voir(libelle) !== true) fautes.push(`libellé de mode du bandeau non visible : ${voir(libelle)}`);
|
else if (voir(libelle) !== true) fautes.push(`libellé de mode du bandeau non visible : ${voir(libelle)}`);
|
||||||
if (barre === null) fautes.push(`libellé de mode absent de la barre (${mode})`);
|
if (barre === null) fautes.push(`libellé de mode absent de la barre (${mode})`);
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ const ENTREES = [
|
||||||
['data-mention', 'aperçu : une mention d’une page du plan imprimé — disposition relative, listes hors d’échelle', ['listes', 'relative']],
|
['data-mention', 'aperçu : une mention d’une page du plan imprimé — disposition relative, listes hors d’échelle', ['listes', 'relative']],
|
||||||
['data-menu', 'plan : le menu d’une personne', null],
|
['data-menu', 'plan : le menu d’une personne', null],
|
||||||
['data-mode', 'événement : la barre, la tête et la surface de l’événement, par son mode', null],
|
['data-mode', 'événement : la barre, la tête et la surface de l’événement, par son mode', null],
|
||||||
['data-mode-libelle', 'le libellé de mode', ['bandeau', 'cadre']],
|
['data-mode-libelle', 'le libellé de mode', ['bandeau', 'barre']],
|
||||||
['data-motif', 'import : le motif d’une ligne refusée', ['']],
|
['data-motif', 'import : le motif d’une ligne refusée', ['']],
|
||||||
['data-multiligne', 'import : une ligne sur plusieurs lignes de texte', null],
|
['data-multiligne', 'import : une ligne sur plusieurs lignes de texte', null],
|
||||||
['data-niveau', 'participants : le niveau d’un groupe ou d’un sélecteur', null],
|
['data-niveau', 'participants : le niveau d’un groupe ou d’un sélecteur', null],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue