1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
document.querySelectorAll("textarea[data-md]").forEach(function (area) {
var bar = document.createElement("div");
bar.className = "mdbar";
var write = button("Write"), view = button("Preview"), attach = button("Attach image");
var pick = document.createElement("input");
pick.type = "file";
pick.accept = "image/png,image/jpeg,image/gif,image/webp";
pick.multiple = true;
pick.hidden = true;
var shown = document.createElement("div");
shown.className = "readme mdpreview";
shown.hidden = true;
write.classList.add("on");
bar.append(write, view, attach, pick);
area.before(bar);
area.after(shown);
function button(label) {
var b = document.createElement("button");
b.type = "button";
b.textContent = label;
return b;
}
function mode(preview) {
write.classList.toggle("on", !preview);
view.classList.toggle("on", preview);
area.hidden = preview;
shown.hidden = !preview;
}
write.onclick = function () { mode(false); area.focus(); };
if (area.form) area.form.addEventListener("submit", function () { mode(false); });
view.onclick = function () {
shown.textContent = "Loading…";
mode(true);
fetch("/preview", { method: "POST", body: new URLSearchParams({ body: area.value }) })
.then(function (r) { return r.text(); })
.then(function (html) { shown.innerHTML = area.value.trim() ? html : "<p class=\"muted\">Nothing to preview.</p>"; });
};
attach.onclick = function () { pick.click(); };
pick.onchange = function () { send(pick.files); pick.value = ""; };
area.addEventListener("paste", function (e) {
var files = e.clipboardData && e.clipboardData.files;
if (files && files.length) { e.preventDefault(); send(files); }
});
area.addEventListener("dragover", function (e) { e.preventDefault(); });
area.addEventListener("drop", function (e) {
if (e.dataTransfer.files.length) { e.preventDefault(); send(e.dataTransfer.files); }
});
function insert(text) {
var at = area.selectionStart, end = area.selectionEnd;
area.value = area.value.slice(0, at) + text + area.value.slice(end);
area.selectionStart = area.selectionEnd = at + text.length;
}
function send(files) {
Array.prototype.forEach.call(files, function (file) {
var name = file.name.replace(/[\[\]()]/g, "") || "image";
var marker = "![Uploading " + name + "…]()";
insert(marker + "\n");
fetch("/attachments", { method: "POST", body: file })
.then(function (r) { return r.ok ? r.json() : r.text().then(function (t) { throw new Error(t.trim()); }); })
.then(function (j) { area.value = area.value.replace(marker, ""); })
.catch(function (err) { area.value = area.value.replace(marker + "\n", ""); alert(err.message); });
});
}
});
|