From 7c0f1ed427753755822db0f11da2a86bc8d61e81 Mon Sep 17 00:00:00 2001 From: william Date: Fri, 28 Aug 2026 06:07:08 +0200 Subject: [PATCH] =?UTF-8?q?Corrige=20la=20r=C3=A9gression=20du=20correctif?= =?UTF-8?q?=20overlay=20:=20/elements//geometry=20plantait=20(500)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le correctif précédent (81c31a9) retirait TOUTE position/taille du cadre .canvasElement/.playElement d'une "superposition" pour ne plus piéger son propre z-index:9999 dans un contexte d'empilement local — mais ce même cadre sert aussi, dans l'ÉDITEUR, de prise pour le glisser-déposer/ redimensionnement de ce widget (screen_edit.html). Sans position:absolute + left/top/width/height, ce cadre s'effondre à 0×0 (son contenu réel est en position:fixed, hors flux) : le calcul de geometrie divise alors par une dimension nulle, produit NaN, et JSON.stringify(NaN) envoie littéralement "null" au serveur — qui plantait sur float(None) dans routes/elements/element_geometry.py (500, reproduit par l'utilisateur en posant un template lié à un objet et en essayant de repositionner l'overlay dans l'éditeur). Correctif plus ciblé : le cadre garde position/left/top/width/height comme n'importe quel widget (l'éditeur redevient fonctionnel) — SEUL le z-index est omis pour ce widget précis. position:absolute SANS z-index explicite (donc z-index:auto) ne crée PAS de nouveau contexte d'empilement CSS : le z-index:9999 posé plus profond (render_overlay.py) continue donc de se comparer directement aux autres éléments de l'écran, et gagne toujours — le bug de superposition visuelle (81c31a9) reste corrigé, sans regression sur l'éditeur cette fois. test_confort.py mis à jour (position:absolute attendu, plus d'assertion "position:static") + nouveau test qui appelle directement la route /geometry sur une superposition pour confirmer qu'elle répond 200. 137 tests au vert au total. Co-Authored-By: Claude Sonnet 5 --- filters/element_style_filter.py | 43 +++++++++++++++++++------------ tests/test_confort.py | 45 +++++++++++++++++++++++++-------- 2 files changed, 61 insertions(+), 27 deletions(-) diff --git a/filters/element_style_filter.py b/filters/element_style_filter.py index daf9cbe9..4618102b 100644 --- a/filters/element_style_filter.py +++ b/filters/element_style_filter.py @@ -20,25 +20,36 @@ def _element_style(el): Bug corrigé : le widget "superposition" (render_overlay.py) ignore déjà x/y/width/height et pose lui-même position:fixed; inset:0; z-index:9999 sur SA PROPRE balise — mais tant que CE cadre-ci gardait quand même - "position:absolute; z-index:{z_index}" (le z-index de sa place dans le - canevas, souvent petit), il devenait un élément positionné avec z-index - explicite, donc un NOUVEAU contexte d'empilement CSS — le z-index:9999 - posé plus profond ne se comparait alors plus qu'AU SEIN de ce contexte, - et perdait face au z-index (plus grand) d'un frère ajouté après lui sur - le canevas, qui se retrouvait affiché PAR-DESSUS le dialogue censé tout - couvrir. En ne posant ICI aucune position/z-index pour ce widget (sa - place dans le flux normal, invisible puisque son contenu est en - position:fixed de toute façon), plus aucun contexte d'empilement n'est - créé à ce niveau : le z-index:9999 se compare alors directement aux - autres éléments de l'écran, et gagne toujours.""" - if el.get("widget") == "superposition": - return "position:static;" - return "; ".join([ + "z-index:{z_index}" (le z-index de sa place dans le canevas, souvent + petit), un élément positionné avec un z-index EXPLICITE (même sur ce + cadre, pas sur son contenu) devient un NOUVEAU contexte d'empilement + CSS — le z-index:9999 posé plus profond ne se comparait alors plus + qu'AU SEIN de ce contexte, et perdait face au z-index (plus grand) d'un + frère ajouté après lui sur le canevas, qui se retrouvait affiché + PAR-DESSUS le dialogue censé tout couvrir. + + Première correction tentée (retirer aussi position/left/top/width/ + height ici) : régression dans l'ÉDITEUR — ce même cadre (.canvasElement) + sert aussi de prise pour glisser-déposer/redimensionner CE widget dans + le canevas (voir screen_edit.html), dont le calcul se base sur ses + dimensions réelles ; sans position:absolute + left/top/width/height, ce + cadre s'effondre à 0×0 (son contenu réel est en position:fixed, donc + hors flux), le calcul division par zéro produit NaN, et + JSON.stringify(NaN) donne "null" — element_geometry.py plantait alors + sur float(None). left/top/width/height restent donc posés comme pour + n'importe quel widget (l'éditeur continue de fonctionner normalement) : + SEUL le z-index est omis pour ce widget précis. position:absolute SANS + z-index explicite (donc z-index:auto) ne crée PAS de nouveau contexte + d'empilement — le z-index:9999 posé plus profond se compare alors + directement aux autres éléments de l'écran, et gagne toujours.""" + parts = [ "position:absolute", f"left:{el['x']}%", f"top:{el['y']}%", f"width:{el['width']}%", f"height:{el['height']}%", - f"z-index:{el['z_index']}", - ]) + ";" + ] + if el.get("widget") != "superposition": + parts.append(f"z-index:{el['z_index']}") + return "; ".join(parts) + ";" def _element_transform_style(el): diff --git a/tests/test_confort.py b/tests/test_confort.py index 4d622083..d62894bc 100644 --- a/tests/test_confort.py +++ b/tests/test_confort.py @@ -184,15 +184,19 @@ def test_overlay_widget_renders_fullscreen_fixed_box(client, game): def test_overlay_wrapper_does_not_trap_its_own_z_index(client, game): """Régression : le cadre .playElement/.canvasElement partagé par TOUS les widgets (voir filters/element_style_filter.py) posait quand même - "position:absolute; z-index:" sur la - superposition, MÊME SI son propre contenu (render_overlay.py) ignore - x/y/width/height et pose déjà position:fixed + z-index:9999 lui-même. - Un élément positionné avec un z-index explicite crée un NOUVEAU contexte - d'empilement CSS : le 9999 posé plus profond ne se comparait alors plus - qu'AU SEIN de ce contexte, et perdait face au z-index (plus grand) d'un - élément normal ajouté APRÈS l'overlay sur le canevas — qui s'affichait - donc PAR-DESSUS le dialogue censé tout couvrir. Le cadre ne doit donc - plus poser aucune position/z-index pour ce widget.""" + "z-index:" sur la superposition, MÊME SI son + propre contenu (render_overlay.py) ignore x/y/width/height et pose déjà + position:fixed + z-index:9999 lui-même. Un élément positionné avec un + z-index EXPLICITE crée un NOUVEAU contexte d'empilement CSS : le 9999 + posé plus profond ne se comparait alors plus qu'AU SEIN de ce contexte, + et perdait face au z-index (plus grand) d'un élément normal ajouté + APRÈS l'overlay sur le canevas — qui s'affichait donc PAR-DESSUS le + dialogue censé tout couvrir. Le cadre garde position/left/top/width/ + height comme tout widget (l'éditeur en a besoin pour glisser-déposer/ + redimensionner ce cadre — les retirer a fait planter element_geometry + en régression), mais n'écrit plus DU TOUT de z-index pour ce widget : + position:absolute avec z-index:auto (omis) ne crée pas de contexte + d'empilement, donc le 9999 se compare directement aux autres éléments.""" screen_id = _create_screen(client, game) overlay_id = _add_element(client, game, screen_id, "superposition") # Ajouté APRÈS l'overlay -> z_index plus grand que le sien. @@ -204,8 +208,27 @@ def test_overlay_wrapper_does_not_trap_its_own_z_index(client, game): assert idx != -1 tag_start = html.rfind("