From 248cdafa49202fc564264280172f9124ed2bb852 Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Sat, 22 Aug 2026 14:33:58 +0100 Subject: [PATCH] fix(android): a note can be written on several lines, and Enter means Enter The creation form still put a note's body behind a single-line input, so one could read and edit multi-line text but never create it - the note had to be created, then reopened to be laid out. And the newline could not be typed at all: the handler that turns the validate key into "fold the keyboard" applied to every field. That rule exists because in a one-line field the key can only jump to the next one, and the next one sat on an off-screen view - which is how the unclosable keyboard happened. In a text area, Enter means Enter. It is the third time that handler has misfired by treating "any field" as one thing; it now carries its three exceptions explicitly. Two things fixed in the same code, since they lived there: Rows were recognised BY THEIR LABEL - prose. Renaming a caption would have been enough for this code to stop acting on it, silently. They go by id now. And what is already typed survives a change of kind. Replacing the control without carrying the value over would have wiped the entry for a mere change of mind between Login and Note. --- android-client/web/app.html | 81 ++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/android-client/web/app.html b/android-client/web/app.html index 2855cd0..d514f2e 100644 --- a/android-client/web/app.html +++ b/android-client/web/app.html @@ -852,7 +852,7 @@ function editorControl(k) { // partait au depot a l'enregistrement suivant. if (detailRows[k].m) return ''; if (editField !== 'folder') @@ -1013,6 +1013,11 @@ addEventListener('keydown', function (ev) { var el = ev.target; if (ev.key !== 'Enter' || !el.classList || !el.classList.contains('field-in')) return; + // DANS UNE ZONE DE TEXTE, ENTREE VEUT DIRE ENTREE. Cette regle vaut pour les + // champs d'une ligne, ou la touche ne peut que sauter au suivant ; appliquee + // au corps d'une note, elle rendait impossible d'y sauter une ligne - le + // clavier semblait ne pas en avoir la touche. + if (el.tagName === 'TEXTAREA') return; ev.preventDefault(); el.blur(); if (el.id !== 'editval') return; @@ -1042,12 +1047,28 @@ function newFolderField() { return html + ''; } -function newField(id, label, type) { - return '
' + label + '
' - + '
' - + '
'; +var FIELD_STYLE = 'margin:0;flex:1;min-width:0;width:auto'; + +function newField(id, label, rowId) { + return '
' + label + + '
'; +} + +/// LE CORPS D'UNE NOTE SE SAISIT SUR PLUSIEURS LIGNES. Un applique la +/// sanitisation de HTML et retire les retours a la ligne : on pouvait lire et +/// modifier du multiligne, mais pas en creer - il fallait creer la note puis +/// l'ouvrir pour la mettre en forme. +function newBodyControl(kind) { + if (kind === 'note') + return ''; + return ''; } function openNewEntry() { @@ -1059,12 +1080,13 @@ function openNewEntry() { + '' + '' + newFolderField() - + newField('nTitle', 'Name', 'text') - + newField('nSite', 'Site', 'text') - + newField('nUser', 'Username', 'text') + + newField('nTitle', 'Name', 'nTitleRow') + + newField('nSite', 'Site', 'nSiteRow') + + newField('nUser', 'Username', 'nUserRow') // EN CLAIR pendant la saisie, comme l'editeur : on tape un mot de passe // qu'aucune confirmation ne rattrape et qu'on ne peut relire nulle part. - + newField('nPwd', 'Password', 'text') + + '
Password
' + + '
' + newBodyControl('login') + '
' + '
' // flex:1 et non .wide : .wide ne regle que le rembourrage, et la largeur // pleine vient d'etre etire dans son conteneur. @@ -1082,20 +1104,33 @@ document.getElementById('fields').addEventListener('click', function (ev) { var kind = ev.target.getAttribute('data-kind'); if (kind) { newKind = kind; - var all = document.querySelectorAll('[data-kind]'); - for (var i = 0; i < all.length; i++) + var all = document.querySelectorAll('[data-kind]'), i; + for (i = 0; i < all.length; i++) all[i].classList.toggle('main', all[i].getAttribute('data-kind') === kind); + + // PAR IDENTIFIANT, PAS PAR LIBELLE. Les rangees se reconnaissaient a leur + // intitule - de la prose - donc renommer un champ aurait suffi a ce que + // ce code cesse silencieusement d'agir sur lui. + // + // Une note n'a ni site ni identifiant : les laisser proposes revient a + // demander de remplir ce que rien n'affichera. + document.getElementById('nSiteRow').hidden = (kind === 'note'); + document.getElementById('nUserRow').hidden = (kind === 'note'); + // Le corps d'une note EST son mot de passe cote stockage : meme champ, - // autre intitule, et rien a masquer. - var caps = document.querySelectorAll('#fields .cap'); - for (i = 0; i < caps.length; i++) { - if (caps[i].textContent === 'Password' || caps[i].textContent === 'Content') - caps[i].textContent = (kind === 'note') ? 'Content' : 'Password'; - // Une note n'a ni site ni identifiant. Les laisser proposes revient a - // demander de remplir ce qui ne sera jamais affiche. - if (caps[i].textContent === 'Site' || caps[i].textContent === 'Username') - caps[i].parentNode.hidden = (kind === 'note'); - } + // autre intitule, et rien a masquer - mais plusieurs lignes. + var row = document.getElementById('nBodyRow'); + row.querySelector('.cap').textContent = + (kind === 'note') ? 'Content' : 'Password'; + var line = row.querySelector('.line'); + // CE QUI EST DEJA TAPE SURVIT AU CHANGEMENT. Remplacer le controle sans le + // reporter effacerait la saisie sans un mot, pour un simple changement + // d'avis sur le genre. + var old = document.getElementById('nPwd'); + var kept = old ? old.value : ''; + line.classList.toggle('wrap', kind === 'note'); + line.innerHTML = newBodyControl(kind); + document.getElementById('nPwd').value = kept; return; } if (ev.target.id !== 'nSave') return;