mirror of
https://codeberg.org/TicklishHoneyBee/CLIte.git
synced 2026-03-11 09:04:37 +00:00
initial commit
This commit is contained in:
commit
96bf936ec9
6 changed files with 267 additions and 0 deletions
60
clite/core.css
Normal file
60
clite/core.css
Normal 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
166
clite/core.js
Normal 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, '&')
|
||||
.replace(/'/g, '&apos')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/</g, '<')
|
||||
.replace(/ /g, ' ');
|
||||
}
|
||||
}
|
||||
8
data/filesys.txt
Normal file
8
data/filesys.txt
Normal 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
6
data/intro
Normal 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
20
index.html
Normal 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
7
index.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<!--?php
|
||||
if (!isset($_POST['CLITE_SESSION'])) {
|
||||
?-->
|
||||
|
||||
<!--?php
|
||||
}
|
||||
?-->
|
||||
Loading…
Reference in a new issue