@bobfrankston/rmfmail 1.2.260 → 1.2.263

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.
@@ -2236,6 +2236,9 @@ function installPreviewControls(iframe) {
2236
2236
  const doc = iframe.contentDocument;
2237
2237
  if (!doc)
2238
2238
  return;
2239
+ if (doc.__mvControlsBound)
2240
+ return;
2241
+ doc.__mvControlsBound = true;
2239
2242
  applyZoom(doc);
2240
2243
  refreshSearchHighlight(iframe, true);
2241
2244
  doc.addEventListener("keydown", (e) => {
@@ -2280,10 +2283,9 @@ function installPreviewControls(iframe) {
2280
2283
  setZoom(previewZoom + (e.deltaY < 0 ? ZOOM_STEP : -ZOOM_STEP), doc);
2281
2284
  }, { passive: false });
2282
2285
  };
2286
+ iframe.addEventListener("load", attach);
2283
2287
  if (iframe.contentDocument?.readyState === "complete")
2284
2288
  attach();
2285
- else
2286
- iframe.addEventListener("load", attach, { once: true });
2287
2289
  queueMicrotask(() => {
2288
2290
  const doc = iframe.contentDocument;
2289
2291
  if (!doc)
@@ -2566,16 +2568,7 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
2566
2568
  const fromEl = headerEl.querySelector(".mv-from");
2567
2569
  const toEl = headerEl.querySelector(".mv-to");
2568
2570
  fromEl.textContent = formatAddr(msg.from);
2569
- let toLine = `To: ${msg.to.map(formatAddr).join(", ")}`;
2570
- if (msg.cc?.length)
2571
- toLine += ` Cc: ${msg.cc.map(formatAddr).join(", ")}`;
2572
- const toAddrs = (msg.to || []).map((a) => a.address.toLowerCase());
2573
- const ccAddrs = (msg.cc || []).map((a) => a.address.toLowerCase());
2574
- const dt = (msg.deliveredTo || "").toLowerCase();
2575
- if (msg.deliveredTo && !toAddrs.includes(dt) && !ccAddrs.includes(dt)) {
2576
- toLine += ` Delivered-To: ${msg.deliveredTo}`;
2577
- }
2578
- toEl.textContent = toLine;
2571
+ setRecipientLine(toEl, msg.to, msg.cc, msg.deliveredTo);
2579
2572
  headerEl.querySelector(".mv-subject").textContent = msg.subject;
2580
2573
  document.dispatchEvent(new CustomEvent("mailx-message-shown", { detail: { accountId } }));
2581
2574
  for (const el of [fromEl, toEl]) {
@@ -2583,7 +2576,9 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
2583
2576
  e.preventDefault();
2584
2577
  const me = e;
2585
2578
  const items = [];
2586
- const addrs = el === fromEl ? [msg.from] : [...msg.to || [], ...msg.cc || []];
2579
+ const allAddrs = el === fromEl ? [msg.from] : [...msg.to || [], ...msg.cc || []];
2580
+ const addrs = allAddrs.slice(0, CONTEXT_MENU_ADDR_CAP);
2581
+ const omitted = allAddrs.length - addrs.length;
2587
2582
  for (const addr of addrs) {
2588
2583
  if (!addr?.address)
2589
2584
  continue;
@@ -2658,6 +2653,14 @@ async function showMessage(accountId, uid, folderId, specialUse, isRetry = false
2658
2653
  items.push({ label: "", action: () => {
2659
2654
  }, separator: true });
2660
2655
  }
2656
+ if (omitted > 0) {
2657
+ items.push({
2658
+ label: `\u2026 ${omitted} more recipients \u2014 copy the whole list`,
2659
+ action: () => navigator.clipboard.writeText(allAddrs.map(formatAddr).join(", "))
2660
+ });
2661
+ items.push({ label: "", action: () => {
2662
+ }, separator: true });
2663
+ }
2661
2664
  items.push({ label: "Reply", action: () => document.dispatchEvent(new CustomEvent("mailx-compose", { detail: { mode: "reply" } })) });
2662
2665
  items.push({ label: "Reply All", action: () => document.dispatchEvent(new CustomEvent("mailx-compose", { detail: { mode: "replyAll" } })) });
2663
2666
  items.push({ label: "Forward", action: () => document.dispatchEvent(new CustomEvent("mailx-compose", { detail: { mode: "forward" } })) });
@@ -3242,6 +3245,40 @@ function formatAddr(addr) {
3242
3245
  return `${addr.name} <${addr.address}>`;
3243
3246
  return addr.address;
3244
3247
  }
3248
+ function setRecipientLine(toEl, to, cc, deliveredTo) {
3249
+ const toList = to || [];
3250
+ const ccList = cc || [];
3251
+ let line = `To: ${toList.map(formatAddr).join(", ")}`;
3252
+ if (ccList.length)
3253
+ line += ` Cc: ${ccList.map(formatAddr).join(", ")}`;
3254
+ if (deliveredTo) {
3255
+ const dt = deliveredTo.toLowerCase();
3256
+ const covered = [...toList, ...ccList].some((a) => a.address.toLowerCase() === dt);
3257
+ if (!covered)
3258
+ line += ` Delivered-To: ${deliveredTo}`;
3259
+ }
3260
+ toEl.textContent = "";
3261
+ toEl.classList.remove("mv-to-expanded");
3262
+ const text = document.createElement("span");
3263
+ text.className = "mv-to-text";
3264
+ text.textContent = line;
3265
+ toEl.append(text);
3266
+ const count = toList.length + ccList.length;
3267
+ const clamped = text.scrollHeight > text.clientHeight + 1;
3268
+ if (count <= MANY_RECIPIENTS && !clamped)
3269
+ return;
3270
+ const toggle = document.createElement("button");
3271
+ toggle.className = "mv-to-toggle";
3272
+ toggle.type = "button";
3273
+ const label = count === 1 ? "1 recipient" : `${count} recipients`;
3274
+ const paint = (open) => {
3275
+ toggle.textContent = `${open ? "\u25BE" : "\u25B8"} ${label}`;
3276
+ toggle.title = open ? "Collapse the recipient list" : "Show the full recipient list";
3277
+ };
3278
+ paint(false);
3279
+ toggle.addEventListener("click", () => paint(toEl.classList.toggle("mv-to-expanded")));
3280
+ toEl.append(toggle);
3281
+ }
3245
3282
  function renderHeaderFromEnvelope(headerEl, env) {
3246
3283
  headerEl.hidden = false;
3247
3284
  const fromEl = headerEl.querySelector(".mv-from");
@@ -3250,12 +3287,8 @@ function renderHeaderFromEnvelope(headerEl, env) {
3250
3287
  const dateEl = headerEl.querySelector(".mv-date");
3251
3288
  if (fromEl)
3252
3289
  fromEl.textContent = formatAddr(env.from);
3253
- if (toEl) {
3254
- let toLine = `To: ${(env.to || []).map(formatAddr).join(", ")}`;
3255
- if (env.cc?.length)
3256
- toLine += ` Cc: ${env.cc.map(formatAddr).join(", ")}`;
3257
- toEl.textContent = toLine;
3258
- }
3290
+ if (toEl)
3291
+ setRecipientLine(toEl, env.to, env.cc);
3259
3292
  if (subjEl)
3260
3293
  subjEl.textContent = env.subject || "";
3261
3294
  if (dateEl) {
@@ -4025,7 +4058,7 @@ function spawnDesktopPopout(msg, accountId) {
4025
4058
  function escapeHtmlLocal(s) {
4026
4059
  return (s || "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
4027
4060
  }
4028
- var pendingImageCopies, imageCopySeq, IMAGE_COPY_TIMEOUT_MS, currentMessage, currentAccountId, dragOutUrls, showMessageGeneration, retryCount, lastEnvelope, PARSED_CACHE_LIMIT, parsedCache, sessionAllowedRemote, recentFetchErrors, WAIT_GIVE_UP_SECS, ZOOM_KEY, ZOOM_MIN, ZOOM_MAX, ZOOM_STEP, previewZoom, HIGHLIGHT_NAME, HIGHLIGHT_MAX, searchHighlightTerms, RENDER_MARK_KEY, RENDER_MARK_MAX_AGE_MS, poisonedMessages, renderKey, PROGRESSIVE_TEXT_THRESHOLD, TEXT_CHUNK_BYTES;
4061
+ var pendingImageCopies, imageCopySeq, IMAGE_COPY_TIMEOUT_MS, currentMessage, currentAccountId, dragOutUrls, showMessageGeneration, retryCount, lastEnvelope, PARSED_CACHE_LIMIT, parsedCache, sessionAllowedRemote, recentFetchErrors, WAIT_GIVE_UP_SECS, ZOOM_KEY, ZOOM_MIN, ZOOM_MAX, ZOOM_STEP, previewZoom, HIGHLIGHT_NAME, HIGHLIGHT_MAX, searchHighlightTerms, RENDER_MARK_KEY, RENDER_MARK_MAX_AGE_MS, poisonedMessages, renderKey, MANY_RECIPIENTS, CONTEXT_MENU_ADDR_CAP, PROGRESSIVE_TEXT_THRESHOLD, TEXT_CHUNK_BYTES;
4029
4062
  var init_message_viewer = __esm({
4030
4063
  "client/components/message-viewer.js"() {
4031
4064
  "use strict";
@@ -4109,6 +4142,8 @@ var init_message_viewer = __esm({
4109
4142
  } catch {
4110
4143
  }
4111
4144
  })();
4145
+ MANY_RECIPIENTS = 6;
4146
+ CONTEXT_MENU_ADDR_CAP = 12;
4112
4147
  PROGRESSIVE_TEXT_THRESHOLD = 200 * 1024;
4113
4148
  TEXT_CHUNK_BYTES = 64 * 1024;
4114
4149
  subscribeStore("*", (ev) => {