@bobfrankston/rmfmail 1.2.325 → 1.2.326

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.
@@ -22,5 +22,13 @@ Session: Claude Fable 5.1, started 2026-09-13 ~17:00 EDT.
22
22
  4. Bump mailx-settings, mailx-imap; rebuild.cmd.
23
23
 
24
24
  ## Status
25
- - [x] edits - [x] tsc + bundles - [ ] rebuild.cmd (running) - [ ] Bob restarts app
25
+ - [x] edits - [x] tsc + bundles - [x] rebuild.cmd → rmfmail 1.2.325, settings 0.1.94, imap 0.1.186, APK built (17:10) - [ ] Bob restarts app
26
26
  - DONE.md entry written as v1.2.325; .commitmsg written; versions: settings 0.1.92, imap 0.1.185
27
+
28
+ ## Follow-on (same session, ~18:45): typing at a link edge extended the link (TinyMCE)
29
+ - Cause: 2026-09-10 step-out ran only after paste; Backspace/click/arrow left the caret in TinyMCE's
30
+ inline-boundary "inside, at end" position (blue highlight) → every keystroke grew the link.
31
+ - Fix: `keepTypingOutsideLinks` in client/compose/editor.ts — check before every printable keydown and
32
+ one tick after paste; moves the caret just after (or before) the anchor when only whitespace/U+FEFF
33
+ separates it from the edge. Quill's typed path NOT covered (not the configured editor).
34
+ - Ships as rmfmail 1.2.326 via rebuild.cmd (running). Bob must restart the daemon for the new bundle.
@@ -5324,32 +5324,43 @@ async function createTinyMceEditor2(container2, opts = {}) {
5324
5324
  const body = native?.getBody?.();
5325
5325
  if (native && body) {
5326
5326
  wireMarkdownPaste(body, (html) => native.insertContent(html));
5327
- stepCaretOutOfPastedLink(native);
5327
+ keepTypingOutsideLinks(native);
5328
5328
  }
5329
5329
  } catch {
5330
5330
  }
5331
5331
  return ed;
5332
5332
  }
5333
- function stepCaretOutOfPastedLink(native) {
5334
- native.on("paste", () => {
5335
- setTimeout(() => {
5336
- try {
5337
- const rng = native.selection.getRng();
5338
- if (!rng || !rng.collapsed)
5339
- return;
5340
- const node = native.selection.getNode();
5341
- const a = node?.closest?.("a[href]");
5342
- if (!a)
5343
- return;
5344
- const rest = rng.cloneRange();
5345
- rest.setEnd(a, a.childNodes.length);
5346
- if (rest.toString().trim())
5347
- return;
5333
+ function keepTypingOutsideLinks(native) {
5334
+ const isBlank = (s) => !s.replace(/\uFEFF/g, "").trim();
5335
+ const stepOutOfLinkEdge = () => {
5336
+ try {
5337
+ const rng = native.selection.getRng();
5338
+ if (!rng || !rng.collapsed)
5339
+ return;
5340
+ const node = native.selection.getNode();
5341
+ const a = node?.closest?.("a[href]");
5342
+ if (!a)
5343
+ return;
5344
+ const toEnd = rng.cloneRange();
5345
+ toEnd.setEnd(a, a.childNodes.length);
5346
+ const fromStart = rng.cloneRange();
5347
+ fromStart.setStart(a, 0);
5348
+ if (isBlank(toEnd.toString())) {
5348
5349
  native.selection.setCursorLocation(a.parentNode, native.dom.nodeIndex(a) + 1);
5349
- } catch (e) {
5350
- console.warn("[editor] could not move the caret past the pasted link:", e?.message || e);
5350
+ } else if (isBlank(fromStart.toString())) {
5351
+ native.selection.setCursorLocation(a.parentNode, native.dom.nodeIndex(a));
5351
5352
  }
5352
- }, 0);
5353
+ } catch (e) {
5354
+ console.warn("[editor] could not move the caret off the link edge:", e?.message || e);
5355
+ }
5356
+ };
5357
+ native.on("paste", () => {
5358
+ setTimeout(stepOutOfLinkEdge, 0);
5359
+ });
5360
+ native.on("keydown", (e) => {
5361
+ if (e.ctrlKey || e.metaKey || e.altKey || e.key.length !== 1)
5362
+ return;
5363
+ stepOutOfLinkEdge();
5353
5364
  });
5354
5365
  }
5355
5366