<!-- from https://cristobal.space/note --> <head> <meta charset="UTF-8"> <style> body { font-family: monospace; width: 400px; } img { max-width: 600px; width: 100%; margin: 12px 0px; } #drop { width: 400px; height: 100px; border: 1px dashed black; border-radius: 4px; margin-bottom: 12px; display: flex; justify-content: center; align-items: center; } #text { width: 400px; height: 100px; border-radius: 4px; resize: none; margin-bottom: 12px; padding: 6px; } #content { margin-top: 12px; } </style> </head> <body><textarea id="text">Write HTML...</textarea> <div id="drop"><i>DROP IMAGES</i></div> <button onclick="append()"><i>APPEND</i></button> <button onclick="fork()"><i>FORK</i></button> <button onclick="publish()"><i>PUBLISH</i></button> <div id="content"> </div> <script> const noop = e => { e.preventDefault(); e.stopPropagation(); } const toBase64 = blob => new Promise(resolve => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.readAsDataURL(blob); }) const content = document.getElementById("content"); const textArea = document.getElementById("text"); const dropArea = document.getElementById("drop"); dropArea.addEventListener("dragenter", e => { noop(e); dropArea.style.border = "1px dotted black"; }) dropArea.addEventListener("drop", async e => { noop(e); dropArea.style.border = "1px dashed black"; const img = document.createElement("img"); const f = e.dataTransfer.files[0]; const b64 = await toBase64(f); img.src = b64; content.appendChild(img); }) dropArea.addEventListener("dragover", noop); dropArea.addEventListener("dragexit", noop); const append = () => { content.innerHTML += textArea.value; } const download = (html) => { // Write data into self-contained html file const data = new Blob([html], {type: 'text/plain'}); // Download the file const url = window.URL.createObjectURL(data); const a = document.createElement("a"); a.href = url; a.download = "note.html"; a.click(); } const fork = () => download(document.documentElement.innerHTML); const publish = () => download(content.innerHTML); </script> </body>