github.com/ngocphuongnb/tetua@v0.0.7-alpha/app/themes/default/assets/js/main.js (about) 1 function fileInputPreviewer(element) { 2 element.addEventListener("click", function () { 3 var fileInputId = element.getAttribute("for"); 4 var previewerElm = element.querySelector("img"); 5 var fileInput = document.getElementById(fileInputId); 6 fileInput.click(); 7 8 fileInput.onchange = function () { 9 var file = fileInput.files[0]; 10 var reader = new FileReader(); 11 reader.onload = function (e) { 12 previewerElm.src = e.target.result; 13 }; 14 reader.readAsDataURL(file); 15 }; 16 }); 17 } 18 19 function deleteNode(nodeType, url, nodeID, callback, e) { 20 fetch(url + `/${nodeID}`, { method: "DELETE" }) 21 .then(function (response) { 22 if (response.status !== 200) { 23 alert(`Error deleting ${nodeType}`); 24 return; 25 } 26 if (typeof callback === "string") { 27 window.location.href = callback; 28 } 29 if (typeof callback === "function") { 30 callback(e, response); 31 } 32 }) 33 .catch(function (err) { 34 console.error(err); 35 alert(`Error deleting ${nodeType}`); 36 }); 37 } 38 39 function listenDeleteNodeEvents(nodeType, url, callback) { 40 var selector = `.delete-${nodeType}`; 41 var nodeElms = Array.from(document.querySelectorAll(selector)); 42 43 for (var nodeElm of nodeElms) { 44 nodeElm.addEventListener("click", function (e) { 45 e.preventDefault(); 46 e.stopImmediatePropagation(); 47 var nodeID = e.target.getAttribute("data-id"); 48 49 if ( 50 !nodeID || 51 !confirm(`Are you sure you want to delete this ${nodeType}?`) 52 ) { 53 return; 54 } 55 56 deleteNode(nodeType, url, nodeID, callback, e); 57 }); 58 } 59 } 60 61 function uploadHandler(file, callback) { 62 const formData = new FormData(); 63 formData.append("file", file); 64 fetch("/files/upload", { method: "POST", body: formData }) 65 .then((res) => { 66 if (!res.ok) { 67 throw new Error("File upload failed"); 68 } 69 70 return res.json() 71 }) 72 .then((res) => callback(res.url)) 73 .catch((e) => callback(null, e)); 74 } 75 76 window.addEventListener('load', function () { 77 var imagePreviewers = Array.from( 78 document.querySelectorAll(".image-upload-previewer") 79 ); 80 81 for (var imagePreviewer of imagePreviewers) { 82 fileInputPreviewer(imagePreviewer); 83 } 84 85 if (window.hljs) { 86 var hlNodes = document.querySelectorAll("pre code"); 87 var languages = hljs.listLanguages(); 88 89 for (var hlNode of Array.from(hlNodes)) { 90 var language = (hlNode.className || "").substring("language-".length) || "auto"; 91 hlNode.setAttribute("data-language", language); 92 hlNode.parentNode.setAttribute("data-language", language); 93 94 if (languages.includes(language)) { 95 hljs.highlightElement(hlNode, { language }); 96 } else { 97 var rs = hljs.highlightAuto(hlNode.textContent); 98 hlNode.innerHTML = rs.value; 99 } 100 } 101 } 102 103 var commentInputs = Array.from( 104 document.querySelectorAll(".comments textarea") 105 ); 106 for (var commentInput of commentInputs) { 107 commentInput.addEventListener("keyup", function (e) { 108 e.target.style.height = e.target.scrollHeight + "px"; 109 }); 110 commentInput.addEventListener("mouseup", function (e) { 111 e.target.style.height = e.target.scrollHeight + "px"; 112 }); 113 } 114 115 var commentEditBtns = Array.from(document.querySelectorAll(".edit-comment")); 116 for (var commentEditBtn of commentEditBtns) { 117 commentEditBtn.addEventListener("click", function (e) { 118 e.preventDefault(); 119 e.stopImmediatePropagation(); 120 var commentElm = e.target.closest(".comment"); 121 var textareaElm = commentElm.querySelector("textarea"); 122 commentElm.classList.add("editing"); 123 textareaElm.style.height = textareaElm.scrollHeight + "px"; 124 }); 125 } 126 127 listenDeleteNodeEvents("comment", "/comments", function (ev) { 128 ev.target.closest(".comment").remove(); 129 }); 130 });