import static files
This commit is contained in:
159
data/static/js/babycode-editor.js
Normal file
159
data/static/js/babycode-editor.js
Normal file
@@ -0,0 +1,159 @@
|
||||
{
|
||||
let ta = document.getElementById("babycode-content");
|
||||
|
||||
ta.addEventListener("keydown", (e) => {
|
||||
if(e.key === "Enter" && e.ctrlKey) {
|
||||
// console.log(e.target.form)
|
||||
e.target.form?.submit();
|
||||
}
|
||||
})
|
||||
|
||||
const inThread = () => {
|
||||
const scheme = window.location.pathname.split("/");
|
||||
return scheme[1] === "threads" && scheme[2] !== "create";
|
||||
}
|
||||
|
||||
ta.addEventListener("input", () => {
|
||||
if (!inThread()) return;
|
||||
|
||||
localStorage.setItem(window.location.pathname, ta.value);
|
||||
})
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
if (!inThread()) return;
|
||||
const prevContent = localStorage.getItem(window.location.pathname);
|
||||
if (!prevContent) return;
|
||||
ta.value = prevContent;
|
||||
})
|
||||
|
||||
const buttonBold = document.getElementById("post-editor-bold");
|
||||
const buttonItalics = document.getElementById("post-editor-italics");
|
||||
const buttonStrike = document.getElementById("post-editor-strike");
|
||||
const buttonUrl = document.getElementById("post-editor-url");
|
||||
const buttonCode = document.getElementById("post-editor-code");
|
||||
const buttonImg = document.getElementById("post-editor-img");
|
||||
const buttonOl = document.getElementById("post-editor-ol");
|
||||
const buttonUl = document.getElementById("post-editor-ul");
|
||||
|
||||
function insertTag(tagStart, newline = false, prefill = "") {
|
||||
const hasAttr = tagStart[tagStart.length - 1] === "=";
|
||||
let tagEnd = tagStart;
|
||||
let tagInsertStart = `[${tagStart}]${newline ? "\n" : ""}`;
|
||||
if (hasAttr) {
|
||||
tagEnd = tagEnd.slice(0, -1);
|
||||
}
|
||||
const tagInsertEnd = `${newline ? "\n" : ""}[/${tagEnd}]`;
|
||||
const hasSelection = ta.selectionStart !== ta.selectionEnd;
|
||||
const text = ta.value;
|
||||
if (hasSelection) {
|
||||
const realStart = Math.min(ta.selectionStart, ta.selectionEnd);
|
||||
const realEnd = Math.max(ta.selectionStart, ta.selectionEnd);
|
||||
const selectionLength = realEnd - realStart;
|
||||
|
||||
const strStart = text.slice(0, realStart);
|
||||
const strEnd = text.substring(realEnd);
|
||||
const frag = `${tagInsertStart}${text.slice(realStart, realEnd)}${tagInsertEnd}`;
|
||||
const reconst = `${strStart}${frag}${strEnd}`;
|
||||
ta.value = reconst;
|
||||
if (!hasAttr){
|
||||
ta.setSelectionRange(realStart + tagInsertStart.length, realStart + tagInsertStart.length + selectionLength);
|
||||
} else {
|
||||
ta.setSelectionRange(realStart + tagInsertEnd.length - 1, realStart + tagInsertEnd.length - 1); // cursor on attr
|
||||
}
|
||||
ta.focus()
|
||||
} else {
|
||||
if (hasAttr) {
|
||||
tagInsertStart += prefill;
|
||||
}
|
||||
const cursor = ta.selectionStart;
|
||||
const strStart = text.slice(0, cursor);
|
||||
const strEnd = text.substr(cursor);
|
||||
|
||||
let newCursor = strStart.length + tagInsertStart.length;
|
||||
if (hasAttr) {
|
||||
newCursor = cursor + tagInsertStart.length - prefill.length - 1;
|
||||
}
|
||||
const reconst = `${strStart}${tagInsertStart}${tagInsertEnd}${strEnd}`;
|
||||
ta.value = reconst;
|
||||
ta.setSelectionRange(newCursor, newCursor);
|
||||
ta.focus()
|
||||
}
|
||||
}
|
||||
|
||||
buttonBold.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
insertTag("b")
|
||||
})
|
||||
buttonItalics.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
insertTag("i")
|
||||
})
|
||||
buttonStrike.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
insertTag("s")
|
||||
})
|
||||
buttonUrl.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
insertTag("url=", false, "link label");
|
||||
})
|
||||
buttonCode.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
insertTag("code", true)
|
||||
})
|
||||
buttonImg.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
insertTag("img=", false, "alt text");
|
||||
})
|
||||
buttonOl.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
insertTag("ol", true);
|
||||
})
|
||||
buttonUl.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
insertTag("ul", true);
|
||||
})
|
||||
|
||||
const previewEndpoint = "/api/babycode-preview";
|
||||
let previousMarkup = "";
|
||||
const previewTab = document.getElementById("tab-preview");
|
||||
previewTab.addEventListener("tab-activated", async () => {
|
||||
const previewContainer = document.getElementById("babycode-preview-container");
|
||||
const previewErrorsContainer = document.getElementById("babycode-preview-errors-container");
|
||||
// previewErrorsContainer.textContent = "";
|
||||
const markup = ta.value.trim();
|
||||
if (markup === "" || markup === previousMarkup) {
|
||||
return;
|
||||
}
|
||||
previousMarkup = markup;
|
||||
const req = await fetch(previewEndpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({markup: markup})
|
||||
})
|
||||
if (!req.ok) {
|
||||
switch (req.status) {
|
||||
case 429:
|
||||
previewErrorsContainer.textContent = "(Old preview, try again in a few seconds.)"
|
||||
previousMarkup = "";
|
||||
break;
|
||||
case 400:
|
||||
previewErrorsContainer.textContent = "(Request got malformed.)"
|
||||
break;
|
||||
case 401:
|
||||
previewErrorsContainer.textContent = "(You are not logged in.)"
|
||||
break;
|
||||
default:
|
||||
previewErrorsContainer.textContent = "(Error. Check console.)"
|
||||
console.error(req.error);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const json_resp = await req.json();
|
||||
previewContainer.innerHTML = json_resp.html;
|
||||
previewErrorsContainer.textContent = "";
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user