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
| Log | Files | Refs | README | LICENSE |
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:
| M | extension/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();