mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-26 04:31:34 +08:00
174 lines
4.9 KiB
HTML
174 lines
4.9 KiB
HTML
<!DOCTYPE html> <html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>FTXUI examples WebAssembly</title>
|
|
<script src="https://cdn.jsdelivr.net/npm/xterm@4.18.0/lib/xterm.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-webgl@0.11.4/lib/xterm-addon-webgl.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.min.js"></script>
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@4.11.0/css/xterm.css"></link>
|
|
<!--Add COOP/COEP via a ServiceWorker to use SharedArrayBuffer-->
|
|
<script>
|
|
if ("serviceWorker" in navigator && !window.crossOriginIsolated) {
|
|
navigator.serviceWorker.register(new URL("./sw.js", location.href)).then(
|
|
registration => {
|
|
if (registration.active && !navigator.serviceWorker.controller) {
|
|
window.location.reload();
|
|
}
|
|
},
|
|
);
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<script id="example_script"></script>
|
|
<div class="page">
|
|
<h1>FTXUI WebAssembly Example </h1>
|
|
<p>
|
|
<a href="https://github.com/ArthurSonzogni/FTXUI">FTXUI</a> is a single
|
|
C++ library for terminal user interface.
|
|
</p>
|
|
<p>
|
|
On this page, you can try all the examples contained in: <a
|
|
href="https://github.com/ArthurSonzogni/FTXUI/tree/master/examples">./example/</a>
|
|
Those are compiled using WebAssembly.
|
|
</p>
|
|
<select id="selectExample"></select>
|
|
<div id="terminal"></div>
|
|
</div>
|
|
</body>
|
|
<script>
|
|
const example_list = "@EXAMPLES@".split(";");
|
|
|
|
const url_search_params = new URLSearchParams(window.location.search);
|
|
const example = url_search_params.get("file") || "dom/color_gallery";
|
|
const select = document.getElementById("selectExample");
|
|
|
|
for(var i = 0; i < example_list.length; i++) {
|
|
var opt = example_list[i];
|
|
var el = document.createElement("option");
|
|
el.textContent = opt;
|
|
el.value = opt;
|
|
select.appendChild(el);
|
|
}
|
|
select.selectedIndex = example_list.findIndex(path => path == example) || 0;
|
|
select.addEventListener("change", () => {
|
|
location.href = (location.href).split('?')[0] + "?file=" +
|
|
example_list[select.selectedIndex];
|
|
});
|
|
|
|
let stdin_buffer = [];
|
|
const stdin = () => {
|
|
return stdin_buffer.shift() || 0;
|
|
}
|
|
|
|
let stdout_buffer = [];
|
|
const stdout = code => {
|
|
if (code == 0) {
|
|
term.write(new Uint8Array(stdout_buffer));
|
|
stdout_buffer = [];
|
|
} else {
|
|
stdout_buffer.push(code)
|
|
}
|
|
}
|
|
let stderrbuffer = [];
|
|
const stderr = code => {
|
|
if (code == 0 || code == 10) {
|
|
console.error(String.fromCodePoint(...stderrbuffer));
|
|
stderrbuffer = [];
|
|
} else {
|
|
stderrbuffer.push(code)
|
|
}
|
|
}
|
|
const term = new Terminal();
|
|
const term_element = document.querySelector('#terminal');
|
|
term.open(term_element);
|
|
|
|
const webgl_addon = new (WebglAddon.WebglAddon)();
|
|
term.loadAddon(webgl_addon);
|
|
|
|
const onBinary = e => {
|
|
for(c of e)
|
|
stdin_buffer.push(c.charCodeAt(0));
|
|
}
|
|
term.onBinary(onBinary);
|
|
term.onData(onBinary)
|
|
term.resize(140,43);
|
|
window.Module = {
|
|
preRun: () => {
|
|
FS.init(stdin, stdout, stderr);
|
|
},
|
|
postRun: [],
|
|
onRuntimeInitialized: () => {
|
|
if (window.Module._ftxui_on_resize == undefined)
|
|
return;
|
|
|
|
const fit_addon = new (FitAddon.FitAddon)();
|
|
term.loadAddon(fit_addon);
|
|
fit_addon.fit();
|
|
const resize_handler = () => {
|
|
const {cols, rows} = fit_addon.proposeDimensions();
|
|
term.resize(cols, rows);
|
|
window.Module._ftxui_on_resize(cols, rows);
|
|
};
|
|
const resize_observer = new ResizeObserver(resize_handler);
|
|
resize_observer.observe(term_element);
|
|
resize_handler();
|
|
|
|
// Disable scrollbar
|
|
term.write('\x1b[?47h')
|
|
},
|
|
};
|
|
|
|
const words = example.split('/')
|
|
words[1] = "ftxui_example_" + words[1] + ".js"
|
|
document.querySelector("#example_script").src = words.join('/');
|
|
</script>
|
|
|
|
<style>
|
|
|
|
body {
|
|
background-color:#EEE;
|
|
padding:20px;
|
|
font-family: Helvetica, sans-serif;
|
|
font-size: 130%;
|
|
}
|
|
|
|
.page {
|
|
max-width:1300px;
|
|
margin: auto;
|
|
}
|
|
|
|
h1 {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
select {
|
|
display:block;
|
|
padding: .6em 1.4em .5em .8em;
|
|
border-radius: 20px 20px 0px 0px;
|
|
font-size: 16px;
|
|
font-family: sans-serif;
|
|
font-weight: 700;
|
|
|
|
color: #444;
|
|
line-height: 1.3;
|
|
background-color:black;
|
|
border:0px;
|
|
color:white;
|
|
transition: color 0.2s linear;
|
|
transition: background-color 0.2s linear;
|
|
}
|
|
|
|
#terminal {
|
|
width:100%;
|
|
height: 500px;
|
|
height: calc(clamp(200px, 100vh - 300px, 900px));
|
|
overflow: hidden;
|
|
border:none;
|
|
padding:auto;
|
|
}
|
|
|
|
</style>
|
|
|
|
</html>
|