fix(ext/popup): close 3 critical regressions from slice-2 code review

- C1: escapeHtml now escapes " and ' so values stored in data-field-value
  attributes (concealed rows, copyable rows) round-trip correctly. Prior
  impl silently truncated passwords containing quotes. +3 regression tests.
- C2: centralize view-teardown. login.ts exports teardown() that stops
  the TOTP ticker and removes the active keydown handler; item-detail.ts
  and item-form.ts dispatchers call it before rendering the next view;
  each button handler also calls teardown() locally for belt-and-suspenders.
- C3: restore alpha's keyboard shortcuts on login detail view: c
  (copy username), p (copy password), t (copy TOTP), f (autofill), e
  (edit), d (trash), plus Escape (back). All gated by the
  is-editable-target guard so they don't eat keystrokes inside form fields.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken
2026-04-23 22:21:40 -04:00
parent 11c274053b
commit 23d4f736e1
5 changed files with 124 additions and 11 deletions

View File

@@ -6,6 +6,7 @@ import type { Item, ItemType } from '../../shared/types';
import * as login from './types/login';
export function renderItemForm(app: HTMLElement, mode: 'add' | 'edit'): void {
login.teardown(); // detail-view's ticker/listener don't leak into form
const state = getState();
const existing = mode === 'edit' ? state.selectedItem : null;
const type: ItemType = existing?.type ?? state.newType ?? 'login';