initial commit

This commit is contained in:
Lisa Milne 2023-11-05 09:32:15 +10:00
commit 96bf936ec9
6 changed files with 267 additions and 0 deletions

60
clite/core.css Normal file
View file

@ -0,0 +1,60 @@
html,body {margin:0; padding:0; overflow:auto; width:100%; height:100%; background-color:#000000; color:#FFFFFF; font-family:monospace; font-size:14px;}
body {}
div, header, section, article, p, form, h1 {display:block; margin:0; padding:0;}
header {padding:10px;}
header h1 {line-height:40px; font-size:30px;}
section {}
section.content {}
section.content div#terminal {border: 1px solid #FFFFFF; width:100%; min-width: 500px; max-width:1000px; margin:10px auto; overflow:hidden; min-height:100px; padding:10px;}
section.content article {}
section.content form {}
section.content form label, section.content form input, section.content form input:focus {display:block; float:left; border:none; margin:0; padding:0; font-family:monospace; font-size:14px; line-height:20px; background-color:#000000; color:#FFFFFF; outline:none;}
div.vga {margin:auto; z-index:10; background-color:#000000;}
div.io {position:absolute; top:0px; left:0px; width:100px; height:100px; z-index:3;}
div.ioblank {position:absolute; top:0px; left:0px; width:100px; height:100px; z-index:9; background-color:black;}
div.io textarea {display:block; width:50px; height:50px;}
div.io audio {display:block; width:20px; height:20px;}
div.output {z-index:4;}
div.input {z-index:5;}
div span {margin:0; padding:0; border:0;}
.vga-f0 {color:#000000;}
.vga-f1 {color:#0000AA;}
.vga-f2 {color:#00AA00;}
.vga-f3 {color:#00AAAA;}
.vga-f4 {color:#AA0000;}
.vga-f5 {color:#AA00AA;}
.vga-f6 {color:#AA5500;}
.vga-f7 {color:#AAAAAA;}
.vga-f8 {color:#555555;}
.vga-f9 {color:#5555FF;}
.vga-fA {color:#55FF55;}
.vga-fB {color:#55FFFF;}
.vga-fC {color:#FF5555;}
.vga-fD {color:#FF55FF;}
.vga-fE {color:#FFFF55;}
.vga-fF {color:#FFFFFF;}
.vga-b0 {background-color:#000000;}
.vga-b1 {background-color:#0000AA;}
.vga-b2 {background-color:#00AA00;}
.vga-b3 {background-color:#00AAAA;}
.vga-b4 {background-color:#AA0000;}
.vga-b5 {background-color:#AA00AA;}
.vga-b6 {background-color:#AA5500;}
.vga-b7 {background-color:#AAAAAA;}
.vga-b8 {background-color:#555555;}
.vga-b9 {background-color:#5555FF;}
.vga-bA {background-color:#55FF55;}
.vga-bB {background-color:#55FFFF;}
.vga-bC {background-color:#FF5555;}
.vga-bD {background-color:#FF55FF;}
.vga-bE {background-color:#FFFF55;}
.vga-bF {background-color:#FFFFFF;}
.vga-blink {
animation: blink 1s steps(1) infinite;
}
@keyframes blink { 50% { color: transparent; } }

166
clite/core.js Normal file
View file

@ -0,0 +1,166 @@
var clite = {
state:{
isinit:false,
terminal:null,
input:{
ispass:false,
form:null,
field:null
}
},
events:{
keyup:function(e) {
if (e.key == 'Down' || e.key == 'ArrowDown') {
clite.shell.history.down();
return false;
}
if (e.key == 'Up' || e.key == 'ArrowUp') {
clite.shell.history.up();
return false;
}
var t = clite.state.input.field.value;
if (e.key != 'Enter') {
clite.shell.history.setCurrent(t);
return true;
}
clite.shell.exec(t);
return false;
},
refocus:function(e) {
clite.core.genForm();
clite.state.input.field.focus();
}
},
core:{
genForm:function() {
var f = document.getElementById('form');
if (!f)
f = document.createElement('form');
f.id = 'form';
f.innerHTML = '';
var l = document.createElement('label');
l.innerHTML = clite.shell.prompt.getHTML();
f.appendChild(l);
var i = document.createElement('input');
i.type = clite.state.input.ispass ? 'password' : 'text';
i.value = clite.shell.history.getCurrent();
f.appendChild(i);
clite.state.input.form = f;
clite.state.input.field = i;
var t = document.getElementById('terminal');
if (!t)
return;
t.appendChild(f);
i.onkeyup = clite.events.keyup;
i.onfocusout = clite.events.refocus;
i.onblur = clite.events.refocus;
f.onsubmit = function() {return false;};
},
setPass:function(is) {
clite.state.input.ispass = !!is;
if (typeof clite.state.input.ispass != 'Boolean')
clite.state.input.ispass = false;
}
},
init:function() {
if (this.state.isinit)
return;
this.state.isinit = true;
document.getElementById('terminal').innerHTML = '';
// TODO: read in /usr/share/introduction
this.events.refocus();
}
};
clite.shell = {
readLine:function(cb) {
},
writeLine:function(txt) {
var a = document.createElement('article');
a.innerHTML = txt;
var t = document.getElementById('terminal');
if (!t)
return;
t.appendChild(a);
clite.events.refocus();
},
exec:function(txt) {
if (txt.length < 1) {
clite.shell.writeLine(clite.shell.prompt.getHTML());
return;
}
clite.shell.history.add(txt);
clite.shell.history.resetCurrent();
clite.shell.writeLine(clite.shell.prompt.getHTML()+txt);
// TODO: actually execute the command
},
prompt:{
list:[],
data:'$ ',
set:function(txt) {
clite.shell.prompt.list = [];
clite.shell.prompt.data = txt;
},
push:function(txt) {
clite.shell.prompt.list.push(clite.shell.prompt.data);
clite.shell.prompt.data = txt;
},
pop:function() {
clite.shell.prompt.data = clite.shell.prompt.list.pop();
},
get:function() {
return clite.shell.prompt.data;
},
getHTML:function() {
return clite.lib.htmlEncode(clite.shell.prompt.data);
}
},
history:{
data:[],
current:'',
index:0,
add:function(txt) {
if (txt.length < 1)
return;
clite.shell.history.data.push(txt);
clite.shell.history.index = clite.shell.history.data.length;
},
up:function() {
if (clite.shell.history.index == 0)
return;
clite.shell.history.index--;
clite.events.refocus();
},
down:function() {
if (clite.shell.history.index == clite.shell.history.data.length)
return;
clite.shell.history.index++;
clite.events.refocus();
},
setCurrent:function(txt) {
clite.shell.history.current = txt;
},
getCurrent:function() {
if (clite.shell.history.index == clite.shell.history.data.length)
return clite.shell.history.current;
return clite.shell.history.data[clite.shell.history.index];
},
resetCurrent:function() {
clite.shell.history.current = '';
clite.shell.history.index = clite.shell.history.data.length;
}
}
};
clite.lib = {
htmlEncode:function(txt) {
return txt
.replace(/&/g, '&amp')
.replace(/'/g, '&apos')
.replace(/"/g, '&quot')
.replace(/>/g, '&gt')
.replace(/</g, '&lt')
.replace(/ /g, '&nbsp;');
}
}

8
data/filesys.txt Normal file
View file

@ -0,0 +1,8 @@
# filesystem index file
# line format: url:filepath:permissions
# url is the server-side file path and name, relative to the data directory
# filepath is CLIte's Unix-like path, such as /usr/share/introduction
# permissions is CLIte's Unix-like file permissions for the file, such as rwxrwxrwx
# empty lines, or lines beginning with a # are ignored
intro:/usr/share/introduction:rw-rw-r--

6
data/intro Normal file
View file

@ -0,0 +1,6 @@
BEGINDATAWelcome, this site runs on Clite, the command line site management system.
Clite works like a Unix terminal, a guest login will be automatically generated for you.
Clite has many Unix-like commands for navigating the website, simply type in a command and press enter to run it.
Not sure how this works? Use the `help' command at any time.
Press Enter to begin.

20
index.html Normal file
View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>CLITE</title>
<script type="text/javascript" src="clite/core.js"></script>
<link rel="stylesheet" type="text/css" href="clite/core.css" />
<style type="text/css"></style>
</head>
<body>
<header>
<h1 id="title">CLITE</h1>
</header>
<section class="content">
<div id="terminal">
<noscript>This site requires Javascript.</noscript>
</div>
</section>
<script type="text/javascript">clite.init();</script>
</body>
</html>

7
index.php Normal file
View file

@ -0,0 +1,7 @@
<!--?php
if (!isset($_POST['CLITE_SESSION'])) {
?-->
<!--?php
}
?-->