144 lines
4.2 KiB
HTML
144 lines
4.2 KiB
HTML
|
|
<!DOCTYPE html>
|
||
|
|
<html>
|
||
|
|
<head>
|
||
|
|
<meta charset="utf-8">
|
||
|
|
<title>apfl Playground</title>
|
||
|
|
<style type="text/css">
|
||
|
|
.apfl_playground {
|
||
|
|
--bg: #E0E0E0;
|
||
|
|
--fg: #101010;
|
||
|
|
--err: #FF0086;
|
||
|
|
--prompt-bg: #ececec;
|
||
|
|
--prompt-placeholder: #555;
|
||
|
|
}
|
||
|
|
|
||
|
|
@media screen and (prefers-color-scheme: dark) {
|
||
|
|
html {
|
||
|
|
background: #000;
|
||
|
|
}
|
||
|
|
|
||
|
|
.apfl_playground {
|
||
|
|
--bg: #101010;
|
||
|
|
--fg: #E0E0E0;
|
||
|
|
--err: #EC3308;
|
||
|
|
--prompt-bg: #333;
|
||
|
|
--prompt-placeholder: #ccc;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.apfl_playground {
|
||
|
|
background: var(--bg);
|
||
|
|
color: var(--fg);
|
||
|
|
padding: 0;
|
||
|
|
border-radius: 4px;
|
||
|
|
font-family: monospace;
|
||
|
|
font-size: 1em;
|
||
|
|
overflow: hidden;
|
||
|
|
box-shadow: 2px 2px 4px rgba(0, 0, 0, 30%), 0 0 2px rgba(0,0,0,30%);
|
||
|
|
}
|
||
|
|
.apfl_playground .error {
|
||
|
|
color: var(--err);
|
||
|
|
}
|
||
|
|
.apfl_playground_output {
|
||
|
|
margin: 0;
|
||
|
|
padding: 4px 10px 0;
|
||
|
|
min-height: 50px;
|
||
|
|
max-height: 80vh;
|
||
|
|
overflow-y: auto;
|
||
|
|
}
|
||
|
|
.apfl_playground form {
|
||
|
|
display: flex;
|
||
|
|
padding: 2px 10px 4px;
|
||
|
|
background: var(--prompt-bg);
|
||
|
|
margin-top: 2px;
|
||
|
|
}
|
||
|
|
.apfl_playground_input {
|
||
|
|
flex-grow: 1;
|
||
|
|
background: transparent;
|
||
|
|
border: 0;
|
||
|
|
font-family: monospace;
|
||
|
|
padding: 0;
|
||
|
|
margin: 0;
|
||
|
|
font-size: 1em;
|
||
|
|
color: inherit;
|
||
|
|
}
|
||
|
|
.apfl_playground_input::placeholder {
|
||
|
|
font-style: italic;
|
||
|
|
color: var(--prompt-placeholder);
|
||
|
|
}
|
||
|
|
.apfl_playground_prompt {
|
||
|
|
padding-right: 1ch;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
<script>
|
||
|
|
var input_resolve = null;
|
||
|
|
var queue = [];
|
||
|
|
function playground_write(error, s) {
|
||
|
|
var span = document.createElement("span");
|
||
|
|
if (error) {
|
||
|
|
span.classList.add("error");
|
||
|
|
}
|
||
|
|
var lines = s.split("\n");
|
||
|
|
var scroll = false;
|
||
|
|
for (var i = 0 ; i < lines.length; i++) {
|
||
|
|
if (i > 0) {
|
||
|
|
span.appendChild(document.createElement("br"));
|
||
|
|
scroll = true;
|
||
|
|
}
|
||
|
|
var line = lines[i];
|
||
|
|
if (line != "") {
|
||
|
|
span.appendChild(document.createTextNode(lines[i]));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
output = document.getElementById("output");
|
||
|
|
output.append(span);
|
||
|
|
if (scroll) {
|
||
|
|
output.scrollTop = output.scrollHeight - output.clientHeight;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function enqueue(s) {
|
||
|
|
if (input_resolve) {
|
||
|
|
input_resolve(s);
|
||
|
|
input_resolve = null;
|
||
|
|
} else {
|
||
|
|
queue.push(s);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function playground_get_input(need) {
|
||
|
|
document.getElementById("prompt").innerText = need ? "..." : ">";
|
||
|
|
|
||
|
|
if (queue.length > 0) {
|
||
|
|
return Promise.resolve(queue.shift());
|
||
|
|
} else {
|
||
|
|
return new Promise(function (resolve, _) {
|
||
|
|
input_resolve = resolve;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function do_submit(ev) {
|
||
|
|
ev.preventDefault();
|
||
|
|
var input = document.getElementById("input");
|
||
|
|
var s = input.value;
|
||
|
|
input.value = "";
|
||
|
|
if (s == "") {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
s += "\n";
|
||
|
|
playground_write(false, document.getElementById("prompt").innerText + " " + s);
|
||
|
|
enqueue(s);
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
<script type="text/javascript" src="playground.js"></script>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div class="apfl_playground" id="terminal">
|
||
|
|
<pre class="apfl_playground_output" id="output"></pre>
|
||
|
|
<form onsubmit="do_submit(event)">
|
||
|
|
<span class="apfl_playground_prompt" id="prompt">></span>
|
||
|
|
<input type="text" class="apfl_playground_input" id="input" placeholder="code ...">
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</body>
|
||
|
|
</html>
|