fix(edit-history): harden diff after review

Address findings from 2 review agents on the edit-history diff:

- Perf: diffWords is O(n*m); cap at 2000 tokens/side and fall back to a
  coarse whole-block replaced diff above that, so a very large multi-edit
  message can't freeze the main thread. Memoize the per-row diff in
  DiffText. (Added a unit test for the coarse fallback.)

- Perceivability (a11y/design): the added-word <ins> highlight was
  color-fill only, which is faint against the modal surface in the lotus
  themes. Add a Success.ContainerLine border + horizontal padding (so the
  rounded corners read as a chip) + box-decoration-break: clone for clean
  wrapping, so the "added" cue survives low fill contrast.

- Consistency: a media/no-body edit now renders "(no text)" in diff mode
  too (matched the toggle-off view; was blank).

- Softened the code comment's screen-reader claim (bare <ins>/<del> aren't
  announced by default).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 11:11:16 -04:00
co-authored by Claude Opus 4.8
parent 961789fd71
commit 90e6901a60
3 changed files with 36 additions and 4 deletions
+12
View File
@@ -78,6 +78,18 @@ test('diffWords does not mutate its inputs', () => {
assert.equal(b, 'alpha gamma');
});
test('very large inputs fall back to a coarse whole-block diff', () => {
const big = Array.from({ length: 5000 }, (_, i) => `w${i}`).join(' ');
const out = diffWords(big, `${big} extra`);
// Coarse fallback: one removed block + one added block (no per-word LCS).
assert.deepEqual(
out.map((s) => s.type),
['removed', 'added'],
);
assert.equal(oldText(out), big);
assert.equal(newText(out), `${big} extra`);
});
test('word-level granularity (not character-level)', () => {
const out = diffWords('cat', 'cats');
// "cat" and "cats" are different tokens → full removed + added, no partial.