diff options
author | Devaev Maxim <[email protected]> | 2018-07-15 11:21:44 +0300 |
---|---|---|
committer | Devaev Maxim <[email protected]> | 2018-07-15 11:21:44 +0300 |
commit | 999d3f245710013425cc2413f81d900ec1fc2f24 (patch) | |
tree | 07bf519cab5da1b522e8146a362724762c8a3e7c | |
parent | 4122ecdb55abae00f2168d27df5f88527fc02341 (diff) |
big js refactoring
-rw-r--r-- | kvmd/web/css/main.css | 17 | ||||
-rw-r--r-- | kvmd/web/index.html | 26 | ||||
-rw-r--r-- | kvmd/web/js/atx.js | 55 | ||||
-rw-r--r-- | kvmd/web/js/hid.js | 29 | ||||
-rw-r--r-- | kvmd/web/js/keyboard.js | 27 | ||||
-rw-r--r-- | kvmd/web/js/kvmd.js | 290 | ||||
-rw-r--r-- | kvmd/web/js/main.js | 4 | ||||
-rw-r--r-- | kvmd/web/js/mouse.js | 86 | ||||
-rw-r--r-- | kvmd/web/js/session.js | 61 | ||||
-rw-r--r-- | kvmd/web/js/stream.js | 53 | ||||
-rw-r--r-- | kvmd/web/js/tools.js | 27 |
11 files changed, 363 insertions, 312 deletions
diff --git a/kvmd/web/css/main.css b/kvmd/web/css/main.css index 20d7c714..95eee02e 100644 --- a/kvmd/web/css/main.css +++ b/kvmd/web/css/main.css @@ -10,29 +10,22 @@ img#stream-image { display: inline-block; border: 1px solid grey; } -img.stream-image-on { - cursor: cell; +img.stream-image-active { + cursor: crosshair; -webkit-filter: none; filter: none; } -img.stream-image-off { +img.stream-image-inactive { cursor: wait; -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */ filter: grayscale(100%); } -div.session-active { - color: grey; -} -div.session-closed { - color: #ff3d40; -} - div#atx-power-led, div#hid-mouse-led, div#msd-led { font-weight: bold; font-size: 150%; } -div#atx-hdd-led, div#screen-led, div#hid-keyboard-led { +div#atx-hdd-led, div#stream-led, div#hid-keyboard-led { font-size: 150%; } div.led-on { @@ -45,5 +38,5 @@ div.led-busy { color: #ff373a; } -button#power-button, button#reset-button { +button#stream-reset-button button#atx-power-button, button#atx-reset-button { } diff --git a/kvmd/web/index.html b/kvmd/web/index.html index 3fec1ae3..76c94c2f 100644 --- a/kvmd/web/index.html +++ b/kvmd/web/index.html @@ -6,24 +6,30 @@ <link rel="stylesheet" href="css/main.css"> </head> -<script src="js/kvmd.js"></script> -<script>window.onload = runKvmdUi;</script> +<script src="js/tools.js"></script> +<script src="js/stream.js"></script> +<script src="js/atx.js"></script> +<script src="js/keyboard.js"></script> +<script src="js/mouse.js"></script> +<script src="js/hid.js"></script> +<script src="js/session.js"></script> +<script src="js/main.js"></script> + +<script>window.onload = main;</script> <body> <div id="stream-box"> - <img src="/streamer/?action=stream" id="stream-image" class="stream-image-off" alt="Loading..."/> + <img src="/streamer/?action=stream" id="stream-image" class="stream-image-inactive" alt="Loading..."/> <hr> <table cellpadding="0" cellspacing="0" style="border: none;"> <tr> - <td><div id="screen-led" class="led-off">🖵</div></td> + <td><div id="stream-led" class="led-off">🖵</div></td> <td> </td> <td><div id="hid-keyboard-led" class="led-off">⌨</div></td> <td> </td> <td><div id="hid-mouse-led" class="led-off">🖰</div></td> <td> </td> - <td><button id="reset-stream-button" type="button" title="Click here if your video looks like crap" onclick="clickResetStreamButton(this);">Reset stream</button></td> - <td> </td> - <td><div id="session-status">Not connected yet...</div></td> + <td><button id="stream-reset-button" type="button" title="Click here if your video looks like crap" onclick="stream.clickResetButton(this);">Reset stream</button></td> </tr> </table> </div> @@ -35,9 +41,9 @@ <td> </td> <!--<td><div id="msd-led" class="led-off">✇</div></td> <td> </td>--> - <td><button id="atx-power-button" type="button" title="Click hardware power button" onclick="clickAtxButton(this);">Power</button></td> - <td><button id="atx-power-button-long" type="button" title="Click hardware power button (long press)" onclick="clickAtxButton(this);">Power (long)</button></td> - <td><button id="atx-reset-button" type="button" title="Click to force reset" onclick="clickAtxButton(this);">Reset</button></td> + <td><button id="atx-power-button" type="button" title="Click hardware power button" onclick="atx.clickButton(this);">Power</button></td> + <td><button id="atx-power-button-long" type="button" title="Click hardware power button (long press)" onclick="atx.clickButton(this);">Power (long)</button></td> + <td><button id="atx-reset-button" type="button" title="Click to force reset" onclick="atx.clickButton(this);">Reset</button></td> </tr> </table> </body> diff --git a/kvmd/web/js/atx.js b/kvmd/web/js/atx.js new file mode 100644 index 00000000..6e753bdf --- /dev/null +++ b/kvmd/web/js/atx.js @@ -0,0 +1,55 @@ +var atx = new function() { + this.setLedsState = function(leds) { + $("atx-power-led").className = (leds.power ? "led-on" : "led-off"); + $("atx-hdd-led").className = (leds.hdd ? "led-busy" : "led-off"); + }; + + this.clearLeds = function() { + atx.setLedsState(false, false); + }; + + this.clickButton = function(el_button) { + switch (el_button.id) { + case "atx-power-button": + var button = "power"; + var confirm_msg = "Are you sure to click the power button?"; + break; + case "atx-power-button-long": + var button = "power_long"; + var confirm_msg = "Are you sure to perform the long press of the power button?"; + break; + case "atx-reset-button": + var button = "reset"; + var confirm_msg = "Are you sure to reboot the server?"; + break; + default: + var button = null; + var confirm_msg = null; + break; + } + + if (button && confirm(confirm_msg)) { + __setButtonsBusy(true); + var http = tools.makeRequest("POST", "/kvmd/atx/click?button=" + button, function() { + if (http.readyState === 4) { + if (http.status === 409) { + alert("Performing another ATX operation for other client, please try again later"); + } else if (http.status !== 200) { + alert("Click error:", http.responseText); + } + __setButtonsBusy(false); + } + }); + } + }; + + var __setButtonsBusy = function(busy) { + [ + "atx-power-button", + "atx-power-button-long", + "atx-reset-button", + ].forEach(function(name) { + tools.setButtonBusy(document.getElementById(name), busy); + }); + }; +}; diff --git a/kvmd/web/js/hid.js b/kvmd/web/js/hid.js new file mode 100644 index 00000000..3d0ed961 --- /dev/null +++ b/kvmd/web/js/hid.js @@ -0,0 +1,29 @@ +var hid = new function() { + var __install_timer = null; + + this.installCapture = function(ws) { + var http = tools.makeRequest("GET", "/kvmd/hid", function() { + if (http.readyState === 4) { + if (http.status === 200) { + features = JSON.parse(http.responseText).result.features; + if (features.mouse) { + mouse.installCapture(ws); + } + keyboard.installCapture(ws); + } else { + tools.error("Can't resolve HID features:", http.responseText); + __install_timer = setTimeout(() => hid.installCapture(ws), 1000); + } + } + }); + }; + + this.clearCapture = function() { + if (__install_timer) { + clearTimeout(__install_timer); + __install_timer = null; + } + mouse.clearCapture(); + keyboard.clearCapture(); + }; +} diff --git a/kvmd/web/js/keyboard.js b/kvmd/web/js/keyboard.js new file mode 100644 index 00000000..4f1ade8b --- /dev/null +++ b/kvmd/web/js/keyboard.js @@ -0,0 +1,27 @@ +var keyboard = new function() { + this.installCapture = function(ws) { + // https://www.codeday.top/2017/05/03/24906.html + tools.info("Installing keyboard capture ...") + document.onkeydown = (event) => __keyHandler(ws, event, true); + document.onkeyup = (event) => __keyHandler(ws, event, false); + $("hid-keyboard-led").className = "led-on"; + }; + + this.clearCapture = function() { + tools.info("Removing keyboard capture ...") + document.onkeydown = null; + document.onkeyup = null; + $("hid-keyboard-led").className = "led-off"; + }; + + var __keyHandler = function(ws, event, state) { + // https://github.com/wesbos/keycodes/blob/gh-pages/scripts.js + tools.debug("Key", (state ? "pressed:" : "released:"), event) + event.preventDefault(); + ws.send(JSON.stringify({ + event_type: "key", + key: event.code, + state: state, + })); + }; +}; diff --git a/kvmd/web/js/kvmd.js b/kvmd/web/js/kvmd.js deleted file mode 100644 index 044908e1..00000000 --- a/kvmd/web/js/kvmd.js +++ /dev/null @@ -1,290 +0,0 @@ -function runKvmdUi() { - __startSessionPoller(); - __startStreamPoller(); -} - - -// ----------------------------------------------------------------------------- -function __startSessionPoller() { - var ws = new WebSocket("ws://" + location.host + "/kvmd/ws"); - - ws.onopen = function(event) { - __installHidHandlers(ws); - __setSessionStatus(true); - __startSessionPoller.ping_server_timer = setInterval(() => __pingServer(ws), 2000); - }; - - ws.onmessage = function(event) { - // console.log("KVMD:", event.data); - event = JSON.parse(event.data); - if (event.msg_type === "event") { - if (event.msg.event === "pong") { - __pingServer.missed_heartbeats = 0; - } else if (event.msg.event === "atx_state") { - leds = event.msg.event_attrs.leds; - document.getElementById("atx-power-led").className = (leds.power ? "led-on" : "led-off"); - document.getElementById("atx-hdd-led").className = (leds.hdd ? "led-busy" : "led-off"); - } - } - }; - - ws.onclose = function(event) { - if (__startSessionPoller.ping_server_timer) { - clearInterval(__startSessionPoller.ping_server_timer); - } - __clearHidHandlers(); - __setSessionStatus(false); - document.getElementById("atx-power-led").className = "led-off"; - document.getElementById("atx-hdd-led").className = "led-off"; - setTimeout(__startSessionPoller, 2000); - }; - - ws.onerror = function(error) { - ws.close(); - }; -} - -function __pingServer(ws) { - try { - __pingServer.missed_heartbeats++; - if (__pingServer.missed_heartbeats >= 5) { - throw new Error("Too many missed heartbeats"); - } - ws.send(JSON.stringify({"event_type": "ping"})); - } catch (err) { - __pingServer.missed_heartbeats = 0; - console.warn("Closing session:", err.message); - ws.close(); - } -} -__pingServer.missed_heartbeats = 0; - -function __setSessionStatus(status) { - var el_session_status = document.getElementById("session-status"); - el_session_status.innerHTML = (status ? "Session active" : "Session closed, trying to reconnect..."); - el_session_status.className = (status ? "session-active" : "session-closed"); -} - -function __installHidHandlers(ws) { - var http = __request("GET", "/kvmd/hid", function() { - if (http.readyState === 4) { - if (http.status === 200) { - features = JSON.parse(http.responseText).result.features; - if (features.keyboard) { - // https://www.codeday.top/2017/05/03/24906.html - document.onkeydown = (event) => __onKeyEvent(ws, event, true); - document.onkeyup = (event) => __onKeyEvent(ws, event, false); - document.getElementById("hid-keyboard-led").className = "led-on"; - } - if (features.mouse) { - el_stream_image = document.getElementById("stream-image"); - el_stream_image.onmousedown = (event) => __onMouseButton(ws, event, true); - el_stream_image.onmouseup = (event) => __onMouseButton(ws, event, false); - el_stream_image.oncontextmenu = (event) => event.preventDefault(); - el_stream_image.onmousemove = __onMouseMove; - el_stream_image.onwheel = (event) => __onMouseWheel(ws, event); - document.getElementById("hid-mouse-led").className = "led-on"; - - __installHidHandlers.mouse_move_timer = setInterval(() => __handleMouseMove(ws), 100); - } - } else { - alert("Can't fetch HID features:", http.responseText); - } - } - }); -} - -function __clearHidHandlers() { - if (__installHidHandlers.mouse_move_timer) { - clearInterval(__installHidHandlers.mouse_move_timer); - } - - document.onkeydown = null; - document.onkeyup = null; - document.getElementById("hid-keyboard-led").className = "led-off"; - - el_stream_image = document.getElementById("stream-image"); - el_stream_image.onmousedown = null; - el_stream_image.onmouseup = null; - el_stream_image.oncontextmenu = null; - el_stream_image.onmousemove = null; - el_stream_image.onwheel = null; - document.getElementById("hid-mouse-led").className = "led-off"; -} - -function __onKeyEvent(ws, event, state) { - // console.log("KVMD: Key", (state ? "pressed:" : "released:"), event) - if (!event.metaKey) { // https://github.com/wesbos/keycodes/blob/gh-pages/scripts.js - event.preventDefault(); - } - ws.send(JSON.stringify({ - event_type: "key", - key: event.code, - state: state, - })); -} - -function __onMouseButton(ws, event, state) { - // https://www.w3schools.com/jsref/event_button.asp - switch (event.button) { - case 0: var button = "Left"; break; - case 2: var button = "Right"; break; - default: var button = null; break - } - if (button) { - // console.log("KVMD: Mouse button", (state ? "pressed:" : "released:"), button); - event.preventDefault(); - __handleMouseMove(ws); - ws.send(JSON.stringify({ - event_type: "mouse_button", - button: button, - state: state, - })); - } -} - -function __onMouseMove(event) { - var rect = event.target.getBoundingClientRect(); - __onMouseMove.pos = { - x: Math.round(event.clientX - rect.left), - y: Math.round(event.clientY - rect.top), - }; -} -__onMouseMove.pos = {x: 0, y:0}; - -function __handleMouseMove(ws) { - var pos = __onMouseMove.pos; - if (pos.x !== __handleMouseMove.old_pos.x || pos.y !== __handleMouseMove.old_pos.y) { - ws.send(JSON.stringify({ - event_type: "mouse_move", - to: pos, - })); - __handleMouseMove.old_pos = pos; - } -} -__handleMouseMove.old_pos = {x: 0, y:0}; - -function __onMouseWheel(ws, event) { - // https://learn.javascript.ru/mousewheel - if (event.preventDefault) { - event.preventDefault(); - } - ws.send(JSON.stringify({ - event_type: "mouse_wheel", - delta: { - x: event.deltaX, - y: event.deltaY, - }, - })); -} - - -// ----------------------------------------------------------------------------- -function clickAtxButton(el_button) { - switch (el_button.id) { - case "atx-power-button": - var button = "power"; - var confirm_msg = "Are you sure to click the power button?"; - break; - case "atx-power-button-long": - var button = "power_long"; - var confirm_msg = "Are you sure to perform the long press of the power button?"; - break; - case "atx-reset-button": - var button = "reset"; - var confirm_msg = "Are you sure to reboot the server?"; - break; - default: - var button = null; - var confirm_msg = null; - break; - } - - if (button && confirm(confirm_msg)) { - __setAtxButtonsBusy(true); - var http = __request("POST", "/kvmd/atx/click?button=" + button, function() { - if (http.readyState === 4) { - if (http.status === 409) { - alert("Performing another ATX operation for other client, please try again later"); - } else if (http.status !== 200) { - alert("Click error:", http.responseText); - } - __setAtxButtonsBusy(false); - } - }); - } -} - -function __setAtxButtonsBusy(busy) { - [ - "atx-power-button", - "atx-power-button-long", - "atx-reset-button", - ].forEach(function(name) { - __setButtonBusy(document.getElementById(name), busy); - }); -} - - -// ----------------------------------------------------------------------------- -function __startStreamPoller() { - var http = __request("GET", "/streamer/?action=snapshot", function() { - if (http.readyState === 2 || http.readyState === 4) { - var status = http.status; - http.onreadystatechange = null; - http.abort(); - if (status !== 200) { - console.log("Refreshing stream ..."); - __startStreamPoller.last = false; - document.getElementById("stream-image").className = "stream-image-off"; - document.getElementById("screen-led").className = "led-off"; - } else if (!__startStreamPoller.last) { - __refreshStream(); - __startStreamPoller.last = true; - document.getElementById("stream-image").className = "stream-image-on"; - document.getElementById("screen-led").className = "led-on"; - } - } - }); - setTimeout(__startStreamPoller, 2000); -} -__startStreamPoller.last = false; - -function __refreshStream() { - var http = __request("GET", "/kvmd/streamer", function() { - if (http.readyState === 4 && http.status === 200) { - size = JSON.parse(http.responseText).result.size; - el_stream_box = document.getElementById("stream-image"); - el_stream_box.style.width = size.width + "px"; - el_stream_box.style.height = size.height + "px"; - document.getElementById("stream-image").src = "/streamer/?action=stream&time=" + new Date().getTime(); - } - }); -} - -function clickResetStreamButton(el_button) { - __setButtonBusy(el_button, true); - var http = __request("POST", "/kvmd/streamer/reset", function() { - if (http.readyState === 4) { - if (http.status !== 200) { - alert("Can't reset stream:", http.responseText); - } - __setButtonBusy(el_button, false); - } - }); -} - - -// ----------------------------------------------------------------------------- -function __request(method, url, callback) { - var http = new XMLHttpRequest(); - http.open(method, url, true) - http.onreadystatechange = callback; - http.send(); - return http; -} - -function __setButtonBusy(el_button, busy) { - el_button.disabled = busy; - el_button.style.cursor = (busy ? "wait" : "default"); -} diff --git a/kvmd/web/js/main.js b/kvmd/web/js/main.js new file mode 100644 index 00000000..b0f03109 --- /dev/null +++ b/kvmd/web/js/main.js @@ -0,0 +1,4 @@ +function main () { + session.startPoller(); + stream.startPoller(); +} diff --git a/kvmd/web/js/mouse.js b/kvmd/web/js/mouse.js new file mode 100644 index 00000000..f906e146 --- /dev/null +++ b/kvmd/web/js/mouse.js @@ -0,0 +1,86 @@ +var mouse = new function() { + var __send_move_timer = null; + var __current_pos = {x: 0, y:0}; + var __sent_pos = {x: 0, y:0}; + + this.installCapture = function(ws) { + tools.info("Installing mouse capture ..."); + el_stream_image = $("stream-image"); + el_stream_image.onmousedown = (event) => __buttonHandler(ws, event, true); + el_stream_image.onmouseup = (event) => __buttonHandler(ws, event, false); + el_stream_image.oncontextmenu = (event) => event.preventDefault(); + el_stream_image.onmousemove = __moveHandler; + el_stream_image.onwheel = (event) => __wheelHandler(ws, event); + __send_move_timer = setInterval(() => __sendMove(ws), 100); + $("hid-mouse-led").className = "led-on"; + }; + + this.clearCapture = function() { + tools.info("Removing mouse capture ..."); + if (__send_move_timer) { + clearInterval(__send_move_timer); + __send_move_timer = null; + } + __current_pos = {x: 0, y:0}; + __sent_pos = {x: 0, y:0}; + el_stream_image = $("stream-image"); + el_stream_image.onmousedown = null; + el_stream_image.onmouseup = null; + el_stream_image.oncontextmenu = null; + el_stream_image.onmousemove = null; + el_stream_image.onwheel = null; + $("hid-mouse-led").className = "led-off"; + }; + + var __buttonHandler = function(ws, event, state) { + // https://www.w3schools.com/jsref/event_button.asp + switch (event.button) { + case 0: var button = "Left"; break; + case 2: var button = "Right"; break; + default: var button = null; break + } + if (button) { + tools.debug("Mouse button", (state ? "pressed:" : "released:"), button); + event.preventDefault(); + __sendMove(ws); + ws.send(JSON.stringify({ + event_type: "mouse_button", + button: button, + state: state, + })); + } + }; + + var __moveHandler = function(event) { + var rect = event.target.getBoundingClientRect(); + __current_pos = { + x: Math.round(event.clientX - rect.left), + y: Math.round(event.clientY - rect.top), + }; + }; + + var __sendMove = function(ws) { + var pos = __current_pos; + if (pos.x !== __sent_pos.x || pos.y !== __sent_pos.y) { + tools.debug("Mouse move:", pos); + ws.send(JSON.stringify({ + event_type: "mouse_move", + to: pos, + })); + __sent_pos = pos; + } + }; + + var __wheelHandler = function(ws, event) { + // https://learn.javascript.ru/mousewheel + if (event.preventDefault) { + event.preventDefault(); + } + delta = {x: event.deltaX, y: event.deltaY}; + tools.debug("Mouse wheel:", delta); + ws.send(JSON.stringify({ + event_type: "mouse_wheel", + delta: delta, + })); + }; +}; diff --git a/kvmd/web/js/session.js b/kvmd/web/js/session.js new file mode 100644 index 00000000..31a76f68 --- /dev/null +++ b/kvmd/web/js/session.js @@ -0,0 +1,61 @@ +var session = new function() { + var __ws = null; + var __ping_timer = null; + var __missed_heartbeats = 0; + + this.startPoller = function() { + __ws = new WebSocket("ws://" + location.host + "/kvmd/ws"); + __ws.onopen = __wsOpenHandler; + __ws.onmessage = __wsMessageHandler; + __ws.onerror = __wsErrorHandler; + __ws.onclose = __wsCloseHandler; + }; + + var __wsOpenHandler = function(event) { + tools.debug("WebSocket opened:", event); + hid.installCapture(__ws); + __missed_heartbeats = 0; + __ping_timer = setInterval(__pingServer, 1000); + }; + + var __wsMessageHandler = function(event) { + // tools.debug("WebSocket: received data:", event.data); + event = JSON.parse(event.data); + if (event.msg_type === "pong") { + __missed_heartbeats = 0; + } else if (event.msg_type === "event") { + if (event.msg.event === "atx_state") { + atx.setLedsState(event.msg.event_attrs.leds); + } + } + }; + + var __wsErrorHandler = function(event) { + tools.error("WebSocket error:", event); + __ws.close(); + }; + + var __wsCloseHandler = function(event) { + tools.debug("WebSocket closed:", event); + if (__ping_timer) { + clearInterval(__ping_timer); + __ping_timer = null; + } + hid.clearCapture(); + atx.clearLeds(); + setTimeout(session.startPoller, 1000); + }; + + var __pingServer = function(event) { + try { + __missed_heartbeats += 1; + if (__missed_heartbeats >= 5) { + throw new Error("Too many missed heartbeats"); + } + __ws.send(JSON.stringify({"event_type": "ping"})); + } catch (err) { + tools.error("Ping error:", err.message); + __ws.close(); + } + }; +}; diff --git a/kvmd/web/js/stream.js b/kvmd/web/js/stream.js new file mode 100644 index 00000000..afaed1ae --- /dev/null +++ b/kvmd/web/js/stream.js @@ -0,0 +1,53 @@ +var stream = new function() { + var __prev_state = false; + + this.startPoller = function() { + var http = tools.makeRequest("GET", "/streamer/?action=snapshot", function() { + if (http.readyState === 2 || http.readyState === 4) { + var status = http.status; + http.onreadystatechange = null; + http.abort(); + if (status !== 200) { + tools.info("Refreshing stream ..."); + __prev_state = false; + $("stream-image").className = "stream-image-inactive"; + $("stream-led").className = "led-off"; + } else if (!__prev_state) { + __refreshImage(); + __prev_state = true; + $("stream-image").className = "stream-image-active"; + $("stream-led").className = "led-on"; + } + } + }); + setTimeout(stream.startPoller, 2000); + }; + +// this.setActive = function(active) { +// $("stream-image").className = (active ? "stream-image-active" : "stream-image-inactive"); +// }; + + this.clickResetButton = function(el_button) { + tools.setButtonBusy(el_button, true); + var http = tools.makeRequest("POST", "/kvmd/streamer/reset", function() { + if (http.readyState === 4) { + if (http.status !== 200) { + alert("Can't reset stream:", http.responseText); + } + tools.setButtonBusy(el_button, false); + } + }); + }; + + var __refreshImage = function() { + var http = tools.makeRequest("GET", "/kvmd/streamer", function() { + if (http.readyState === 4 && http.status === 200) { + size = JSON.parse(http.responseText).result.size; + el_stream_image = $("stream-image"); + el_stream_image.style.width = size.width + "px"; + el_stream_image.style.height = size.height + "px"; + el_stream_image.src = "/streamer/?action=stream&time=" + new Date().getTime(); + } + }); + }; +}; diff --git a/kvmd/web/js/tools.js b/kvmd/web/js/tools.js new file mode 100644 index 00000000..c8d492e2 --- /dev/null +++ b/kvmd/web/js/tools.js @@ -0,0 +1,27 @@ +var tools = new function() { + this.makeRequest = function(method, url, callback) { + var http = new XMLHttpRequest(); + http.open(method, url, true) + http.onreadystatechange = callback; + http.send(); + return http; + }; + + this.setButtonBusy = function(el_button, busy) { + el_button.disabled = busy; + el_button.style.cursor = (busy ? "wait" : "default"); + }; + + var __debug = (new URL(window.location.href)).searchParams.get("debug"); + + this.debug = function(...args) { + if (__debug) { + console.log(...args); + } + }; + + this.info = console.log; + this.error = console.error; +}; + +var $ = function(id) { return document.getElementById(id); }; |