402 lines
9.3 KiB
HTML
402 lines
9.3 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<html>
|
|
|
|
<head>
|
|
<title>Web Keyboard</title>
|
|
|
|
<style>
|
|
|
|
div.container > div {
|
|
display: inline-block;
|
|
}
|
|
|
|
div#indicators {
|
|
text-align: center;
|
|
vertical-align: top;
|
|
font-size: 1.2em;
|
|
}
|
|
|
|
div#indicators .on {
|
|
background-color: #40ff40;
|
|
}
|
|
|
|
div#indicators .off {
|
|
background-color: #dddddd;
|
|
}
|
|
|
|
div#keyboard {
|
|
background-color: #000000;
|
|
}
|
|
|
|
div.key {
|
|
text-align:center;
|
|
vertical-align: top;
|
|
display: inline-block;
|
|
background-color: #dddddd;
|
|
margin: 1px;
|
|
width: 3em;
|
|
height: 3.5em;
|
|
font-size: 0.8em;
|
|
}
|
|
|
|
div.pressed {
|
|
background-color: #ff4040;
|
|
}
|
|
|
|
div.blank {
|
|
opacity: 0;
|
|
}
|
|
|
|
div.info div {
|
|
font-size: 1.5em;
|
|
display: inline-block;
|
|
margin: 1em;
|
|
}
|
|
|
|
div#macros div {
|
|
width: 9em;
|
|
display: inline-block;
|
|
background-color: #dddddd;
|
|
margin: 1em;
|
|
text-align: center;
|
|
}
|
|
|
|
div#macros .mousedown{
|
|
background-color: #4040ff;
|
|
}
|
|
|
|
div#status_frames {
|
|
visibility: hidden;
|
|
}
|
|
|
|
div.menu {
|
|
display: inline-block;
|
|
padding: 1em;
|
|
background-color: #dddddd;
|
|
}
|
|
|
|
div.menu a {
|
|
text-decoration: none;
|
|
color: #0000ff;
|
|
}
|
|
|
|
div.menu a:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
</style>
|
|
|
|
<script>
|
|
var keys = [];
|
|
var fetchqueue = [];
|
|
var curLed = 0;
|
|
const indicator_list = [
|
|
{id: "num", label: "NumLock"},
|
|
{id: "caps", label: "CapsLock"},
|
|
{id: "scroll", label: "ScrollLock"}
|
|
];
|
|
const macro_list = [
|
|
{id: "power", label: "Power/Wake", keys: ["WakeUp"]},
|
|
{id: "reset", label: "CTRL+ALT+DEL", keys: ["ControlLeft","AltLeft","Delete"]},
|
|
{id: "close", label: "ALT+F4", keys: ["AltLeft", "F4"]},
|
|
{id: "cycle", label: "ALT+Tab", keys: ["AltLeft", "Tab"]}
|
|
];
|
|
const key_list = [
|
|
[
|
|
{id: "Escape", label: "ESC", width: 2},
|
|
{id: "F1", label: "F1"},
|
|
{id: "F2", label: "F2"},
|
|
{id: "F3", label: "F3"},
|
|
{id: "F4", label: "F4"},
|
|
{id: "F5", label: "F5"},
|
|
{id: "F6", label: "F6"},
|
|
{id: "F7", label: "F7"},
|
|
{id: "F8", label: "F8"},
|
|
{id: "F9", label: "F9"},
|
|
{id: "F10", label: "F10"},
|
|
{id: "F11", label: "F11"},
|
|
{id: "F12", label: "F12"},
|
|
{id: "", label: ""},
|
|
{id: "PrintScreen", label: "Print<br>Screen"},
|
|
{id: "ScrollLock", label: "Scroll<br>Lock"},
|
|
{id: "Pause", label: "Pause"}
|
|
],
|
|
[
|
|
{id: "Backquote", label: "~<br>`"},
|
|
{id: "Digit1", label: "!<br>1"},
|
|
{id: "Digit2", label: "@<br>2"},
|
|
{id: "Digit3", label: "#<br>3"},
|
|
{id: "Digit4", label: "$<br>4"},
|
|
{id: "Digit5", label: "%<br>5"},
|
|
{id: "Digit6", label: "^<br>6"},
|
|
{id: "Digit7", label: "&<br>7"},
|
|
{id: "Digit8", label: "*<br>8"},
|
|
{id: "Digit9", label: "(<br>9"},
|
|
{id: "Digit0", label: ")<br>0"},
|
|
{id: "Minus", label: "_<br>-"},
|
|
{id: "Equal", label: "+<br>="},
|
|
{id: "Backspace", label: "Backspace", width: 2},
|
|
{id: "Insert", label: "Insert" },
|
|
{id: "Home", label: "Home" },
|
|
{id: "PageUp", label: "Page<br>Up"},
|
|
{id: "NumLock", label: "Num"},
|
|
{id: "NumpadDivide", label: "/"},
|
|
{id: "NumpadMultiply", label: "*"},
|
|
{id: "NumpadSubtract", label: "-"}
|
|
],
|
|
[
|
|
{id: "Tab", label: "Tab", width: 1.5},
|
|
{id: "KeyQ", label: "Q"},
|
|
{id: "KeyW", label: "W"},
|
|
{id: "KeyE", label: "E"},
|
|
{id: "KeyR", label: "R"},
|
|
{id: "KeyT", label: "T"},
|
|
{id: "KeyY", label: "Y"},
|
|
{id: "KeyU", label: "U"},
|
|
{id: "KeyI", label: "I"},
|
|
{id: "KeyO", label: "O"},
|
|
{id: "KeyP", label: "P"},
|
|
{id: "BracketLeft", label: "{<br>["},
|
|
{id: "BracketRight", label: "}<br>]"},
|
|
{id: "Backslash", label: "|<br>\\", width: 1.5},
|
|
{id: "Delete", label: "Delete"},
|
|
{id: "End", label: "End"},
|
|
{id: "PageDown", label: "Page<br>Down"},
|
|
{id: "Numpad7", label: "Home<br>7"},
|
|
{id: "Numpad8", label: "Up<br>8"},
|
|
{id: "Numpad9", label: "PgUp<br>9"},
|
|
{id: "NumpadAdd", label: "+", height: 2}
|
|
],
|
|
[
|
|
{id: "CapsLock", label: "Caps<br>Lock", width: 2},
|
|
{id: "KeyA", label: "A"},
|
|
{id: "KeyS", label: "S"},
|
|
{id: "KeyD", label: "D"},
|
|
{id: "KeyF", label: "F"},
|
|
{id: "KeyG", label: "G"},
|
|
{id: "KeyH", label: "H"},
|
|
{id: "KeyJ", label: "J"},
|
|
{id: "KeyK", label: "K"},
|
|
{id: "KeyL", label: "L"},
|
|
{id: "Semicolon", label: ":<br>;"},
|
|
{id: "Quote", label: "\"<br>\'"},
|
|
{id: "Enter", label: "Enter", width: 2},
|
|
{id: "", label: "", width: 3.17},
|
|
{id: "Numpad4", label: "Left<br>4"},
|
|
{id: "Numpad5", label: "5"},
|
|
{id: "Numpad6", label: "Right<br>6"}
|
|
],
|
|
[
|
|
{id: "ShiftLeft", label: "Shift", width: 2.5},
|
|
{id: "KeyZ", label: "Z"},
|
|
{id: "KeyX", label: "X"},
|
|
{id: "KeyC", label: "C"},
|
|
{id: "KeyV", label: "V"},
|
|
{id: "KeyB", label: "B"},
|
|
{id: "KeyN", label: "N"},
|
|
{id: "KeyM", label: "M"},
|
|
{id: "Comma", label: "\<<br>,"},
|
|
{id: "Period", label: "\><br>."},
|
|
{id: "Slash", label: "?<br>/"},
|
|
{id: "ShiftRight", label: "Shift", width: 2.6},
|
|
{id: "", label: ""},
|
|
{id: "ArrowUp", label: "Up"},
|
|
{id: "", label: ""},
|
|
{id: "Numpad1", label: "End<br>1"},
|
|
{id: "Numpad2", label: "Down<br>2"},
|
|
{id: "Numpad3", label: "PgDn<br>3"},
|
|
{id: "NumpadEnter", label: "Enter", height: 2}
|
|
],
|
|
[
|
|
{id: "ControlLeft", label: "Control", width: 2},
|
|
{id: "MetaLeft", label: "Meta"},
|
|
{id: "AltLeft", label: "Alt", width: 1.5},
|
|
{id: "Space", label: "Space", width: 6.4},
|
|
{id: "AltRight", label: "Alt", width: 1.5},
|
|
{id: "MetaRight", label: "Meta"},
|
|
{id: "ControlRight", label: "Control", width: 2},
|
|
{id: "ArrowLeft", label: "Left"},
|
|
{id: "ArrowDown", label: "Down"},
|
|
{id: "ArrowRight", label: "Right"},
|
|
{id: "Numpad0", label: "Ins<br>0", width: 2},
|
|
{id: "NumpadDecimal", label: "Del<br>."}
|
|
],
|
|
];
|
|
|
|
window.setInterval("refreshIndicators();",2000);
|
|
|
|
window.addEventListener("keydown", onKeyDown, true);
|
|
window.addEventListener("keyup", onKeyUp, true);
|
|
|
|
window.onload = (event) => {
|
|
createMacros("macros");
|
|
createKeys("keyboard");
|
|
}
|
|
|
|
function onKeyDown(event) {
|
|
if (event.defaultPrevented) {
|
|
return; // Do nothing if the event was already processed
|
|
}
|
|
|
|
pressKey(event.code);
|
|
|
|
// Cancel the default action to avoid it being handled twice
|
|
event.preventDefault();
|
|
}
|
|
|
|
function pressKey(code) {
|
|
if (keys.includes(code)) { return; }
|
|
|
|
keys.push(code);
|
|
|
|
sendKeys(keys);
|
|
}
|
|
|
|
function onKeyUp(event) {
|
|
if (event.defaultPrevented) {
|
|
return; // Do nothing if the event was already processed
|
|
}
|
|
|
|
releaseKey(event.code);
|
|
|
|
// Cancel the default action to avoid it being handled twice
|
|
event.preventDefault();
|
|
}
|
|
|
|
function releaseKey(code) {
|
|
if (keys.includes(code)) {
|
|
keys.splice(keys.indexOf(code),1);
|
|
}
|
|
|
|
sendKeys(keys);
|
|
}
|
|
|
|
|
|
function sendKeys(curKeys) {
|
|
const url="sendkeys.cgi?keys=".concat(curKeys);
|
|
fetchqueue.push(url);
|
|
console.log(fetchqueue);
|
|
document.getElementById("downKeys")
|
|
.innerHTML = curKeys;
|
|
prev_keys = document.getElementsByClassName("pressed");
|
|
for (let key of curKeys) {
|
|
keyDiv = document.getElementById(key);
|
|
keyDiv.classList.add("pressed");
|
|
}
|
|
for (let key of prev_keys) {
|
|
if (!curKeys.includes(key.id)) {
|
|
key.classList.remove("pressed");
|
|
}
|
|
}
|
|
if (fetchqueue.length == 1) {
|
|
runQueue();
|
|
}
|
|
}
|
|
|
|
async function runQueue() {
|
|
const url = fetchqueue[0];
|
|
await fetch(url);
|
|
fetchqueue.shift();
|
|
if (fetchqueue.length > 0) {
|
|
runQueue();
|
|
}
|
|
}
|
|
|
|
function updateIndicators() {
|
|
let indicatorFrame = document.getElementById("indicatorFrame");
|
|
let indicatorDiv = document.getElementById("indicators");
|
|
indicatorDiv.innerHTML = indicatorFrame.contentDocument.body.innerHTML;
|
|
}
|
|
|
|
function refreshIndicators() {
|
|
let indicatorFrame = document.getElementById("indicatorFrame");
|
|
indicatorFrame.contentWindow.location.reload(true);
|
|
}
|
|
|
|
function createKeys(keyboard_id) {
|
|
let keyboardDiv = document.getElementById(keyboard_id);
|
|
for (let row of key_list) {
|
|
let newRow = document.createElement("div");
|
|
keyboardDiv.appendChild(newRow);
|
|
for (let key of row) {
|
|
let newDiv = document.createElement("div");
|
|
if (key.id) {
|
|
newDiv.id = key.id;
|
|
newDiv.innerHTML = key.label;
|
|
newDiv.className = "key";
|
|
newDiv.addEventListener("touchstart", function (event) {
|
|
event.preventDefault(); pressKey(key.id); });
|
|
newDiv.addEventListener("touchend", function (event) {
|
|
event.preventDefault(); releaseKey(key.id); });
|
|
newDiv.addEventListener("mousedown", function () {
|
|
pressKey(key.id); });
|
|
newDiv.addEventListener("mouseup", function () {
|
|
releaseKey(key.id); });
|
|
} else {
|
|
newDiv.className = "key blank";
|
|
}
|
|
newRow.appendChild(newDiv);
|
|
if (key.width) {
|
|
newDiv.style = "width:" + (key.width*newDiv.clientWidth ) + "px;";
|
|
}
|
|
if (key.height) {
|
|
newDiv.style = "height:" + (key.height*newDiv.clientHeight ) + "px; float: right;";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function createMacros(macro_id) {
|
|
let macroDiv = document.getElementById(macro_id);
|
|
for (let macro of macro_list) {
|
|
let newDiv = document.createElement("div");
|
|
newDiv.id = macro.id;
|
|
newDiv.textContent = macro.label;
|
|
newDiv.addEventListener("touchstart", function (event) {
|
|
event.preventDefault(); sendKeys(macro.keys); });
|
|
newDiv.addEventListener("touchend", function (event) {
|
|
event.preventDefault(); sendKeys([]);; });
|
|
newDiv.addEventListener("mousedown", function () {
|
|
sendKeys(macro.keys); });
|
|
newDiv.addEventListener("mouseup", function () {
|
|
sendKeys([]); });
|
|
macroDiv.appendChild(newDiv);
|
|
}
|
|
}
|
|
|
|
</script>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
<div class="container">
|
|
<div id="keyboard"></div>
|
|
<div id="indicators"></div>
|
|
</div>
|
|
|
|
<div id="macros"></div>
|
|
|
|
<div class="info">
|
|
<div>Currently pressed keys:</div>
|
|
<div id="downKeys"></div>
|
|
</div>
|
|
|
|
<div>
|
|
<div class="menu">
|
|
<a href="wifi.shtml">Configure Wi-Fi</a>
|
|
</div>
|
|
<div class="menu">
|
|
<a href="reboot.cgi">Reboot</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="status_frames">
|
|
<iframe id="indicatorFrame" src="indicators.shtml"
|
|
onload="updateIndicators();"></iframe>
|
|
</div>
|
|
|
|
</body>
|
|
|
|
</html>
|