<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>guava editor</title>
<style>
* { font-family: sans-serif;}
body { padding: 0.25em 2em; background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIj48ZGVmcz48cGF0dGVybiBpZD0icGF0dGVybiIgd2lkdGg9IjEwMCIgaGVpZ2h0PSIxMDAiIHZpZXdCb3g9IjAgMCA0MCw0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgcGF0dGVyblRyYW5zZm9ybT0icm90YXRlKDEyNykgIj48cmVjdCBpZD0icGF0dGVybi1iYWNrZ3JvdW5kIiB3aWR0aD0iNDAwJSIgaGVpZ2h0PSI0MDAlIiBmaWxsPSJyZ2JhKDE3OCwgMjQ1LCAyMzQsMSkiPjwvcmVjdD4gPHBhdGggZmlsbD0icmdiYSgyNTQsIDI1MiwgMTkxLDEpIiBkPSIKICAgICAgICAgICAgICAgIE0tMjAgMzYgbDIwIC0yMCBsMjAgMjAgbDIwIC0yMCBsMjAgMjAgbDIwIC0yMCBsMjAgMjAgdi0xMiBsLTIwIC0yMCBsLTIwIDIwIGwtMjAgLTIwIGwtMjAgMjAgbC0yMCAtMjAgbC0yMCAyMCB6CiAgICAgICAgICAgICAgICBNLTIwIC00IGwyMCAtMjAgbDIwIDIwIGwyMCAtMjAgbDIwIDIwIGwyMCAtMjAgbDIwIDIwIHYtMTIgbC0yMCAtMjAgbC0yMCAyMCBsLTIwIC0yMCBsLTIwIDIwIGwtMjAgLTIwIGwtMjAgMjAgegogICAgICAgICAgICAgICAgTS0yMCA3NiBsMjAgLTIwIGwyMCAyMCBsMjAgLTIwIGwyMCAyMCBsMjAgLTIwIGwyMCAyMCB2LTEyIGwtMjAgLTIwIGwtMjAgMjAgbC0yMCAtMjAgbC0yMCAyMCBsLTIwIC0yMCBsLTIwIDIwIHoKICAgICAgICAgICAgICAgICIgZmlsdGVyPSJ1cmwoI2ZpbHRlcjFwYXR0ZXJuKSI+PC9wYXRoPjxwYXRoIGZpbGw9InJnYmEoMjM3LCAyNDIsIDI0NywxKSIgZD0iCiAgICAgICAgICAgICAgICBNLTIwIDYwIGwyMCAtMjAgbDIwIDIwIGwyMCAtMjAgbDIwIDIwIGwyMCAtMjAgbDIwIDIwIHYtMjAgbC0yMCAtMjAgbC0yMCAyMCBsLTIwIC0yMCBsLTIwIDIwIGwtMjAgLTIwIGwtMjAgMjAgegogICAgICAgICAgICAgICAgTS0yMCAyMCBsMjAgLTIwIGwyMCAyMCBsMjAgLTIwIGwyMCAyMCBsMjAgLTIwIGwyMCAyMCB2LTIwIGwtMjAgLTIwIGwtMjAgMjAgbC0yMCAtMjAgbC0yMCAyMCBsLTIwIC0yMCBsLTIwIDIwIHoKICAgICAgICAgICAgICAgIE0tMjAgMTAwIGwyMCAtMjAgbDIwIDIwIGwyMCAtMjAgbDIwIDIwIGwyMCAtMjAgbDIwIDIwIHYtMjAgbC0yMCAtMjAgbC0yMCAyMCBsLTIwIC0yMCBsLTIwIDIwIGwtMjAgLTIwIGwtMjAgMjAgegogICAgICAgICAgICAgICAgIiBmaWx0ZXI9InVybCgjZmlsdGVyMnBhdHRlcm4pIj48L3BhdGg+PC9wYXR0ZXJuPiA8ZmlsdGVyIGlkPSJmaWx0ZXIxcGF0dGVybiI+PGZlVHVyYnVsZW5jZSBiYXNlRnJlcXVlbmN5PSIwLjMwMDAwMDAwMDAwMDAwMDA0IiBudW1PY3RhdmVzPSIyIiByZXN1bHQ9InJlc3VsdDEiIHR5cGU9ImZyYWN0YWxOb2lzZSI+PC9mZVR1cmJ1bGVuY2U+PGZlRGlzcGxhY2VtZW50TWFwIGluMj0icmVzdWx0MSIgc2NhbGU9IjE5IiByZXN1bHQ9InJlc3VsdDIiIHhDaGFubmVsU2VsZWN0b3I9IlIiIGluPSJTb3VyY2VHcmFwaGljIj48L2ZlRGlzcGxhY2VtZW50TWFwPjxmZUNvbXBvc2l0ZSBpbjI9InJlc3VsdDIiIGluPSJTb3VyY2VHcmFwaGljIiBvcGVyYXRvcj0iYXRvcCIgcmVzdWx0PSJmYlNvdXJjZUdyYXBoaWMiPjwvZmVDb21wb3NpdGU+PC9maWx0ZXI+IDxmaWx0ZXIgaWQ9ImZpbHRlcjJwYXR0ZXJuIj48ZmVUdXJidWxlbmNlIGJhc2VGcmVxdWVuY3k9IjEiIG51bU9jdGF2ZXM9IjIiIHR5cGU9ImZyYWN0YWxOb2lzZSIgcmVzdWx0PSJyZXN1bHQxIj48L2ZlVHVyYnVsZW5jZT48ZmVEaXNwbGFjZW1lbnRNYXAgaW4yPSJyZXN1bHQxIiBzY2FsZT0iMTQiIHJlc3VsdD0icmVzdWx0MiIgeENoYW5uZWxTZWxlY3Rvcj0iUiIgaW49IlNvdXJjZUdyYXBoaWMiPjwvZmVEaXNwbGFjZW1lbnRNYXA+PGZlQ29tcG9zaXRlIGluMj0icmVzdWx0MiIgaW49IlNvdXJjZUdyYXBoaWMiIG9wZXJhdG9yPSJhdG9wIiByZXN1bHQ9ImZiU291cmNlR3JhcGhpYyI+PC9mZUNvbXBvc2l0ZT48L2ZpbHRlcj48L2RlZnM+IDxyZWN0IGZpbGw9InVybCgjcGF0dGVybikiIGhlaWdodD0iMTAwJSIgd2lkdGg9IjEwMCUiPjwvcmVjdD48L3N2Zz4="); }
textarea {
font-family: monospace;
font-size: 14px;
width: 100%;
max-width: 93vw;
height: 75vh;
margin: 0 auto;
display: block;
padding: 9px 0 9px 9px;
background-color: #edf2f7;
border: 4px solid #b2f5ea;
border-radius: 8px;
box-shadow: 3px 3px 0 0;
}
textarea:disabled {
background-color: #edf2f7;
}
button {
color: black;
background-color: #fefcbf;
border: 3px solid #b2f5ea;
border-radius: 8px;
margin: 1em 0.75em 1em 0;
box-shadow: 3px 3px 0 0;
}
button:hover {
cursor: pointer;
border: 3px solid black;
transition-duration: 0.3s;
}
.buttons {
display: flex;
}
.buttons > .push {
margin-left: auto;
}
</style>
<script type="text/javascript" src="guava.js"></script>
<script type="text/javascript" src="guava-helper.js"></script>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<link rel="icon" href="favicon.ico" type="image/x-icon">
</head>
<body>
<h3>Output</h3>
<div id="playground"></div>
<button id="clear" onclick="document.getElementById('output').value = null;" title="Clear log output.">Clear</button>
<textarea style="height: 5em;" id="output" disabled></textarea>
<h3 style="margin-bottom: 0;">Input</h3>
<div class="buttons">
<button id="code" onclick="getInputValueED('editor', 'output');return false" title="Run code.">Run</button>
<button id="clean" title="Empty stack and clear log output.">Clean</button>
<button id="destroy" title="Delete contents of editor.">Destroy</button>
<button id="export" title="Save the contents of editor to disk.">Export</button>
<input type="file" id="upload" class="push" title="Upload a file's contents to the editor.">
</div>
<textarea id="editor"></textarea>
<script>
const editor = document.getElementById('editor');
const load = document.getElementById('load');
const destroy = document.getElementById('destroy');
const clean = document.getElementById('clean');
const exportToDisk = document.getElementById('export');
const dataStore = window.localStorage;
const saveInput = () => { dataStore.setItem('personInput', editor.value); };
const loadInput = () => { editor.value = dataStore.getItem('personInput'); };
document.addEventListener('keydown', event => {
if (event.ctrlKey && event.key === 'r') {
if (editor.value) {
getInputValueED('editor', 'output');
}
}
if (event.ctrlKey && event.key === 'c') {
document.getElementById('output').value = null;
}
if (event.ctrlKey && event.key === 'd') {
const doubleCheck = confirm('🚨 Are you sure you\'d like to destroy the input data?');
if (doubleCheck) { dataStore.clear(); loadInput(); }
}
if (event.ctrlKey && event.key === 'k') {
saveInput();
window.location.reload(true);
}
});
const upload = document.getElementById("upload");
upload.addEventListener("change", handleFiles, false);
function handleFiles() {
const fileList = this.files; /* now you can work with the file list */
const read = new FileReader();
read.readAsBinaryString(fileList[0]);
read.onloadend = function(){
editor.value = read.result;
saveInput();
}
}
editor.addEventListener('keyup', () => { saveInput(); });
if (dataStore.getItem('personInput')) {
window.addEventListener('load', () => { loadInput(); });
}
destroy.addEventListener('click', () => {
const doubleCheck = confirm('🚨 Are you sure you\'d like to destroy the input data?');
if (doubleCheck) { dataStore.clear(); loadInput(); }
});
clean.addEventListener('click', () => {
saveInput();
window.location.reload(true);
});
exportToDisk.addEventListener('click', () => {
saveInput();
loadInput();
const data = editor.value;
const dataUri = 'data:text/plain;charset=utf=8,' + encodeURIComponent(data);
const rightNow = new Date();
const exportFileDefaultName = rightNow.toISOString() + '--ed_export.guava';
let a = document.createElement('a');
a.setAttribute('href', dataUri);
a.setAttribute('download', exportFileDefaultName);
const doubleCheck = confirm('Export your data?');
if (doubleCheck) { a.click(); };
});
</script>
</body>
</html>