From 006d7797ac27739e1adb500749e384c0006ba00a Mon Sep 17 00:00:00 2001 From: kj_sh604 Date: Sun, 15 Mar 2026 13:58:33 -0400 Subject: refactor: multiple fixes and features --- src/index.html | 293 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/main.js | 111 ++++++++++++++++++++++ src/server.py | 20 ++++ 3 files changed, 423 insertions(+), 1 deletion(-) create mode 100644 src/main.js diff --git a/src/index.html b/src/index.html index 6e166fd..e906dd3 100644 --- a/src/index.html +++ b/src/index.html @@ -1 +1,292 @@ -kj-clipboard

kj-clipboard

no frills, just a public clipboard on the internet that you can use to share snippets around... that's it.


 encrypted with mojicrypt
link:
\ No newline at end of file + + + + + + + + + + + kj-clipboard + + + + + +

kj-clipboard

+

no frills, just a public clipboard on the internet that you can use to share snippets around... that's it.

+ +

 encrypted with mojicrypt +
link:
+
+ + + + \ No newline at end of file diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..9b33dca --- /dev/null +++ b/src/main.js @@ -0,0 +1,111 @@ +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), + }); + const data = await resp.json(); + if (data.error) { + setStatus("error: " + data.error); + btn.disabled = false; + btn.textContent = "generate link"; + 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); + } + btn.disabled = false; + btn.textContent = "generate link"; +} + +function copyLink() { + const url = document.getElementById("result-link").textContent; + navigator.clipboard.writeText(url); +} + +function setStatus(msg) { + document.getElementById("status").textContent = msg; +} + +restoreFormState(); + +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(); + } +}); diff --git a/src/server.py b/src/server.py index fe4537b..4653af4 100644 --- a/src/server.py +++ b/src/server.py @@ -41,6 +41,10 @@ ALLOWED_LANGUAGES = { "abnf", "accesslog", "ada", + "angelscript", + "apache", + "applescript", + "arcade", "arduino", "armasm", "asciidoc", @@ -118,6 +122,7 @@ ALLOWED_LANGUAGES = { "jboss-cli", "json", "julia", + "julia-repl", "kotlin", "lasso", "latex", @@ -209,6 +214,7 @@ ALLOWED_LANGUAGES = { "vala", "vbnet", "vbscript", + "vbscript-html", "verilog", "vhdl", "vim", @@ -653,6 +659,20 @@ class ClipboardHandler(http.server.BaseHTTPRequestHandler): self.send_html(200, landing_page()) return + if path == "/main.js": + js_path = BASE_DIR / "main.js" + if not js_path.exists(): + self.send_plain(404, "not found") + return + data = js_path.read_bytes() + self.send_response(200) + self.send_header("Content-Type", "application/javascript; charset=utf-8") + self.send_header("Content-Length", str(len(data))) + self.add_security_headers() + self.end_headers() + self.wfile.write(data) + return + if path.startswith("/raw/"): paste_id = path[5:] if not is_valid_paste_id(paste_id): -- cgit v1.2.3