From 9ae7b58767f4286fc633e51d8433079d688a25a3 Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Fri, 25 Sep 2026 17:03:27 +0100 Subject: [PATCH] fix(apk): le formulaire garde la vue 'detail', sinon chaque champ perdait le focus Un gardien defocalise tout ce qui prend le focus hors de l'ecran courant, en comparant 'view' a l'identifiant de l'ecran. Le formulaire vit dans l'ecran 'detail' ; poser view='edit' le faisait donc blurer a chaque focusin - clavier ouvert, pas de curseur, rien ne rentrait. Un drapeau 'editing' dit desormais qu'on modifie, et 'view' continue de nommer l'ecran. Mesure au protocole DevTools sur le telephone : le champ etait bien atteignable et focalise, ce qui a elimine le DOM et le CSS. Co-Authored-By: Claude Opus 5 --- android-client/web/app.html | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/android-client/web/app.html b/android-client/web/app.html index 2185452..b1dee7b 100644 --- a/android-client/web/app.html +++ b/android-client/web/app.html @@ -1076,6 +1076,7 @@ function renderDetail(d) { document.getElementById('kebab').hidden = false; document.getElementById('pencil').hidden = false; document.getElementById('dav').hidden = true; + editing = false; var html = '', i; if (d.totp) html += '
2FA code
' @@ -1398,6 +1399,7 @@ function openNewEntry() { // reutilise pour la creation, et son menu proposait Duplicate et Delete - // qui, cote Delphi, visent la derniere entree ouverte. closeMenu(); + editing = false; document.getElementById('kebab').hidden = true; document.getElementById('pencil').hidden = true; document.getElementById('dav').hidden = true; @@ -1525,6 +1527,10 @@ function openMenu() { /// Ce que le formulaire porte a cet instant, par nom de champ. Sert a le /// rouvrir tel quel apres une action d'icone, qui passe par un enregistrement. var editAgain = null; +/// Le formulaire occupe l'ecran du detail : 'view' reste donc 'detail', et +/// c'est ce drapeau qui dit qu'on y modifie - la fleche et la touche retour +/// s'en servent pour refermer le formulaire avant de quitter l'entree. +var editing = false; function collectEditValues() { var ins = document.querySelectorAll('#fields [data-ef]'), m = {}, i; @@ -1558,13 +1564,12 @@ function openEditEntry() { + (r.m ? ' wrap' : '') + '">' + (r.e === 'folder' ? folderSelect(r.v) : r.m ? '' + + ' enterkeyhint="enter" autocorrect="off" spellcheck="false"' + + ' style="' + FIELD_STYLE + ';height:auto;resize:vertical">' : '') + + ' spellcheck="false" style="' + FIELD_STYLE + '">') + (r.e === 'password' ? genButton('editpwd') : '') + '
'; } @@ -1577,11 +1582,20 @@ function openEditEntry() { + '' + ''; document.getElementById('fields').innerHTML = html; + // Les valeurs APRES le rendu, jamais en attribut : c'est ainsi que + // procedait l'editeur d'une ligne, qui acceptait la frappe. + var fill = document.querySelectorAll('#fields [data-ef]'), fi, fe; + for (fi = 0; fi < fill.length; fi++) { + fe = fill[fi].getAttribute('data-ef'); + for (var fk = 0; fk < detailRows.length; fk++) + if (detailRows[fk].e === fe && fill[fi].tagName !== 'SELECT') + fill[fi].value = detailRows[fk].v; + } document.getElementById('eCancel').addEventListener('click', function () { renderDetail(lastDetail); }); document.getElementById('eSave').addEventListener('click', saveEditEntry); - view = 'edit'; + editing = true; if (editAgain) { var ins = document.querySelectorAll('#fields [data-ef]'), i, f; for (i = 0; i < ins.length; i++) { @@ -1590,7 +1604,9 @@ function openEditEntry() { } editAgain = null; } - send('touch'); + // MEME SORTIE QUE LA CREATION, qui elle accepte la frappe : c'est le seul + // appel qui differait a l'ouverture du formulaire. + send('state?view=detail'); } /// UN SEUL ENVOI, ET SEULEMENT CE QUI A CHANGE : le reste du coffre n'a pas a @@ -1969,6 +1985,7 @@ function goList() { document.body.classList.remove('on-detail'); document.body.classList.add('on-list'); view = 'list'; + editing = false; // Les valeurs en clair partent avec la vue, pas seulement de l'ecran. detailRows = []; document.getElementById('fields').innerHTML = ''; @@ -1977,7 +1994,7 @@ function goList() { // LA FLECHE REFERME D'ABORD LE FORMULAIRE. Elle ramenait a la liste, donc une // modification en cours disparaissait sans qu'on ait vu l'entree. document.getElementById('back').addEventListener('click', function () { - if (view === 'edit') { renderDetail(lastDetail); return; } + if (editing) { renderDetail(lastDetail); return; } goList(); }); @@ -2227,7 +2244,7 @@ var PM = { // Touche retour du telephone : le formulaire d'abord, la liste ensuite. // Delphi ne connait que 'detail' - la page seule sait qu'elle edite. back: function () { - if (view === 'edit') { renderDetail(lastDetail); return; } + if (editing) { renderDetail(lastDetail); return; } if (view === 'detail') goList(); }, cancelEdit: function () { renderDetail(lastDetail); },