Corrige le clignotement de la boîte de dialogue entière au lieu du seul texte
Suite du correctif précédent (124f250, marqueur "dataBound") : le
rafraîchissement fonctionnait, mais remplaçait tout l'élément de PREMIER
NIVEAU marqué — pour un Texte "Donnée liée" posé DANS un élément de jeu
réutilisable (ex. une boîte de dialogue), le seul élément de premier
niveau existant est l'EXEMPLAIRE lui-même (ses descendants internes ne
sont jamais des entrées séparées de la scène, voir list_elements.py) :
tout l'exemplaire — voile plein écran, boîte, tout — était donc remplacé
d'un bloc, ce qui le faisait visuellement disparaître puis réapparaître
pour un simple changement de texte à l'intérieur.
Correctif (templates/play.html, refreshRuntimeData()) : avant de
remplacer un élément marqué en bloc, on cherche d'abord, DANS le nouveau
fragment, des descendants plus précis portant eux-mêmes un marqueur en
commentaire ("visibilityGated"/"dataBound" — jamais "repeaterItem"/
"jaugeBar", qui restent volontairement régénérés en bloc, un
comportement déjà correct pour un Répéteur/une Jauge). S'il en existe,
seuls CES éléments précis sont patchés individuellement (retrouvés via
leur propre data-element-id) ; sinon, comportement inchangé (remplace
l'élément entier, cas normal d'un Texte "Donnée liée" posé directement
sur une scène, hors élément de jeu réutilisable).
155 tests toujours au vert (changement purement côté client — le
rendu serveur et la présence du marqueur, eux, étaient déjà couverts par
les tests du commit précédent). Vérifié structurellement (adjacence
</p><!--dataBound--> confirmée dans le rendu réel du projet "test").
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
124f250d2b
commit
ed4dd78dad
+42
-1
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user