mirror of
https://git.ari.lt/ari.lt/ari.lt.git
synced 2025-02-04 17:49:24 +01:00
start work on the personal
branch
Signed-off-by: Ari Archer <ari.web.xyz@gmail.com>
This commit is contained in:
parent
7ebec490bd
commit
a55acd0200
11 changed files with 1 additions and 1489 deletions
|
@ -1,234 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Confetti.js source: https://www.cssscript.com/confetti-falling-animation/
|
|
||||||
|
|
||||||
let max_partics = 150; // set max confetti count
|
|
||||||
let partic_spd = 2; // set the particle animation speed
|
|
||||||
|
|
||||||
let confetti; // call to start confetti animation
|
|
||||||
let stop_confetti; // call to stop adding confetti
|
|
||||||
let rm_confetti; // call to stop the confetti animation and remove all confetti immediately
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
confetti = start_confetti_inner;
|
|
||||||
stop_confetti = stop_confetti_inner;
|
|
||||||
rm_confetti = remove_confetti_inner;
|
|
||||||
|
|
||||||
let ctx, canvas;
|
|
||||||
let clrs = [
|
|
||||||
"DodgerBlue",
|
|
||||||
"OliveDrab",
|
|
||||||
"Gold",
|
|
||||||
"Pink",
|
|
||||||
"SlateBlue",
|
|
||||||
"LightBlue",
|
|
||||||
"Violet",
|
|
||||||
"PaleGreen",
|
|
||||||
"SteelBlue",
|
|
||||||
"SandyBrown",
|
|
||||||
"Chocolate",
|
|
||||||
"Crimson",
|
|
||||||
];
|
|
||||||
let confetti_on = false;
|
|
||||||
let anim_t = null;
|
|
||||||
let particles = [];
|
|
||||||
let wav_angle = 0;
|
|
||||||
|
|
||||||
function reset_particle(part, width, height) {
|
|
||||||
part.color = clrs[(Math.random() * clrs.length) | 0];
|
|
||||||
part.x = Math.random() * width;
|
|
||||||
part.y = Math.random() * height - height;
|
|
||||||
part.diameter = Math.random() * 10 + 5;
|
|
||||||
part.tilt = Math.random() * 10 - 10;
|
|
||||||
part.tiltAngleIncrement = Math.random() * 0.07 + 0.05;
|
|
||||||
part.tiltAngle = 0;
|
|
||||||
|
|
||||||
return part;
|
|
||||||
}
|
|
||||||
|
|
||||||
function stop_confetti_inner() {
|
|
||||||
confetti_on = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove_confetti_inner() {
|
|
||||||
stop_confetti();
|
|
||||||
rm_confetti();
|
|
||||||
particles = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
function start_confetti_inner(text, textclr) {
|
|
||||||
let width = window.innerWidth;
|
|
||||||
let height = window.innerHeight;
|
|
||||||
|
|
||||||
window.req_animf = (function () {
|
|
||||||
return (
|
|
||||||
window.requestAnimationFrame ||
|
|
||||||
window.webkitRequestAnimationFrame ||
|
|
||||||
window.mozRequestAnimationFrame ||
|
|
||||||
window.oRequestAnimationFrame ||
|
|
||||||
window.msRequestAnimationFrame ||
|
|
||||||
function (callback) {
|
|
||||||
return window.setTimeout(callback, 16.6666667);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
})();
|
|
||||||
|
|
||||||
canvas = document.getElementById("c");
|
|
||||||
|
|
||||||
if (canvas === null) {
|
|
||||||
canvas = document.createElement("canvas");
|
|
||||||
canvas.setAttribute("id", "c");
|
|
||||||
canvas.setAttribute(
|
|
||||||
"style",
|
|
||||||
"display:block;z-index:999999;pointer-events:none;overflow-y:hidden;min-width:100%;min-height:100%;position:fixed;top:0;left:0"
|
|
||||||
);
|
|
||||||
|
|
||||||
document.body.appendChild(canvas);
|
|
||||||
|
|
||||||
canvas.width = width;
|
|
||||||
canvas.height = height;
|
|
||||||
|
|
||||||
window.addEventListener(
|
|
||||||
"resize",
|
|
||||||
() => {
|
|
||||||
canvas.width = window.innerWidth;
|
|
||||||
canvas.height = window.innerHeight;
|
|
||||||
},
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = canvas.getContext("2d");
|
|
||||||
|
|
||||||
while (particles.length < max_partics)
|
|
||||||
particles.push(reset_particle({}, width, height));
|
|
||||||
|
|
||||||
confetti_on = true;
|
|
||||||
|
|
||||||
if (anim_t === null) {
|
|
||||||
(function anim() {
|
|
||||||
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
|
|
||||||
|
|
||||||
if (particles.length === 0) {
|
|
||||||
anim_t = null;
|
|
||||||
ctx.clearRect(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
window.innerWidth,
|
|
||||||
window.innerHeight
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
upd_partics();
|
|
||||||
drw_partics();
|
|
||||||
|
|
||||||
anim_t = req_animf(anim);
|
|
||||||
|
|
||||||
ctx.textAlign = "center";
|
|
||||||
ctx.fillStyle = textclr;
|
|
||||||
ctx.font = "2em sans-serif";
|
|
||||||
|
|
||||||
ctx.fillText(
|
|
||||||
text,
|
|
||||||
canvas.width / 2,
|
|
||||||
canvas.height / 2
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
|
|
||||||
alert(`\u{0001f389} ${text} \u{0001f389}`);
|
|
||||||
particles = [];
|
|
||||||
|
|
||||||
return stop_confetti();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function drw_partics() {
|
|
||||||
let part, x;
|
|
||||||
|
|
||||||
for (let i = 0; i < particles.length; i++) {
|
|
||||||
part = particles[i];
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.lineWidth = part.diameter;
|
|
||||||
ctx.strokeStyle = part.color;
|
|
||||||
|
|
||||||
x = part.x + part.tilt;
|
|
||||||
|
|
||||||
ctx.moveTo(x + part.diameter / 2, part.y);
|
|
||||||
ctx.lineTo(
|
|
||||||
x,
|
|
||||||
part.y + part.tilt + part.diameter / 2
|
|
||||||
);
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function upd_partics() {
|
|
||||||
let width = window.innerWidth;
|
|
||||||
let height = window.innerHeight;
|
|
||||||
let part;
|
|
||||||
|
|
||||||
wav_angle += 0.01;
|
|
||||||
|
|
||||||
for (let i = 0; i < particles.length; i++) {
|
|
||||||
part = particles[i];
|
|
||||||
|
|
||||||
if (!confetti_on && part.y < -15)
|
|
||||||
part.y = height + 100;
|
|
||||||
else {
|
|
||||||
part.tiltAngle += part.tiltAngleIncrement;
|
|
||||||
part.x += Math.sin(wav_angle);
|
|
||||||
part.y +=
|
|
||||||
(Math.cos(wav_angle) + part.diameter + partic_spd) *
|
|
||||||
0.5;
|
|
||||||
part.tilt = Math.sin(part.tiltAngle) * 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
part.x > width + 20 ||
|
|
||||||
part.x < -20 ||
|
|
||||||
part.y > height
|
|
||||||
) {
|
|
||||||
if (confetti_on && particles.length <= max_partics)
|
|
||||||
reset_particle(part, width, height);
|
|
||||||
else {
|
|
||||||
particles.splice(i, 1);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
function human_num(n) {
|
|
||||||
let tmp_numr = NUMERICS[n - 1];
|
|
||||||
return `${n}${tmp_numr ? tmp_numr : NUMERICS[NUMERICS.length - 1]}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
let ctime = new Date();
|
|
||||||
|
|
||||||
if (
|
|
||||||
BIRTHDAY.getDate() == ctime.getDate() &&
|
|
||||||
BIRTHDAY.getMonth() == ctime.getMonth() &&
|
|
||||||
BIRTHDAY.getFullYear() != ctime.getFullYear() &&
|
|
||||||
(!("bday" in window.localStorage) ||
|
|
||||||
window.localStorage["bday"] != ctime.getFullYear())
|
|
||||||
) {
|
|
||||||
let bday = ctime.getFullYear() - BIRTHDAY.getFullYear();
|
|
||||||
|
|
||||||
confetti(
|
|
||||||
`Happy ${human_num(bday)} birthday, ${site_name}!`,
|
|
||||||
"#f0f7ff"
|
|
||||||
);
|
|
||||||
|
|
||||||
setTimeout(() => stop_confetti(), 5000);
|
|
||||||
|
|
||||||
window.localStorage.setItem("bday", ctime.getFullYear());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", main);
|
|
|
@ -1,144 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const boot = document.getElementById("boot");
|
|
||||||
const max_username_len = 100;
|
|
||||||
const site_name = "ari-web";
|
|
||||||
const kernel_version = "1.0.0";
|
|
||||||
const boot_message = {
|
|
||||||
0: {
|
|
||||||
type: "ok",
|
|
||||||
text: `Booting '${site_name}'...`,
|
|
||||||
sleep_time: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const do_sleep = true;
|
|
||||||
const locations = [
|
|
||||||
{
|
|
||||||
url: "/git",
|
|
||||||
desc: "The source code of this website",
|
|
||||||
aliases: ["src", "source", "git", "github"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/",
|
|
||||||
desc: "The home page",
|
|
||||||
aliases: ["home", "root", "index"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/page/reset",
|
|
||||||
desc: "Reset your account",
|
|
||||||
aliases: ["reset", "erase", "del", "delete"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/page/minimal.txt",
|
|
||||||
desc: "The minimal page",
|
|
||||||
aliases: ["mini", "minimal", "txt", "min"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/page/blog",
|
|
||||||
desc: "Blog page",
|
|
||||||
aliases: ["blog", "news", "blogs", "articles"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/dotfiles",
|
|
||||||
desc: "My dotfiles-cleaned github repository",
|
|
||||||
aliases: ["rice", "dotfiles", "dots", "dwm"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/page/novpn",
|
|
||||||
desc: "A page about how you shouldn't use VPNs",
|
|
||||||
aliases: ["vpn", "novpn"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/mp",
|
|
||||||
desc: "My music playlist",
|
|
||||||
aliases: ["music", "playlist"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/tdotfiles",
|
|
||||||
desc: "My dotfiles-termux github repository",
|
|
||||||
aliases: ["trice", "tdotfiles", "tdots", "termux"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/page/ttytheme",
|
|
||||||
desc: "TTY theme generator",
|
|
||||||
aliases: ["tty", "ttytheme", "ttheme", "tty-theme"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/user",
|
|
||||||
desc: "Ari-web comments",
|
|
||||||
aliases: ["comment", "user", "usr", "chat"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/api",
|
|
||||||
desc: "Ari-web api(s)",
|
|
||||||
aliases: ["api", "API"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/page/amiunique",
|
|
||||||
desc: "'Am I unique?' test",
|
|
||||||
aliases: ["uniqueness", "unqtest", "unique", "unqquiz"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/page/90s",
|
|
||||||
desc: "90s page",
|
|
||||||
aliases: ["90s", "90", "vintage", "old"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/page/export",
|
|
||||||
desc: "Export and/or import your ari-web data",
|
|
||||||
aliases: ["export", "import", "data"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/m",
|
|
||||||
desc: "Favourite song",
|
|
||||||
aliases: ["song", "favsong"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/page/info",
|
|
||||||
desc: "Important ari-web info",
|
|
||||||
aliases: ["info", "important"],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
url: "/etc",
|
|
||||||
desc: "Random ari-web pages, projects, etc.",
|
|
||||||
aliases: ["etc", "projects", "urandom"],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const escape_HTML = (str) =>
|
|
||||||
str.replace(
|
|
||||||
/[&<>'"]/g,
|
|
||||||
(tag) =>
|
|
||||||
({
|
|
||||||
"&": "&",
|
|
||||||
"<": "<",
|
|
||||||
">": ">",
|
|
||||||
"'": "'",
|
|
||||||
'"': """,
|
|
||||||
}[tag] || tag)
|
|
||||||
);
|
|
||||||
|
|
||||||
const BIRTHDAY = new Date(2020, 9, 17, 0, 0, 0, 0); // Ari-web start: 2020/10/17
|
|
||||||
|
|
||||||
/*
|
|
||||||
let dt = new Date();
|
|
||||||
const BIRTHDAY = new Date(dt.getFullYear() - 2, dt.getMonth(), dt.getDate(), 0, 0, 0, 0);
|
|
||||||
*/
|
|
||||||
|
|
||||||
const NUMERICS = ["st", "nd", "rd", "th"];
|
|
|
@ -1,101 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var root = false;
|
|
||||||
var not_return = false;
|
|
||||||
|
|
||||||
add_boot_entry(boot_message);
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
let is_logged_in =
|
|
||||||
localStorage.getItem("username") && localStorage.getItem("password");
|
|
||||||
|
|
||||||
let tmp_boot_entries = {
|
|
||||||
0: {
|
|
||||||
type: "error",
|
|
||||||
text: "No user account found",
|
|
||||||
},
|
|
||||||
1: {
|
|
||||||
type: "warning",
|
|
||||||
text: "Creating account",
|
|
||||||
sleep_time: 500,
|
|
||||||
},
|
|
||||||
3: {
|
|
||||||
type: "ok",
|
|
||||||
text: `Found user account: <b>${
|
|
||||||
localStorage.getItem("username")
|
|
||||||
? escape_HTML(localStorage.getItem("username"))
|
|
||||||
: ""
|
|
||||||
}</b>`,
|
|
||||||
},
|
|
||||||
4: {
|
|
||||||
type: "ok",
|
|
||||||
text: "Loading HTML",
|
|
||||||
},
|
|
||||||
5: {
|
|
||||||
type: "ok",
|
|
||||||
text: "Loading a basic shell",
|
|
||||||
},
|
|
||||||
6: {
|
|
||||||
type: "ok",
|
|
||||||
text: `'${site_name}' has been booted! Type <b>help</b> for help.`,
|
|
||||||
},
|
|
||||||
7: {
|
|
||||||
type: "error",
|
|
||||||
text: 'A fatal error has occured, report it <a href="/git">here</a>',
|
|
||||||
sleep_time: 0,
|
|
||||||
},
|
|
||||||
8: {
|
|
||||||
type: "warning",
|
|
||||||
text: '<a href="https://blog.ari-web.xyz/b/important--impersonation-of-me-on-the-internet/">Currently there has been a lot of impersonating happening! Be careful!</a>',
|
|
||||||
sleep_time: 1000,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
await add_boot_entry({ 0: tmp_boot_entries[8] });
|
|
||||||
|
|
||||||
if (!is_logged_in) {
|
|
||||||
await add_boot_entry({
|
|
||||||
0: tmp_boot_entries[0],
|
|
||||||
1: tmp_boot_entries[1],
|
|
||||||
});
|
|
||||||
await sleep(500);
|
|
||||||
await user_account_create().catch(async (e) => {
|
|
||||||
window.localStorage.clear();
|
|
||||||
let boot_error = {
|
|
||||||
type: "error",
|
|
||||||
text: e,
|
|
||||||
sleep_time: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
await add_boot_entry({ 0: boot_error, 1: tmp_boot_entries[7] });
|
|
||||||
not_return = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!not_return) window.location.reload();
|
|
||||||
} else {
|
|
||||||
if (
|
|
||||||
window.localStorage.username.length > max_username_len ||
|
|
||||||
!window.localStorage.username
|
|
||||||
) {
|
|
||||||
window.localStorage.username = pprompt(
|
|
||||||
`Invalid username found, change it (must be between 1 and ${max_username_len} characters)`
|
|
||||||
);
|
|
||||||
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
await add_boot_entry({
|
|
||||||
0: tmp_boot_entries[3],
|
|
||||||
});
|
|
||||||
await add_boot_entry({
|
|
||||||
0: tmp_boot_entries[4],
|
|
||||||
1: tmp_boot_entries[5],
|
|
||||||
2: tmp_boot_entries[6],
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("shell").style.display = "block";
|
|
||||||
document.getElementById("prompt").focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", main);
|
|
|
@ -1,74 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
let user_canceled = false;
|
|
||||||
|
|
||||||
function pprompt(message) {
|
|
||||||
if (user_canceled) return;
|
|
||||||
|
|
||||||
let value = prompt(message);
|
|
||||||
|
|
||||||
if (value === null) {
|
|
||||||
user_canceled = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value.replaceAll(" ", "") ? value : pprompt(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function user_account_create() {
|
|
||||||
alert(
|
|
||||||
"This account is not a *real* account, this is just a toy to refer \
|
|
||||||
to you by your username and for more realistic 'root' access"
|
|
||||||
);
|
|
||||||
|
|
||||||
let username = pprompt(`Enter (make up) your username`);
|
|
||||||
let password = pprompt(`Enter the password for '${username}'`);
|
|
||||||
let password_confirm = pprompt(`Confirm the password for '${username}'`);
|
|
||||||
|
|
||||||
let tmp_boot_entries = {
|
|
||||||
0: {
|
|
||||||
type: "error",
|
|
||||||
text: "User account not created: canceled by user",
|
|
||||||
sleep_time: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let msg = "unknown reason (please report this bug)";
|
|
||||||
let valid = false;
|
|
||||||
|
|
||||||
// Lord forgive me, but what else am I supposed to do
|
|
||||||
if (!password_confirm) msg = "no password confirmation supplied";
|
|
||||||
else if (password.length < 6) msg = "password is shorter than 6 characters";
|
|
||||||
else if (username.length > max_username_len || !username)
|
|
||||||
msg = `username is not between 1 and ${max_username_len} characters`;
|
|
||||||
else if (password !== password_confirm)
|
|
||||||
msg = "password and password confirmation did not match";
|
|
||||||
else valid = true;
|
|
||||||
|
|
||||||
if (!valid) {
|
|
||||||
if (
|
|
||||||
!user_canceled &&
|
|
||||||
confirm(
|
|
||||||
`The credentials you entered are not valid: ${msg}, try again?`
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
user_account_create();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_boot_entry({ 0: tmp_boot_entries[0] });
|
|
||||||
await sleep(2500);
|
|
||||||
} else {
|
|
||||||
alert("The next popup will show your credentials, press OK to proceed");
|
|
||||||
let confirm_credentials = confirm(`Are these credentials correct?:
|
|
||||||
USER: ${username}
|
|
||||||
PASS: ${password}`);
|
|
||||||
|
|
||||||
if (confirm_credentials) {
|
|
||||||
localStorage.setItem("username", username);
|
|
||||||
localStorage.setItem("password", hash(password));
|
|
||||||
|
|
||||||
alert("Credentials saved!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,115 +0,0 @@
|
||||||
function sleep(ms) {
|
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function add_boot_entry(entry_object) {
|
|
||||||
for (const entry in entry_object) {
|
|
||||||
if (do_sleep) {
|
|
||||||
let sleep_time;
|
|
||||||
if (typeof entry_object[entry]["sleep_time"] !== "undefined") {
|
|
||||||
sleep_time = entry_object[entry]["sleep_time"];
|
|
||||||
} else {
|
|
||||||
sleep_time = Math.floor(Math.random() * 2000 + 500);
|
|
||||||
}
|
|
||||||
await sleep(sleep_time);
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_entry = document.createElement("p");
|
|
||||||
new_entry.innerHTML = entry_object[entry]["text"];
|
|
||||||
new_entry.classList.add("bmsg");
|
|
||||||
|
|
||||||
let entry_class;
|
|
||||||
switch (entry_object[entry]["type"]) {
|
|
||||||
case "error":
|
|
||||||
entry_class = "error";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "warning":
|
|
||||||
entry_class = "warn";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "ok":
|
|
||||||
entry_class = "ok";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw `Type '${entry_object[entry]["type"]}' not found.`;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_entry.setAttribute("bmsg_type", entry_class);
|
|
||||||
boot.appendChild(new_entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function hash(string) {
|
|
||||||
return string.split("").reduce(function (a, b) {
|
|
||||||
a = (a << 5) - a + b.charCodeAt(0);
|
|
||||||
return a & a;
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function to_filename(filename) {
|
|
||||||
return filename.replaceAll(" ", "_");
|
|
||||||
}
|
|
||||||
|
|
||||||
function to_storage(filename) {
|
|
||||||
return `file.${to_filename(filename)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function file_exists(filename) {
|
|
||||||
return to_storage(filename) in window.localStorage;
|
|
||||||
}
|
|
||||||
|
|
||||||
function save_file(filename, content) {
|
|
||||||
try {
|
|
||||||
window.localStorage.setItem(to_storage(filename), btoa(content));
|
|
||||||
} catch (e) {
|
|
||||||
alert(`Failed to save ${to_filename(filename)}: ${e}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_file(filename) {
|
|
||||||
let file = window.localStorage.getItem(to_storage(filename));
|
|
||||||
return file ? atob(file) : "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function remove_file(filename) {
|
|
||||||
window.localStorage.removeItem(to_storage(filename));
|
|
||||||
}
|
|
||||||
|
|
||||||
function list_files() {
|
|
||||||
let files = [];
|
|
||||||
|
|
||||||
Object.keys(localStorage).forEach((key) => {
|
|
||||||
if (key.startsWith("file.")) files.push(key.slice(5));
|
|
||||||
});
|
|
||||||
|
|
||||||
return files;
|
|
||||||
}
|
|
||||||
|
|
||||||
function disable(element) {
|
|
||||||
element.setAttribute("disabled", "disabled");
|
|
||||||
element.setAttribute("readonly", "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
function enable(element) {
|
|
||||||
element.removeAttribute("disabled");
|
|
||||||
element.removeAttribute("readonly");
|
|
||||||
}
|
|
||||||
|
|
||||||
function invoke_download(filename, data) {
|
|
||||||
let blob = new Blob([data], { type: "text/plain" });
|
|
||||||
|
|
||||||
if (window.navigator.msSaveOrOpenBlob)
|
|
||||||
window.navigator.msSaveBlob(blob, filename);
|
|
||||||
else {
|
|
||||||
let elem = window.document.createElement("a");
|
|
||||||
|
|
||||||
elem.href = window.URL.createObjectURL(blob);
|
|
||||||
elem.download = filename;
|
|
||||||
|
|
||||||
document.body.appendChild(elem);
|
|
||||||
elem.click();
|
|
||||||
document.body.removeChild(elem);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,183 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var commands = {
|
|
||||||
clear: {
|
|
||||||
func: clear,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "A command to clear the screen",
|
|
||||||
short_desc: "Clear the screen",
|
|
||||||
examples: ["clear"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
reboot: {
|
|
||||||
func: reboot,
|
|
||||||
root_only: true,
|
|
||||||
help: {
|
|
||||||
desc: "A command to reboot",
|
|
||||||
short_desc: "Reboot",
|
|
||||||
examples: ["reboot"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
help: {
|
|
||||||
func: help,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "A command to print help",
|
|
||||||
short_desc: "Print help",
|
|
||||||
examples: ["help", "help help"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
show: {
|
|
||||||
func: show,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "A command to show pages",
|
|
||||||
short_desc: "Show page",
|
|
||||||
examples: ["show src", "show"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
cd: {
|
|
||||||
func: cd,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "A command to go to pages",
|
|
||||||
short_desc: "Go to a page via an alias",
|
|
||||||
examples: ["cd src", "cd"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
list: {
|
|
||||||
func: list,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "A command to list available pages",
|
|
||||||
short_desc: "List pages",
|
|
||||||
examples: ["list"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
su: {
|
|
||||||
func: su,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "A command to run commands as <b>root</b>, use 'su .' to switch between the users.",
|
|
||||||
short_desc: "Run as root",
|
|
||||||
examples: ["su .", "su reboot"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
passwd: {
|
|
||||||
func: passwd,
|
|
||||||
root_only: true,
|
|
||||||
help: {
|
|
||||||
desc: "A command to change your password",
|
|
||||||
short_desc: "Change password",
|
|
||||||
examples: ["passwd"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
whoami: {
|
|
||||||
func: whoami,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "A command to show your current user",
|
|
||||||
short_desc: "Show user",
|
|
||||||
examples: ["whoami"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
echo: {
|
|
||||||
func: echo,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "Output a string",
|
|
||||||
short_desc: "Output a string",
|
|
||||||
examples: ["echo hello world"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
webfetch: {
|
|
||||||
func: webfetch,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "Neofetch, but for the web",
|
|
||||||
short_desc: "Neofetch for the web",
|
|
||||||
examples: ["webfetch"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
wed: {
|
|
||||||
func: wed,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "Standard web editor",
|
|
||||||
short_desc: "Standard web editor",
|
|
||||||
examples: ["wed file"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
rm: {
|
|
||||||
func: rm,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "Remove file(s)",
|
|
||||||
short_desc: "Remove a file",
|
|
||||||
examples: ["rm file", "rm file1 file"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
ls: {
|
|
||||||
func: ls,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "List files",
|
|
||||||
short_desc: "List files",
|
|
||||||
examples: ["ls", "ls file"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
mv: {
|
|
||||||
func: mv,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "Move files",
|
|
||||||
short_desc: "Move files",
|
|
||||||
examples: ["mv file file1"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
cat: {
|
|
||||||
func: cat,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "Concat files",
|
|
||||||
short_desc: "Concat files",
|
|
||||||
examples: ["cat file", "cat file file1"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
upload: {
|
|
||||||
func: upload,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "Upload file(s)",
|
|
||||||
short_desc: "File upload",
|
|
||||||
examples: ["upload"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
download: {
|
|
||||||
func: download,
|
|
||||||
root_only: false,
|
|
||||||
help: {
|
|
||||||
desc: "Download file(s)",
|
|
||||||
short_desc: "File download",
|
|
||||||
examples: ["download file", "download file1 file"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,384 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function clear() {
|
|
||||||
document.getElementById("command_output").innerHTML = "";
|
|
||||||
document.getElementById("cmd_hist").innerHTML = "";
|
|
||||||
document.getElementById("content").innerHTML = "";
|
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function reboot() {
|
|
||||||
window.location.reload();
|
|
||||||
return "Rebooting...";
|
|
||||||
}
|
|
||||||
|
|
||||||
function help(cmd) {
|
|
||||||
let help_page = "";
|
|
||||||
let help_cmd = cmd[0];
|
|
||||||
|
|
||||||
if (help_cmd && !commands[help_cmd]) {
|
|
||||||
return `Help page for '${help_cmd}' does not exist`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (help_cmd) {
|
|
||||||
let cmd_help = commands[help_cmd]["help"];
|
|
||||||
|
|
||||||
help_page += `<b>NAME</b>: ${help_cmd}<br/>`;
|
|
||||||
help_page += `<b>SUID</b>: ${commands[help_cmd]["root_only"]}<br/>`;
|
|
||||||
help_page += `<b>DESCRIPTION</b>: ${cmd_help["desc"]}<br/>`;
|
|
||||||
help_page += `<b>EXAMPLES</b>:<br/>`;
|
|
||||||
|
|
||||||
for (const example in cmd_help["examples"]) {
|
|
||||||
help_page += `<b>$</b> ${cmd_help["examples"][example]}<br/>`;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
for (const h in commands) {
|
|
||||||
let cmd_help = commands[h]["help"];
|
|
||||||
|
|
||||||
help_page += `<b>NAME</b>: ${h}<br/>`;
|
|
||||||
help_page += `<b>SUID</b>: ${commands[h]["root_only"]}<br/>`;
|
|
||||||
help_page += `<b>DESCRIPTION</b>: ${cmd_help["short_desc"]}<br/>`;
|
|
||||||
help_page += `<b>EXAMPLE</b>: ${cmd_help["examples"][0]}<br/>`;
|
|
||||||
help_page += `<br/>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return help_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
function show(dest) {
|
|
||||||
let dst = dest[0];
|
|
||||||
let iframe = document.createElement("iframe");
|
|
||||||
iframe.setAttribute("class", "iframe");
|
|
||||||
|
|
||||||
if (!dst) return help(["show"]);
|
|
||||||
else
|
|
||||||
for (const l of locations) {
|
|
||||||
if (l["aliases"].includes(dst)) {
|
|
||||||
iframe.setAttribute("src", l["url"]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iframe.src) return iframe.outerHTML;
|
|
||||||
else return `Page '${dst}' not found`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function cd(dest) {
|
|
||||||
let dst = dest[0];
|
|
||||||
|
|
||||||
if (!dst) {
|
|
||||||
window.location = "/";
|
|
||||||
return "Returning to the home page";
|
|
||||||
} else {
|
|
||||||
for (const l of locations) {
|
|
||||||
if (l["aliases"].includes(dst)) {
|
|
||||||
window.location = l["url"];
|
|
||||||
return `Going to ${l["url"]}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return `Page ${dst} does not exist`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function list() {
|
|
||||||
let locs = "";
|
|
||||||
|
|
||||||
for (const l of locations) {
|
|
||||||
locs += `<b>URL</b>: ${l["url"]}<br/>`;
|
|
||||||
locs += `<b>DESCRIPTION</b>: ${l["desc"]}<br/>`;
|
|
||||||
locs += `<b>ALIASES</b>: ${l["aliases"].join(", ")}<br/>`;
|
|
||||||
locs += `<br/>`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return locs;
|
|
||||||
}
|
|
||||||
|
|
||||||
function su(cmd) {
|
|
||||||
let password_hash;
|
|
||||||
if (!root) {
|
|
||||||
password_hash = hash(prompt("Enter your password"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!password_hash && !root) {
|
|
||||||
return "Not authenticated. (empty password)";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (password_hash != localStorage.getItem("password") && !root) {
|
|
||||||
return "Wrong password.";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd[0]) {
|
|
||||||
if (cmd[0] === ".") {
|
|
||||||
root = !root;
|
|
||||||
return `Switched to the <b>${
|
|
||||||
root ? "root" : escape_HTML(localStorage.getItem("username"))
|
|
||||||
}</b> user.`;
|
|
||||||
} else {
|
|
||||||
root = true;
|
|
||||||
let ret = "Command not found";
|
|
||||||
let err = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
ret = commands[cmd[0]]["func"](cmd.slice(1));
|
|
||||||
} catch (e) {
|
|
||||||
if (e.constructor !== TypeError) err = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
root = false;
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
alert(`ERROR (report it to 'cd src'): ${err}`);
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return help(["su"]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function passwd() {
|
|
||||||
let current_password = hash(prompt("Current password"));
|
|
||||||
let password1 = prompt("New password");
|
|
||||||
let password2 = prompt("Confirm new password");
|
|
||||||
|
|
||||||
if (current_password === parseInt(localStorage.getItem("password"))) {
|
|
||||||
if (password1 === password2) {
|
|
||||||
localStorage.setItem("password", hash(password1));
|
|
||||||
alert(`password set`);
|
|
||||||
} else {
|
|
||||||
return "Passwords don't match";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return "Wrong password";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function whoami() {
|
|
||||||
return root ? "root" : escape_HTML(window.localStorage.getItem("username"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function echo(argv) {
|
|
||||||
return escape_HTML(argv.join(" "));
|
|
||||||
}
|
|
||||||
|
|
||||||
function webfetch() {
|
|
||||||
let head_str = `${window.localStorage.username}@${site_name}`;
|
|
||||||
|
|
||||||
return escape_HTML(`\`8.\`888b ,8' ${head_str}
|
|
||||||
\`8.\`888b ,8' ${"-".repeat(head_str.length)}
|
|
||||||
\`8.\`888b ,8' OS: WebOS
|
|
||||||
\`8.\`888b .b ,8' Kernel: Wkernel ${kernel_version}
|
|
||||||
\`8.\`888b 88b ,8' Shell: Wsh
|
|
||||||
\`8.\`888b .\`888b,8' Terminal: HTML
|
|
||||||
\`8.\`888b8.\`8888' CPU: ${site_name[0].toUpperCase()}${site_name.slice(
|
|
||||||
1
|
|
||||||
)} web cpu (1) @ 1GHz
|
|
||||||
\`8.\`888\`8.\`88' Memory: 2B / 8B
|
|
||||||
\`8.\`8' \`8,\`' Init: WebRC
|
|
||||||
\`8.\` \`8'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function wed(argv) {
|
|
||||||
if (!argv.length) return "Wed: Error: No file specified";
|
|
||||||
|
|
||||||
let shell_prompt = document.getElementById("prompt");
|
|
||||||
|
|
||||||
disable(shell_prompt);
|
|
||||||
|
|
||||||
for (let elem of document.getElementsByClassName("editor")) elem.remove();
|
|
||||||
|
|
||||||
let editor = document.createElement("div");
|
|
||||||
let editor_box = document.createElement("textarea");
|
|
||||||
let editor_name = document.createElement("h1");
|
|
||||||
|
|
||||||
let editor_buttons = document.createElement("div");
|
|
||||||
let editor_save = document.createElement("button");
|
|
||||||
let editor_quit = document.createElement("button");
|
|
||||||
|
|
||||||
editor_box.value = get_file(argv[0]);
|
|
||||||
editor_box.spellcheck = false;
|
|
||||||
editor_box.placeholder = "Enter content here...";
|
|
||||||
|
|
||||||
editor_save.innerText = "Save";
|
|
||||||
editor_quit.innerText = "Quit";
|
|
||||||
|
|
||||||
editor_name.innerText = argv[0];
|
|
||||||
|
|
||||||
editor_buttons.appendChild(editor_save);
|
|
||||||
editor_buttons.appendChild(editor_quit);
|
|
||||||
|
|
||||||
editor_quit.onclick = () => {
|
|
||||||
editor.remove();
|
|
||||||
shell_prompt.focus();
|
|
||||||
|
|
||||||
enable(shell_prompt);
|
|
||||||
shell_prompt.focus();
|
|
||||||
};
|
|
||||||
|
|
||||||
editor_save.onclick = () => {
|
|
||||||
save_file(argv[0], editor_box.value);
|
|
||||||
editor_quit.onclick();
|
|
||||||
};
|
|
||||||
|
|
||||||
editor.appendChild(editor_name);
|
|
||||||
editor.appendChild(editor_box);
|
|
||||||
editor.appendChild(editor_buttons);
|
|
||||||
|
|
||||||
editor.classList.add("editor");
|
|
||||||
editor_buttons.classList.add("editor-buttons");
|
|
||||||
|
|
||||||
document.body.appendChild(editor);
|
|
||||||
|
|
||||||
editor_box.focus();
|
|
||||||
|
|
||||||
return `Editing: ${escape_HTML(argv[0])}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function rm(argv) {
|
|
||||||
if (!argv.length) return "Rm: no files specified";
|
|
||||||
|
|
||||||
for (let file of argv) {
|
|
||||||
if (!file_exists(file))
|
|
||||||
return `Rm: ${escape_HTML(file)}: Nothing appropriate`;
|
|
||||||
remove_file(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "Removed file(s)";
|
|
||||||
}
|
|
||||||
|
|
||||||
function ls(argv) {
|
|
||||||
if (argv.length) {
|
|
||||||
let out = "";
|
|
||||||
|
|
||||||
for (let file of argv)
|
|
||||||
if (file_exists(file)) out += `${escape_HTML(file)}\n`;
|
|
||||||
|
|
||||||
return out ? out : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let out = "";
|
|
||||||
|
|
||||||
for (let file of list_files()) out += `${escape_HTML(file)}\n`;
|
|
||||||
return out ? out : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function mv(argv) {
|
|
||||||
if (!argv.length || !file_exists(argv[0]))
|
|
||||||
return "No valid input file specified";
|
|
||||||
if (!argv[1]) return "No output file specified";
|
|
||||||
if (argv[0] === argv[1]) return "Input must not be the same as output";
|
|
||||||
|
|
||||||
let old_file = get_file(argv[0]);
|
|
||||||
|
|
||||||
remove_file(argv[0]);
|
|
||||||
save_file(argv[1], old_file);
|
|
||||||
|
|
||||||
return `${escape_HTML(argv[0])} -> ${escape_HTML(argv[1])}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function cat(argv) {
|
|
||||||
if (!argv.length) return "No input file specified";
|
|
||||||
|
|
||||||
let out = "";
|
|
||||||
|
|
||||||
for (let file of argv) {
|
|
||||||
if (file_exists(file)) out += `${escape_HTML(get_file(file))}\n`;
|
|
||||||
else out += `Cat: ${escape_HTML(file)}: No such file\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
function upload() {
|
|
||||||
let input_id = `upload_${document.getElementsByTagName("input").length}`;
|
|
||||||
|
|
||||||
let upload_container = document.createElement("div");
|
|
||||||
upload_container.classList.add("upload");
|
|
||||||
|
|
||||||
let upload_input = document.createElement("input");
|
|
||||||
upload_input.setAttribute("type", "file");
|
|
||||||
upload_input.setAttribute("multiple", "true");
|
|
||||||
upload_input.setAttribute("id", input_id);
|
|
||||||
|
|
||||||
let commit_upload = document.createElement("button");
|
|
||||||
commit_upload.innerText = "Commit";
|
|
||||||
commit_upload.setAttribute("id", `commit_upload_${input_id}`);
|
|
||||||
commit_upload.setAttribute(
|
|
||||||
"onclick",
|
|
||||||
`
|
|
||||||
function uploader_${input_id}() {
|
|
||||||
if (typeof FileReader !== 'function') {
|
|
||||||
alert("The FileReader API isn't supported on this browser");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let upload = document.getElementById("${input_id}");
|
|
||||||
let upload_button = document.getElementById("${commit_upload.id}");
|
|
||||||
|
|
||||||
let files = upload.files;
|
|
||||||
|
|
||||||
if (!files.length) {
|
|
||||||
alert("Pick at least 1 file to upload");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let file of files) {
|
|
||||||
let filename = to_filename(file.name);
|
|
||||||
|
|
||||||
if (file_exists(filename)) {
|
|
||||||
alert(\`File \${filename} alredy exists, please rm it\`)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let file of files) {
|
|
||||||
let filename = to_filename(file.name);
|
|
||||||
|
|
||||||
let reader = new FileReader();
|
|
||||||
reader.readAsText(file, "UTF-8");
|
|
||||||
|
|
||||||
reader.onload = (evt) => {
|
|
||||||
save_file(filename, evt.target.result);
|
|
||||||
};
|
|
||||||
|
|
||||||
reader.onerror = (err) => {
|
|
||||||
alert(\`error reading the file: \${err}\`);
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
upload_button.innerText = "Uploaded";
|
|
||||||
|
|
||||||
disable(upload);
|
|
||||||
disable(upload_button)
|
|
||||||
}
|
|
||||||
|
|
||||||
uploader_${input_id}();
|
|
||||||
document.getElementById("prompt").focus();
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
upload_container.appendChild(upload_input);
|
|
||||||
upload_container.appendChild(commit_upload);
|
|
||||||
|
|
||||||
return upload_container.outerHTML;
|
|
||||||
}
|
|
||||||
|
|
||||||
function download(argv) {
|
|
||||||
if (!argv.length) return "No specified files to download";
|
|
||||||
|
|
||||||
argv = [...new Set(argv)];
|
|
||||||
|
|
||||||
for (let file of argv) {
|
|
||||||
if (!file_exists(file))
|
|
||||||
return `File ${escape_HTML(file)} does not exist`;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let file of argv) invoke_download(file, get_file(file));
|
|
||||||
|
|
||||||
return "File(s) downloaded";
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
let cmd_prompt = document.getElementById("prompt");
|
|
||||||
let cmd_output = document.getElementById("command_output");
|
|
||||||
let cmd_history = document.getElementById("cmd_hist");
|
|
||||||
let shell = document.getElementById("shell");
|
|
||||||
|
|
||||||
function check_hist() {
|
|
||||||
if (cmd_prompt?.history === undefined)
|
|
||||||
cmd_prompt.history = cmd_history.children.length - 1;
|
|
||||||
|
|
||||||
if (cmd_prompt.history > cmd_history.children.length - 1)
|
|
||||||
cmd_prompt.history = cmd_history.children.length - 1;
|
|
||||||
|
|
||||||
if (cmd_prompt.history < 0) cmd_prompt.history = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
cmd_prompt.history = cmd_history.children.length - 1;
|
|
||||||
|
|
||||||
cmd_prompt.onkeydown = (e) => {
|
|
||||||
check_hist();
|
|
||||||
|
|
||||||
switch (e.key) {
|
|
||||||
case "Enter": {
|
|
||||||
if (!cmd_prompt.value) return;
|
|
||||||
|
|
||||||
let is_comment = false;
|
|
||||||
let command_list = cmd_prompt.value.trimStart().split(" ");
|
|
||||||
let command = command_list[0].toLocaleLowerCase();
|
|
||||||
let argv = command_list.slice(1);
|
|
||||||
|
|
||||||
if (commands[command]) {
|
|
||||||
if (commands[command]["root_only"] && !root) {
|
|
||||||
cmd_output.innerHTML = `'${escape_HTML(
|
|
||||||
command
|
|
||||||
)}' can <i>only</i> be ran as <b>root</b>. see <b>help su</b>`;
|
|
||||||
} else {
|
|
||||||
let out = commands[command]["func"](argv);
|
|
||||||
|
|
||||||
if (out === null) is_comment = true;
|
|
||||||
else cmd_output.innerHTML = out;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (command[0] != "#")
|
|
||||||
cmd_output.innerText = `-wsh: ${command}: command not found`;
|
|
||||||
else is_comment = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
cmd_output.innerHTML.toString().replace(/\s/g, "") ||
|
|
||||||
is_comment
|
|
||||||
) {
|
|
||||||
let shell_old = document.createElement("pre");
|
|
||||||
shell_old.setAttribute("class", "shell");
|
|
||||||
shell_old.setAttribute(
|
|
||||||
"prompt",
|
|
||||||
shell.getAttribute("prompt")
|
|
||||||
);
|
|
||||||
|
|
||||||
let cmd = document.createElement("input");
|
|
||||||
cmd.setAttribute("class", "prompt");
|
|
||||||
cmd.setAttribute("value", cmd_prompt.value);
|
|
||||||
disable(cmd);
|
|
||||||
|
|
||||||
let output = document.createElement("div");
|
|
||||||
output.setAttribute("class", "output");
|
|
||||||
output.innerHTML = cmd_output.innerHTML;
|
|
||||||
|
|
||||||
shell_old.appendChild(cmd);
|
|
||||||
shell_old.appendChild(output);
|
|
||||||
|
|
||||||
cmd_history.appendChild(shell_old);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd_prompt.value = "";
|
|
||||||
cmd_output.innerHTML = "";
|
|
||||||
|
|
||||||
window.scrollTo(0, document.body.scrollHeight);
|
|
||||||
|
|
||||||
if (root) shell.setAttribute("prompt", "root");
|
|
||||||
else shell.setAttribute("prompt", "");
|
|
||||||
|
|
||||||
cmd_prompt.history = cmd_history.children.length - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "ArrowUp": {
|
|
||||||
cmd_prompt.value =
|
|
||||||
cmd_history.children[cmd_prompt.history--]?.firstChild
|
|
||||||
.value || cmd_prompt.value;
|
|
||||||
|
|
||||||
cmd_prompt.selectionStart = cmd_prompt.value.length - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "ArrowDown": {
|
|
||||||
cmd_prompt.value =
|
|
||||||
cmd_history.children[cmd_prompt.history++]?.firstChild
|
|
||||||
.value || cmd_prompt.value;
|
|
||||||
|
|
||||||
cmd_prompt.selectionStart = cmd_prompt.value.length - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", main);
|
|
|
@ -1,75 +0,0 @@
|
||||||
@import "../config/_main.scss";
|
|
||||||
|
|
||||||
.boot {
|
|
||||||
margin: 1em 0em 1em 1em;
|
|
||||||
font-size: 1.5em;
|
|
||||||
-ms-overflow-style: none;
|
|
||||||
scrollbar-width: none;
|
|
||||||
|
|
||||||
& * {
|
|
||||||
-ms-overflow-style: none;
|
|
||||||
scrollbar-width: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#bootver {
|
|
||||||
color: $boot_header_colour;
|
|
||||||
margin-left: 1.12em; /* makes it that it aligns with 'boot' messages */
|
|
||||||
}
|
|
||||||
|
|
||||||
#bootver::before {
|
|
||||||
content: "WebRC version " $boot_ver;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bmsg[bmsg_type="ok"] {
|
|
||||||
&::after {
|
|
||||||
content: "[OK]";
|
|
||||||
float: right;
|
|
||||||
color: $ok_colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: " * ";
|
|
||||||
color: $ok_colour;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bmsg[bmsg_type="warn"] {
|
|
||||||
&::after {
|
|
||||||
content: "[WARNING]";
|
|
||||||
float: right;
|
|
||||||
color: $warn_colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: " * ";
|
|
||||||
color: $warn_colour;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bmsg[bmsg_type="error"] {
|
|
||||||
&::after {
|
|
||||||
content: "[ERROR]";
|
|
||||||
float: right;
|
|
||||||
color: $error_colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: " * ";
|
|
||||||
color: $error_colour;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.bmsg::first-letter {
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bmsg {
|
|
||||||
word-wrap: break-word;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.boot::-webkit-scrollbar,
|
|
||||||
.boot *::-webkit-scrollbar {
|
|
||||||
display: none;
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
@import "../config/_main.scss";
|
|
||||||
|
|
||||||
.shell {
|
|
||||||
margin: 2em;
|
|
||||||
|
|
||||||
.prompt {
|
|
||||||
color: $shell_colour;
|
|
||||||
background-color: $bg_colour;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
font-size: $shell_font_size;
|
|
||||||
width: 90%;
|
|
||||||
padding: 0 0 1.2em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.prompt:focus {
|
|
||||||
border: none;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.output {
|
|
||||||
font-size: $shell_font_size / 1.2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.shell::before {
|
|
||||||
content: "$ ";
|
|
||||||
font-size: $shell_font_size;
|
|
||||||
color: $default_content_colour;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shell[prompt="root"]::before {
|
|
||||||
content: "# ";
|
|
||||||
font-size: $shell_font_size;
|
|
||||||
color: $default_content_colour;
|
|
||||||
}
|
|
35
index.html
35
index.html
|
@ -21,9 +21,6 @@
|
||||||
<meta name="theme-color" content="black" />
|
<meta name="theme-color" content="black" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="/content/styles/generic/main.min.css" />
|
<link rel="stylesheet" href="/content/styles/generic/main.min.css" />
|
||||||
<link rel="stylesheet" href="/content/styles/boot/main.min.css" />
|
|
||||||
<link rel="stylesheet" href="/content/styles/shell/main.min.css" />
|
|
||||||
<link rel="stylesheet" href="/content/styles/editor/main.min.css" />
|
|
||||||
<link rel="stylesheet" href="/content/styles/clean/index.css" />
|
<link rel="stylesheet" href="/content/styles/clean/index.css" />
|
||||||
|
|
||||||
<link rel="manifest" href="/manifest.json" />
|
<link rel="manifest" href="/manifest.json" />
|
||||||
|
@ -56,39 +53,9 @@
|
||||||
|
|
||||||
//--><!]]>
|
//--><!]]>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="/content/js/helpers/index.js" defer></script>
|
|
||||||
<script src="/content/js/handlers/user_account.js" defer></script>
|
|
||||||
<script src="/content/js/config/index.js" defer></script>
|
|
||||||
<script src="/content/js/generic/index.js" defer></script>
|
|
||||||
<script src="/content/js/shell/func.js" defer></script>
|
|
||||||
<script src="/content/js/shell/commands.js" defer></script>
|
|
||||||
<script src="/content/js/shell/index.js" defer></script>
|
|
||||||
<script src="/content/js/bday/index.js" defer></script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="content">
|
<h1>this branch is WIP</h1>
|
||||||
<div class="boot" id="boot">
|
|
||||||
<p id="bootver"></p>
|
|
||||||
<noscript>
|
|
||||||
<p class="bmsg" bmsg_type="error">
|
|
||||||
JavaScript is <b>DISABLED</b>, read how to enable it
|
|
||||||
<a href="//enable-javascript.com">here</a>. here is the
|
|
||||||
<a href="/git">source code.</a>
|
|
||||||
</p>
|
|
||||||
<p class="bmsg" bmsg_type="error">
|
|
||||||
Still wanna explore? <a href="/90s">See the 90s page</a>
|
|
||||||
</p>
|
|
||||||
</noscript>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="cmd_hist"></div>
|
|
||||||
|
|
||||||
<div class="shell" id="shell" style="display: none">
|
|
||||||
<input type="text" class="prompt" id="prompt" />
|
|
||||||
<div class="output" id="command_output"></div>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Add table
Reference in a new issue