@bobfrankston/rmfmail 1.2.222 → 1.2.223
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.js +6 -9
- package/bin/mailx.js.map +1 -1
- package/bin/mailx.ts +6 -9
- package/client/app.bundle.js +68 -1
- package/client/app.bundle.js.map +2 -2
- package/client/components/context-menu.js +76 -0
- package/client/components/context-menu.js.map +1 -1
- package/client/components/context-menu.ts +77 -0
- package/client/compose/compose.bundle.js +274 -114
- package/client/compose/compose.bundle.js.map +4 -4
- package/client/compose/compose.js +4 -149
- package/client/compose/compose.js.map +1 -1
- package/client/compose/compose.ts +4 -104
- package/client/compose/edit-commands.js +207 -0
- package/client/compose/edit-commands.js.map +1 -0
- package/client/compose/edit-commands.ts +181 -0
- package/client/compose/editor.js +6 -0
- package/client/compose/editor.js.map +1 -1
- package/client/compose/editor.ts +6 -0
- package/client/compose/spellcheck.js +19 -0
- package/client/compose/spellcheck.js.map +1 -1
- package/client/compose/spellcheck.ts +11 -0
- package/package.json +3 -3
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-104584 → node_modules.npmglobalize-stash-65000}/.package-lock.json +0 -0
package/bin/mailx.ts
CHANGED
|
@@ -188,21 +188,18 @@ const isDaemon = hasFlag("daemon"); // internal: re-spawned detached process
|
|
|
188
188
|
* suggestions live) and gates these to editable targets, so they never show
|
|
189
189
|
* on the read-only list or message preview.
|
|
190
190
|
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
191
|
+
* Deliberately NO Cut/Copy/Paste here: WebView2's own menu already carries
|
|
192
|
+
* them (with the right enabled/disabled state and the Ctrl+X/C/V hints), so
|
|
193
|
+
* app copies would just be duplicates a few rows further down. The menu that
|
|
194
|
+
* genuinely lacks them is mailx's spell menu, which preventDefaults the
|
|
195
|
+
* native one away — that gap is filled in compose/edit-commands.ts, at the
|
|
196
|
+
* menu that actually has the hole (Bob 2026-08-07).
|
|
197
197
|
*
|
|
198
198
|
* Ids are dispatched to compose.ts via window.__msgerContextCommand — one
|
|
199
199
|
* list, both windows (in-window compose overlay + popout compose), because
|
|
200
200
|
* drift between the two is what produced "right mouse isn't showing any
|
|
201
201
|
* formatting options" in the first place (Bob 2026-07-18). */
|
|
202
202
|
const COMPOSE_CONTEXT_MENU_ITEMS = [
|
|
203
|
-
{ id: "cut", label: "Cut" },
|
|
204
|
-
{ id: "copy", label: "Copy" },
|
|
205
|
-
{ id: "paste", label: "Paste" },
|
|
206
203
|
{ id: "bold", label: "Bold" },
|
|
207
204
|
{ id: "italic", label: "Italic" },
|
|
208
205
|
{ id: "underline", label: "Underline" },
|
package/client/app.bundle.js
CHANGED
|
@@ -723,7 +723,14 @@ __export(context_menu_exports, {
|
|
|
723
723
|
closeContextMenu: () => closeContextMenu,
|
|
724
724
|
showContextMenu: () => showContextMenu
|
|
725
725
|
});
|
|
726
|
+
function closeSubmenu() {
|
|
727
|
+
if (activeSubmenu) {
|
|
728
|
+
activeSubmenu.remove();
|
|
729
|
+
activeSubmenu = null;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
726
732
|
function closeContextMenu() {
|
|
733
|
+
closeSubmenu();
|
|
727
734
|
if (activeMenu) {
|
|
728
735
|
activeMenu.remove();
|
|
729
736
|
activeMenu = null;
|
|
@@ -737,6 +744,45 @@ function closeContextMenu() {
|
|
|
737
744
|
escapeListener = null;
|
|
738
745
|
}
|
|
739
746
|
}
|
|
747
|
+
function openSubmenu(parentRow, items) {
|
|
748
|
+
closeSubmenu();
|
|
749
|
+
const sub = document.createElement("div");
|
|
750
|
+
sub.className = "ctx-menu";
|
|
751
|
+
for (const item of items) {
|
|
752
|
+
if (item.separator) {
|
|
753
|
+
const sep = document.createElement("div");
|
|
754
|
+
sep.className = "ctx-sep";
|
|
755
|
+
sub.appendChild(sep);
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
const el = document.createElement("div");
|
|
759
|
+
el.className = "ctx-item" + (item.disabled ? " ctx-disabled" : "");
|
|
760
|
+
el.textContent = item.label;
|
|
761
|
+
if (item.tooltip)
|
|
762
|
+
el.title = item.tooltip;
|
|
763
|
+
if (!item.disabled) {
|
|
764
|
+
el.addEventListener("click", () => {
|
|
765
|
+
closeContextMenu();
|
|
766
|
+
item.action();
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
sub.appendChild(el);
|
|
770
|
+
}
|
|
771
|
+
document.body.appendChild(sub);
|
|
772
|
+
const anchor = parentRow.getBoundingClientRect();
|
|
773
|
+
const vw = window.visualViewport?.width ?? window.innerWidth;
|
|
774
|
+
const vh = window.visualViewport?.height ?? window.innerHeight;
|
|
775
|
+
const rect = sub.getBoundingClientRect();
|
|
776
|
+
let left = anchor.right - 2;
|
|
777
|
+
if (left + rect.width > vw)
|
|
778
|
+
left = anchor.left - rect.width + 2;
|
|
779
|
+
let top = anchor.top;
|
|
780
|
+
if (top + rect.height > vh)
|
|
781
|
+
top = vh - rect.height - 4;
|
|
782
|
+
sub.style.left = `${Math.max(4, left)}px`;
|
|
783
|
+
sub.style.top = `${Math.max(4, top)}px`;
|
|
784
|
+
activeSubmenu = sub;
|
|
785
|
+
}
|
|
740
786
|
function showContextMenu(x, y, items) {
|
|
741
787
|
closeContextMenu();
|
|
742
788
|
const menu = document.createElement("div");
|
|
@@ -755,6 +801,24 @@ function showContextMenu(x, y, items) {
|
|
|
755
801
|
el.textContent = item.label;
|
|
756
802
|
if (item.tooltip)
|
|
757
803
|
el.title = item.tooltip;
|
|
804
|
+
if (item.submenu && item.submenu.length > 0 && !item.disabled) {
|
|
805
|
+
el.style.display = "flex";
|
|
806
|
+
el.style.justifyContent = "space-between";
|
|
807
|
+
el.style.gap = "12px";
|
|
808
|
+
const caret = document.createElement("span");
|
|
809
|
+
caret.textContent = "\u25B8";
|
|
810
|
+
caret.style.opacity = "0.6";
|
|
811
|
+
el.appendChild(caret);
|
|
812
|
+
const open = () => openSubmenu(el, item.submenu);
|
|
813
|
+
el.addEventListener("mouseenter", open);
|
|
814
|
+
el.addEventListener("click", (e) => {
|
|
815
|
+
e.stopPropagation();
|
|
816
|
+
open();
|
|
817
|
+
});
|
|
818
|
+
menu.appendChild(el);
|
|
819
|
+
continue;
|
|
820
|
+
}
|
|
821
|
+
el.addEventListener("mouseenter", closeSubmenu);
|
|
758
822
|
if (!item.disabled) {
|
|
759
823
|
el.addEventListener("click", () => {
|
|
760
824
|
closeContextMenu();
|
|
@@ -786,6 +850,8 @@ function showContextMenu(x, y, items) {
|
|
|
786
850
|
activeMenu = menu;
|
|
787
851
|
requestAnimationFrame(() => {
|
|
788
852
|
dismissListener = (e) => {
|
|
853
|
+
if (activeSubmenu?.contains(e.target))
|
|
854
|
+
return;
|
|
789
855
|
if (activeMenu && !activeMenu.contains(e.target)) {
|
|
790
856
|
closeContextMenu();
|
|
791
857
|
}
|
|
@@ -801,13 +867,14 @@ function showContextMenu(x, y, items) {
|
|
|
801
867
|
document.addEventListener("keydown", escapeListener, true);
|
|
802
868
|
});
|
|
803
869
|
}
|
|
804
|
-
var activeMenu, dismissListener, escapeListener;
|
|
870
|
+
var activeMenu, dismissListener, escapeListener, activeSubmenu;
|
|
805
871
|
var init_context_menu = __esm({
|
|
806
872
|
"client/components/context-menu.js"() {
|
|
807
873
|
"use strict";
|
|
808
874
|
activeMenu = null;
|
|
809
875
|
dismissListener = null;
|
|
810
876
|
escapeListener = null;
|
|
877
|
+
activeSubmenu = null;
|
|
811
878
|
document.addEventListener("scroll", closeContextMenu, true);
|
|
812
879
|
document.addEventListener("contextmenu", () => {
|
|
813
880
|
});
|