@bobfrankston/rmfmail 1.2.221 → 1.2.222

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.
package/bin/mailx.ts CHANGED
@@ -183,6 +183,35 @@ const isDaemon = hasFlag("daemon"); // internal: re-spawned detached process
183
183
  }
184
184
  }
185
185
 
186
+ /** App entries appended to the NATIVE right-click menu inside compose. msger
187
+ * keeps the WebView2 default menu (that is the only place spellcheck
188
+ * suggestions live) and gates these to editable targets, so they never show
189
+ * on the read-only list or message preview.
190
+ *
191
+ * Clipboard entries are ours rather than the browser's on purpose: Chromium
192
+ * OMITS Cut/Copy from the default menu when the caret is collapsed, and a
193
+ * right-click on a word is a collapsed caret — so the menu the user actually
194
+ * sees while editing has no Cut or Copy (Bob 2026-08-07). Ours expand to the
195
+ * word under the caret first, exactly like the formatting entries below
196
+ * already do, so "right-click a word → Copy" means what it looks like.
197
+ *
198
+ * Ids are dispatched to compose.ts via window.__msgerContextCommand — one
199
+ * list, both windows (in-window compose overlay + popout compose), because
200
+ * drift between the two is what produced "right mouse isn't showing any
201
+ * formatting options" in the first place (Bob 2026-07-18). */
202
+ const COMPOSE_CONTEXT_MENU_ITEMS = [
203
+ { id: "cut", label: "Cut" },
204
+ { id: "copy", label: "Copy" },
205
+ { id: "paste", label: "Paste" },
206
+ { id: "bold", label: "Bold" },
207
+ { id: "italic", label: "Italic" },
208
+ { id: "underline", label: "Underline" },
209
+ { id: "strike", label: "Strikethrough" },
210
+ { id: "link", label: "Link…" },
211
+ { id: "clear", label: "Clear formatting" },
212
+ { id: "source", label: "View HTML source…" },
213
+ ];
214
+
186
215
  /** Windows mailto: registration — registry keys via reg.exe. Shared by the
187
216
  * `-register-mailto` CLI flag and the Settings → "Make default email app"
188
217
  * menu action (injected into MailxService; the registry work stays HERE in
@@ -2420,15 +2449,7 @@ RFC 5322 with CRLF line endings. Bodies are quoted-printable encoded (readable i
2420
2449
  // App entries on the NATIVE right-click menu (native stays
2421
2450
  // so spellcheck suggestions survive). compose.ts maps ids
2422
2451
  // to editor commands via window.__msgerContextCommand.
2423
- contextMenuItems: [
2424
- { id: "bold", label: "Bold" },
2425
- { id: "italic", label: "Italic" },
2426
- { id: "underline", label: "Underline" },
2427
- { id: "strike", label: "Strikethrough" },
2428
- { id: "link", label: "Link…" },
2429
- { id: "clear", label: "Clear formatting" },
2430
- { id: "source", label: "View HTML source…" },
2431
- ],
2452
+ contextMenuItems: COMPOSE_CONTEXT_MENU_ITEMS,
2432
2453
  });
2433
2454
  popoutWindows.set(key, h);
2434
2455
  if (typeof h.pid === "number") addChildPid(h.pid);
@@ -2552,15 +2573,7 @@ RFC 5322 with CRLF line endings. Bodies are quoted-printable encoded (readable i
2552
2573
  // "right mouse isn't showing any formatting options let alone source").
2553
2574
  // msger gates these to editable targets, so they DON'T appear on
2554
2575
  // right-clicks in the read-only list / message preview.
2555
- contextMenuItems: [
2556
- { id: "bold", label: "Bold" },
2557
- { id: "italic", label: "Italic" },
2558
- { id: "underline", label: "Underline" },
2559
- { id: "strike", label: "Strikethrough" },
2560
- { id: "link", label: "Link…" },
2561
- { id: "clear", label: "Clear formatting" },
2562
- { id: "source", label: "View HTML source…" },
2563
- ],
2576
+ contextMenuItems: COMPOSE_CONTEXT_MENU_ITEMS,
2564
2577
  });
2565
2578
  // Late-bind the popout-action forwarder now that the main window's
2566
2579
  // service channel exists.
@@ -9117,6 +9117,17 @@ function showComposeOverlay(title = "Compose") {
9117
9117
  document.body.appendChild(wrapper);
9118
9118
  return frame;
9119
9119
  }
9120
+ window.__msgerContextCommand = (id) => {
9121
+ const frames = [...document.querySelectorAll(".compose-overlay iframe")];
9122
+ const target = frames.sort((a, b) => {
9123
+ const z = (el) => Number(el.closest(".compose-overlay")?.style.zIndex || 0);
9124
+ return z(b) - z(a);
9125
+ })[0];
9126
+ try {
9127
+ target?.contentWindow?.__msgerContextCommand?.(id);
9128
+ } catch {
9129
+ }
9130
+ };
9120
9131
  function installDragShield(cursor) {
9121
9132
  const shield = document.createElement("div");
9122
9133
  shield.style.cssText = `position:fixed;inset:0;z-index:9999;background:transparent;cursor:${cursor};user-select:none;`;