@bobfrankston/rmfmail 1.2.153 → 1.2.154

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.
@@ -2052,7 +2052,7 @@ async function createTinyMceEditor(container2, opts = {}) {
2052
2052
  // window; TinyMCE's fullscreen plugin re-positions the container in
2053
2053
  // ways that produce a blank body, so it's not in the plugin list.
2054
2054
  menu: {
2055
- view: { title: "View", items: "code | visualaid visualchars visualblocks | preview | zoomIn zoomOut zoomReset" }
2055
+ view: { title: "View", items: "rmfsource | visualaid visualchars visualblocks | preview | zoomIn zoomOut zoomReset" }
2056
2056
  },
2057
2057
  // Disable the "Get all features" upsell badge that TinyMCE 6+
2058
2058
  // injects automatically when no premium plugins are listed.
@@ -2397,6 +2397,11 @@ async function createTinyMceEditor(container2, opts = {}) {
2397
2397
  text: "Code block\u2026",
2398
2398
  onAction: openCodeDialog
2399
2399
  });
2400
+ ed.ui.registry.addMenuItem("rmfsource", {
2401
+ icon: "sourcecode",
2402
+ text: "HTML source\u2026",
2403
+ onAction: () => openSourceDialog(ed)
2404
+ });
2400
2405
  ed.ui.registry.addMenuItem("zoomIn", {
2401
2406
  text: "Zoom in",
2402
2407
  shortcut: "Ctrl+=",
@@ -2624,9 +2629,77 @@ async function createTinyMceEditor(container2, opts = {}) {
2624
2629
  off(event, handler) {
2625
2630
  editor2.off(event, handler);
2626
2631
  },
2632
+ showSource() {
2633
+ openSourceDialog(editor2);
2634
+ },
2627
2635
  nativeEditor: editor2
2628
2636
  };
2629
2637
  }
2638
+ function openSourceDialog(editor2) {
2639
+ const SENTINEL = "\uE000";
2640
+ let offset = -1;
2641
+ try {
2642
+ const insert = () => editor2.selection.setContent(SENTINEL);
2643
+ if (typeof editor2.undoManager?.ignore === "function")
2644
+ editor2.undoManager.ignore(insert);
2645
+ else
2646
+ insert();
2647
+ const marked = editor2.getContent();
2648
+ offset = marked.indexOf(SENTINEL);
2649
+ try {
2650
+ const body = editor2.getBody();
2651
+ const doc = editor2.getDoc();
2652
+ const walk = doc.createTreeWalker(body, NodeFilter.SHOW_TEXT, null);
2653
+ let n;
2654
+ while (n = walk.nextNode()) {
2655
+ if (n.nodeValue && n.nodeValue.indexOf(SENTINEL) >= 0) {
2656
+ n.nodeValue = n.nodeValue.replace(SENTINEL, "");
2657
+ break;
2658
+ }
2659
+ }
2660
+ } catch {
2661
+ }
2662
+ } catch {
2663
+ }
2664
+ const source = editor2.getContent();
2665
+ const caretAt = offset >= 0 ? Math.min(offset, source.length) : source.length;
2666
+ editor2.windowManager.open({
2667
+ title: "HTML source",
2668
+ size: "large",
2669
+ body: {
2670
+ type: "panel",
2671
+ items: [{ type: "textarea", name: "src", label: "", maximized: true }]
2672
+ },
2673
+ initialData: { src: source },
2674
+ buttons: [
2675
+ { type: "cancel", text: "Cancel" },
2676
+ { type: "submit", text: "Save", primary: true }
2677
+ ],
2678
+ onSubmit: (api) => {
2679
+ const data = api.getData();
2680
+ editor2.undoManager.transact(() => editor2.setContent(data.src || ""));
2681
+ editor2.nodeChanged();
2682
+ api.close();
2683
+ }
2684
+ });
2685
+ const win = editor2.getWin && editor2.getWin() || window;
2686
+ const raf = win.requestAnimationFrame || ((f) => setTimeout(f, 16));
2687
+ raf(() => raf(() => {
2688
+ const tas = Array.from(document.querySelectorAll(".tox-dialog textarea"));
2689
+ const ta = tas[tas.length - 1];
2690
+ if (!ta)
2691
+ return;
2692
+ try {
2693
+ ta.focus();
2694
+ ta.setSelectionRange(caretAt, caretAt);
2695
+ const before = ta.value.slice(0, caretAt);
2696
+ const line = before.split("\n").length - 1;
2697
+ const lineH = parseFloat(getComputedStyle(ta).lineHeight) || 18;
2698
+ ta.scrollTop = Math.max(0, line * lineH - ta.clientHeight / 2);
2699
+ } catch {
2700
+ }
2701
+ }));
2702
+ }
2630
2703
  var init_rmf_tiny = __esm({
2631
2704
  "client/lib/rmf-tiny.js"() {
2632
2705
  "use strict";
@@ -5370,6 +5443,13 @@ window.addEventListener("compose-popout", () => {
5370
5443
  void popoutHandoff();
5371
5444
  });
5372
5445
  window.__msgerContextCommand = (id) => {
5446
+ if (id === "source") {
5447
+ try {
5448
+ editor?.showSource?.();
5449
+ } catch {
5450
+ }
5451
+ return;
5452
+ }
5373
5453
  const ne = editor?.nativeEditor;
5374
5454
  if (!ne) return;
5375
5455
  const isTiny = typeof ne.execCommand === "function" && ne.selection;