start work on the personal branch

Signed-off-by: Ari Archer <ari.web.xyz@gmail.com>
This commit is contained in:
Ari Archer 2023-04-04 23:03:58 +03:00
parent 7ebec490bd
commit a55acd0200
11 changed files with 1 additions and 1489 deletions

View file

@ -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);

View file

@ -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) =>
({
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
"'": "&#39;",
'"': "&quot;",
}[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"];

View file

@ -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);

View file

@ -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!");
}
}
}

View file

@ -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);
}
}

View file

@ -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"],
},
},
};

View 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";
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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>