@bobfrankston/rmfmail 1.2.328 → 1.2.331

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -52,3 +52,6 @@ Session: Claude Fable 5.1, started 2026-09-13 ~17:00 EDT.
52
52
  exists, converts -word.htm; sweep protects -word.htm/-word_files. Head/tail split (v1.2.327) unchanged.
53
53
  - Calendar default = primary always (calendar-sidebar.ts, sticky localStorage choice removed). Publishing as 1.2.328 (rebuild4.log).
54
54
  localStorage pref else "primary").
55
+
56
+ ## 2026-09-14 ~13:40: separator above the signature removed (v1.2.329, publishing — rebuild5.log)
57
+ - No hr above the sig; sig wrapped in `<div class="mailx-sig">` as the Word-split marker; legacy hr forms still matched.
@@ -5664,6 +5664,17 @@ if (fromInput) {
5664
5664
  openFromPicker();
5665
5665
  });
5666
5666
  fromInput.addEventListener("click", openFromPicker);
5667
+ const copyFromBtn = document.getElementById("btn-copy-from");
5668
+ copyFromBtn?.addEventListener("click", async () => {
5669
+ const value = getFromAddress();
5670
+ if (!value) return;
5671
+ try {
5672
+ await navigator.clipboard.writeText(value);
5673
+ showDraftStatus(`Copied From: ${value}`, false);
5674
+ } catch (e) {
5675
+ showDraftStatus(`Copy From failed: ${e?.message || e}`, true);
5676
+ }
5677
+ });
5667
5678
  fromInput.addEventListener("blur", () => {
5668
5679
  if (fromInput.value.trim() === "" && fromInput.dataset.prevFrom) {
5669
5680
  fromInput.value = fromInput.dataset.prevFrom;
@@ -5817,7 +5828,9 @@ function getFromAccountId() {
5817
5828
  return def?.id || "";
5818
5829
  }
5819
5830
  function getFromAddress() {
5820
- return fromInput.value.trim();
5831
+ const live = fromInput.value.trim();
5832
+ if (live) return live;
5833
+ return (fromInput.dataset.prevFrom || "").trim();
5821
5834
  }
5822
5835
  function smartTab(current) {
5823
5836
  const fields = [toInput, ccInput, bccInput, subjectInput];
@@ -6259,8 +6272,7 @@ function applyInit(init) {
6259
6272
  sigHtml = acct.signature;
6260
6273
  }
6261
6274
  if (sigHtml) {
6262
- const sigRule = '<hr class="mailx-sig-rule" style="width:3cm;margin:0.8em 0 0.5em 0;border:0;border-top:1px solid #999;">';
6263
- const sigBlock = `<br>${sigRule}${sigHtml}`;
6275
+ const sigBlock = `<br><div class="mailx-sig">${sigHtml}</div>`;
6264
6276
  bodyToRender = isReplyForward ? `<br>${sigBlock}<br>${bodyToRender}` : `${bodyToRender}${sigBlock}`;
6265
6277
  }
6266
6278
  }
@@ -6389,6 +6401,10 @@ var baselineSnapshot = "";
6389
6401
  function getContentSnapshot() {
6390
6402
  return JSON.stringify({
6391
6403
  body: editor?.getHtml() || "",
6404
+ // 2026-09-15 — Claude Code (Fable 5.1). From was not part of the
6405
+ // snapshot, so picking a different identity never triggered a save;
6406
+ // the draft kept the old From until the body or subject changed.
6407
+ from: fromInput ? getFromAddress() : "",
6392
6408
  to: toInput?.value || "",
6393
6409
  cc: ccInput?.value || "",
6394
6410
  bcc: bccInput?.value || "",
@@ -7053,7 +7069,11 @@ var wordEditOpening = false;
7053
7069
  function splitWordEditable(html) {
7054
7070
  const doc = new DOMParser().parseFromString(html, "text/html");
7055
7071
  const nodes = Array.from(doc.body.childNodes);
7056
- const cutAt = nodes.findIndex((n) => n instanceof HTMLElement && n.matches('hr.mailx-sig-rule, hr[style*="3cm"], div.reply'));
7072
+ const cutAt = nodes.findIndex((n) => (
7073
+ // div.mailx-sig is the current marker (2026-09-14); the two hr forms
7074
+ // cover drafts saved while the signature still had a rule above it.
7075
+ n instanceof HTMLElement && n.matches('div.mailx-sig, hr.mailx-sig-rule, hr[style*="3cm"], div.reply')
7076
+ ));
7057
7077
  if (cutAt < 0) return { head: html, tail: "" };
7058
7078
  const serialize = (part) => {
7059
7079
  const box = doc.createElement("div");