Base de travail V7.8 reprise du répertoire de travail

Commit technique : reproduit à l'identique l'état non commité de la copie
de travail (sécurisation V7.8, CSP à nonce, Session, migration des droits)
afin que le travail d'ergonomie qui suit soit isolable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
PTA
2026-08-10 16:32:10 +02:00
parent 57bd8da5c8
commit 66cc8c8ade
30 changed files with 1015 additions and 141 deletions

View File

@@ -5,12 +5,9 @@
if (!PTA) return;
const { readJsonResponse, apiErrorMessage, escapeHtml, formatDate } = PTA.utils;
const el = (id) => document.getElementById(id);
const escapeAttr = (value) => String(value ?? '')
.replaceAll('&', '&amp;')
.replaceAll('\"', '&quot;')
.replaceAll("'", '&#039;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;');
// escapeHtml échappe désormais aussi les guillemets : une seule
// implémentation partagée, valable en contexte texte comme attribut.
const escapeAttr = escapeHtml;
let current = null;
function show(text, type = 'info') {

View File

@@ -44,10 +44,21 @@
const dayNames = ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi'];
/**
* Échappe une valeur pour l'insertion dans du HTML, texte ET attribut.
*
* La sérialisation via textContent/innerHTML n'échappe ni " ni ' : elle est
* sûre entre deux balises, mais permet de sortir d'un attribut value="…" ou
* title="…". PTA insère des libellés de vacances, des noms de lieux et des
* commentaires dans des attributs : les guillemets doivent être échappés.
*/
function escapeHtml(value) {
const div = document.createElement('div');
div.textContent = String(value ?? '');
return div.innerHTML;
return String(value ?? '')
.replaceAll('&', '&amp;')
.replaceAll('<', '&lt;')
.replaceAll('>', '&gt;')
.replaceAll('"', '&quot;')
.replaceAll("'", '&#039;');
}
function showMessage(text, type = 'info') {

View File

@@ -195,7 +195,7 @@
templateSelect.disabled = false;
templateSelect.innerHTML = '<option value="">Choisir une semaine type</option>' + templates.map((template) => (
`<option value="${template.id}">${escapeHtml(template.name)}</option>`
`<option value="${Number(template.id)}">${escapeHtml(template.name)}</option>`
)).join('');
renderSelectedTemplateDetails();
}
@@ -364,7 +364,7 @@
}
periodTemplateSelect.disabled = false;
periodTemplateSelect.innerHTML = '<option value="">Choisir une semaine type</option>' + templates.map((template) => (
`<option value="${template.id}">${escapeHtml(template.name)}</option>`
`<option value="${Number(template.id)}">${escapeHtml(template.name)}</option>`
)).join('');
}