[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
|
||||
// dans ses mesures, à part des choisies.
|
||||
//
|
||||
// resumeDuRetenu donne à la liste des événements deux nombres du retenu,
|
||||
// lus dans la même mesure que sa ligne du tableau, sans le diagnostic ni
|
||||
// les plafonds : la liste en résume chaque événement du dossier.
|
||||
// premiereDuClassement est la seule définition de la proposition au rang 1
|
||||
// : la section de la génération la lit dans sa table, resumeDuMeilleur la
|
||||
// donne à la liste, sur la même table d'évaluation, diagnostic compris — le
|
||||
// premier critère du classement lit le plafond a priori.
|
||||
// resumeDuRetenu donne à la liste des événements la différence à la cible
|
||||
// du retenu, lue dans la même mesure que sa ligne du tableau, sans le
|
||||
// diagnostic ni les plafonds : la liste en résume chaque événement du
|
||||
// dossier. premiereDuClassement est la seule définition de la proposition
|
||||
// au rang 1 : la section de la génération la lit dans sa table,
|
||||
// resumeDuMeilleur en donne l'identifiant à la liste, sur la même table
|
||||
// d'évaluation, diagnostic compris — le premier critère du classement lit
|
||||
// le plafond a priori.
|
||||
import { classer } from '../moteur/classement.js';
|
||||
import { indexerPlan, normaliser } from '../moteur/configuration.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,
|
||||
* § 8.9) : ses collisions cumulées et sa somme de redondance Σ r(p), celles
|
||||
* de mesurer, que la ligne du retenu d'evaluer porte aussi ; la cible de
|
||||
* l'événement (cibleRedondance) ; et diffRedondance, la valeur absolue de la
|
||||
* cible moins Σ r(p). null sans retenu, pour un retenu fautif ou en dérive,
|
||||
* et quand la configuration ne se normalise pas : rien ne s'y mesure, et
|
||||
* la liste écrit « — ». Ne modifie pas la charge.
|
||||
* § 8.9) : diffRedondance, la valeur absolue de la cible de l'événement
|
||||
* (cibleRedondance) moins la somme de redondance Σ r(p) du retenu, celle de
|
||||
* mesurer, que la ligne du retenu d'evaluer porte aussi. null sans retenu,
|
||||
* pour un retenu fautif ou en dérive, et quand la configuration ne se
|
||||
* normalise pas : rien ne s'y mesure, et la liste écrit « — ». Ne modifie
|
||||
* pas la charge.
|
||||
*
|
||||
* @param {import('../stockage/types.js').Charge} charge
|
||||
* @returns {{collisionsCumulees: number, totalRedondance: number,
|
||||
* cibleRedondance: number, diffRedondance: number}|null}
|
||||
* @returns {{diffRedondance: number}|null}
|
||||
*/
|
||||
export function resumeDuRetenu(charge) {
|
||||
const { retenu } = charge;
|
||||
|
|
@ -183,9 +183,8 @@ export function resumeDuRetenu(charge) {
|
|||
if (erreur instanceof ErreurConfiguration) return null;
|
||||
throw erreur;
|
||||
}
|
||||
const { collisionsCumulees, totalRedondance } = mesurer(instance, indexerPlan(instance, planDepuisFichier(retenu)));
|
||||
const cible = cibleRedondance(charge);
|
||||
return { collisionsCumulees, totalRedondance, cibleRedondance: cible, diffRedondance: Math.abs(cible - totalRedondance) };
|
||||
const { totalRedondance } = mesurer(instance, indexerPlan(instance, planDepuisFichier(retenu)));
|
||||
return { diffRedondance: Math.abs(cibleRedondance(charge) - totalRedondance) };
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -204,15 +203,14 @@ export function premiereDuClassement(table) {
|
|||
|
||||
/**
|
||||
* La meilleure proposition du classement que montre la liste des
|
||||
* événements (§ 5.4, § 5.7, § 8.1) : l'identifiant de la proposition au
|
||||
* rang 1 (premiereDuClassement) et ses collisions cumulées, celles de sa
|
||||
* ligne d'evaluer. null sans proposition, quand aucune ne se compare —
|
||||
* toutes fautives ou en dérive —, et quand la configuration ne se normalise
|
||||
* pas : la liste écrit alors « — ». Le retenu n'y entre pas. Ne modifie pas
|
||||
* la charge.
|
||||
* événements (§ 5.4, § 5.7, § 8.1) : id, l'identifiant de la proposition au
|
||||
* rang 1 (premiereDuClassement). null sans proposition, quand aucune ne se
|
||||
* compare — toutes fautives ou en dérive —, et quand la configuration ne se
|
||||
* normalise pas : la liste écrit alors « — ». Le retenu n'y entre pas. Ne
|
||||
* modifie pas la charge.
|
||||
*
|
||||
* @param {import('../stockage/types.js').Charge} charge
|
||||
* @returns {{id: number, collisionsCumulees: number}|null}
|
||||
* @returns {{id: number}|null}
|
||||
*/
|
||||
export function resumeDuMeilleur(charge) {
|
||||
if (charge.propositions.length === 0) return null;
|
||||
|
|
@ -224,5 +222,5 @@ export function resumeDuMeilleur(charge) {
|
|||
throw erreur;
|
||||
}
|
||||
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.
|
||||
function retenue() {
|
||||
const generees = generee(chargeDemo('petite-conflit'), { graine: 3, nombre: 3, arret: 300 });
|
||||
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 resume = resumeDuRetenu(charge);
|
||||
const { mesures } = evaluer(charge).retenu;
|
||||
assert.ok(mesures.collisionsCumulees > 0, 'la petite démonstration en conflit compte des collisions');
|
||||
assert.deepEqual(resume, {
|
||||
collisionsCumulees: mesures.collisionsCumulees,
|
||||
totalRedondance: mesures.totalRedondance,
|
||||
cibleRedondance: 1000,
|
||||
diffRedondance: Math.abs(1000 - mesures.totalRedondance),
|
||||
});
|
||||
assert.ok(mesures.totalRedondance !== 1000, 'la différence se distingue de zéro');
|
||||
assert.deepEqual(resume, { diffRedondance: Math.abs(1000 - mesures.totalRedondance) });
|
||||
const instance = normaliser(configurationDepuisCharge(charge));
|
||||
const attendues = mesurer(instance, indexerPlan(instance, planDepuisFichier(charge.retenu)));
|
||||
assert.equal(resume.totalRedondance, attendues.totalRedondance);
|
||||
assert.equal(resume.collisionsCumulees, attendues.collisionsCumulees);
|
||||
assert.equal(attendues.totalRedondance, mesures.totalRedondance);
|
||||
assert.equal(CIBLE_REDONDANCE_PAR_DEFAUT, 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", () => {
|
||||
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]) {
|
||||
const avecCible = executer(charge, 'changerCibleRedondance', { cible: String(cible) });
|
||||
assert.equal(cibleRedondance(avecCible), cible);
|
||||
const resume = resumeDuRetenu(avecCible);
|
||||
assert.equal(resume.cibleRedondance, cible);
|
||||
assert.equal(resume.diffRedondance, Math.abs(cible - total), String(cible));
|
||||
assert.deepEqual(resumeDuRetenu(avecCible), { diffRedondance: Math.abs(cible - total) }, String(cible));
|
||||
}
|
||||
const dessous = executer(charge, 'changerCibleRedondance', { cible: '0' });
|
||||
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)', () => {
|
||||
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
|
||||
// en tête avec 6 collisions cumulées, quand la 1 n'en porte que 4.
|
||||
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);
|
||||
const table = evaluer(charge);
|
||||
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).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", () => {
|
||||
|
|
@ -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 });
|
||||
const [premiere] = evaluer(charge).propositions;
|
||||
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);
|
||||
const derniere = charge.propositions.at(-1).id;
|
||||
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
|
||||
// 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
|
||||
// liste nomme ainsi la proposition au rang 1, et son nombre, que le bloc de
|
||||
// génération de l'événement ouvert nomme (§ 8.1). null pour un état absent
|
||||
// ou qui ne s'ouvre pas.
|
||||
// liste nomme ainsi la proposition au rang 1 que le bloc de génération de
|
||||
// l'événement ouvert nomme (§ 8.1). null pour un état absent ou qui ne
|
||||
// s'ouvre pas.
|
||||
async function chargeExaminee(fs, racine, base) {
|
||||
try {
|
||||
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 });
|
||||
}
|
||||
|
||||
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();
|
||||
fs.deposer('portable', `retenue${SUFFIXES.etat}`, texteRetenu());
|
||||
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 charge = analyser(texteRetenu()).charge;
|
||||
const { mesures } = evaluer(charge).retenu;
|
||||
assert.deepEqual(par.retenue.mesuresDuRetenu, {
|
||||
collisionsCumulees: mesures.collisionsCumulees,
|
||||
totalRedondance: mesures.totalRedondance,
|
||||
cibleRedondance: 1000,
|
||||
diffRedondance: Math.abs(1000 - mesures.totalRedondance),
|
||||
});
|
||||
assert.deepEqual(par.retenue.mesuresDuRetenu, { diffRedondance: Math.abs(1000 - mesures.totalRedondance) });
|
||||
assert.deepEqual(par.retenue.mesuresDuRetenu, resumeDuRetenu(charge));
|
||||
assert.equal(par['soiree-a'].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);
|
||||
const ligne = (await listerResume(facade)).find(({ base }) => base === 'retenue');
|
||||
const { totalRedondance } = evaluer(analyser(texte).charge).retenu.mesures;
|
||||
assert.equal(ligne.mesuresDuRetenu.cibleRedondance, 25);
|
||||
assert.equal(ligne.mesuresDuRetenu.diffRedondance, Math.abs(25 - totalRedondance));
|
||||
assert.notEqual(Math.abs(25 - totalRedondance), Math.abs(1000 - 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 () => {
|
||||
|
|
@ -716,7 +711,7 @@ describe('lister (§ 8.1, § 19.4)', () => {
|
|||
const charge = analyser(texte).charge;
|
||||
const [premiere] = evaluer(charge).propositions;
|
||||
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.equal(par.proposee.mesuresDuRetenu, null);
|
||||
|
|
@ -724,7 +719,7 @@ describe('lister (§ 8.1, § 19.4)', () => {
|
|||
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 { fs, facade } = montage;
|
||||
// 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);
|
||||
for (let pas = 0; pas < lignes.length; pas += 1) await unPas(horloge);
|
||||
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));
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -148,7 +148,8 @@ export function signalementsDe(ligne) {
|
|||
*
|
||||
* @param {Object} ligne LigneListe (evenements.js)
|
||||
* @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,
|
||||
* modification: string, chemin: string, enAttente: boolean,
|
||||
* 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)', () => {
|
||||
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', () => {
|
||||
const mesuresDuRetenu = { collisionsCumulees: 8765, totalRedondance: 1500, cibleRedondance: 1000, diffRedondance: 500 };
|
||||
const affichee = ligneAffichee(ligne(), format, { ...AUCUN, mesuresDuRetenu });
|
||||
assert.equal(affichee.diffRedondance, format.nombre(500));
|
||||
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('la différence à la cible, celle de la façade, mise en forme, sans calcul ici', () => {
|
||||
for (const diffRedondance of [500, 7, 0]) {
|
||||
const affichee = ligneAffichee(ligne(), format, { ...AUCUN, mesuresDuRetenu: { diffRedondance } });
|
||||
assert.equal(affichee.diffRedondance, format.nombre(diffRedondance), String(diffRedondance));
|
||||
}
|
||||
});
|
||||
|
||||
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.equal(ligneAffichee(ligne(), format, AUCUN).enAttente, false);
|
||||
const recu = ligneAffichee(ligne(), format, {
|
||||
mesuresDuRetenu: { collisionsCumulees: 12, totalRedondance: 990, cibleRedondance: 1000, diffRedondance: 10 },
|
||||
meilleureDuClassement: { id: 3, collisionsCumulees: 9 },
|
||||
mesuresDuRetenu: { diffRedondance: 10 },
|
||||
meilleureDuClassement: { id: 3 },
|
||||
});
|
||||
assert.equal(recu.enAttente, false);
|
||||
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 });
|
||||
}
|
||||
|
||||
test("l'identifiant que rend la façade, mis en forme, sans calcul ici ; ses collisions cumulées ne se montrent pas", () => {
|
||||
const affichee = ligneAffichee(ligne(), format, { ...AUCUN, meilleureDuClassement: { id: 1234, collisionsCumulees: 5678 } });
|
||||
test("l'identifiant que rend la façade, mis en forme, sans calcul ici", () => {
|
||||
const affichee = ligneAffichee(ligne(), format, { ...AUCUN, meilleureDuClassement: { id: 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
|
||||
// message : l'action n'étroitise que la première phrase. La zone des
|
||||
// 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 Commande from '../primitives/Commande.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
|
||||
// travail.
|
||||
//
|
||||
// Son fond et son filet sont ceux du mode, son icône de la teinte du mode
|
||||
// (--couleur-cadre-…), son texte de l'encre de la page (marques.js :
|
||||
// Son fond et son filet sont ceux du mode (--couleur-mode-…-fond et
|
||||
// -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).
|
||||
// Région d'état, elle annonce le mode quand il change.
|
||||
//
|
||||
|
|
@ -68,14 +69,14 @@
|
|||
|
||||
.signe {
|
||||
display: flex;
|
||||
color: var(--couleur-cadre-lecture);
|
||||
color: var(--couleur-mode-lecture);
|
||||
}
|
||||
|
||||
.ecriture .signe {
|
||||
color: var(--couleur-cadre-ecriture);
|
||||
color: var(--couleur-mode-ecriture);
|
||||
}
|
||||
|
||||
.bloque .signe {
|
||||
color: var(--couleur-cadre-bloque);
|
||||
color: var(--couleur-mode-bloque);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl) -->
|
||||
|
||||
<script>
|
||||
// L'en-tête de l'événement ouvert, en tête de la tête (CadreMode.svelte) :
|
||||
// son nom, puis, sur la même ligne tant qu'elle a la place, son résumé — la date
|
||||
// quand il en a une, les participants, les tables et leurs sièges, les
|
||||
// tours (resumeEvenement, modele.js) —, d'encre secondaire. Le nom se
|
||||
// coupe où il le faut, même sans espace : un nom long de glyphes larges
|
||||
// passe à la ligne au lieu d'élargir la page. Le résumé passe à la ligne
|
||||
// entre ses éléments, jamais dans l'un d'eux.
|
||||
// L'en-tête de l'événement ouvert, en tête de la tête
|
||||
// (SurfaceEvenement.svelte) : son nom, puis, sur la même ligne tant qu'elle
|
||||
// a la place, son résumé — la date quand il en a une, les participants, les
|
||||
// tables et leurs sièges, les tours (resumeEvenement, modele.js) —, d'encre
|
||||
// secondaire. Le nom se coupe où il le faut, même sans espace : un nom
|
||||
// long de glyphes larges passe à la ligne au lieu d'élargir la page. Le
|
||||
// résumé passe à la ligne entre ses éléments, jamais dans l'un d'eux.
|
||||
import { getContext } from 'svelte';
|
||||
import { resumeEvenement } from './modele.js';
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ afterEach(() => {
|
|||
const dans = (m, selecteur) => m.racine.querySelector(selecteur);
|
||||
const tous = (m, selecteur) => [...m.racine.querySelectorAll(selecteur)];
|
||||
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 fixe = (m, nom) => dans(m, `[data-place-fixe] [data-commande="${nom}"]`);
|
||||
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([b.left, b.right], mode).toEqual([0, 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 près, et la barre, la tête et la surface avec lui, sans
|
||||
// trait autour d'elles.
|
||||
const retrait = Number.parseFloat(style(ecran(m).parentElement).paddingLeft);
|
||||
expect(retrait, mode).toBeGreaterThan(0);
|
||||
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);
|
||||
expect(e.left, mode).toBeCloseTo(retrait, 0);
|
||||
expect(e.right, mode).toBeCloseTo(innerWidth - retrait, 0);
|
||||
}
|
||||
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(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);
|
||||
hauteurs.push(b.height);
|
||||
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}`;
|
||||
expect(fond(region), lieu).toEqual(jeton(`--couleur-mode-${mode}-fond`));
|
||||
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);
|
||||
exigerTextesLisibles(region, lieu);
|
||||
});
|
||||
|
|
@ -235,7 +235,7 @@ describe('la carte d’en-tête', () => {
|
|||
expect(imprimer.textContent).toBe(t('impression.commande.ouvrir'));
|
||||
expect(entete.contains(imprimer)).toBe(false);
|
||||
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.height).toBeGreaterThanOrEqual(44);
|
||||
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, ni le message, ni aucune boîte qui les porte jusqu'au cadre
|
||||
// ne déborde de sa hauteur, et chacun tient dans la boîte visible de
|
||||
// chaque ascendant qui 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
|
||||
// le texte, ni le message, ni aucune boîte qui les porte jusqu'à la
|
||||
// surface de l'événement (SurfaceEvenement.svelte) ne déborde de sa
|
||||
// hauteur, et chacun tient dans la boîte visible de chaque ascendant qui
|
||||
// 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.
|
||||
for (const largeur of [1366, 1024]) {
|
||||
for (const manque of [1, 4, 13]) {
|
||||
|
|
@ -489,7 +489,7 @@ describe('les avertissements, en messages d’avis', () => {
|
|||
const a = boite(action);
|
||||
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);
|
||||
const borne = cadre(m);
|
||||
const borne = surface(m);
|
||||
for (let element = texte; element !== borne.parentElement; element = element.parentElement) {
|
||||
const nom = `${element.tagName.toLowerCase()}${element.hasAttribute('data-annonces') ? '[data-annonces]' : ''}`;
|
||||
expect(element.scrollHeight, `${nom} : hauteur du contenu`).toBeLessThanOrEqual(element.clientHeight + 1);
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@
|
|||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Dans une barre étroite (CadreMode.svelte), l'intertitre s'efface : le
|
||||
groupe garde son nom, et les quatre étapes leur ligne. */
|
||||
/* Dans une barre étroite (SurfaceEvenement.svelte), l'intertitre
|
||||
s'efface : le groupe garde son nom, et les quatre étapes leur ligne. */
|
||||
@container barre (max-width: 80rem) {
|
||||
.intertitre {
|
||||
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 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 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 avertissement = (m, code) => dans(m, `[data-avertissement="${code}"]`);
|
||||
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']) {
|
||||
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(visible(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')]);
|
||||
// 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.
|
||||
const avant = libelleCadre(m).getBoundingClientRect().toJSON();
|
||||
const avant = libelleBarre(m).getBoundingClientRect().toJSON();
|
||||
const haut = document.createElement('div');
|
||||
haut.style.height = '3000px';
|
||||
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) {
|
||||
porteur.scrollTop = porteur.scrollHeight;
|
||||
}
|
||||
expect(libelleCadre(m).getBoundingClientRect().toJSON()).toEqual(avant);
|
||||
expect(visible(libelleCadre(m))).toBe(true);
|
||||
expect(libelleBarre(m).getBoundingClientRect().toJSON()).toEqual(avant);
|
||||
expect(visible(libelleBarre(m))).toBe(true);
|
||||
expect(visible(fixe(m, 'debloquer'))).toBe(true);
|
||||
haut.remove();
|
||||
});
|
||||
|
|
@ -396,7 +396,7 @@ describe('l’inactivité (§ 8.4, § 19.4)', () => {
|
|||
m.horloge.avancer(INACTIVITE_MS);
|
||||
await attendre(() => expect(m.seance.etat().mode).toBe('lecture'));
|
||||
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'));
|
||||
const annonce = avertissement(m, 'RETOUR_AUTOMATIQUE');
|
||||
expect(annonce.textContent).toContain(t('RETOUR_AUTOMATIQUE', {}));
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
<script>
|
||||
// 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
|
||||
// (CadreMode.svelte), sans trait autour d'elles. La barre porte la place
|
||||
// fixe, le libellé de mode, Défaire et Refaire, puis les outils — la
|
||||
// (SurfaceEvenement.svelte), sans trait autour d'elles. La barre porte 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
|
||||
// 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
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
// 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
|
||||
// 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 SectionBadges from '../badges/SectionBadges.svelte';
|
||||
import Diagnostic from '../diagnostic/Diagnostic.svelte';
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
import Avertissements from './Avertissements.svelte';
|
||||
import BandeMode from './BandeMode.svelte';
|
||||
import Commande from '../primitives/Commande.svelte';
|
||||
import CadreMode from './CadreMode.svelte';
|
||||
import SurfaceEvenement from './SurfaceEvenement.svelte';
|
||||
import EnteteEvenement from './EnteteEvenement.svelte';
|
||||
import EtatsPlan from './EtatsPlan.svelte';
|
||||
import SupportRompu from './SupportRompu.svelte';
|
||||
|
|
@ -138,9 +138,9 @@
|
|||
|
||||
<div class="evenement" data-ecran="evenement">
|
||||
<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 />
|
||||
</CadreMode>
|
||||
</SurfaceEvenement>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
@ -176,7 +176,7 @@
|
|||
|
||||
/* 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
|
||||
1 366 px (CadreMode.svelte). */
|
||||
1 366 px (SurfaceEvenement.svelte). */
|
||||
nav {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@
|
|||
</script>
|
||||
|
||||
<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="fixe" data-place-fixe>
|
||||
{#if commande === 'format'}
|
||||
|
|
@ -115,7 +115,7 @@
|
|||
</div>
|
||||
{#if libelle !== null}
|
||||
<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
|
||||
>
|
||||
</span>
|
||||
|
|
@ -114,7 +114,7 @@
|
|||
<div class="tete">
|
||||
<h2>{t('impression.titre')}</h2>
|
||||
{#if cleMode !== null}
|
||||
<span class="mode" data-mode-libelle="cadre">{t(cleMode)}</span>
|
||||
<span class="mode" data-mode-libelle="barre">{t(cleMode)}</span>
|
||||
{/if}
|
||||
</div>
|
||||
<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,
|
||||
puis son fond et son filet. */
|
||||
--couleur-cadre-lecture: #5c6878;
|
||||
--couleur-cadre-ecriture: #2e7d32;
|
||||
--couleur-cadre-bloque: #7b3fa0;
|
||||
--couleur-mode-lecture: #5c6878;
|
||||
--couleur-mode-ecriture: #2e7d32;
|
||||
--couleur-mode-bloque: #7b3fa0;
|
||||
--couleur-mode-lecture-fond: #e9edf3;
|
||||
--couleur-mode-lecture-filet: #c3cbd6;
|
||||
--couleur-mode-ecriture-fond: #e3f4e8;
|
||||
|
|
@ -311,9 +311,9 @@ textarea {
|
|||
--couleur-appartenance-6-fond: #152826;
|
||||
--couleur-appartenance-6-marque: #298e88;
|
||||
|
||||
--couleur-cadre-lecture: #9aa5b4;
|
||||
--couleur-cadre-ecriture: #81c784;
|
||||
--couleur-cadre-bloque: #ce93d8;
|
||||
--couleur-mode-lecture: #9aa5b4;
|
||||
--couleur-mode-ecriture: #81c784;
|
||||
--couleur-mode-bloque: #ce93d8;
|
||||
--couleur-mode-lecture-fond: #1f252d;
|
||||
--couleur-mode-lecture-filet: #3a434f;
|
||||
--couleur-mode-ecriture-fond: #16291c;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ export const TABLE = new Map([
|
|||
['evenement.phase.produire', 'Produire'],
|
||||
|
||||
// --- 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.refaire', 'Refaire'],
|
||||
|
||||
|
|
|
|||
|
|
@ -102,9 +102,9 @@ export const SIGNES = Object.freeze([
|
|||
marque('signeAvis', 'avis-marque', ['avis-fond']),
|
||||
marque('signeRefus', 'refus-marque', ['refus-fond']),
|
||||
marque('signeInformation', 'information-marque', ['information-fond']),
|
||||
marque('bandeEcriture', 'cadre-ecriture', ['mode-ecriture-fond']),
|
||||
marque('bandeLecture', 'cadre-lecture', ['mode-lecture-fond']),
|
||||
marque('bandeBloque', 'cadre-bloque', ['mode-bloque-fond']),
|
||||
marque('bandeEcriture', 'mode-ecriture', ['mode-ecriture-fond']),
|
||||
marque('bandeLecture', 'mode-lecture', ['mode-lecture-fond']),
|
||||
marque('bandeBloque', 'mode-bloque', ['mode-bloque-fond']),
|
||||
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.
|
||||
for (const mode of ['Ecriture', 'Lecture', 'Bloque']) {
|
||||
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);
|
||||
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 libelle = dans('[data-mode-libelle="cadre"]');
|
||||
const libelle = dans('[data-mode-libelle="barre"]');
|
||||
expect(visible(bande)).toBe(true);
|
||||
expect(visible(libelle)).toBe(true);
|
||||
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');
|
||||
expect(charge().tables).toHaveLength(0);
|
||||
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');
|
||||
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);
|
||||
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 () => {
|
||||
|
|
|
|||
|
|
@ -149,9 +149,9 @@
|
|||
font-size: var(--taille-texte);
|
||||
line-height: 1.4;
|
||||
overflow-wrap: anywhere;
|
||||
/* Jamais plus haute que la surface qui la porte (CadreMode) : ouverte
|
||||
sous la grille, dans une fenêtre étroite, elle se montre en entier,
|
||||
et son contenu défile en elle. */
|
||||
/* Jamais plus haute que la surface qui la porte
|
||||
(SurfaceEvenement.svelte) : ouverte sous la grille, dans une fenêtre
|
||||
étroite, elle se montre en entier, et son contenu défile en elle. */
|
||||
max-height: 100cqb;
|
||||
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
|
||||
// plan — les annonces du cadre de mode, avertissements compris, prennent
|
||||
// leur hauteur à la surface —, la vue se déplace d'abord, par le cadrage de
|
||||
// la séance, pour poser la chaise au centre du cadre, au même k.
|
||||
// plan — les annonces de l'écran de l'événement, avertissements compris,
|
||||
// prennent leur hauteur à la surface —, la vue se déplace d'abord, par le
|
||||
// cadrage de la séance, pour poser la chaise au centre du cadre, au même k.
|
||||
async function cliquerChaise(m, table, siege) {
|
||||
const atteinte = () => {
|
||||
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)', () => {
|
||||
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();
|
||||
await deuxImages();
|
||||
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.height).toBeGreaterThan(avant.height);
|
||||
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) {
|
||||
expect(temoin).not.toBeNull();
|
||||
expect(visible(temoin)).toBe(true);
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ function releverEtats(m) {
|
|||
function signatureMode(racine) {
|
||||
const surface = racine.querySelector('[data-mode]');
|
||||
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;
|
||||
const s = getComputedStyle(surface);
|
||||
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`);
|
||||
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})`);
|
||||
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})`);
|
||||
|
|
|
|||
|
|
@ -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-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-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-multiligne', 'import : une ligne sur plusieurs lignes de texte', null],
|
||||
['data-niveau', 'participants : le niveau d’un groupe ou d’un sélecteur', null],
|
||||
|
|
|
|||
Loading…
Reference in a new issue