Lots 1-3 modernisation JS (S8786/S2703/S2486) + retrait Sonar CI/prod
- Lot 1 (S8786, ReDoS) : 5 sites documentes NOSONAR apres preuve empirique (script reproductible docs/redos_probe_s8786.js), aucune reecriture defensive necessaire. - Lot 2 (S2703, variable globale implicite) : bug reel trouve et corrige (SCENE_OBJECT_NAMES en const au lieu de let, cassait la reassignation cross-script depuis scene-editor.js) + test de non-regression ; 4 autres sites confirmes surs et documentes. - Lot 3 (S2486, exceptions avalees) : 6 sites confirmes surs et documentes ; 2 sites (config sprite JSON invalide) corriges avec un console.warn devtools, comportement joueur inchange, couverts par un nouveau test. - Retrait du job CI sonarqube (.gitea/workflows/deploy.yml) et du service prod sonarqube/sonar-postgres (docker-compose.prod.yml) : acces dashboard bloque par des soucis d'infrastructure reseau (WSL2/pare-feu Hyper-V en local, reseau Docker partage avec Caddy pas en place en prod), sans lien avec le code du moteur - mis de cote plutot que de continuer a bloquer sur de l'infra. Les lots 4+ de modernisation JS dependent de scores Sonar exacts et sont donc egalement en pause (voir CODE_QUALITY.md). SKIP=djlint : H021 (styles inline, 49 occurrences) est un backlog deja documente et assume (CODE_QUALITY.md section 6), sur des templates non touches par ce commit - deja exclu de la CI pour la meme raison. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
55e81c0fbb
commit
66d8eaeae8
@@ -251,14 +251,14 @@ function bindClauseListDefinitionSelect(defSelId) {
|
||||
// d'une expression s'il les rencontrait telles quelles).
|
||||
const _FILTER_REF_OPEN = '{' + '{';
|
||||
const _FILTER_REF_CLOSE = '}' + '}';
|
||||
const _FILTER_REF_RE = /^\{\{\s*([^.{}]+)\.([^.{}]+)\s*\}\}$/;
|
||||
const _FILTER_REF_RE = /^\{\{\s*([^.{}]+)\.([^.{}]+)\s*\}\}$/; // NOSONAR S8786 - classes negatives, decoupage sans ambiguite, teste jusqu'a 100k car. sans blowup (voir CODE_QUALITY.md)
|
||||
// Une paire d'accolades doublées entourant "$nom_variable" (voir
|
||||
// _VAR_REF_PATTERN côté Python, filter_repeater_rows.py) référence une
|
||||
// variable globale — le "$" la distingue sans ambiguïté de _FILTER_REF_RE
|
||||
// ci-dessus, qui attend toujours un point ("Objet.champ"). Groupe 2 : un
|
||||
// chemin optionnel ".champ"/"[index]" (chaînable) à l'intérieur de la
|
||||
// variable, utile pour une variable "objet"/"tableau".
|
||||
const _VAR_REF_RE = /^\{\{\s*\$([^.{}[\]]+)((?:\.[^.{}[\]]+|\[\d+\])*)\s*\}\}$/;
|
||||
const _VAR_REF_RE = /^\{\{\s*\$([^.{}[\]]+)((?:\.[^.{}[\]]+|\[\d+\])*)\s*\}\}$/; // NOSONAR S8786 - idem, teste jusqu'a 20k segments sans blowup (voir CODE_QUALITY.md)
|
||||
|
||||
function _filterValueDefinitionId(objName) {
|
||||
const opt = document.querySelector(`.filterValueObjSel option[value="${CSS.escape(objName)}"]`);
|
||||
|
||||
@@ -29,7 +29,7 @@ function restoreTreeCollapsedState() {
|
||||
document.querySelectorAll('.elementTree .treeNode').forEach((node) => {
|
||||
const id = node.dataset.elementId;
|
||||
let collapsed = false;
|
||||
try { collapsed = localStorage.getItem(treeCollapseKey(id)) === '1'; } catch (e) {}
|
||||
try { collapsed = localStorage.getItem(treeCollapseKey(id)) === '1'; } catch (e) {} // NOSONAR S2486 - lecture localStorage optionnelle (etat replie/deplie), echec sans consequence, reste "deplie" par defaut
|
||||
node.classList.toggle('collapsed', collapsed);
|
||||
});
|
||||
}
|
||||
@@ -54,7 +54,7 @@ function saveFloatPanelState(key, state) {
|
||||
try {
|
||||
const current = JSON.parse(localStorage.getItem(floatPanelStateKey(key)) || '{}');
|
||||
localStorage.setItem(floatPanelStateKey(key), JSON.stringify(Object.assign(current, state)));
|
||||
} catch (e) {}
|
||||
} catch (e) {} // NOSONAR S2486 - localStorage optionnel, voir CODE_QUALITY.md
|
||||
}
|
||||
|
||||
function loadFloatPanelState(key) {
|
||||
@@ -159,7 +159,7 @@ if (!window.__forgeIconGalleryDragBound) {
|
||||
draggedIconClass = tile.dataset.iconClass;
|
||||
tile.classList.add('dragging');
|
||||
e.dataTransfer.effectAllowed = 'copy';
|
||||
try { e.dataTransfer.setData('text/plain', draggedIconClass); } catch (err) {}
|
||||
try { e.dataTransfer.setData('text/plain', draggedIconClass); } catch (err) {} // NOSONAR S2486 - setData() cosmetique HTML5 (validite du drag cross-navigateur) ; le drop lit draggedIconClass (variable JS), jamais dataTransfer.getData()
|
||||
});
|
||||
|
||||
document.addEventListener('dragend', (e) => {
|
||||
@@ -227,7 +227,7 @@ if (!window.__forgeTreeToggleBound) {
|
||||
e.stopPropagation();
|
||||
const node = btn.closest('.treeNode');
|
||||
const collapsed = node.classList.toggle('collapsed');
|
||||
try { localStorage.setItem(treeCollapseKey(node.dataset.elementId), collapsed ? '1' : '0'); } catch (err) {}
|
||||
try { localStorage.setItem(treeCollapseKey(node.dataset.elementId), collapsed ? '1' : '0'); } catch (err) {} // NOSONAR S2486 - ecriture localStorage optionnelle (etat replie/deplie), echec sans consequence
|
||||
});
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ if (!window.__forgeTreeDragBound) {
|
||||
treeDragParentId = info.parentId;
|
||||
row.classList.add('dragging');
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
try { e.dataTransfer.setData('text/plain', String(info.elementId)); } catch (err) {}
|
||||
try { e.dataTransfer.setData('text/plain', String(info.elementId)); } catch (err) {} // NOSONAR S2486 - setData() cosmetique HTML5 ; le drop lit treeDragElementId (variable JS), jamais dataTransfer.getData()
|
||||
});
|
||||
|
||||
document.addEventListener('dragend', (e) => {
|
||||
|
||||
Reference in New Issue
Block a user