Skip to content

Instantly share code, notes, and snippets.

@olls
Last active May 10, 2024 11:24
Show Gist options
  • Save olls/9199222 to your computer and use it in GitHub Desktop.
Save olls/9199222 to your computer and use it in GitHub Desktop.
A JavaScript notepad with open, save, local storage and markdown preview.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>NotePad!</title>
<meta name="description" content="A simple notepad.">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html, body {
margin: 0;
padding: 0;
height: 100%;
font-family: sans-serif;
}
*:focus {
outline: none;
}
#buttons {
border-bottom: 1px solid rgba(0, 0, 15, .3);
margin: 0;
padding: 0;
height: 40px;
width: 100%;
position: fixed;
background-color: white;
}
[id*=btn] {
display: inline-block;
height: 40px;
padding: 10px 15px;
margin: 0;
border: none;
font-size: 1em;
color: rgba(0, 0, 0, 1);
text-decoration: none;
background-color: rgba(0, 0, 0, .1);
cursor: pointer;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
[id*=btn]:hover {
background-color: rgba(0, 0, 50, .15);
color: rgba(0, 0, 15, .7);
}
#font-btn span:first-child:after {
content: ' | ';
color: black;
}
#font-btn.mono span:last-child,
#font-btn.prop span:first-child {
color: rgba(0, 0, 0, .1);
text-shadow: 0 0 20px rgba(0, 0, 0, .65);
}
#open-dilg {
position: fixed;
opacity: 0;
z-index: -100;
}
#edit-box {
width: 100%;
min-height: 100%;
height: auto;
margin: 0;
margin-top: 40px;
font-size: 1.1em;
border: none;
display: inline-block;
resize: none;
font-family: sans-serif;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#edit-box.mkdn-on {
width: 50%;
border-right: 1px dashed rgba(0, 0, 0, 0.7);
}
#mkdn-box {
width: 49%;
min-height: 100%;
height: auto;
margin: 0;
margin-top: 40px;
font-size: 1.1em;
border: none;
display: none;
float: right;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
</style>
</head>
<body>
<form id="buttons">
<input id="open-dilg" type="file" name="files[]">
<a href="#" id="save-btn">Save</a>
<a href="#" id="open-btn">Open</a>
<a href="#" id="font-btn"><span>Mono-space</span><span>Proportional</span></a>
<a href="#" id="mkdn-btn"></a>
</form>
<div contenteditable id="edit-box" autofocus>Hello World!</div>
<div id="mkdn-box"></div>
<script src="js/markdown.min.js"></script>
<script>
var buttons = document.getElementById("buttons");
var save_btn = document.getElementById("save-btn");
var open_btn = document.getElementById("open-btn");
var font_btn = document.getElementById("font-btn");
var mkdn_btn = document.getElementById("mkdn-btn");
var edit_box = document.getElementById("edit-box");
var open_dilg = document.getElementById("open-dilg");
var mkdn_box = document.getElementById("mkdn-box");
var mkdn_on = "Markdown: On";
var mkdn_off = "Markdown: Off";
var mkdn = false;
mkdn_btn.innerHTML = mkdn_off;
var mono = "monospace";
var prop = "sans-serif";
var font = prop;
save_btn.onclick = function () {
var filename = prompt('Save with name:', '.txt');
save_btn.download = filename;
save_btn.href = "data:application/octet-stream," + escape(edit_box.innerHTML);
};
open_btn.onclick = function () {
if (window.File && window.FileReader && window.FileList && window.Blob) {
open_dilg.click();
} else {
alert("The File APIs are not fully supported in this browser.");
}
return false;
};
open_dilg.addEventListener("change", open_file, false);
function open_file(e) {
var file = e.target.files;
var reader = new FileReader();
reader.onload = function(e) {
edit_box.innerHTML = e.target.result.replace(/\n/g, '<br>');;
buttons.reset();
update_mkdn();
};
reader.readAsText(file[0]);
}
font_btn.onclick = function () {
if (font == prop) {
font = mono;
} else {
font = prop;
}
update_font();
return false;
};
function update_font() {
if (font == mono) {
font_btn.classList.remove("prop");
font_btn.classList.add("mono");
} else {
font_btn.classList.remove("mono");
font_btn.classList.add("prop");
}
edit_box.style.fontFamily = font;
}
mkdn_btn.onclick = function () {
if (mkdn) {
mkdn = false;
} else {
mkdn = true;
}
update_mkdn();
return false;
};
function update_mkdn() {
if (mkdn) {
// Turned on
mkdn_btn.innerHTML = mkdn_on;
mkdn_box.style.display = "inline-block";
edit_box.classList.add("mkdn-on");
var text = edit_box.innerHTML.replace(/< *br *\/* *>/g, "\n");
var text = text.replace(/&nbsp;/g, " ");
mkdn_box.innerHTML = markdown.toHTML(text);
} else {
// Turned off
mkdn_btn.innerHTML = mkdn_off;
mkdn_box.style.display = "none";
edit_box.classList.remove("mkdn-on");
}
}
edit_box.addEventListener("keyup", update_mkdn, false);
/* localstorage polyfill from https://gist.github.com/350433 */
("undefined"==typeof window.localStorage||"undefined"==typeof window.sessionStorage)&&function(){function e(f){function e(a){var b;b=new Date;b.setTime(b.getTime()+31536E6);document.cookie="localStorage="+a+("; expires="+b.toGMTString())+"; path=/"}function g(a){a=JSON.stringify(a);"session"==f?window.name=a:e(a)}var d=function(){var a;if("session"==f)a=window.name;else a:{a=document.cookie.split(";");var b,c;for(b=0;b<a.length;b++){for(c=a[b];" "==c.charAt(0);)c=c.substring(1,c.length);if(0==c.indexOf("localStorage=")){a=c.substring(13,c.length);break a}}a=null}return a?JSON.parse(a):{}}();return{length:0,clear:function(){d={};this.length=0;"session"==f?window.name="":e("")},getItem:function(a){return void 0===d[a]?null:d[a]},key:function(a){var b=0,c;for(c in d){if(b==a)return c;b++}return null},removeItem:function(a){delete d[a];this.length--;g(d)},setItem:function(a,b){d[a]=b+"";this.length++;g(d)}}}if("undefined"==typeof window.localStorage)window.localStorage=new e("local");if("undefined"==typeof window.sessionStorage)window.sessionStorage=new e("session")}();
function save_settings() {
localStorage.setItem("edit-box", edit_box.innerHTML);
localStorage.setItem("font", font);
localStorage.setItem("mkdn", mkdn);
}
function load_settings(argument) {
edit_box.innerHTML = localStorage.getItem("edit-box");
font = localStorage.getItem("font");
if (font == mono) {
font = mono;
} else {
font = prop;
}
update_font();
mkdn = localStorage.getItem("mkdn");
if (mkdn == 'true') {
mkdn = true;
} else {
mkdn = false;
}
update_mkdn();
}
if (window.localStorage) {
load_settings()
}
edit_box.addEventListener("keyup", save_settings, false);
window.addEventListener("unload", save_settings, false);
setInterval(save_settings, 500);
</script>
</body>
</html>
@geraintwhite
Copy link

You missed a bit - the markdown.js

@olls
Copy link
Author

olls commented Feb 26, 2014

@olls
Copy link
Author

olls commented Feb 26, 2014

The settings are now stored in local storage too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment