(function () { "use strict"; var $ = window.MailSharp; // Images inserted via the upload button (as opposed to the URL-based insertImage command) - // {cid, file}. The editor only ever holds a data: URI preview of these locally; the raw file // is uploaded separately (see submit()) and the src is rewritten to "cid:" right before // the HtmlBody is serialized, so the final message references the attached inline part instead // of embedding the image twice. var inlineImages = []; $.apiFetch("api/auth/state").then(function (authState) { if (!authState.isLoggedIn) { window.location.href = "Account/Login"; return; } document.getElementById("AccountId").value = authState.account.id; return $.apiFetch("api/language/state").then(function (langState) { $.applyStrings(langState.strings); document.documentElement.lang = langState.current; document.getElementById("linkBtn").setAttribute("data-prompt", langState.strings.compose_prompt_link_url); document.getElementById("imageBtn").setAttribute("data-prompt", langState.strings.compose_prompt_image_url); document.getElementById("ToInput").placeholder = langState.strings.compose_to_placeholder; applyPrefill(authState.account); }); }); function applyPrefill(account) { var raw = sessionStorage.getItem("mailsharp_compose_prefill"); sessionStorage.removeItem("mailsharp_compose_prefill"); var p = {}; if (raw) { try { p = JSON.parse(raw) || {}; } catch (e) { p = {}; } } if (p.to) document.getElementById("ToInput").value = p.to; if (p.cc) document.querySelector("[name=Cc]").value = p.cc; if (p.subject) document.querySelector("[name=Subject]").value = p.subject; var editor = document.getElementById("editor"); if (p.quoteHtml) { editor.innerHTML = p.quoteHtml; } else if (account && account.signature) { editor.innerHTML = "

" + $.esc(account.signature).replace(/\n/g, "
"); } } document.querySelectorAll("[data-cmd]").forEach(function (btn) { btn.addEventListener("click", function (e) { e.preventDefault(); var editor = document.getElementById("editor"); var cmd = btn.getAttribute("data-cmd"); if (cmd === "createLink") { var url = window.prompt(btn.getAttribute("data-prompt"), "https://"); if (!url) return; document.execCommand("createLink", false, url); } else if (cmd === "insertImage") { var imgUrl = window.prompt(btn.getAttribute("data-prompt"), "https://"); if (!imgUrl) return; document.execCommand("insertImage", false, imgUrl); } else { document.execCommand(cmd, false, undefined); } editor.focus(); }); }); document.getElementById("uploadImageBtn").addEventListener("click", function (e) { e.preventDefault(); document.getElementById("inlineImageInput").click(); }); document.getElementById("inlineImageInput").addEventListener("change", function (e) { var files = Array.prototype.slice.call(e.target.files || []); e.target.value = ""; // allow re-selecting the same file later files.forEach(function (file) { var cid = "img" + Date.now() + Math.floor(Math.random() * 100000) + "@mailsharp"; var reader = new FileReader(); reader.onload = function () { inlineImages.push({ cid: cid, file: file }); var editor = document.getElementById("editor"); editor.focus(); document.execCommand("insertHTML", false, ''); }; reader.readAsDataURL(file); }); }); function renderAttachmentsList() { var input = document.getElementById("attachmentsInput"); var files = Array.prototype.slice.call(input.files || []); var list = document.getElementById("attachmentsList"); list.innerHTML = files.map(function (f) { return '
📎 ' + $.esc(f.name) + " (" + Math.round(f.size / 1024 * 10) / 10 + " kB)
"; }).join(""); } document.getElementById("attachmentsInput").addEventListener("change", renderAttachmentsList); document.getElementById("fontName").addEventListener("change", function (e) { document.execCommand("fontName", false, e.target.value); document.getElementById("editor").focus(); }); document.getElementById("fontSize").addEventListener("change", function (e) { document.execCommand("fontSize", false, e.target.value); document.getElementById("editor").focus(); }); document.getElementById("textColor").addEventListener("input", function (e) { document.execCommand("foreColor", false, e.target.value); document.getElementById("editor").focus(); }); document.getElementById("bgColor").addEventListener("input", function (e) { document.execCommand("hiliteColor", false, e.target.value); document.getElementById("editor").focus(); }); function submit(endpoint) { var form = document.getElementById("composeForm"); var editor = document.getElementById("editor"); // Rewrite each uploaded inline image's src from its local data: URI preview to "cid:" // right before serializing - only for images still actually present in the editor (the // user may have deleted one after inserting it), so nothing gets uploaded/attached for an // image that's no longer referenced anywhere in the body. Done on a detached clone, not the // live editor, so a failed send doesn't leave the visible editor showing broken images. var clone = editor.cloneNode(true); var usedCids = {}; clone.querySelectorAll("img[data-cid]").forEach(function (img) { var cid = img.getAttribute("data-cid"); usedCids[cid] = true; img.setAttribute("src", "cid:" + cid); }); document.getElementById("HtmlBody").value = clone.innerHTML; var formData = new FormData(form); inlineImages.forEach(function (item) { if (usedCids[item.cid]) formData.append("inline:" + item.cid, item.file, item.file.name); }); $.apiFetch(endpoint, { method: "POST", body: formData }) .then(function (result) { if (result && result.sentError) { window.alert("Verzonden, maar niet opgeslagen in Verzonden items: " + result.sentError); } window.location.href = "./"; }) .catch(function (err) { if (!err.cancelled) window.alert(err.message); }); } document.getElementById("composeForm").addEventListener("submit", function (e) { e.preventDefault(); submit("api/mail/send"); }); document.getElementById("saveDraftBtn").addEventListener("click", function () { submit("api/mail/save-draft"); }); })();