Corrige le filtre "élément le plus spécifique" (logique inversée)
Les deux commits précédents (ciblage des éléments imbriqués dans applyOpenRowBindings() et refreshRuntimeData()) n'avaient AUCUN effet visible, confirmé par l'utilisateur après redémarrage du serveur — cause trouvée : leur filtre "ne garder que les éléments les plus spécifiques" vérifiait l'inverse de ce qu'il fallait. Un CONTENEUR contient toujours le HTML de ses descendants dans son propre rendered_html — donc un ancêtre "a le marqueur/placeholder" quasi systématiquement dès qu'un descendant l'a. Le filtre précédent excluait un élément candidat si un de ses ANCÊTRES était candidat — ce qui, vu ce qui précède, ne gardait quasiment jamais que l'ancêtre RACINE de l'écran, reproduisant exactement le bug d'origine (tout l'écran régénéré) que ces commits visaient à corriger. Fix : inversion du sens du filtre — un candidat est désormais exclu si l'un de ses PROPRES DESCENDANTS est aussi candidat (le descendant sera déjà régénéré individuellement, inutile de régénérer aussi son ancêtre). Vérifié par une simulation Node.js reproduisant la structure réelle de l'écran de test (Répéteur niché sous 2 conteneurs, "mail content" sous 2 autres) : la nouvelle logique cible bien uniquement le Répéteur et "mail content", plus jamais le conteneur racine de l'écran. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
f4a7a7340e
commit
5e4e226794
+32
-17
@@ -351,26 +351,33 @@
|
||||
// rechargement de page (flash à vide) à chaque clic sur une ligne.
|
||||
//
|
||||
// Parmi les éléments qui ont un {{champ}} non résolu, on ne garde que
|
||||
// les plus "hauts" dans l'arbre : si un ancêtre ET un de ses
|
||||
// descendants sont tous deux candidats, seul l'ancêtre est régénéré
|
||||
// (son rendered_html inclut déjà ce descendant) — sans ce filtre, le
|
||||
// descendant serait régénéré deux fois, la 2e fois à partir du DOM déjà
|
||||
// à jour de la 1re passe.
|
||||
// les plus SPÉCIFIQUES (les plus profonds) : si un élément ET l'un de
|
||||
// ses DESCENDANTS sont tous deux candidats, seul le descendant est
|
||||
// régénéré (rendered_html d'un conteneur inclut TOUJOURS celui de ses
|
||||
// descendants, donc un conteneur "candidat" ne l'est souvent que parce
|
||||
// qu'un descendant à lui l'est — le garder en plus regénérerait
|
||||
// inutilement tout son sous-arbre, à l'exact opposé du but recherché).
|
||||
// ATTENTION : la version précédente de ce filtre vérifiait l'inverse
|
||||
// (exclure un élément si un ANCÊTRE est candidat) — comme un ancêtre
|
||||
// est presque toujours "candidat" dès qu'un descendant l'est (son HTML
|
||||
// le contient), ce filtre ne gardait en pratique QUE l'ancêtre racine
|
||||
// de l'écran, annulant complètement l'effet recherché par ce correctif.
|
||||
const byId = {};
|
||||
screenData.elements.forEach(function(e){ byId[e.id] = e; });
|
||||
function hasUnresolvedPlaceholder(e) {
|
||||
return !!(e.rendered_html && e.rendered_html.indexOf(PLACEHOLDER_OPEN) !== -1);
|
||||
}
|
||||
function hasCandidateAncestor(e) {
|
||||
function isDescendantOf(e, ancestorId) {
|
||||
let p = e.parent_id ? byId[e.parent_id] : null;
|
||||
while (p) {
|
||||
if (hasUnresolvedPlaceholder(p)) return true;
|
||||
if (p.id === ancestorId) return true;
|
||||
p = p.parent_id ? byId[p.parent_id] : null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const targets = screenData.elements.filter(function(e) {
|
||||
return hasUnresolvedPlaceholder(e) && !hasCandidateAncestor(e);
|
||||
const candidates = screenData.elements.filter(hasUnresolvedPlaceholder);
|
||||
const targets = candidates.filter(function(e) {
|
||||
return !candidates.some(function(other) { return other.id !== e.id && isDescendantOf(other, e.id); });
|
||||
});
|
||||
|
||||
targets.forEach(function(el) {
|
||||
@@ -480,25 +487,33 @@
|
||||
// qui portait le marqueur (le Répéteur imbriqué à l'intérieur)
|
||||
// et se retrouvait régénéré en entier à sa place — potentiellement
|
||||
// l'écran entier (jauges, onglets... compris) s'il n'y avait
|
||||
// qu'un seul gros conteneur racine. Comme pour
|
||||
// applyOpenRowBindings(), on ne garde que les éléments marqués
|
||||
// les plus "hauts" dans l'arbre, pour ne jamais régénérer un même
|
||||
// nœud deux fois.
|
||||
// qu'un seul gros conteneur racine.
|
||||
//
|
||||
// Parmi les éléments marqués, on ne garde que les plus
|
||||
// SPÉCIFIQUES (les plus profonds) : un ancêtre est presque
|
||||
// toujours "marqué" lui aussi dès qu'un descendant l'est, puisque
|
||||
// son rendered_html contient celui de ses descendants — le
|
||||
// garder EN PLUS régénérerait tout son sous-arbre pour rien.
|
||||
// (Une version antérieure de ce filtre vérifiait l'inverse —
|
||||
// exclure un élément si un ANCÊTRE est marqué — ce qui ne
|
||||
// gardait en pratique que l'ancêtre racine de l'écran et
|
||||
// annulait complètement l'effet recherché.)
|
||||
const byId = {};
|
||||
screenData.elements.forEach(function(e){ byId[e.id] = e; });
|
||||
function hasMarker(e) {
|
||||
return !!(e.rendered_html && (e.rendered_html.indexOf('repeaterItem') !== -1 || e.rendered_html.indexOf('jaugeBar') !== -1 || e.rendered_html.indexOf('visibilityGated') !== -1));
|
||||
}
|
||||
function hasMarkedAncestor(e) {
|
||||
function isDescendantOf(e, ancestorId) {
|
||||
let p = e.parent_id ? byId[e.parent_id] : null;
|
||||
while (p) {
|
||||
if (hasMarker(p)) return true;
|
||||
if (p.id === ancestorId) return true;
|
||||
p = p.parent_id ? byId[p.parent_id] : null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
screenData.elements.filter(function(e) {
|
||||
return hasMarker(e) && !hasMarkedAncestor(e);
|
||||
const markedCandidates = screenData.elements.filter(hasMarker);
|
||||
markedCandidates.filter(function(e) {
|
||||
return !markedCandidates.some(function(other) { return other.id !== e.id && isDescendantOf(other, e.id); });
|
||||
}).forEach(function(el) {
|
||||
const target = screenDiv.querySelector('[data-element-id="' + el.id + '"]');
|
||||
if (!target) return;
|
||||
|
||||
Reference in New Issue
Block a user