~gitpocket/gitpocket

4
ef9167bb0e271e16e00190335578bd4a6a870e89
mainfeed-discovery
gitpocket/static/editor.js -rw-r--r--2.8 KiB ViewLogBlameView rawPermalink a6b5bf4fe7 feat(markdown): image attachments and preview 8 days ago
 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, "![" + name + "](" + j.url + ")"); })
        .catch(function (err) { area.value = area.value.replace(marker + "\n", ""); alert(err.message); });
    });
  }
});