feat(autofill): etiquette no-autofill pour exclure une entree, copie du mot de passe toujours visible en vue tableau

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-09-18 15:22:14 +01:00
parent f1b7dd9bff
commit ab1da7e319
3 changed files with 14 additions and 4 deletions
+1
View File
@@ -2885,6 +2885,7 @@ body[data-editor-position="center"]:has(#settingsPanel.is-open)::before {
.col-actions { width: 100%; min-width: 80px; text-align: right; white-space: nowrap; }
.col-actions .icon-btn { opacity: 0; transition: opacity var(--t-fast); }
.entry-row:hover .col-actions .icon-btn { opacity: 0.7; }
.col-actions .icon-btn.is-always { opacity: 0.7; }
.col-actions .entry-kebab-wrap { display: inline-block; vertical-align: middle; }
/* Hide Edge/IE native password reveal eye (we ship our own toggle). */
+10 -3
View File
@@ -147,6 +147,8 @@ function autofillPushHotkeys(silent) {
const BROWSER_SUFFIX_RE =
/\s*[-—–|]\s*(google chrome|chromium|mozilla firefox|firefox|microsoft edge|edge|brave|opera|vivaldi|safari|tor browser|tor|arc)\s*$/i;
const AUTOFILL_SKIP_TAG = 'no-autofill';
function autofillStripBrowserSuffix(title) {
return (title || '').replace(BROWSER_SUFFIX_RE, '').trim();
}
@@ -274,9 +276,14 @@ async function autofillHandleRequest(windowTitle, kind) {
// The 2FA hotkey can only serve entries that actually carry a TOTP secret
// — filtering here (not after scoring) also means the picker never lists a
// candidate that would fail once chosen.
const pool = (kind === 'totp')
? state.entries.filter(e => e.totp_secret && e.totp_iv)
: state.entries;
// EXCLUE DE L'AUTOFILL par l'etiquette reservee AUTOFILL_SKIP_TAG : une
// etiquette et non un champ, car elle voyage deja partout (chiffree, synchro,
// export, rotation) sans une colonne de plus, et un clic dessus liste toutes
// les entrees exclues. La recherche rapide (Ctrl+Shift+Q) les garde : c'est
// un choix explicite, pas une correspondance devinee sur un titre.
const pool = state.entries
.filter(e => !parseTags(e.tags).some(t => t.toLowerCase() === AUTOFILL_SKIP_TAG))
.filter(e => kind !== 'totp' || (e.totp_secret && e.totp_iv));
const scored = pool
.map(e => ({ entry: e, score: autofillScore(e, titleLower) }))
.filter(x => x.score > 0)
+3 -1
View File
@@ -3606,8 +3606,10 @@ function renderTableRow(e) {
break;
case 'actions': {
td = el('td', { class: 'col-actions' });
// TOUJOURS VISIBLE, contrairement aux autres actions de la
// ligne : c'est le geste le plus frequent de la vue tableau.
const pwBtn = el('button', {
class: 'icon-btn icon-btn-sm',
class: 'icon-btn icon-btn-sm is-always',
title: e.kind === 'note' ? 'Copy note content' : 'Copy password',
on: { click: ev => { ev.stopPropagation(); copyPassword(e); } },
});