@bobfrankston/rmfmail 1.2.287 → 1.2.289
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/.commitmsg +12 -33
- package/client/android-bootstrap.bundle.js +22 -5
- package/client/android-bootstrap.bundle.js.map +2 -2
- package/client/app.bundle.js +2 -1
- package/client/app.bundle.js.map +2 -2
- package/client/components/message-viewer.js +9 -1
- package/client/components/message-viewer.js.map +1 -1
- package/client/components/message-viewer.ts +10 -2
- package/client/compose/compose.bundle.js +63 -1
- package/client/compose/compose.bundle.js.map +3 -3
- package/client/lib/rmf-tiny.js +85 -0
- package/npmchanges.md +68 -0
- package/package.json +7 -7
- package/packages/mailx-imap/package-lock.json +2 -2
- package/packages/mailx-imap/package.json +1 -1
- package/packages/mailx-settings/package.json +1 -1
- package/packages/mailx-store/package.json +1 -1
- package/packages/mailx-store-web/package.json +1 -1
- package/packages/mailx-types/package.json +1 -1
- package/packages/mailx-types/trust.d.ts +7 -1
- package/packages/mailx-types/trust.d.ts.map +1 -1
- package/packages/mailx-types/trust.js +44 -4
- package/packages/mailx-types/trust.js.map +1 -1
- package/packages/mailx-types/trust.ts +58 -6
- /package/packages/mailx-imap/{node_modules.npmglobalize-stash-38644 → node_modules.npmglobalize-stash-53712}/.package-lock.json +0 -0
|
@@ -2686,7 +2686,15 @@ async function createTinyMceEditor(container2, opts = {}) {
|
|
|
2686
2686
|
// window; TinyMCE's fullscreen plugin re-positions the container in
|
|
2687
2687
|
// ways that produce a blank body, so it's not in the plugin list.
|
|
2688
2688
|
menu: {
|
|
2689
|
-
view: { title: "View", items: "rmfsource | visualaid visualchars visualblocks | preview | zoomIn zoomOut zoomReset" }
|
|
2689
|
+
view: { title: "View", items: "rmfsource | visualaid visualchars visualblocks | preview | zoomIn zoomOut zoomReset" },
|
|
2690
|
+
// Insert menu — TinyMCE's default list minus the items whose
|
|
2691
|
+
// plugins we don't load (media, pagebreak, anchor, accordion),
|
|
2692
|
+
// plus the two quoting items. Listed in full because naming a
|
|
2693
|
+
// menu REPLACES its item list; the defaults do not carry over.
|
|
2694
|
+
insert: {
|
|
2695
|
+
title: "Insert",
|
|
2696
|
+
items: "image link inserttable | rmfblockquote rmfquotepaste | rmfcode codesample charmap emoticons | hr nonbreaking insertdatetime"
|
|
2697
|
+
}
|
|
2690
2698
|
},
|
|
2691
2699
|
// Disable the "Get all features" upsell badge that TinyMCE 6+
|
|
2692
2700
|
// injects automatically when no premium plugins are listed.
|
|
@@ -3107,6 +3115,18 @@ async function createTinyMceEditor(container2, opts = {}) {
|
|
|
3107
3115
|
text: "Code block\u2026",
|
|
3108
3116
|
onAction: openCodeDialog
|
|
3109
3117
|
});
|
|
3118
|
+
ed.ui.registry.addMenuItem("rmfblockquote", {
|
|
3119
|
+
icon: "quote",
|
|
3120
|
+
text: "Blockquote",
|
|
3121
|
+
onAction: () => ed.execCommand("mceBlockQuote")
|
|
3122
|
+
});
|
|
3123
|
+
ed.ui.registry.addMenuItem("rmfquotepaste", {
|
|
3124
|
+
icon: "quote",
|
|
3125
|
+
text: "Quoted text (paste)\u2026",
|
|
3126
|
+
onAction: () => {
|
|
3127
|
+
void pasteAsQuote(ed);
|
|
3128
|
+
}
|
|
3129
|
+
});
|
|
3110
3130
|
ed.ui.registry.addMenuItem("rmfsource", {
|
|
3111
3131
|
icon: "sourcecode",
|
|
3112
3132
|
text: "HTML source\u2026",
|
|
@@ -3345,6 +3365,48 @@ async function createTinyMceEditor(container2, opts = {}) {
|
|
|
3345
3365
|
nativeEditor: editor2
|
|
3346
3366
|
};
|
|
3347
3367
|
}
|
|
3368
|
+
async function pasteAsQuote(ed) {
|
|
3369
|
+
const notify = (text, type) => {
|
|
3370
|
+
try {
|
|
3371
|
+
ed.notificationManager.open({ text, type, timeout: 4e3 });
|
|
3372
|
+
} catch {
|
|
3373
|
+
}
|
|
3374
|
+
};
|
|
3375
|
+
const escape = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
3376
|
+
const fragment = (html2) => {
|
|
3377
|
+
const marked = html2.match(/<!--\s*StartFragment\s*-->([\s\S]*?)<!--\s*EndFragment\s*-->/i);
|
|
3378
|
+
const inner = marked ? marked[1] : html2.replace(/[\s\S]*<body[^>]*>|<\/body>[\s\S]*/gi, "");
|
|
3379
|
+
return inner.trim();
|
|
3380
|
+
};
|
|
3381
|
+
let html = "";
|
|
3382
|
+
try {
|
|
3383
|
+
const clip = navigator.clipboard;
|
|
3384
|
+
if (clip?.read) {
|
|
3385
|
+
const items = await clip.read();
|
|
3386
|
+
for (const item of items) {
|
|
3387
|
+
if (!item.types.includes("text/html"))
|
|
3388
|
+
continue;
|
|
3389
|
+
html = fragment(await (await item.getType("text/html")).text());
|
|
3390
|
+
break;
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
if (!html) {
|
|
3394
|
+
const text = await navigator.clipboard?.readText?.() || "";
|
|
3395
|
+
if (text.trim()) {
|
|
3396
|
+
html = text.trim().split(/\n\s*\n/).map((para) => `<p>${escape(para).replace(/\n/g, "<br>")}</p>`).join("");
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
} catch (e) {
|
|
3400
|
+
notify(`Could not read the clipboard: ${e?.message || e}`, "error");
|
|
3401
|
+
return;
|
|
3402
|
+
}
|
|
3403
|
+
if (!html) {
|
|
3404
|
+
notify("There is nothing on the clipboard to quote.", "warning");
|
|
3405
|
+
return;
|
|
3406
|
+
}
|
|
3407
|
+
ed.insertContent(`<blockquote>${html}</blockquote>`);
|
|
3408
|
+
ed.undoManager.add();
|
|
3409
|
+
}
|
|
3348
3410
|
function openSourceDialog(editor2) {
|
|
3349
3411
|
const SENTINEL = "\uE000";
|
|
3350
3412
|
let offset = -1;
|