Last active
October 19, 2015 06:25
-
-
Save tomhodgins/c6f4b30abb1073c302ba to your computer and use it in GitHub Desktop.
JOE: The JavaScript Operating Environment. Running live at http://staticresource.com
This file contains 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
<!DOCTYPE html> | |
<html manifest=joe.manifest> | |
<head> | |
<meta charset=utf-8> | |
<title>JOE: The JavaScript Operating Environment</title> | |
<meta name=apple-mobile-web-app-capable content=yes> | |
<meta name=apple-mobile-web-app-title content=JOE> | |
<meta name=apple-mobile-web-app-status-bar-style content=black> | |
<meta name=viewport content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,minimal-ui"> | |
<link href="http://fonts.googleapis.com/css?family=Source+Sans+Pro:200,300,400,600,700,900,200italic,300italic,400italic,600italic,700italic,900italic" rel=stylesheet type=text/css> | |
<link href="http://fonts.googleapis.com/css?family=Source+Code+Pro:300,400,500,600,700,900" rel=stylesheet type=text/css> | |
<style> | |
* {box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-kerning:auto} | |
body {font-family:'OpenSans','Source Sans Pro',Roboto,'HelveticaNeue-Light','Helvetica Neue Light','Helvetica Neue','Myriad Pro','Segoe UI',Myriad,Helvetica,'Lucida Grande','DejaVu Sans Condensed','Liberation Sans','Nimbus Sans L',Tahoma,Geneva,Arial,sans-serif;margin:0;-webkit-text-size-adjust:100%;background:#073642;color:#839496;font-size:12pt} | |
code,pre {display:inline-block;font-size:100%;font-family:'Source Code Pro',Consolas,'Andale Mono WT','Andale Mono','Lucida Console','Lucida Sans Typewriter','DejaVu Sans Mono','Bitstream Vera Sans Mono','Liberation Mono','Nimbus Mono L',Monaco,'Courier New',Courier,monospace;font-weight:400;color:#eee8d5;cursor:pointer} | |
code:hover {background:#eee8d5;color:#073642} | |
section {position:relative;padding:20px;-webkit-user-select:none;user-select:none} | |
section + section {border-top:1px solid #002b36} | |
section .exit, section .zoom {font-size:24pt;position:absolute;top:5px;right:15px;color:#586e75;cursor:pointer;transition:color .1s ease-in-out} | |
section .zoom {right:45px} | |
section .exit:hover,section .exit:focus,section .zoom:hover,section .zoom:focus {color:#dc322f} | |
section h1 {margin:0;color:#839496} | |
section h1 + div,section h1 + iframe{margin-top:.5em} | |
input[type=text] {width:calc(100% - 65px);float:left;-webkit-appearance:none;appearance:none;background:#002b36;color:#eee8d5;border:1px solid #586e75;border-radius:1px;padding:5px;font-size:14pt;font-weight:normal;outline:none} | |
input[type=submit] {width:50px;float:right;margin-bottom:20px;-webkit-appearance:none;appearance:none;background:#586e75;color:#002b36;border:1px solid #586e75;border-radius:1px;padding:5px;font-size:14pt;font-weight:normal;outline:none;cursor:pointer} | |
input[type=submit]:hover,input[type=submit]:focus { background:#657b83;border-color:#657b83} | |
iframe {border:none;width:100%;min-height:350px;overflow:auto;resize:vertical} | |
</style> | |
<script>eval(unescape(escape('♶♡♲☠♡☽♤♯♣♵♭♥♮♴☮♣♲♥♡♴♥♅♬♥♭♥♮♴☨☢♣♡♮♶♡♳☢☩☬♢☽♡☮♧♥♴♃♯♮♴♥♸♴☨☢☲♤☢☩☬♣☽♤♯♣♵♭♥♮♴☮♣♲♥♡♴♥♅♬♥♭♥♮♴☨☢♬♩♮♫☢☩☬♤☽♤♯♣♵♭♥♮♴☮♣♲♥♡♴♥♅♬♥♭♥♮♴☨☢♬♩♮♫☢☩☻♡☮♷♩♤♴♨☽☲☰☰☻♡☮♨♥♩♧♨♴☽☲☰☰☻♢☮♦♩♬♬♓♴♹♬♥☽☢☣☰☷☳☶☴☲☢☻♢☮♢♥♧♩♮♐♡♴♨☨☩☻♢☮♭♯♶♥♔♯☨☱☰☬☰☩☻♢☮♬♩♮♥♔♯☨☱☹☰☬☰☩☻♢☮♱♵♡♤♲♡♴♩♣♃♵♲♶♥♔♯☨☲☰☰☬☰☬☲☰☰☬☱☰☩☻♢☮♬♩♮♥♔♯☨☲☰☰☬☱☹☰☩☻♢☮♱♵♡♤♲♡♴♩♣♃♵♲♶♥♔♯☨☲☰☰☬☲☰☰☬☱☹☰☬☲☰☰☩☻♢☮♬♩♮♥♔♯☨☱☰☬☲☰☰☩☻♢☮♱♵♡♤♲♡♴♩♣♃♵♲♶♥♔♯☨☰☬☲☰☰☬☰☬☱☹☰☩☻♢☮♬♩♮♥♔♯☨☰☬☱☰☩☻♢☮♱♵♡♤♲♡♴♩♣♃♵♲♶♥♔♯☨☰☬☰☬☱☰☬☰☩☻♢☮♣♬♯♳♥♐♡♴♨☨☩☻♢☮♦♩♬♬☨☩☻♢☮♦♩♬♬♓♴♹♬♥☽☢☣☸☳☹☴☹☶☢☻♢☮♦♯♮♴☽☢♢♯♬♤☠☱☰☰♰♸☠♃♯♵♲♩♥♲☢☻♢☮♦♩♬♬♔♥♸♴☨☢♪☢☬☱☵☬☱☲☵☩☻♢☮♦♩♬♬♔♥♸♴☨☢♯♥☢☬☶☳☬☱☲☵☩☻♣☮♴♹♰♥☽☢♩♭♡♧♥☯♸☭♩♣♯♮☢☻♣☮♲♥♬☽☢♳♨♯♲♴♣♵♴☠♩♣♯♮☢☻♤☮♲♥♬☽☢♡♰♰♬♥☭♴♯♵♣♨☭♩♣♯♮☢☻♣☮♨♲♥♦☽♤☮♨♲♥♦☽♡☮♴♯♄♡♴♡♕♒♌☨☢♩♭♡♧♥☯♰♮♧☢☩☻♤♯♣♵♭♥♮♴☮♧♥♴♅♬♥♭♥♮♴♳♂♹♔♡♧♎♡♭♥☨☢♨♥♡♤☢☩♛☰♝☮♡♰♰♥♮♤♃♨♩♬♤☨♣☩☻♤♯♣♵♭♥♮♴☮♧♥♴♅♬♥♭♥♮♴♳♂♹♔♡♧♎♡♭♥☨☢♨♥♡♤☢☩♛☰♝☮♡♰♰♥♮♤♃♨♩♬♤☨♤☩☻').replace(/u../g,'')))</script> | |
</head> | |
<body> | |
<section> | |
<input type=text autocapitalize=off autocorrect=off> | |
<input type=submit onclick=enterCommand(input.value) value=Go> | |
</section> | |
<script> | |
var prompt = document.getElementsByTagName('section')[0], | |
prompt_input = document.querySelectorAll('[type=text]')[0], | |
iHeight = window.innerHeight - 175, | |
log = '', | |
output = '', | |
known = '', | |
entries = '', | |
fullscreen_mode = false, | |
silent_mode = false, | |
command = { | |
calc: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="http://staticresource.com/calc.html" style="height:'+iHeight+'px;min-height:'+550+'px"></iframe>' | |
}, | |
cards: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="http://staticresource.com/deck.html" style="height:'+iHeight+'px"></iframe>' | |
}, | |
clear: function (){ | |
if (silent_mode !== true){ | |
silent_mode = true | |
} | |
var sections = document.querySelectorAll('section'); | |
for (i=0;i<sections.length;i++){ | |
if (i<sections.length-1){ | |
sections[i].remove() | |
} | |
} | |
}, | |
demos: function(){ | |
var demos = { | |
'Notifications': { | |
url: 'http://staticresource.com/notifications.html', | |
desc: 'JavaScript Notifications Plugin' | |
}, | |
'Gestures': { | |
url: 'http://staticresource.com/gestures.html', | |
desc: 'Simple gesture detection in JS' | |
}, | |
'Multitouch': { | |
url: 'http://staticresource.com/touches.html', | |
desc: 'Multouch Support in JS' | |
}, | |
'Conjure': { | |
url: 'http://staticresource.com/conjure.html', | |
desc: 'Front-end templating in JS' | |
}, | |
'Countdown': { | |
url: 'http://staticresource.com/count.html', | |
desc: 'Countdown using a random interval' | |
}, | |
'Validation': { | |
url: 'http://staticresource.com/validation.html', | |
desc: 'Form Validation with filters, tests, and error messages' | |
}, | |
'Guided Form': { | |
url: 'http://staticresource.com/guidedForm.html', | |
desc: 'Clickable backdrop behind form that focuses next empty field ' | |
}, | |
'Personas': { | |
url: 'http://staticresource.com/personas-demo.html', | |
desc: 'Adding custom content for different target audiences' | |
} | |
}; | |
output = '' | |
for (entries in demos){ | |
output += '<a href="#" onclick="this.parentNode.innerHTML=\'<iframe src='+demos[entries].url+' style=height:'+iHeight+'px;background:white></iframe>\'">'+entries+'</a><span>'+demos[entries].desc+'</span><br>' | |
} | |
output += '<style>.demos a:not(.exit){display:inline-block;color:#0087ff;padding: 5px 0;}.demos a:not(.exit):hover,.demos a:not(.exit):focus{color:#00afaf;}.demos span:before {content:" - "}</style>' | |
}, | |
draw: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="http://staticresource.com/sketch.html" style="height:'+iHeight+'px"></iframe>' | |
}, | |
encode: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="http://staticresource.com/encode.html" style="height:'+iHeight+'px"></iframe>' | |
}, | |
game: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="http://staticresource.com/game.html" style="height:'+iHeight+'px"></iframe>' | |
}, | |
gold: function(){ | |
output = '<img src="http://www.kitconet.com/charts/metals/gold/t24_au_en_caoz_2.gif" style="width:500px;max-width:100%;opacity:.6;border-radius:2px">' | |
}, | |
help: function(){ | |
output = 'Known commands include: ' | |
for (known in command){ | |
output += '<code onclick="interpret(\''+known+'\');addToHistory(\''+known+'\');">'+known+'</code>' | |
} | |
output += '<style>.help code:after {content:",";display:inline;background:#073642;padding-right:5px}.help code:last-of-type:after {content:""}code:hover:after{color:#eee8d5}</style>' | |
}, | |
hexadecimal: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="http://staticresource.com/grid.html" style="height:'+iHeight+'px"></iframe>' | |
}, | |
menu: function(){ | |
var menu = { | |
'Control Panel': 'https://staticresource.com:10000', | |
'Hue Scenes': 'https://my.meethue.com/en-us/my-scenes', | |
'PHPmyAdmin': 'http://staticresource.com/pma', | |
'Plex': 'http://staticresource.com/plex', | |
'BuildMogul': 'http://buildmogul.com/vip', | |
'Ballr': 'http://staticresource.com:3010/users/sign_in', | |
'Unicons': 'http://unicons.io/' | |
}; | |
output = '' | |
for (entries in menu){ | |
output += '<a href="'+menu[entries]+'">'+entries+'</a><br>' | |
} | |
output += '<style>.menu a:not(.exit){display:inline-block;color:#0087ff;padding: 5px 0;}.menu a:not(.exit):hover,.menu a:not(.exit):focus{color:#00afaf;}</style>' | |
}, | |
memo: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="http://staticresource.com/tinkerpad" style="height:'+iHeight+'px"></iframe>' | |
}, | |
reminder: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="http://staticresource.com/reminders.html" style="height:'+iHeight+'px"></iframe>' | |
}, | |
search: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="https://qwant.com" style="height:'+iHeight+'px"></iframe>' | |
}, | |
shuffle: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="http://staticresource.com/shuffle.html" style="height:'+iHeight+'px"></iframe>' | |
}, | |
silver: function(){ | |
output = '<img src="http://www.kitconet.com/charts/metals/silver/t24_ag_en_caoz_2.gif" style="width:500px;max-width:100%;opacity:.6;border-radius:2px">' | |
}, | |
time: function(){ | |
var d = new Date(), | |
days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], | |
day = days[d.getDay()], | |
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], | |
month = months[d.getMonth()], | |
date = d.getDate(), | |
suf = ['th','st','nd','rd'], | |
v = date%100, | |
date = date+(suf[(v-20)%10]||suf[v]||suf[0]), | |
hours = d.getHours(), | |
minutes = d.getMinutes(), | |
noon = ''; | |
// Display hours in 12-hour format, and set am/pm | |
if (hours==12){ | |
noon = 'pm' | |
} else if (hours>12){ | |
hours = hours-12 | |
noon = 'pm' | |
} else if (hours==0){ | |
hours = 12 | |
noon = 'am' | |
} else { | |
noon = 'am' | |
} | |
// Add '0' to minutes if less than 10 | |
if(minutes<10){ | |
minutes = '0'+minutes | |
} | |
// Output the Timestamp | |
var timestamp = day+' '+month+' '+date+', '+hours+':'+minutes+' '+noon; | |
output = timestamp | |
}, | |
usd: function(){ | |
output = '<img src="http://www.weblinks247.com/exrate/24hr-cad-small.gif" style="width:500px;max-width:100%;opacity:.6;border-radius:2px">' | |
}, | |
web: function(){ | |
fullscreen_mode = true | |
output = '<iframe src="http://staticresource.com/speedtest.html" style="height:'+iHeight+'px"></iframe>' | |
}, | |
weather: function(){ | |
output = '<div style="background:#839496;padding-top:5px;max-height:245px;overflow:hidden;border-radius:2px;"><iframe id="forecast_embed" src="http://forecast.io/embed/#lat=43.612426&lon=-79.488147&name=Mimico&color=#fdf6e3&font=Open+Sans&units=ca"> </iframe></div>' | |
}, | |
welcome: function(){ | |
output = '<p>Welcome to JOE, the JavaScript Operating Environment. This is a web page concept using keyboard input as a means to access and control the display of information.</p><p>Type “<code onclick="interpret(\'help\');addToHistory(\'help\');">help</code>” to see a list of known commands.</p>' | |
} | |
}; | |
function enterCommand(input){ | |
if(prompt_input.value != ''){ | |
log = input | |
prompt_input.value = '' | |
interpret(input) | |
if (silent_mode !== true){ | |
addToHistory(input) | |
} else { | |
silent_mode = false | |
} | |
prompt_input.focus() | |
} else { | |
prompt_input.focus() | |
} | |
} | |
function interpret(input){ | |
for (known in command){ | |
if (input == known){ | |
window.command[known]() | |
} | |
} | |
} | |
function addToHistory(input){ | |
var section = document.createElement('section'), | |
history = document.createElement('h1'), | |
exit = document.createElement('a'); | |
exit.innerHTML = '×' | |
exit.classList.add('exit') | |
exit.setAttribute('onclick', 'this.parentNode.remove();prompt_input.focus()') | |
section.appendChild(exit) | |
section.classList.add(input) | |
history.innerHTML = input | |
section.appendChild(history) | |
if (output != ''){ | |
if (fullscreen_mode == true){ | |
output = output + '<a class="zoom" onclick="if(this.previousSibling.requestFullscreen){this.previousSibling.requestFullscreen()}else if(this.previousSibling.msRequestFullscreen){this.previousSibling.msRequestFullscreen()}else if(this.previousSibling.mozRequestFullScreen){this.previousSibling.mozRequestFullScreen()}else if(this.previousSibling.webkitRequestFullscreen){this.previousSibling.webkitRequestFullscreen()}">+</a>' | |
fullscreen_mode = false | |
} | |
var content = document.createElement('div'); | |
content.innerHTML = output | |
section.appendChild(content) | |
output = '' | |
} | |
document.getElementsByTagName('body')[0].insertBefore(section, prompt) | |
window.scrollTo(0, document.body.scrollHeight) | |
} | |
document.onkeydown = function(e){ | |
e = e || window.event | |
var charCode = (typeof e.which=='number')?e.which:e.keyCode; | |
charCode==13 && enterCommand(prompt_input.value) // enter key submits the command | |
charCode==38 && (prompt_input.value = log) // up key shows last command | |
} | |
interpret('welcome') | |
addToHistory('welcome') | |
window.addEventListener('load', function(e){ | |
window.scrollTo(0,0) | |
prompt_input.focus() | |
}) | |
</script> | |
</body> | |
</html> |
This file contains 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
CACHE MANIFEST | |
# version 9 | |
CACHE: | |
http://staticresource.com/index.html | |
#apps | |
http://staticresource.com/sketch.html | |
http://staticresource.com/encode.html | |
http://staticresource.com/game.html | |
http://staticresource.com/shuffle.html | |
http://staticresource.com/reminders.html | |
http://staticresource.com/speedtest.html | |
http://staticresource.com/calc.html | |
http://staticresource.com/deck.html | |
http://staticresource.com/grid.html | |
#demos | |
http://staticresource.com/gestures.html | |
http://staticresource.com/touches.html | |
http://staticresource.com/notifications.html | |
http://staticresource.com/conjure.html | |
http://staticresource.com/count.html | |
http://staticresource.com/validation.html | |
http://staticresource.com/guidedForm.html | |
http://staticresource.com/personas-demo.html | |
NETWORK: | |
* |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment