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("