Build and deploy / test-python (push) Failing after 59s
Build and deploy / test-js (push) Successful in 50s
Build and deploy / lint-python (push) Failing after 59s
Build and deploy / lint-js (push) Failing after 1m1s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 59s
Cinquieme mini-jeu du support de formation : le createur ecrit une situation initiale, definit 2 a 4 choix, indique lequel est le bon, et redige la consequence de chaque choix. Plusieurs scenarios peuvent etre crees, joues dans l'ordre d'ecriture (jamais melanges, contrairement a Association/Memory/Mots meles : ce sont des mises en situation sequentielles). En Apercu, l'apprenant lit la situation, choisit une option, decouvre la consequence de SON choix et si c'etait le bon, puis passe au scenario suivant. Comme Association/Memory/Mots meles, le dernier scenario reste affiche une fois repondu : seul le bouton Recommencer apparait, jamais un ecran de resultat separe (reserve au Quiz). Reutilise les classes visuelles du Quiz (docQuizOptions/ docQuizFeedback/docQuizNextBar) plutot que de dupliquer ces regles. Verifie via simulation DOM reelle (jsdom) : progression entre plusieurs scenarios, choix correct/incorrect avec revelation de la bonne reponse, comportement de fin de partie, panneau Proprietes (ajout/suppression de scenario, changement du nombre de choix, selection du bon choix). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
123 lines
7.8 KiB
Markdown
123 lines
7.8 KiB
Markdown
# document_engine/rendering/
|
|
|
|
Rendu HTML du document — point d'entrée unique utilisé à la fois par le
|
|
canevas d'édition et par le Mode Aperçu (même fonction, voir
|
|
`docs/plan/PLAN.md` — "Aperçu réel").
|
|
|
|
## `render_document(elements: list[dict[str, Any]]) -> str`
|
|
Assemble le document entier à partir de la liste à plat renvoyée par
|
|
`document_engine.list_document_elements` : regroupe les éléments par
|
|
`parent_id`, puis rend récursivement les éléments top-niveau dans
|
|
l'ordre (une rangée rend elle-même ses propres enfants côte à côte).
|
|
- **Retour** : le HTML complet du document.
|
|
- **Exceptions** : aucune.
|
|
|
|
## `render_document_element(el: dict[str, Any], children_by_parent: dict[int | None, list[dict[str, Any]]]) -> str`
|
|
HTML d'un seul élément — dispatch par dict (table `_RENDERERS`) selon
|
|
`el["kind"]`, plutôt qu'un enchaînement de `if` (mirroir de l'esprit de
|
|
`game_engine/scenes/render_scene_object.py`). `children_by_parent` est le
|
|
regroupement précalculé par `render_document`, transmis pour que les
|
|
rangées puissent rendre récursivement leurs enfants sans refaire le
|
|
regroupement à chaque appel.
|
|
- **Retour** : le HTML de cet élément (et de ses enfants s'il s'agit
|
|
d'une rangée).
|
|
- **Exceptions** : aucune ; un `kind` inconnu produit un bloc
|
|
`docUnknown` visible plutôt qu'une levée d'exception.
|
|
|
|
### Détail des rendus par catégorie (fonctions privées, table de dispatch)
|
|
- **Rangée** (`row`) : conteneur flex (`gap`/`align-items`/
|
|
`justify-content` réels depuis `attributes`), enfants rendus
|
|
récursivement.
|
|
- **Formes** (`rectangle`/`cercle`/`triangle`/`trait`) : `<div>` positionné
|
|
en absolu (`x`/`y`/`width`/`height`/`rotation`/`z_index` réels) contenant
|
|
un SVG (`rect`/`circle`/`polygon`/`line` selon le type).
|
|
- **Texte** (`titre`/`paragraphe`) : `<div>` stylé selon `style` (préréglage
|
|
taille/graisse/interligne) et `bold`/`italic`/`underline`/`align`/`color`.
|
|
- **Image** : `<img>`, ou un bloc placeholder si `src` est vide.
|
|
- **Bouton** : `<button>` avec son `label` et un `data-target` optionnel.
|
|
- **Quiz** : toujours une carte résumant la config réelle (nombre de
|
|
questions, total des points via `quiz_total_points`, minuteur si
|
|
activé) — sanitizée (`sanitize_quiz_config`) avant lecture, jamais un
|
|
rendu direct d'`attributes` brut. Si au moins une question existe,
|
|
s'y ajoute (fonction privée `_render_quiz_player`) le questionnaire
|
|
RÉEL et interactif affiché en Mode Aperçu (voir docs/plan/maquettes/
|
|
document-formation-web.html — référence visuelle), masqué en édition
|
|
par CSS (`.docQuizPlayer`, voir static/document/document-editor.css) :
|
|
les questions sont embarquées en JSON dans un attribut `data-quiz-config`
|
|
(jamais un `<script>` par élément), échappé pour l'HTML
|
|
(`html.escape(..., quote=True)`) — static/document/js/document-editor.js
|
|
lit cet attribut et gère tout le déroulé (réponse/score/question
|
|
suivante/résultat) côté client, sans aucun aller-retour serveur.
|
|
- **Association** : toujours une carte résumant la config réelle (nombre
|
|
de paires) — sanitizée (`sanitize_association_config`) avant lecture.
|
|
Si au moins une paire existe, s'y ajoute (fonction privée
|
|
`_render_association_player`) le plateau de glisser-déposer RÉEL et
|
|
interactif affiché en Mode Aperçu, masqué en édition par CSS
|
|
(`.docAssocPlayer`) : les deux colonnes (termes/correspondances) sont
|
|
mélangées INDÉPENDAMMENT (`random.shuffle`, mélange d'affichage — voir
|
|
`CODE_QUALITY.md`) puis embarquées en JSON dans un attribut
|
|
`data-assoc-config`, échappé pour l'HTML — même principe que le Quiz,
|
|
aucun aller-retour serveur pendant qu'on joue. Contrairement au Quiz,
|
|
le plateau reste affiché en permanence une fois la partie terminée :
|
|
seul le bouton "Recommencer" (`.docMinigameRestartBar`, partagé avec
|
|
Memory) apparaît, jamais d'écran de résultat séparé qui le
|
|
remplacerait.
|
|
- **Memory** : toujours une carte résumant la config réelle (nombre de
|
|
cartes définies, mode paire/simple) — sanitizée
|
|
(`sanitize_memory_config`) avant lecture. Si au moins une carte existe,
|
|
s'y ajoute (fonction privée `_render_memory_player`) le plateau de
|
|
retournement RÉEL et interactif : en mode `"paire"`, chaque carte
|
|
définie est DUPLIQUÉE en deux instances partageant le même
|
|
`card_index` (l'appariement se fait dessus, classique Memory) ; en mode
|
|
`"single"`, une seule instance par carte (simple retournement, sans
|
|
appariement). Les instances sont mélangées (`random.shuffle`, mélange
|
|
d'affichage — voir `CODE_QUALITY.md`) puis embarquées en JSON dans un
|
|
attribut `data-memory-config`, échappé pour l'HTML — même principe que
|
|
le Quiz/l'Association, aucun aller-retour serveur pendant qu'on joue.
|
|
Comme l'Association, le plateau reste affiché une fois toutes les
|
|
paires trouvées (ou toutes les cartes révélées en mode `"single"`) :
|
|
seul le bouton "Recommencer" (`.docMinigameRestartBar`) apparaît.
|
|
- **Mots mêlés** : toujours une carte résumant la config réelle (nombre
|
|
de mots) — sanitizée (`sanitize_mots_config`) avant lecture. Si au
|
|
moins un mot existe, s'y ajoute (fonction privée `_render_mots_player`)
|
|
la grille RÉELLE et interactive. La grille ET la position exacte de
|
|
chaque mot sont calculées ICI côté serveur (`_build_mots_grid`, jamais
|
|
recalculées côté client) : chaque mot est placé horizontalement,
|
|
verticalement, ou en diagonale (haut-gauche→bas-droite ou
|
|
haut-droite→bas-gauche — jamais à l'envers), les lettres restantes
|
|
tirées au hasard (`random.choice`/`random.randint`, tirage de jeu —
|
|
voir `CODE_QUALITY.md`) ; si un mot ne trouve pas sa place, la grille
|
|
entière est agrandie et le placement retenté depuis zéro, plutôt que
|
|
d'abandonner silencieusement ce mot. Le tout (grille + coordonnées de
|
|
chaque mot) est embarqué en JSON dans un attribut `data-mots-config`,
|
|
échappé pour l'HTML — même principe que les autres mini-jeux, aucun
|
|
aller-retour serveur pendant qu'on joue : `static/document/js/
|
|
document-editor.js` compare les coordonnées EXACTES sélectionnées par
|
|
l'apprenant à celles de chaque mot (jamais une simple comparaison de
|
|
texte, qui se tromperait sur des lettres partagées entre deux mots qui
|
|
se croisent). Comme l'Association/Memory, la grille reste affichée une
|
|
fois tous les mots trouvés : seul le bouton "Recommencer"
|
|
(`.docMinigameRestartBar`) apparaît.
|
|
- **Scénario** : toujours une carte résumant la config réelle (nombre de
|
|
scénarios) — sanitizée (`sanitize_scenario_config`) avant lecture. Si
|
|
au moins un scénario existe, s'y ajoute (fonction privée
|
|
`_render_scenario_player`) la mise en situation RÉELLE et interactive :
|
|
l'apprenant lit la situation, choisit une option, découvre la
|
|
conséquence de SON choix et si c'était le bon, puis passe au scénario
|
|
suivant. Les scénarios gardent l'ORDRE d'écriture du créateur (jamais
|
|
mélangés, contrairement à Association/Memory/Mots mêlés — ce sont des
|
|
mises en situation séquentielles, pas des éléments à faire
|
|
correspondre/retrouver). Réutilise les classes visuelles du Quiz
|
|
(`.docQuizOptions`/`.docQuizFeedback`/`.docQuizNextBar`/
|
|
`.docQuizQuestionText`) plutôt que de dupliquer ces règles. Embarqué en
|
|
JSON dans un attribut `data-scenario-config`, échappé pour l'HTML —
|
|
même principe que les autres mini-jeux, aucun aller-retour serveur
|
|
pendant qu'on joue. Comme l'Association/Memory/Mots mêlés (mais
|
|
contrairement au Quiz), le dernier scénario reste affiché une fois
|
|
répondu : seul le bouton "Recommencer" (`.docMinigameRestartBar`)
|
|
apparaît.
|
|
- **Autres mini-jeux** (`zones`) : carte placeholder portant le libellé
|
|
du type (voir `document_engine/labels/element_kind_labels.py`) —
|
|
emplacement réservé, formulaire de contenu dédié hors périmètre de
|
|
cette passe.
|