@bobfrankston/rmfmail 1.2.256 → 1.2.257

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.
@@ -997,7 +997,7 @@ export async function createTinyMceEditor(container, opts = {}) {
997
997
  function openSourceDialog(editor) {
998
998
  const SENTINEL = ""; // private-use area — never in real mail text
999
999
  let offset = -1;
1000
- let savedRng = null;
1000
+ let bookmark = null;
1001
1001
  try {
1002
1002
  // The sentinel must be INSERTED, never SUBSTITUTED. selection.setContent()
1003
1003
  // replaces whatever is selected — and right-clicking an image selects the
@@ -1008,14 +1008,17 @@ function openSourceDialog(editor) {
1008
1008
  // range START first (that's the caret the source view should land on), then
1009
1009
  // restore the user's original selection once the sentinel is out again.
1010
1010
  const sel = editor.selection;
1011
+ // Bookmark type 2 = non-intrusive path+offset (no marker nodes). A saved
1012
+ // Range object is NOT good enough: setContent re-parses the block, so the
1013
+ // saved range's container node is detached by the time we restore and the
1014
+ // selection came back as the whole paragraph. The path is resolved at
1015
+ // restore time, against a DOM the sentinel strip has put back as it was.
1016
+ bookmark = sel.getBookmark(2, true);
1011
1017
  const rng = sel.getRng();
1012
- if (rng) {
1013
- savedRng = rng.cloneRange(); // live range — tracks the insert/strip
1014
- if (!rng.collapsed) {
1015
- const collapsed = rng.cloneRange();
1016
- collapsed.collapse(true);
1017
- sel.setRng(collapsed);
1018
- }
1018
+ if (rng && !rng.collapsed) {
1019
+ const collapsed = rng.cloneRange();
1020
+ collapsed.collapse(true);
1021
+ sel.setRng(collapsed);
1019
1022
  }
1020
1023
  // Insert the sentinel at the caret without polluting undo history.
1021
1024
  const insert = () => editor.selection.setContent(SENTINEL);
@@ -1043,11 +1046,11 @@ function openSourceDialog(editor) {
1043
1046
  catch { /* sentinel cleanup is best-effort */ }
1044
1047
  // Put the selection back where the user left it (the selected image
1045
1048
  // stays selected, so closing the dialog leaves the quickbar up).
1046
- if (savedRng) {
1049
+ if (bookmark) {
1047
1050
  try {
1048
- editor.selection.setRng(savedRng);
1051
+ editor.selection.moveToBookmark(bookmark);
1049
1052
  }
1050
- catch { /* range invalidated by the strip — caret stays put */ }
1053
+ catch { /* path no longer resolves — caret stays where the sentinel was */ }
1051
1054
  }
1052
1055
  }
1053
1056
  catch { /* fall through to a plain source view at offset 0 */ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/rmfmail",
3
- "version": "1.2.256",
3
+ "version": "1.2.257",
4
4
  "description": "Local-first email client with IMAP sync and standalone native app",
5
5
  "type": "module",
6
6
  "main": "bin/mailx.js",
@@ -41,7 +41,7 @@
41
41
  "@bobfrankston/msger": "^0.1.425",
42
42
  "@bobfrankston/node-tcp-transport": "^0.1.10",
43
43
  "@bobfrankston/oauthsupport": "^1.0.34",
44
- "@bobfrankston/rmf-tiny": "^0.1.47",
44
+ "@bobfrankston/rmf-tiny": "^0.1.48",
45
45
  "@bobfrankston/smtp-direct": "^0.1.9",
46
46
  "@bobfrankston/tcp-transport": "^0.1.8",
47
47
  "@capacitor/android": "^8.3.0",
@@ -121,7 +121,7 @@
121
121
  "@bobfrankston/msger": "^0.1.425",
122
122
  "@bobfrankston/node-tcp-transport": "^0.1.10",
123
123
  "@bobfrankston/oauthsupport": "^1.0.34",
124
- "@bobfrankston/rmf-tiny": "^0.1.47",
124
+ "@bobfrankston/rmf-tiny": "^0.1.48",
125
125
  "@bobfrankston/smtp-direct": "^0.1.9",
126
126
  "@bobfrankston/tcp-transport": "^0.1.8",
127
127
  "@capacitor/android": "^8.3.0",