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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
const FORM_STATE_KEY = "kj-clipboard-form-state-v1";
function saveFormState() {
const state = {
content: document.getElementById("content").value,
isCode: document.getElementById("is-code").checked,
language: document.getElementById("lang-select").value,
};
sessionStorage.setItem(FORM_STATE_KEY, JSON.stringify(state));
}
function restoreFormState() {
const raw = sessionStorage.getItem(FORM_STATE_KEY);
if (!raw) {
toggleLang();
return;
}
try {
const state = JSON.parse(raw);
document.getElementById("content").value =
typeof state.content === "string" ? state.content : "";
document.getElementById("is-code").checked = !!state.isCode;
const langSelect = document.getElementById("lang-select");
if (typeof state.language === "string") {
const langExists = Array.from(langSelect.options).some(
(opt) => opt.value === state.language
);
langSelect.value = langExists ? state.language : "";
}
} catch (_err) {
sessionStorage.removeItem(FORM_STATE_KEY);
}
toggleLang();
}
function toggleLang() {
const sel = document.getElementById("lang-select");
sel.style.display = document.getElementById("is-code").checked
? "inline-block"
: "none";
saveFormState();
}
async function createPaste() {
const content = document.getElementById("content").value.trim();
if (!content) {
setStatus("nothing to paste.");
return;
}
const btn = document.getElementById("get-link-btn");
btn.disabled = true;
btn.textContent = "generating...";
setStatus("");
const body = {
content: content,
is_code: document.getElementById("is-code").checked,
language: document.getElementById("lang-select").value,
passphrase: document.getElementById("passphrase").value,
};
try {
const resp = await fetch("/api/paste", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
let data = null;
try {
data = await resp.json();
} catch (_err) {
setStatus("error: invalid server response");
return;
}
if (!resp.ok || !data || data.error || typeof data.url !== "string") {
const msg = data && data.error ? data.error : "request failed";
setStatus("error: " + msg);
return;
}
const url = window.location.origin + data.url;
const linkEl = document.getElementById("result-link");
linkEl.href = url;
linkEl.textContent = url;
document.getElementById("result").style.display = "block";
setStatus("done.");
} catch (e) {
setStatus("error: " + e.message);
} finally {
btn.disabled = false;
btn.textContent = "generate link";
}
}
async function copyLink() {
const url = document.getElementById("result-link").textContent;
if (!url) {
setStatus("nothing to copy.");
return;
}
try {
await navigator.clipboard.writeText(url);
setStatus("link copied.");
} catch (_err) {
setStatus("error: clipboard copy failed");
}
}
function setStatus(msg) {
document.getElementById("status").textContent = msg;
}
restoreFormState();
document.getElementById("get-link-btn").addEventListener("click", createPaste);
document.getElementById("copy-link-btn").addEventListener("click", function () {
void copyLink();
});
document.getElementById("is-code").addEventListener("change", toggleLang);
document.getElementById("content").addEventListener("input", saveFormState);
document.getElementById("lang-select").addEventListener("change", saveFormState);
// allow tab key in textarea
document.getElementById("content").addEventListener("keydown", function (e) {
if (e.key === "Tab") {
e.preventDefault();
const start = this.selectionStart;
const end = this.selectionEnd;
this.value =
this.value.substring(0, start) + "\t" + this.value.substring(end);
this.selectionStart = this.selectionEnd = start + 1;
saveFormState();
}
});
|