@bobfrankston/rmfmail 1.1.161 → 1.1.163
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/client/app.bundle.js +34 -1
- package/client/app.bundle.js.map +2 -2
- package/client/app.js +44 -1
- package/client/app.js.map +1 -1
- package/client/app.ts +44 -1
- package/client/compose/compose.bundle.js +24 -0
- package/client/compose/compose.bundle.js.map +2 -2
- package/client/compose/spellcheck.js +16 -0
- package/client/compose/spellcheck.js.map +1 -1
- package/client/compose/spellcheck.ts +15 -0
- package/client/lib/rmf-tiny.js +25 -1
- package/package.json +5 -5
- package/packages/mailx-imap/index.d.ts.map +1 -1
- package/packages/mailx-imap/index.js +11 -1
- package/packages/mailx-imap/index.js.map +1 -1
- package/packages/mailx-imap/index.ts +11 -1
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-settings/cloud.d.ts.map +1 -1
- package/packages/mailx-settings/cloud.js +46 -0
- package/packages/mailx-settings/cloud.js.map +1 -1
- package/packages/mailx-settings/cloud.ts +43 -0
- package/packages/mailx-settings/package.json +1 -1
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-4296 → node_modules.npmglobalize-stash-51500}/.package-lock.json +0 -0
package/client/app.ts
CHANGED
|
@@ -3371,6 +3371,7 @@ viewBtn?.addEventListener("click", (e) => {
|
|
|
3371
3371
|
// it renders in the expected position-absolute location.
|
|
3372
3372
|
restoreToolbarDropdown("view-dropdown", "view-menu");
|
|
3373
3373
|
if (viewDropdown) viewDropdown.hidden = !viewDropdown.hidden;
|
|
3374
|
+
refreshToolbarOverlayShield();
|
|
3374
3375
|
});
|
|
3375
3376
|
// Capture-phase pointerdown so we run BEFORE any handler that calls
|
|
3376
3377
|
// stopPropagation. The earlier bubble-phase click listener missed clicks
|
|
@@ -3391,7 +3392,45 @@ document.addEventListener("pointerdown", (e) => {
|
|
|
3391
3392
|
if (settingsDropdown && !settingsDropdown.hidden && !target.closest("#settings-menu") && !target.closest("#settings-dropdown")) {
|
|
3392
3393
|
settingsDropdown.hidden = true;
|
|
3393
3394
|
}
|
|
3395
|
+
refreshToolbarOverlayShield();
|
|
3394
3396
|
}, true);
|
|
3397
|
+
|
|
3398
|
+
// Click-to-dismiss for the toolbar dropdowns relies on `pointerdown` firing
|
|
3399
|
+
// on the parent document. Clicks inside the compose iframe stay in the
|
|
3400
|
+
// iframe's document and never bubble out, so a Settings/View menu opened
|
|
3401
|
+
// over compose used to stay stuck until the user hit Escape or the toolbar
|
|
3402
|
+
// button again. Shield the overlay with a transparent fullscreen catcher
|
|
3403
|
+
// while any toolbar dropdown is open — its pointerdown lands here in the
|
|
3404
|
+
// parent doc, triggering the same outside-click close. The shield sits
|
|
3405
|
+
// above compose (z 1600) but below the dropdown itself (z 2000).
|
|
3406
|
+
function refreshToolbarOverlayShield(): void {
|
|
3407
|
+
const dropdownOpen = ["settings-dropdown", "view-dropdown", "restart-dropdown"]
|
|
3408
|
+
.some(id => {
|
|
3409
|
+
const el = document.getElementById(id);
|
|
3410
|
+
return el && !el.hidden;
|
|
3411
|
+
});
|
|
3412
|
+
const hasOverlay = !!document.querySelector(".compose-overlay, .popout-overlay");
|
|
3413
|
+
let shield = document.getElementById("tb-overlay-shield");
|
|
3414
|
+
if (dropdownOpen && hasOverlay) {
|
|
3415
|
+
if (!shield) {
|
|
3416
|
+
shield = document.createElement("div");
|
|
3417
|
+
shield.id = "tb-overlay-shield";
|
|
3418
|
+
shield.style.cssText = "position:fixed;inset:0;z-index:1999;background:transparent;";
|
|
3419
|
+
shield.addEventListener("pointerdown", (ev) => {
|
|
3420
|
+
ev.preventDefault();
|
|
3421
|
+
ev.stopPropagation();
|
|
3422
|
+
for (const id of ["settings-dropdown", "view-dropdown", "restart-dropdown"]) {
|
|
3423
|
+
const dd = document.getElementById(id);
|
|
3424
|
+
if (dd) dd.hidden = true;
|
|
3425
|
+
}
|
|
3426
|
+
shield?.remove();
|
|
3427
|
+
});
|
|
3428
|
+
document.body.appendChild(shield);
|
|
3429
|
+
}
|
|
3430
|
+
} else if (shield) {
|
|
3431
|
+
shield.remove();
|
|
3432
|
+
}
|
|
3433
|
+
}
|
|
3395
3434
|
// Escape always closes any open dropdown/backdrop, regardless of how it was
|
|
3396
3435
|
// opened or whether an outside-click handler missed firing. Last-resort
|
|
3397
3436
|
// escape hatch for the "stuck modal" case.
|
|
@@ -3406,7 +3445,10 @@ document.addEventListener("keydown", (e) => {
|
|
|
3406
3445
|
if (bd) { bd.remove(); closed = true; }
|
|
3407
3446
|
const themeSub = document.getElementById("theme-submenu");
|
|
3408
3447
|
if (themeSub && !themeSub.hidden) { themeSub.hidden = true; closed = true; }
|
|
3409
|
-
if (closed)
|
|
3448
|
+
if (closed) {
|
|
3449
|
+
e.preventDefault();
|
|
3450
|
+
refreshToolbarOverlayShield();
|
|
3451
|
+
}
|
|
3410
3452
|
});
|
|
3411
3453
|
|
|
3412
3454
|
// Restore saved view settings
|
|
@@ -4385,6 +4427,7 @@ settingsBtn?.addEventListener("click", (e) => {
|
|
|
4385
4427
|
if (restartDd) restartDd.hidden = true;
|
|
4386
4428
|
restoreToolbarDropdown("settings-dropdown", "settings-menu");
|
|
4387
4429
|
if (settingsDropdown) settingsDropdown.hidden = !settingsDropdown.hidden;
|
|
4430
|
+
refreshToolbarOverlayShield();
|
|
4388
4431
|
});
|
|
4389
4432
|
// Close handled by the shared document click handler above
|
|
4390
4433
|
|
|
@@ -746,7 +746,21 @@ async function createTinyMceEditor(container2, opts = {}) {
|
|
|
746
746
|
const ZOOM_STEP = 2;
|
|
747
747
|
const ZOOM_MIN = 8;
|
|
748
748
|
const ZOOM_MAX = 32;
|
|
749
|
+
const ZOOM_STORAGE_KEY = "rmf-tiny:zoom-px";
|
|
749
750
|
let zoomPx = ZOOM_DEFAULT;
|
|
751
|
+
try {
|
|
752
|
+
const stored = Number(localStorage.getItem(ZOOM_STORAGE_KEY));
|
|
753
|
+
if (Number.isFinite(stored) && stored >= ZOOM_MIN && stored <= ZOOM_MAX) {
|
|
754
|
+
zoomPx = stored;
|
|
755
|
+
}
|
|
756
|
+
} catch {
|
|
757
|
+
}
|
|
758
|
+
const saveZoom = () => {
|
|
759
|
+
try {
|
|
760
|
+
localStorage.setItem(ZOOM_STORAGE_KEY, String(zoomPx));
|
|
761
|
+
} catch {
|
|
762
|
+
}
|
|
763
|
+
};
|
|
750
764
|
const applyZoom = () => {
|
|
751
765
|
try {
|
|
752
766
|
const body = ed.getBody();
|
|
@@ -758,6 +772,7 @@ async function createTinyMceEditor(container2, opts = {}) {
|
|
|
758
772
|
const bumpZoom = (delta) => {
|
|
759
773
|
zoomPx = Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, zoomPx + delta));
|
|
760
774
|
applyZoom();
|
|
775
|
+
saveZoom();
|
|
761
776
|
};
|
|
762
777
|
ed.ui.registry.addMenuItem("zoomIn", {
|
|
763
778
|
text: "Zoom in",
|
|
@@ -775,6 +790,7 @@ async function createTinyMceEditor(container2, opts = {}) {
|
|
|
775
790
|
onAction: () => {
|
|
776
791
|
zoomPx = ZOOM_DEFAULT;
|
|
777
792
|
applyZoom();
|
|
793
|
+
saveZoom();
|
|
778
794
|
}
|
|
779
795
|
});
|
|
780
796
|
const installLinkEscape = () => {
|
|
@@ -830,6 +846,8 @@ async function createTinyMceEditor(container2, opts = {}) {
|
|
|
830
846
|
doc.documentElement.setAttribute("lang", "en");
|
|
831
847
|
} catch {
|
|
832
848
|
}
|
|
849
|
+
if (zoomPx !== ZOOM_DEFAULT)
|
|
850
|
+
applyZoom();
|
|
833
851
|
try {
|
|
834
852
|
const doc = ed.getDoc();
|
|
835
853
|
doc.addEventListener("wheel", (e) => {
|
|
@@ -1964,6 +1982,9 @@ function decorate(editor2, sp) {
|
|
|
1964
1982
|
const doc = editor2.getDoc?.();
|
|
1965
1983
|
if (!body || !doc)
|
|
1966
1984
|
return;
|
|
1985
|
+
const _activeSel = doc.getSelection();
|
|
1986
|
+
if (_activeSel && _activeSel.rangeCount > 0 && !_activeSel.isCollapsed)
|
|
1987
|
+
return;
|
|
1967
1988
|
let savedFocusNode = null;
|
|
1968
1989
|
let savedFocusOffset = 0;
|
|
1969
1990
|
const _preSel = doc.getSelection();
|
|
@@ -2289,6 +2310,9 @@ function cleanupCorrected(editor2, sp) {
|
|
|
2289
2310
|
const doc = editor2.getDoc?.();
|
|
2290
2311
|
if (!body || !doc)
|
|
2291
2312
|
return;
|
|
2313
|
+
const activeSel = doc.getSelection();
|
|
2314
|
+
if (activeSel && activeSel.rangeCount > 0 && !activeSel.isCollapsed)
|
|
2315
|
+
return;
|
|
2292
2316
|
const markers = body.querySelectorAll(`span[${MARKER_ATTR}]`);
|
|
2293
2317
|
if (markers.length === 0)
|
|
2294
2318
|
return;
|