first commit

This commit is contained in:
douboer@gmail.com
2026-03-03 13:23:14 +08:00
commit 3b7c1d558a
161 changed files with 28120 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Live Demo | XTerminal</title>
<link rel="stylesheet" href="https://unpkg.com/xterminal/dist/xterminal.css">
<style>
*, *::after, *::before {
box-sizing: border-box;
}
html, body {
padding: 0;
margin: 0;
}
#app {
height: 100vh;
}
:root {
--xt-fg: lime;
--xt-bg: black;
}
.xt {
padding: 10px;
line-height: 1.215;
}
.error {
color: rgb(248, 88, 88);
}
.spinner:after {
animation: changeContent 0.8s linear infinite;
content: "⠋";
}
@keyframes changeContent {
10% { content: "⠙"; }
20% { content: "⠹"; }
30% { content: "⠸"; }
40% { content: "⠼"; }
50% { content: "⠴"; }
60% { content: "⠦"; }
70% { content: "⠧"; }
80% { content: "⠇"; }
90% { content: "⠏"; }
}
</style>
</head>
<body>
<div id="app"></div>
<script src="https://unpkg.com/xterminal/dist/xterminal.umd.js"></script>
<script src="./demo.js"></script>
<script>
window.onload = () => createTerminal('#app');
</script>
</body>
</html>

View File

@@ -0,0 +1,149 @@
/**
* Create a demo shell object
*/
// #region shell
function createShell() {
// Help
const manual = `XTerminal : version ${XTerminal.version}
Type 'help' to see this list
Commands:
gh (username) search for github users
js [expr] execute a JS expression
clear clear the terminal screen
help display this list
`;
// Get public github user information
async function fetchGitHubUser(username) {
return fetch('https://api.github.com/users/' + username)
.then(res => res.json())
.then(res => {
return(
'<table border="0">' +
'<tr>' +
`<td rowspan="3" width="100"><img width="75" src="${res.avatar_url}" alt="${res.name}" /></td>` +
`<td>Name</td>` +
`<td>${res.name}</td>` +
'</tr>' +
'<tr>' +
`<td>Bio</td>` +
`<td>${res.bio}</td>` +
'</tr>' +
'<tr>' +
`<td>Repos</td>` +
`<td>${res.public_repos}</td>` +
'</tr>' +
'</table>'
);
});
}
// evaluate user input from the terminal
// -> can be shared among several terminal objects
function execute(term, command = '') {
let args = command.split(' ');
let cmd = args.shift();
// GitHub User Search
if (cmd == 'gh') {
return new Promise(async (res, rej) => {
let output, error;
term.write('<span class="spinner"></span> Searching...');
await fetchGitHubUser(args.join(''))
.then(val => output = val)
.catch(err => error = ':( Not found!')
.finally(() => term.clearLast());
if (error) rej(error);
else res(output);
});
}
// JavaScript Evaluation
else if (cmd == 'js') {
return new Promise((res, rej) => {
try {
let output = eval(args.join(' ')) + '\n';
res(output);
} catch (error) {
rej(error);
}
});
}
// Help menu
else if (cmd == 'help') {
return Promise.resolve(manual);
}
// Clear the terminal
else if (cmd == 'clear') {
term.clear();
return Promise.resolve(null);
}
// Oopps!
else {
return Promise.reject(`sh: '${cmd}' command not found`);
}
}
return { execute };
}
// #endregion shell
/**
* Create a fresh terminal object
*/
// #region terminal
function createTerminal(target) {
const term = new XTerminal({ target });
const state = {
username: "user",
hostname: "web"
};
// input evaluator
const shell = createShell();
// print prompt and get ready for user input
function promptUser() {
term.write(`┌[${state.username}@${state.hostname}]\n`);
term.write("└$ ");
term.resume();
term.focus();
}
// user input handler
term.on("data", async input => {
// deactivate until the execution is done
term.pause();
// execute command
await shell.execute(term, input)
.then(res => res && term.writeln(res))
.catch(err => {
if (err) {
// sanitize error to prevent xss attacks
// error may contain user input or HTML strings (like script tags)
term.writeln(`<span class="error">${XTerminal.escapeHTML(err)}</span>\n`)
}
})
.finally(promptUser);
});
// greeting message
term.writeln("Welcome to XTerminal (v" + XTerminal.version + ")");
term.writeln("Type `help` for available commands\n");
// kickstart
promptUser();
// remember to free resources
window.addEventListener('unload', () => term.dispose());
}
// #endregion terminal

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -0,0 +1,9 @@
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<g>
<title>XTerminal Logo</title>
<path stroke="#000" d="m-4,-2.5l103.99998,0l0,108l-103.99998,0l0,-108z" stroke-width="0" fill="#444444"/>
<rect stroke="#000" height="33" width="16" y="29" x="42" stroke-width="0" fill="#ffffff"/>
<rect transform="rotate(-45 23.25 40.25)" stroke="#000" height="18.56497" width="6.17157" y="30.96751" x="20.16421" stroke-width="0" fill="#ffffff"/>
<rect transform="rotate(45 22.6036 50.25)" stroke="#000" height="18.75736" width="6" y="40.87132" x="19.60356" stroke-width="0" fill="#ffffff"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 616 B