diff --git a/templates/play.html b/templates/play.html
index fb406600..ab635e79 100644
--- a/templates/play.html
+++ b/templates/play.html
@@ -342,6 +342,26 @@
screenData.elements.filter(function(e){ return !e.parent_id; }).forEach(function(el) {
const wrapper = screenDiv.querySelector('.playElement[data-el-id="' + el.id + '"] .playElementInner');
if (!wrapper || !el.rendered_html || el.rendered_html.indexOf(PLACEHOLDER_OPEN) === -1) return;
+
+ // Avant de regénérer ce sous-arbre depuis le HTML D'ORIGINE (nécessaire
+ // pour ne pas laisser les valeurs d'un mail précédent affichées, voir
+ // plus haut), sauvegarde l'état visuel TRANSITOIRE posé par une action
+ // "Modifier un élément" (jamais enregistré en base — voir
+ // applyElementProperty) sur cet élément ou l'un de ses descendants,
+ // pour le réappliquer après. Sans ça, un panneau rendu visible par
+ // cette action (ex. "mail content") redevenait invisible à CHAQUE
+ // rafraîchissement de données, y compris pour un changement de donnée
+ // sans rapport avec lui — puisque wrapper.innerHTML = html ci-dessous
+ // recrée entièrement ses nœuds à partir de leur état PAR DÉFAUT.
+ const savedState = {};
+ wrapper.querySelectorAll('[data-element-id]').forEach(function(node) {
+ savedState[node.dataset.elementId] = {
+ style: node.getAttribute('style') || '',
+ className: node.className,
+ dataset: Object.assign({}, node.dataset),
+ };
+ });
+
let html = el.rendered_html;
Object.keys(row).forEach(function(fieldName) {
if (fieldName === 'id') return;
@@ -351,6 +371,14 @@
html = html.split(PLACEHOLDER_OPEN + fieldName + PLACEHOLDER_CLOSE).join(tmp.innerHTML);
});
wrapper.innerHTML = html;
+
+ wrapper.querySelectorAll('[data-element-id]').forEach(function(node) {
+ const saved = savedState[node.dataset.elementId];
+ if (!saved) return;
+ node.setAttribute('style', saved.style);
+ node.className = saved.className;
+ Object.assign(node.dataset, saved.dataset);
+ });
});
}