diff --git a/templates/play.html b/templates/play.html
index b82160f9..206db1aa 100644
--- a/templates/play.html
+++ b/templates/play.html
@@ -584,6 +584,31 @@
}
return false;
}
+ // "visibilityGated"/"dataBound" sont posés comme un COMMENTAIRE
+ // HTML juste après la balise concernée (voir _mark() dans
+ // render_element_html.py) — jamais comme une classe CSS, à la
+ // différence de "repeaterItem"/"jaugeBar" (qui, eux, désignent
+ // un widget à régénérer EN BLOC, lignes/valeur comprises, un
+ // comportement déjà correct pour ces deux-là). Repérer ce
+ // commentaire permet de retrouver, à l'intérieur d'un fragment
+ // fraîchement rendu, l'élément PRÉCIS qui a changé — même s'il
+ // est niché dans un exemplaire d'élément de jeu réutilisable
+ // (ex. un Texte "Donnée liée" à l'intérieur d'une boîte de
+ // dialogue), où lui seul porte l'attribut data-element-id qui
+ // l'identifie, son marqueur ne remontant jusqu'au SEUL élément
+ // de premier niveau existant (l'exemplaire) que parce que son
+ // HTML est imbriqué dans le sien.
+ const COMMENT_MARKERS = ['visibilityGated', 'dataBound'];
+ function findCommentMarkedDescendants(root) {
+ const found = [];
+ root.querySelectorAll('[data-element-id]').forEach(function(node) {
+ const sib = node.nextSibling;
+ if (sib && sib.nodeType === Node.COMMENT_NODE && COMMENT_MARKERS.indexOf(sib.data) !== -1) {
+ found.push(node);
+ }
+ });
+ return found;
+ }
const markedCandidates = screenData.elements.filter(hasMarker);
markedCandidates.filter(function(e) {
return !markedCandidates.some(function(other) { return other.id !== e.id && isDescendantOf(other, e.id); });
@@ -593,7 +618,23 @@
const container = document.createElement('div');
container.innerHTML = el.rendered_html;
const newNode = container.firstElementChild;
- if (newNode) target.replaceWith(newNode);
+ if (!newNode) return;
+ const innerMarked = findCommentMarkedDescendants(newNode);
+ if (innerMarked.length) {
+ // Des éléments plus précis existent À L'INTÉRIEUR (ex. un
+ // Texte "Donnée liée" posé dans un élément de jeu
+ // réutilisable) : on ne patche QUE ceux-là, en préservant
+ // tout le reste — une boîte de dialogue ne doit ni
+ // disparaître ni réapparaître juste parce qu'un texte à
+ // l'intérieur a changé.
+ innerMarked.forEach(function(innerNode) {
+ const innerId = innerNode.getAttribute('data-element-id');
+ const liveInner = target.querySelector('[data-element-id="' + innerId + '"]');
+ if (liveInner) liveInner.replaceWith(innerNode);
+ });
+ } else {
+ target.replaceWith(newNode);
+ }
});
applyOpenRowBindings();
} catch (err) {