Created
June 21, 2026 07:56
-
-
Save derekmc/8e0b7917d95a65789930dbb819a0a415 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <html> | |
| <head> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <style> | |
| /* CSS */ | |
| ._000fff{ | |
| background: #000; | |
| color: #fff; | |
| } | |
| #text1{ | |
| font-family: monospace; | |
| } | |
| .border2{ | |
| border: 2px solid black; | |
| } | |
| .b{ | |
| font-weight: bold; | |
| } | |
| /* END */ | |
| </style> | |
| </head> | |
| <body> | |
| <div class="markdown-src"> | |
| <!-- HTML --> | |
| <textarea id='text1' rows='13' cols='50' | |
| class='_000fff border2 b'></textarea> | |
| <br> | |
| <button id='savebtn'>Save</button> | |
| <!-- END --> | |
| </div> | |
| <div style="display: none;"></div> | |
| <script> | |
| let datakey = "__HTML_NOTES__:notedataid=9jO35fQo88" | |
| let inframe = (window!=window.top) | |
| window.Note = {} | |
| window.Note.data = | |
| /* JSON */ | |
| {"filename":"demo/example.txt","files":{"demo/example.txt":"asdf"}}; | |
| /* END */ | |
| (function(){ | |
| window.Note.save = saveData | |
| window.Note.load = loadData | |
| window.Note.autoSave = autoSave | |
| function getNoteModule(){ | |
| if(!window['Note']) window.Note = {} | |
| return window.Note | |
| } | |
| function loadData(){ | |
| let note = getNoteModule() | |
| if(!inframe){ | |
| try{ | |
| let savedata = localStorage.getItem(datakey) | |
| if(savedata && savedata.length){ | |
| note.data = JSON.parse(savedata) | |
| } | |
| window.addEventListener("message", onMessage) | |
| } catch(e){ | |
| console.log("No local data") | |
| console.log(e) | |
| } | |
| } else { | |
| return note.data | |
| } | |
| } | |
| let firstLogCall = true | |
| let originalLogFunc = console.log | |
| function log(x, ...rest){ | |
| if(firstLogCall) | |
| document.body.appendChild(document.createElement("hr")) | |
| else | |
| document.body.appendChild(document.createElement("br")) | |
| document.body.appendChild( | |
| document.createTextNode(x + " " + rest.join(" "))) | |
| firstLogCall = false | |
| originalLogFunc(x, ...rest) | |
| } | |
| console.log = log | |
| let SaveInterval = 500 | |
| window.addEventListener("load", ()=>{ | |
| convertMarkdown() | |
| autoSave() | |
| loadData() // dont wait for async | |
| }) | |
| let saveIntervalRef = null | |
| function autoSave(enable){ | |
| if(enable === undefined) enable = true | |
| clearInterval(saveIntervalRef) | |
| if(enable){ | |
| saveIntervalRef = window.setInterval(saveData, SaveInterval) | |
| } | |
| } | |
| // this is preferred over a 'localstorage' polyfill for a frame, | |
| // so the programmer doesn't assume this is the browsers localstorage | |
| function saveData(){ | |
| let note = getNoteModule() | |
| if(inframe){ | |
| let msg_obj = { | |
| action: "saveData", | |
| data: JSON.stringify(note['data']) | |
| } | |
| let message = JSON.stringify(msg_obj) | |
| window.parent.postMessage(message) | |
| } else { | |
| localStorage.setItem(datakey, JSON.stringify(note['data'])) | |
| } | |
| } | |
| let md_subs = [ | |
| /(\n|^)\s*######\s([^\s#].*)\n*/g, "\n<h6 id=\"$2\">$2</h6>\n", | |
| /(\n|^)\s*#####\s([^\s#].*)\n*/g, "\n<h5 id=\"$2\">$2</h5>\n", | |
| /(\n|^)\s*####\s*([^\s#].*)\n*/g, "\n<h4 id=\"$2\">$2</h4>\n", | |
| /(\n|^)\s*###\s*([^\s#].*)\n*/g, "\n<h3 id=\"$2\">$2</h3>\n", | |
| /(\n|^)\s*##\s*([^\s#].*)\n*/g, "\n<h2 id=\"$2\">$2</h2>\n", | |
| /(\n|^)\s*#\s*([^\s#].*)\n*/g, "\n<h1 id=\"$2\">$2</h1>\n", | |
| /\n(\s*)[\*\-](.*)/g, '\n<ul><li>$2</li></ul>', | |
| /\n+\n(?=[^#\n])/g, "\n\n<br><br>", | |
| /\n+\n/g, "\n", | |
| /__([^_\n]*)__/g, "<b>$1</b>", | |
| /\*\*([^_\n]*)\*\*/g, "<b>$1</b>", | |
| /_([^_\n]*)_/g, "<i>$1</i>", | |
| /\*([^_\n]*)\*/g, "<i>$1</i>", | |
| /\!\[([^\]\n]*)\]\(([^\)\n]*)\)/g, "<img src=\"$2\" alt=\"$1\"></img>", | |
| /\[([^\]\n]*)\]\(([^\)\n]*)\)/g, "<a href=\"$2\" target=\"_blank\">$1</a>", | |
| ] | |
| function onMessage(){ | |
| try{ | |
| let message = JSON.parse(e.data) | |
| // console.log('received message', message) | |
| if(message.hasOwnProperty("event")){ | |
| if(message.event == "keydown" && typeof keydown != "undefined"){ | |
| keydown(message) | |
| } | |
| if(message.event == "keyup" && typeof keyup != "undefined"){ | |
| keydown(message) | |
| } | |
| } | |
| } catch(e){ | |
| console.warn("error processing message: " + e.data) | |
| } | |
| } | |
| function convertMarkdown(){ | |
| let containers = document.getElementsByClassName("markdown-src") | |
| for(let j=0; j<containers.length; ++j){ | |
| let container = containers[j] | |
| let src = container.innerHTML | |
| for(var i=0; i<md_subs.length-1; i += 2){ | |
| var search = md_subs[i] | |
| var replace = md_subs[i+1] | |
| src = src.replace(search, replace) | |
| } | |
| container.innerHTML = src | |
| } | |
| } | |
| })() | |
| //window.addEventListener('load', htmlNotesMainFunc) | |
| //function htmlNotesMainFunc(){ | |
| /* JS */ | |
| let data = Note.data | |
| setTimeout(main, 100) | |
| function main(){ | |
| data.filename = 'demo/example.txt' | |
| console.log('main') | |
| clickHandle('savebtn', saveButton) | |
| } | |
| function saveFile(name, src){ | |
| data.files ??= {} | |
| data.files[name] = src | |
| console.info('saving', name, src) | |
| } | |
| function saveButton(){ | |
| saveFile(data.filename, id('text1').value) | |
| } | |
| function action1(){ | |
| append('text1', "\nAction #1 Clicked!") | |
| } | |
| function id(x){ | |
| return document.getElementById(x) | |
| } | |
| function append(elem, text){ | |
| id(elem).appendChild( | |
| document.createTextNode(text)) | |
| } | |
| function clickHandle(btnid, action){ | |
| id(btnid).addEventListener('click', action) | |
| } | |
| /* END */ | |
| //} | |
| </script> | |
| </body> | |
| <html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment