From 78a373a536c90cd669eadf3a35aaf26f5a17b235 Mon Sep 17 00:00:00 2001 From: william Date: Fri, 28 Aug 2026 06:30:24 +0200 Subject: [PATCH] =?UTF-8?q?Corrige=20la=20vraie=20cause=20:=20la=20bo?= =?UTF-8?q?=C3=AEte=20de=20dialogue=20restait=20invisible=20DANS=20L'?= =?UTF-8?q?=C3=89DITEUR=20(masqu=C3=A9e=20par=20d=C3=A9faut)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Après vérification serveur, le texte était bel et bien rendu dans le HTML (couleur correcte incluse) — donc pas un souci de contenu ni de couleur. La vraie cause : le widget "Superposition / boîte de dialogue" démarre MASQUÉ par défaut à sa création (display:none, voir default_style_for_widget.py — pour ne pas couvrir tout l'écran dès qu'on le pose). Ce display:none est écrit tel quel dans le HTML aussi bien en mode jouable QUE dans l'éditeur, puisque le rendu de ce widget est partagé par les deux. Résultat : toute la boîte (et donc son contenu, peu importe le texte ou sa couleur) restait invisible dans le CANEVAS DE L'ÉDITEUR dès l'instant de sa création — impossible d'y voir/positionner visuellement ce qu'on pose dedans tant qu'on n'a pas pensé à basculer manuellement "Visibilité" sur "Visible" (puis à y repenser pour la remettre sur "Masqué" avant de tester en jeu). Correctif (render_overlay.py) : dans l'ÉDITEUR uniquement (détecté via le ctx "_forge_play_mode" déjà posé par list_elements.py pour le mode jouable), un "display:flex" est ajouté en dernier dans le style — gagnant sur le "display:none" par défaut (CSS : la dernière déclaration de la même propriété l'emporte). Le mode JOUABLE, lui, continue de respecter ce réglage normalement (masqué tant qu'aucune action ne l'affiche). Nouveau test, confirmé en échec sur l'ancien code puis au vert avec le correctif : vérifie explicitement que le style se termine par "display:flex;" dans l'éditeur et par "display:none;" en mode jouable. 139 tests au vert au total. Jeu de démo régénéré. Co-Authored-By: Claude Sonnet 5 --- screens/rendering/render_overlay.py | 17 +++++++++++++++++ tests/test_confort.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/screens/rendering/render_overlay.py b/screens/rendering/render_overlay.py index c573921f..d5a55814 100644 --- a/screens/rendering/render_overlay.py +++ b/screens/rendering/render_overlay.py @@ -44,6 +44,23 @@ def _render_overlay(el, meta, slug, children_map=None, ctx=None, parent_flex_dir "align-items:center; justify-content:center; background:rgba(0,0,0,0.6);" ) style = base_overlay_style + " " + _style_string(el, parent_flex_direction=parent_flex_direction) + if not (ctx and ctx.get("_forge_play_mode")): + # Dans l'ÉDITEUR (ctx sans _forge_play_mode — voir list_elements.py, + # posé uniquement en mode JOUABLE), ce widget doit rester visible + # quel que soit son réglage de visibilité statique — "Masqué" par + # défaut à SA création (default_style_for_widget.py), pour ne pas + # couvrir tout l'écran dès qu'on le pose. Sans ce forçage, la boîte + # de dialogue reste display:none dans le canevas de l'éditeur, donc + # invisible dès sa création : impossible d'y voir/positionner son + # contenu tant qu'on n'a pas basculé "Visibilité" sur "Visible" à la + # main (puis pensé à la remettre sur "Masqué" avant de tester). Le + # "display:flex;" ajouté ICI, en dernier dans la chaîne de style, + # gagne sur le "display:none" éventuellement posé plus tôt par + # _style_string (CSS : même propriété déclarée deux fois -> la + # dernière l'emporte). Seul le mode JOUABLE respecte réellement ce + # réglage (ou une action "Modifier un élément → Visibilité" qui le + # change en cours de partie).""" + style += " display:flex;" attr_parts = [f'style="{html_lib.escape(style)}"'] for k, v in attrs.items(): diff --git a/tests/test_confort.py b/tests/test_confort.py index 3b657b4e..983e146c 100644 --- a/tests/test_confort.py +++ b/tests/test_confort.py @@ -203,6 +203,35 @@ def test_overlay_box_default_text_color_survives_the_bulma_box_class(client, gam assert "color:#e8eaf0" in box_tag +def test_overlay_stays_visible_in_the_editor_despite_starting_masked(client, game): + """Régression : une "superposition" démarre MASQUÉE par défaut à sa + création (display:none — voir default_style_for_widget.py, pour ne + pas couvrir tout l'écran dès qu'on la pose). Ce display:none est écrit + tel quel dans le HTML, aussi bien en mode jouable QUE dans l'éditeur — + sans forçage, la boîte de dialogue restait donc invisible dans le + CANEVAS DE L'ÉDITEUR dès l'instant où elle était créée, rendant + impossible d'y voir/positionner visuellement titres/textes/boutons + posés à l'intérieur ("j'ai mis un texte dedans mais il ne se voit pas" + — le texte était là, mais toute la boîte qui le contient était + display:none). Seul le mode JOUABLE doit respecter ce réglage.""" + screen_id = _create_screen(client, game) + overlay_id = _add_element(client, game, screen_id, "superposition") + client.post(f"/game/{game}/elements/{overlay_id}/children/add", data={"widget": "texte"}) + + edit_html = client.get(f"/game/{game}/screens/{screen_id}/edit").data.decode() + idx = edit_html.find(f'id="elt-{overlay_id}"') + assert idx != -1 + wrapper_style = re.search(r'style="([^"]*)"', edit_html[edit_html.rfind("