fix(web): banner highlight-note dialog prefilled; explicit note boundary; pencil on every note row

- BUG: startBannerEdit extracted the note by splitting row.rich — the
  RENDERED HTML — on \n\n, which the concatenated markup never
  contains, so highlight-note dialogs always opened empty. Both row
  kinds carry the raw note on bannerSources; use that lookup.
- Expanded body now splits at the highlight→note boundary: the
  selection paragraph (left border in the row's highlight color), a
  divider + pencil NOTE label, then the note markdown — instead of the
  two texts flowing together.
- The note-indicator pencil (corner badge) now shows on ALL note rows,
  not just highlights with attached notes.

Verified in headless Chromium: badge on note and highlight rows;
expanded highlight shows the bordered selection, NOTE label, and note
markdown; the highlight edit dialog prefills with the note text.
This commit is contained in:
John O'Keefe committed 2026-10-08 09:11:47 -04:00
1 parent e7ccd7b222
commit 44c0e5640f
4 files changed
+49 -22

No files matched your search

+14 -8
View File
@@ -19,8 +19,11 @@ interface AnnotationRow {
label: string;
/** compact preview line: stripped markdown (note) or capped selection */
preview: string;
/** rich body for the expanded view (pre-sanitized) */
rich: string;
/** expanded view, split so the highlight→note boundary is explicit:
* the escaped selection text, then the note's markdown-rendered HTML
* (empty when the row has no note body). */
richSelection: string;
richNote: string;
/** the ?loc= handoff value for the jump */
loc: string;
/** row accent color (swatch) */
@@ -96,7 +99,8 @@ function buildAnnotationRows(
kind: "note",
label,
preview: stripNote(content) || "(empty note)",
rich: renderNoteHtml(content),
richSelection: "",
richNote: renderNoteHtml(content),
loc,
color: "var(--accent)",
hasNote: true,
@@ -135,17 +139,19 @@ function buildAnnotationRows(
}
const capped = selection.length > 80 ? selection.slice(0, 80) + "…" : selection;
// Expanded body: the full highlight text followed by its rich note.
const rich = note
? `<p style="color: var(--text-secondary); margin: 0 0 .5rem;">${escapeHtmlForRich(selection)}</p>` + renderNoteHtml(note)
: `<p style="color: var(--text-secondary);">${escapeHtmlForRich(selection) || "…"}</p>`;
// Expanded body, split at the highlight→note boundary: the escaped
// selection, then the note's rendered markdown under a labeled divider
// (rendered by the banner template).
const richSelection = escapeHtmlForRich(selection);
const richNote = note ? renderNoteHtml(note) : "";
const row: AnnotationRow = {
key: `hl-${h.id}`,
kind: "highlight",
label,
preview: capped || "(empty highlight)",
rich,
richSelection,
richNote,
loc,
color,
hasNote: !!note,