@bobfrankston/rmfmail 1.0.678 → 1.0.679

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.
@@ -1,42 +1,55 @@
1
1
  /**
2
- * Right-click spell-check for the TinyMCE compose editor.
2
+ * Live spell-check for the TinyMCE compose editor.
3
3
  *
4
4
  * Why this exists: WebView2's built-in spell checker isn't reliably
5
5
  * enabled on our msger-hosted compose iframe (see msger main.rs around
6
- * AreDefaultContextMenusEnabled — settings are left at defaults but
7
- * `IsSpellcheckEnabled` is never explicitly set, and the default varies
8
- * by WebView2 runtime). Rather than depend on the host, we ship a JS
9
- * spellchecker (`nspell`) + the standard `dictionary-en` Hunspell files.
6
+ * AreDefaultContextMenusEnabled — the comment claims it leaves
7
+ * defaults for spell-suggest menus, but `IsSpellcheckEnabled` is never
8
+ * explicitly set and the default varies by WebView2 runtime). Rather
9
+ * than depend on the host, we ship a JS spellchecker (`nspell`) + the
10
+ * standard `dictionary-en` Hunspell files.
10
11
  *
11
- * Scope (intentionally minimal — Bob 2026-05-11):
12
- * - On right-click inside the editor body, find the word at the click.
13
- * - If nspell flags it, show a small popup with suggestions plus an
14
- * "Add to mailx dictionary" item.
15
- * - Custom dictionary persists in localStorage under
16
- * `mailx-user-dict`; added words are also fed to nspell.add() so the
17
- * same session stops flagging them immediately.
18
- * - No live red-underline decoration that would mutate DOM the user
19
- * is actively typing into and adds significant complexity. The
20
- * right-click flow gives the suggestions experience without the
21
- * editing-experience tradeoffs.
12
+ * Two layers:
13
+ * 1. Live decoration words that nspell flags get wrapped in a
14
+ * `<span data-mailx-spellerror="1">` while editing. CSS gives them
15
+ * a wavy red underline (text-decoration: underline wavy #d33). The
16
+ * markers are stripped at serialization time so they never reach
17
+ * the sent message or the saved draft.
18
+ * 2. Right-click clicking on a marker shows our own popup with
19
+ * suggestions plus "Add to dictionary" / "Ignore (this session)".
22
20
  *
23
- * Loads nspell + the ~1 MB dictionary lazily on first right-click in
24
- * an editor session, so picking TinyMCE in Settings doesn't pay this
25
- * cost up front.
21
+ * Decoration runs:
22
+ * - Once after the editor inits + dict loads (initial scan of pre-
23
+ * populated quote / signature, though we skip blockquote content).
24
+ * - Debounced after every input (~500 ms idle).
25
+ * - After setContent (paste, reply-quote insertion, …).
26
+ *
27
+ * The decoration walker:
28
+ * - Skips `<blockquote>` (the quoted reply — not the user's words),
29
+ * `<code>`, `<pre>`, `<a>` (URLs aren't natural-language words),
30
+ * and content inside any existing marker (so re-scans don't double-
31
+ * wrap).
32
+ * - Uses TinyMCE's `undoManager.ignore` + selection bookmarks so the
33
+ * decoration mutations don't pollute undo and don't move the caret.
34
+ *
35
+ * Dictionary persistence:
36
+ * - User additions: `localStorage["mailx-user-dict"]` (a JSON array).
37
+ * - "Ignore this session": in-memory only via `nspell.add()`.
26
38
  */
27
39
  // @ts-expect-error — nspell ships no type defs. Treated as `any`; the
28
40
  // surface we use (`new NSpell({aff, dic})`, `.correct`, `.suggest`,
29
41
  // `.add`) is small and stable.
30
42
  import NSpell from "nspell";
31
43
  const USER_DICT_KEY = "mailx-user-dict";
