thunderbird-patch-review

Easy-to-use patch review interface for Thunderbird

Contribute: ~marcc/thunderbird-review-plugin@lists.sr.ht

git clone git://mccd.space/thunderbird-patch-review

commit f801ebecd98f909249acb24c219cf1e5bed57e13
parent 893b7a0be9f0f09f676f66ca9a3d530f17291e75
Author: Pi Agent <agent@pi.local>
Date:   Sat, 18 Jul 2026 12:52:25 +0200

review: hide the readonly comment while editing it

When the inline or "Comment on patch" editor opens, hide the existing
readonly comment card beneath it so the editor is not duplicated by the
saved view. closeEditors() centralizes tearing down any open editor and
restoring whichever .readonly card was hidden; toggleEditor and
openGeneralEditor track the specific readonly element to restore on
cancel/save. Comment cards/rows are tagged .readonly for the lookup.

Diffstat:
Mextension/review/review.js | 48+++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 41 insertions(+), 7 deletions(-)
diff --git a/extension/review/review.js b/extension/review/review.js
@@ -239,7 +239,7 @@ function codeCell(line, range) {
 
 function commentCard(text, onEdit) {
   const box = document.createElement("div");
-  box.className = "comment-box";
+  box.className = "comment-box readonly";
   const body = document.createElement("div");
   body.className = "comment-text";
   body.textContent = text;
@@ -251,7 +251,7 @@ function commentCard(text, onEdit) {
 
 function commentRow(text, lineRow, loc) {
   const tr = document.createElement("tr");
-  tr.className = "comment-row";
+  tr.className = "comment-row readonly";
   const td = document.createElement("td");
   td.colSpan = 3;
   td.appendChild(commentCard(text, () => toggleEditor(lineRow, loc)));
@@ -262,29 +262,63 @@ function commentRow(text, lineRow, loc) {
 // ---------------------------------------------------------------------------
 // Comment editing
 
+function closeEditors() {
+  document.querySelectorAll(".editor-row, .general-editor").forEach((el) => el.remove());
+  document.querySelectorAll(".readonly[hidden]").forEach((el) => {
+    el.hidden = false;
+  });
+}
+
 function toggleEditor(lineRow, loc) {
   const open = lineRow.nextElementSibling;
   if (open && open.classList.contains("editor-row")) {
-    open.remove();
+    closeEditors();
     return;
   }
-  document.querySelectorAll(".editor-row").forEach((el) => el.remove());
+  closeEditors();
 
   const existing = state.comments[state.current][loc];
+  const ro = findReadonly(lineRow);
+  if (ro) ro.hidden = true;
+
   const tr = document.createElement("tr");
   tr.className = "comment-row editor-row";
   const td = document.createElement("td");
   td.colSpan = 3;
-  td.appendChild(editorBox(existing ? existing.text : "", loc, () => tr.remove()));
+  td.appendChild(
+    editorBox(existing ? existing.text : "", loc, () => {
+      tr.remove();
+      if (ro) ro.hidden = false;
+    })
+  );
   tr.appendChild(td);
   lineRow.after(tr);
   tr.querySelector("textarea").focus();
 }
 
+function findReadonly(lineRow) {
+  let el = lineRow.nextElementSibling;
+  while (el) {
+    if (el.classList.contains("readonly")) return el;
+    el = el.nextElementSibling;
+  }
+  return null;
+}
+
 function openGeneralEditor(anchorEl) {
-  document.querySelectorAll(".editor-row, .general-editor").forEach((el) => el.remove());
+  closeEditors();
   const existing = state.comments[state.current][store.GENERAL];
-  const box = editorBox(existing ? existing.text : "", store.GENERAL, () => box.remove());
+  // The readonly general comment, if any, is the element right after the
+  // commit-message block. Keep a reference back from the anchor so we hide
+  // exactly that one and not some unrelated .readonly down the page.
+  const ro = anchorEl.nextElementSibling?.classList?.contains("readonly")
+    ? anchorEl.nextElementSibling
+    : null;
+  if (ro) ro.hidden = true;
+  const box = editorBox(existing ? existing.text : "", store.GENERAL, () => {
+    box.remove();
+    if (ro) ro.hidden = false;
+  });
   box.classList.add("general-editor");
   anchorEl.after(box);
   box.querySelector("textarea").focus();