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:
@@ -115,3 +115,35 @@ describe('wireFieldHandlers', () => {
|
||||
expect(writeText).toHaveBeenCalledWith('alice@example.com');
|
||||
});
|
||||
});
|
||||
|
||||
describe('concealed-row round-trip with special characters', () => {
|
||||
it('reveals a value containing double quotes correctly', () => {
|
||||
document.body.innerHTML = renderConcealedRow({ id: 'pw', label: 'p', value: 'a"b"c' });
|
||||
wireFieldHandlers(document.body);
|
||||
const btn = document.querySelector('[data-field-action="reveal"]') as HTMLButtonElement;
|
||||
btn.click();
|
||||
const valueEl = document.querySelector('[data-field-role="value"]') as HTMLElement;
|
||||
expect(valueEl.textContent).toBe('a"b"c');
|
||||
});
|
||||
|
||||
it('reveals a value containing single quotes correctly', () => {
|
||||
document.body.innerHTML = renderConcealedRow({ id: 'pw', label: 'p', value: "it's & ok" });
|
||||
wireFieldHandlers(document.body);
|
||||
const btn = document.querySelector('[data-field-action="reveal"]') as HTMLButtonElement;
|
||||
btn.click();
|
||||
const valueEl = document.querySelector('[data-field-role="value"]') as HTMLElement;
|
||||
expect(valueEl.textContent).toBe("it's & ok");
|
||||
});
|
||||
|
||||
it('copies a value containing double quotes correctly', async () => {
|
||||
const writeText = vi.fn().mockResolvedValue(undefined);
|
||||
Object.defineProperty(navigator, 'clipboard', {
|
||||
configurable: true,
|
||||
value: { writeText },
|
||||
});
|
||||
document.body.innerHTML = renderRow({ label: 'p', value: 'a"b"c', copyable: true });
|
||||
wireFieldHandlers(document.body);
|
||||
(document.querySelector('[data-field-action="copy"]') as HTMLButtonElement).click();
|
||||
expect(writeText).toHaveBeenCalledWith('a"b"c');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user