From 0f90b816fc98a418c6f828f7fa4ad28ae3ae974c Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Fri, 25 Sep 2026 15:05:58 +0100 Subject: [PATCH] fix(apk): le crayon par ligne disparait, l'edition passe par le formulaire L'editeur d'une ligne n'a plus de bouton : sa machinerie part avec lui. Seule la liste des dossiers en est gardee (folderSelect), pour que le champ Folder du formulaire reste un choix et non une faute de frappe. Co-Authored-By: Claude Opus 5 --- android-client/web/app.html | 121 +++++------------------------------- 1 file changed, 14 insertions(+), 107 deletions(-) diff --git a/android-client/web/app.html b/android-client/web/app.html index 52f962d..bfd8405 100644 --- a/android-client/web/app.html +++ b/android-client/web/app.html @@ -1093,8 +1093,6 @@ function renderDetail(d) { + (r.a === undefined ? '' : '') - + (r.e ? '' : '') + ''; } document.getElementById('fields').innerHTML = html; @@ -1136,43 +1134,6 @@ document.getElementById('fields').addEventListener('click', function (ev) { if (copy === 'totp') { send('copy?f=totp'); return; } if (copy === 'row') { send('copy?f=row&k=' + t.getAttribute('data-k')); return; } - var edit = t.getAttribute('data-edit'); - if (edit !== null) { openEditor(edit); return; } - if (t.getAttribute('data-editshow') !== null) { - // Masque par defaut, revelable a la demande : on tape un mot de passe - // qu'on ne peut relire nulle part ailleurs, mais il n'a pas a rester - // expose a l'ecran pendant qu'on cherche le bouton. - var iv = document.getElementById('editval'); - var hid = iv.type === 'password'; - iv.type = hid ? 'text' : 'password'; - t.innerHTML = ico(hid ? 'eyeOff' : 'eye', hid ? 'Hide' : 'Show'); - return; - } - if (t.getAttribute('data-editcancel') !== null) { renderDetail(lastDetail); return; } - if (t.getAttribute('data-editsave') !== null) { - var input = document.getElementById('editval'); - if (!input) return; - // VIDER EST LEGITIME sur un site ou un identifiant - pas sur un mot de - // passe, ou ce serait presque toujours une fausse manoeuvre. Le refus se - // dit, sinon le bouton semble ne pas prendre l'appui. - if (!input.value && editField === 'password') { - toast('An empty password is not saved'); - return; - } - // DIRE QUE CA TRAVAILLE. L'enregistrement dechiffre, rechiffre et publie : - // une a deux secondes pendant lesquelles rien ne bougeait, et le bouton - // semblait n'avoir pas pris l'appui. La coche cede la place a un arc qui - // tourne - immobile, elle laisserait croire que c'est fini. - t.innerHTML = ico('loader', 'Saving'); - t.classList.add('spin'); - t.disabled = true; - var cancel = document.querySelector('[data-editcancel]'); - if (cancel) cancel.disabled = true; - input.disabled = true; - send('setfield?f=' + encodeURIComponent(editField) - + '&v=' + encodeURIComponent(input.value)); - return; - } }); /// LE DOSSIER SE CHOISIT, il ne se tape pas. @@ -1184,40 +1145,22 @@ document.getElementById('fields').addEventListener('click', function (ev) { /// /// 'All' est ajoute d'office : c'est le dossier par defaut du poste, et il ne /// figure pas toujours dans la liste. -function editorControl(k) { - var val = detailRows[k].v; - var style = ' style="margin:0;flex:1;min-width:0;width:auto"'; - // UNE ZONE DE TEXTE POUR CE QUI TIENT SUR PLUSIEURS LIGNES. Un - // applique la sanitisation de HTML et retire les retours a la ligne en - // silence : le corps d'une note y perdait sa mise en forme, et la perte - // partait au depot a l'enregistrement suivant. - if (detailRows[k].m) - return ''; - if (editField !== 'folder') - return ''; - - var names = ['All'], i; +/// La liste des dossiers du coffre, pour le champ 'folder' du formulaire. +/// Le dossier courant y est ajoute s'il n'y figure plus - renomme ailleurs, ou +/// venu d'un import -, sinon l'ouvrir suffirait a le remplacer en silence. +function folderSelect(val) { + var names = ['All'], i, html; for (i = 0; i < folders.length; i++) if (folders[i] && names.indexOf(folders[i]) < 0) names.push(folders[i]); - // Le dossier courant peut ne plus figurer dans la liste - il a ete renomme - // ailleurs, ou l'entree vient d'un import. Le proposer quand meme evite de - // le remplacer silencieusement en ouvrant simplement l'editeur. if (val && names.indexOf(val) < 0) names.push(val); - - var html = ''; for (i = 0; i < names.length; i++) html += ''; // CHOISIR NE SUFFIT PAS : le premier dossier d'un coffre n'existe pas encore, // et rien ne permettait de le nommer. Cette option echange la liste contre un - // champ libre, sans quitter l'editeur. + // champ libre, sans quitter le formulaire. html += ''; return html + ''; } @@ -1227,11 +1170,12 @@ var NEW_FOLDER = '\u0001new'; // Le choix "+ new folder" remplace la liste par un champ. Delegue sur #fields // parce que le controle nait et meurt avec l'editeur. document.getElementById('fields').addEventListener('change', function (ev) { - if (ev.target.id !== 'editval' || ev.target.value !== NEW_FOLDER) return; + if (ev.target.getAttribute('data-ef') !== 'folder' + || ev.target.value !== NEW_FOLDER) return; var line = ev.target.parentNode; var input = document.createElement('input'); input.className = 'field-in'; - input.id = 'editval'; + input.setAttribute('data-ef', 'folder'); input.setAttribute('placeholder', 'folder name'); input.setAttribute('autocomplete', 'off'); input.setAttribute('autocapitalize', 'none'); @@ -1256,44 +1200,6 @@ document.getElementById('fields').addEventListener('change', function (ev) { input.focus(); }); -// EDITEUR EN PLACE, pas window.prompt : une invite JavaScript demande au -// moteur un WebChromeClient que FMX ne fournit pas, et prompt() rend alors -// null sans un mot - le bouton semblerait ne rien faire. -// -// La valeur s'affiche EN CLAIR pendant la saisie. On tape un mot de passe -// qu'on ne peut pas relire ailleurs ; le masquer ferait valider a l'aveugle -// une frappe qu'aucune confirmation ne rattrape. -var editField = ''; - -function openEditor(k) { - var row = document.querySelector('[data-v="' + k + '"]'); - if (!row) return; - // 'e' porte le nom du champ dans l'instantane, pas un booleen : c'est Delphi - // qui decide de ce qui se modifie, la page n'a pas a le deduire d'un libelle. - editField = detailRows[k].e || ''; - if (!editField) return; - var line = row.parentNode; - line.classList.toggle('wrap', !!detailRows[k].m); - line.innerHTML = editorControl(k) - + (editField === 'password' ? genButton('editval') : '') - // Show n'a de sens que sur un champ masque. Sur un site en clair il - // n'aurait rien a reveler - et l'inverse : il le CACHERAIT. - // - // LES TROIS EN ICONES, comme les lignes au-dessus : ils partageaient la - // rangee avec le champ de saisie, et trois mots y laissaient a peine de - // quoi lire ce qu'on tape. La croix et la coche se lisent sans traduction. - + (detailRows[k].s ? '' : '') - + '' - + ''; - var input = document.getElementById('editval'); - input.value = detailRows[k].v; - input.focus(); - send('touch'); -} - // RIEN NE GLISSE DE COTE, sauf la bande de dossiers. // // overflow:hidden n'interdit que le GESTE. Le moteur, lui, garde le droit de @@ -1378,8 +1284,9 @@ addEventListener('keydown', function (ev) { if (el.tagName === 'TEXTAREA') return; ev.preventDefault(); el.blur(); - if (el.id !== 'editval') return; - var save = document.querySelector('[data-editsave]'); + // Entree sur un champ du formulaire = enregistrer, comme la coche d'avant. + if (!el.getAttribute('data-ef')) return; + var save = document.getElementById('eSave'); if (save && !save.disabled) save.click(); }); @@ -1593,7 +1500,7 @@ function openEditEntry() { if (!r.e) continue; html += '
' + esc(r.c) + '
' - + (r.m + + (r.e === 'folder' ? folderSelect(r.v) : r.m ? ''