44
+ const MARKER_ATTR = "data-mailx-spellerror";
45
+ const DECORATE_DEBOUNCE_MS = 500;
46
+ const MIN_WORD_LEN = 3;
47
+ const SKIP_TAGS = new Set(["BLOCKQUOTE", "CODE", "PRE", "A", "SCRIPT", "STYLE", "KBD", "SAMP", "VAR"]);
32
48
  let spellPromise = null;
33
49
  async function getSpell() {
34
50
  if (spellPromise)
35
51
  return spellPromise;
36
52
  spellPromise = (async () => {
37
- // Paths are relative to compose.html. msger serves files from
38
- // contentDir=client/, so `../lib/dict/...` lands in the right
39
- // place under both msger.localhost and Android file:// schemes.
40
53
  const [affRes, dicRes] = await Promise.all([
41
54
  fetch("../lib/dict/en.aff"),
42
55
  fetch("../lib/dict/en.dic"),
@@ -46,14 +59,13 @@ async function getSpell() {
46
59
  }
47
60
  const [aff, dic] = await Promise.all([affRes.text(), dicRes.text()]);
48
61
  const sp = new NSpell({ aff, dic });
49
- // Seed with user dictionary.
50
62
  try {
51
63
  const raw = localStorage.getItem(USER_DICT_KEY);
52
64
  if (raw)
53
65
  for (const w of JSON.parse(raw))
54
66
  sp.add(w);
55
67
  }
56
- catch { /* corrupt localStorage entry — start clean */ }
68
+ catch { /* corrupt entry — start clean */ }
57
69
  return sp;
58
70
  })();
59
71
  return spellPromise;
@@ -67,72 +79,156 @@ function addToUserDict(word, sp) {
67
79
  arr.push(word);
68
80
  localStorage.setItem(USER_DICT_KEY, JSON.stringify(arr));
69
81
  }
70
- catch { /* localStorage write failed — at least the in-memory add wins for this session */ }
82
+ catch { /* */ }
71
83
  sp.add(word);
72
84
  }
73
- /** Find the word at a given (x,y) point inside a document. Uses
74
- * `caretPositionFromPoint` (Firefox) or `caretRangeFromPoint`
75
- * (WebKit/Blink). Returns the word string + a Range covering it,
76
- * or null if the click was on whitespace / punctuation / outside text. */
77
- function wordAtPoint(doc, x, y) {
78
- const anyDoc = doc;
79
- let caretNode = null;
80
- let caretOffset = 0;
81
- if (typeof anyDoc.caretRangeFromPoint === "function") {
82
- const r = anyDoc.caretRangeFromPoint(x, y);
83
- if (!r)
84
- return null;
85
- caretNode = r.startContainer;
86
- caretOffset = r.startOffset;
85
+ // ── Live decoration ───────────────────────────────────────────────
86
+ /** Walk the editor body, wrap newly-misspelled words, unwrap markers
87
+ * that are now correct. Mutations are wrapped in undoManager.ignore so
88
+ * they don't pollute undo history; selection is preserved via a
89
+ * TinyMCE bookmark. */
90
+ function decorate(editor, sp) {
91
+ const body = editor.getBody?.();
92
+ const doc = editor.getDoc?.();
93
+ if (!body || !doc)
94
+ return;
95
+ // Don't fight active typing — if the caret is INSIDE a current
96
+ // misspelling marker, the user is mid-correction. Let them finish.
97
+ // We'll re-scan after the debounce on their next pause.
98
+ const sel = doc.getSelection();
99
+ if (sel && sel.rangeCount > 0) {
100
+ const focus = sel.focusNode;
101
+ let p = focus;
102
+ while (p && p !== body) {
103
+ if (p.nodeType === Node.ELEMENT_NODE && p.hasAttribute?.(MARKER_ATTR)) {
104
+ // Cursor inside a marker — skip this pass; re-decorate
105
+ // when they next stop typing.
106
+ return;
107
+ }
108
+ p = p.parentNode;
109
+ }
87
110
  }
88
- else if (typeof anyDoc.caretPositionFromPoint === "function") {
89
- const p = anyDoc.caretPositionFromPoint(x, y);
90
- if (!p)
91
- return null;
92
- caretNode = p.offsetNode;
93
- caretOffset = p.offset;
111
+ const bookmark = editor.selection?.getBookmark?.(2);
112
+ try {
113
+ editor.undoManager?.ignore?.(() => {
114
+ // 1. Unwrap any existing markers — we'll re-wrap fresh based
115
+ // on the current content. Cheaper than incremental update
116
+ // and avoids stale markers if the user fixed a word
117
+ // without going through our menu (just retyped it).
118
+ const old = body.querySelectorAll(`span[${MARKER_ATTR}]`);
119
+ for (const m of old) {
120
+ const parent = m.parentNode;
121
+ if (!parent)
122
+ continue;
123
+ while (m.firstChild)
124
+ parent.insertBefore(m.firstChild, m);
125
+ parent.removeChild(m);
126
+ }
127
+ // Merge text nodes that were split by the now-removed spans.
128
+ body.normalize();
129
+ // 2. Walk text nodes and collect words to wrap.
130
+ const walker = doc.createTreeWalker(body, NodeFilter.SHOW_TEXT, {
131
+ acceptNode(node) {
132
+ let p = node.parentNode;
133
+ while (p && p !== body) {
134
+ if (p.nodeType === Node.ELEMENT_NODE && SKIP_TAGS.has(p.tagName)) {
135
+ return NodeFilter.FILTER_REJECT;
136
+ }
137
+ p = p.parentNode;
138
+ }
139
+ return NodeFilter.FILTER_ACCEPT;
140
+ },
141
+ });
142
+ const hits = [];
143
+ let n = walker.nextNode();
144
+ // Letter / digit / apostrophe / hyphen — tokenize words via
145
+ // Unicode-aware regex so we don't false-flag accented words.
146
+ const WORD_RE = /[\p{L}][\p{L}'’\-]*/gu;
147
+ while (n) {
148
+ const tn = n;
149
+ const text = tn.data;
150
+ let m;
151
+ WORD_RE.lastIndex = 0;
152
+ while ((m = WORD_RE.exec(text)) !== null) {
153
+ const word = m[0];
154
+ if (word.length < MIN_WORD_LEN)
155
+ continue;
156
+ if (sp.correct(word))
157
+ continue;
158
+ hits.push({ node: tn, start: m.index, end: m.index + word.length });
159
+ }
160
+ n = walker.nextNode();
161
+ }
162
+ // 3. Wrap hits in reverse order — wrapping a span splits the
163
+ // text node, which would invalidate earlier offsets. Going
164
+ // right-to-left keeps the not-yet-touched offsets valid.
165
+ hits.reverse();
166
+ for (const h of hits) {
167
+ const range = doc.createRange();
168
+ range.setStart(h.node, h.start);
169
+ range.setEnd(h.node, h.end);
170
+ const span = doc.createElement("span");
171
+ span.setAttribute(MARKER_ATTR, "1");
172
+ try {
173
+ range.surroundContents(span);
174
+ }
175
+ catch { /* range spans a node boundary — rare; skip */ }
176
+ }
177
+ });
94
178
  }
95
- else {
96
- return null;
179
+ finally {
180
+ if (bookmark)
181
+ try {
182
+ editor.selection?.moveToBookmark?.(bookmark);
183
+ }
184
+ catch { /* */ }
97
185
  }
98
- if (!caretNode || caretNode.nodeType !== Node.TEXT_NODE)
99
- return null;
100
- const text = caretNode.data;
101
- // Expand left and right from caret to a word boundary. Hunspell-ish
102
- // word characters: letters, digits, apostrophe, hyphen-in-word.
103
- const isWordChar = (ch) => /[\p{L}\p{N}'’\-]/u.test(ch);
104
- let start = caretOffset;
105
- let end = caretOffset;
106
- while (start > 0 && isWordChar(text[start - 1]))
107
- start--;
108
- while (end < text.length && isWordChar(text[end]))
109
- end++;
110
- if (start === end)
111
- return null;
112
- // Strip leading/trailing punctuation a word boundary regex might
113
- // have included (apostrophe at the edge: "'hello" "hello").
114
- let word = text.slice(start, end);
115
- while (word.length && /^['’\-]/.test(word)) {
116
- word = word.slice(1);
117
- start++;
186
+ }
187
+ /** Inject the wavy-red CSS into the editor iframe. */
188
+ function installDecorationStyle(editor) {
189
+ const doc = editor.getDoc?.();
190
+ if (!doc)
191
+ return;
192
+ if (doc.getElementById("mailx-spell-style"))
193
+ return;
194
+ const style = doc.createElement("style");
195
+ style.id = "mailx-spell-style";
196
+ style.textContent = `
197
+ span[${MARKER_ATTR}] {
198
+ text-decoration: underline wavy #d33;
199
+ text-decoration-skip-ink: none;
200
+ text-underline-offset: 2px;
201
+ /* No background keeps the styling subtle, like a native
202
+ * spell underline, not a Find-highlight. */
203
+ background: transparent;
204
+ }
205
+ `;
206
+ doc.head.appendChild(style);
207
+ }
208
+ /** Strip decoration markers from serialized output. TinyMCE fires
209
+ * attribute filters during getContent / draft-save; this filter
210
+ * unwraps the span so the saved/sent HTML carries only the text. */
211
+ function installSerializerFilter(editor) {
212
+ if (editor.__mailxSpellSerializerWired)
213
+ return;
214
+ editor.__mailxSpellSerializerWired = true;
215
+ try {
216
+ editor.serializer.addAttributeFilter(MARKER_ATTR, (nodes) => {
217
+ for (const node of nodes) {
218
+ // TinyMCE's html-node API: `unwrap()` replaces the node
219
+ // with its children. Exactly what we want — keep the
220
+ // text, drop the span.
221
+ if (typeof node.unwrap === "function")
222
+ node.unwrap();
223
+ }
224
+ });
118
225
  }
119
- while (word.length && /['’\-]$/.test(word)) {
120
- word = word.slice(0, -1);
121
- end--;
226
+ catch (e) {
227
+ console.warn("[spellcheck] serializer filter setup failed:", e);
122
228
  }
123
- if (!word)
124
- return null;
125
- const range = doc.createRange();
126
- range.setStart(caretNode, start);
127
- range.setEnd(caretNode, end);
128
- return { word, range };
129
229
  }
130
- /** Show a small floating menu at (x, y) in the parent document
131
- * (NOT inside the editor iframe — the iframe clips to its own bounds,
132
- * and a positioned menu can extend past the iframe edge). Returns
133
- * a remove() function. */
230
+ // ── Context menu ──────────────────────────────────────────────────
134
231
  function showSuggestionsMenu(parentDoc, x, y, items) {
135
- // Close any prior instance.
136
232
  parentDoc.getElementById("mailx-spell-menu")?.remove();
137
233
  const menu = parentDoc.createElement("div");
138
234
  menu.id = "mailx-spell-menu";
@@ -147,11 +243,11 @@ function showSuggestionsMenu(parentDoc, x, y, items) {
147
243
  box-shadow: 0 4px 16px rgba(0,0,0,0.18);
148
244
  padding: 4px 0;
149
245
  font: 13px system-ui, sans-serif;
150
- min-width: 160px;
246
+ min-width: 180px;
151
247
  max-width: 320px;
152
248
  `;
153
249
  for (const it of items) {
154
- if (it.label === "---") {
250
+ if (it.separator) {
155
251
  const sep = parentDoc.createElement("div");
156
252
  sep.style.cssText = "border-top:1px solid var(--color-border,#ddd); margin: 4px 0;";
157
253
  menu.appendChild(sep);
@@ -179,13 +275,11 @@ function showSuggestionsMenu(parentDoc, x, y, items) {
179
275
  menu.appendChild(btn);
180
276
  }
181
277
  parentDoc.body.appendChild(menu);
182
- // Clamp into viewport if it would overflow.
183
278
  const r = menu.getBoundingClientRect();
184
279
  if (r.right > window.innerWidth)
185
280
  menu.style.left = `${Math.max(8, window.innerWidth - r.width - 8)}px`;
186
281
  if (r.bottom > window.innerHeight)
187
282
  menu.style.top = `${Math.max(8, window.innerHeight - r.height - 8)}px`;
188
- // Dismiss on next click anywhere or Esc.
189
283
  const dismiss = (e) => {
190
284
  if (e.type === "keydown" && e.key !== "Escape")
191
285
  return;
@@ -200,12 +294,13 @@ function showSuggestionsMenu(parentDoc, x, y, items) {
200
294
  parentDoc.addEventListener("keydown", dismiss, true);
201
295
  }, 0);
202
296
  }
203
- /** Replace the text covered by `range` with `replacement` via a normal
204
- * Selection edit TinyMCE observes this through its normal undo /
205
- * dirty-tracking pathway. Document.execCommand("insertText") gives the
206
- * best undo integration; fall back to range mutation if the command
207
- * isn't recognized (older WebViews). */
208
- function replaceRange(doc, range, replacement) {
297
+ /** Replace a misspelling marker span with the correction. Done via
298
+ * range-based selection + insertText so TinyMCE's undo stack and
299
+ * dirty-tracking pick it up properly. */
300
+ function replaceMarker(editor, marker, replacement) {
301
+ const doc = editor.getDoc();
302
+ const range = doc.createRange();
303
+ range.selectNode(marker);
209
304
  const sel = doc.getSelection();
210
305
  if (!sel)
211
306
  return;
@@ -222,75 +317,87 @@ function replaceRange(doc, range, replacement) {
222
317
  range.insertNode(doc.createTextNode(replacement));
223
318
  }
224
319
  }
225
- /** Wire the right-click spell-suggest flow into a TinyMCE editor instance.
226
- * Idempotent (safe to call multiple times only attaches once). */
320
+ // ── Public entry point ────────────────────────────────────────────
321
+ /** Wire the spell-check into a TinyMCE editor instance. Idempotent. */
227
322
  export function wireSpellcheck(editor) {
228
323
  if (editor.__mailxSpellWired)
229
324
  return;
230
325
  editor.__mailxSpellWired = true;
231
- const iframeDoc = editor.getDoc?.() || null;
232
- if (!iframeDoc)
233
- return;
326
+ let sp = null;
327
+ let decorateTimer = null;
328
+ const scheduleDecorate = () => {
329
+ if (!sp)
330
+ return;
331
+ if (decorateTimer)
332
+ clearTimeout(decorateTimer);
333
+ decorateTimer = setTimeout(() => {
334
+ decorateTimer = null;
335
+ if (sp)
336
+ decorate(editor, sp);
337
+ }, DECORATE_DEBOUNCE_MS);
338
+ };
339
+ // Kick off the dictionary load. First decoration runs as soon as
340
+ // it resolves; subsequent runs are triggered by editor events.
341
+ getSpell().then((loaded) => {
342
+ sp = loaded;
343
+ installDecorationStyle(editor);
344
+ installSerializerFilter(editor);
345
+ decorate(editor, loaded);
346
+ }).catch((err) => {
347
+ console.error("[spellcheck] dict load failed:", err);
348
+ });
349
+ // Re-decorate on edits / paste / content swap. `nodechange` covers
350
+ // most of these; `input` catches typing in finer-grained events on
351
+ // some TinyMCE versions.
352
+ editor.on("input nodechange setcontent paste keyup", scheduleDecorate);
353
+ // Right-click handler. If the click landed on a marker span, show
354
+ // suggestions; otherwise let the default menu (WebView2's) fire.
355
+ const iframeDoc = editor.getDoc();
234
356
  iframeDoc.addEventListener("contextmenu", (ev) => {
235
357
  const e = ev;
236
- // Translate the iframe-internal point to the parent's viewport
237
- // for menu positioning. The iframe element's bounding rect plus
238
- // the event's clientX/Y inside the iframe gives parent-relative
239
- // coords.
240
- const iframeEl = editor.iframeElement;
241
- if (!iframeEl)
358
+ const target = e.target;
359
+ if (!target)
242
360
  return;
243
- const found = wordAtPoint(iframeDoc, e.clientX, e.clientY);
244
- if (!found)
245
- return; // not on a word — let WebView2 default fire
246
- // Lazy-load the dictionary. First right-click on a word in any
247
- // editor session triggers the load; subsequent are instant.
248
- getSpell().then(sp => {
249
- if (sp.correct(found.word))
250
- return; // word IS in the dictionary, no menu
251
- // Misspelled — suppress default and show suggestions.
252
- const sugs = sp.suggest(found.word).slice(0, 7);
253
- const iframeRect = iframeEl.getBoundingClientRect();
254
- const menuX = iframeRect.left + e.clientX;
255
- const menuY = iframeRect.top + e.clientY;
256
- const items = [];
257
- if (sugs.length === 0) {
258
- items.push({ label: "(no suggestions)", action: () => { } });
259
- }
260
- else {
261
- for (const s of sugs) {
262
- items.push({
263
- label: s,
264
- emphasized: true,
265
- action: () => replaceRange(iframeDoc, found.range, s),
266
- });
267
- }
268
- }
269
- items.push({ label: "---", action: () => { } });
270
- items.push({
271
- label: `Add "${found.word}" to dictionary`,
272
- action: () => addToUserDict(found.word, sp),
273
- });
274
- items.push({
275
- label: "Ignore (this session)",
276
- action: () => sp.add(found.word),
277
- });
278
- showSuggestionsMenu(document, menuX, menuY, items);
279
- }).catch(err => {
280
- // Dict load failed (network / corrupt files). Don't intercept
281
- // the menu — let WebView2 default fire. Log so it's debuggable.
282
- console.error("[spellcheck] dict load failed:", err);
361
+ const marker = target.closest?.(`span[${MARKER_ATTR}]`);
362
+ if (!marker)
363
+ return; // not on a misspelled word — default menu fires
364
+ const word = marker.textContent || "";
365
+ if (!word || !sp)
283
366
  return;
284
- });
285
- // Preempt the browser default ONLY when we're about to show our
286
- // own menu. We don't know synchronously whether the word is
287
- // misspelled (the load is async), so we have to commit to either
288
- // intercepting or not. Compromise: preempt always when on a
289
- // word, then dismiss instantly if the word turned out correct.
290
- // For the user's typical case (right-click on text), this means
291
- // a brief moment where neither menu shows — acceptable.
292
367
  e.preventDefault();
293
368
  e.stopPropagation();
369
+ const sugs = sp.suggest(word).slice(0, 7);
370
+ const iframeEl = editor.iframeElement;
371
+ const iframeRect = iframeEl ? iframeEl.getBoundingClientRect() : { left: 0, top: 0 };
372
+ const items = [];
373
+ if (sugs.length === 0) {
374
+ items.push({ label: "(no suggestions)", action: () => { } });
375
+ }
376
+ else {
377
+ for (const s of sugs) {
378
+ items.push({
379
+ label: s,
380
+ emphasized: true,
381
+ action: () => {
382
+ replaceMarker(editor, marker, s);
383
+ // Re-decorate so the replacement is checked too.
384
+ scheduleDecorate();
385
+ },
386
+ });
387
+ }
388
+ }
389
+ items.push({ label: "", action: () => { }, separator: true });
390
+ items.push({
391
+ label: `Add "${word}" to dictionary`,
392
+ action: () => { if (sp)
393
+ addToUserDict(word, sp); scheduleDecorate(); },
394
+ });
395
+ items.push({
396
+ label: "Ignore (this session)",
397
+ action: () => { if (sp)
398
+ sp.add(word); scheduleDecorate(); },
399
+ });
400
+ showSuggestionsMenu(document, iframeRect.left + e.clientX, iframeRect.top + e.clientY, items);
294
401
  }, true);
295
402
  }
296
403
  //# sourceMappingURL=spellcheck.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spellcheck.js","sourceRoot":"","sources":["spellcheck.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spellcheck.js","sourceRoot":"","sources":["spellcheck.ts"],"names":[],"mappings":"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"}