diff options
author | Devaev Maxim <[email protected]> | 2018-09-26 02:57:24 +0300 |
---|---|---|
committer | Devaev Maxim <[email protected]> | 2018-09-26 02:57:24 +0300 |
commit | 81a5311349564a1016c4af2bf18ae872b650e85b (patch) | |
tree | d01fd027948494e22ae2c14334b98c1515e5e8a4 /kvmd/web/js | |
parent | f3946f102fc167efdc53c73412b2c0d6ac6c72c5 (diff) |
moved kvmd to the root
Diffstat (limited to 'kvmd/web/js')
-rw-r--r-- | kvmd/web/js/atx.js | 63 | ||||
-rw-r--r-- | kvmd/web/js/hid.js | 186 | ||||
-rw-r--r-- | kvmd/web/js/keyboard.js | 187 | ||||
-rw-r--r-- | kvmd/web/js/main.js | 16 | ||||
-rw-r--r-- | kvmd/web/js/mouse.js | 146 | ||||
-rw-r--r-- | kvmd/web/js/msd.js | 164 | ||||
-rw-r--r-- | kvmd/web/js/session.js | 121 | ||||
-rw-r--r-- | kvmd/web/js/stream.js | 119 | ||||
-rw-r--r-- | kvmd/web/js/tools.js | 43 | ||||
-rw-r--r-- | kvmd/web/js/ui.js | 319 |
10 files changed, 0 insertions, 1364 deletions
diff --git a/kvmd/web/js/atx.js b/kvmd/web/js/atx.js deleted file mode 100644 index f4b4811a..00000000 --- a/kvmd/web/js/atx.js +++ /dev/null @@ -1,63 +0,0 @@ -function Atx() { - var self = this; - - /********************************************************************************/ - - var __init__ = function() { - $("atx-power-led").title = "Power Led"; - $("atx-hdd-led").title = "Disk Activity Led"; - - tools.setOnClick($("atx-power-button"), () => __clickButton("power", null, "Are you sure to click the power button?")); - tools.setOnClick($("atx-power-button-long"), () => __clickButton("power_long", 15000, "Are you sure to perform the long press of the power button?")); - tools.setOnClick($("atx-reset-button"), () => __clickButton("reset", null, "Are you sure to reboot the server?")); - }; - - /********************************************************************************/ - - self.loadInitialState = function() { - var http = tools.makeRequest("GET", "/kvmd/atx", function() { - if (http.readyState === 4) { - if (http.status === 200) { - __setButtonsBusy(JSON.parse(http.responseText).result.busy); - } else { - setTimeout(self.loadInitialState, 1000); - } - } - }); - }; - - self.setState = function(state) { - __setButtonsBusy(state.busy); - $("atx-power-led").className = (state.leds.power ? "led-on" : "led-off"); - $("atx-hdd-led").className = (state.leds.hdd ? "led-hdd-busy" : "led-off"); - }; - - self.clearState = function() { - $("atx-power-led").className = "led-off"; - $("atx-hdd-led").className = "led-off"; - }; - - var __clickButton = function(button, timeout, confirm_msg) { - ui.confirm(confirm_msg).then(function(ok) { - if (ok) { - var http = tools.makeRequest("POST", "/kvmd/atx/click?button=" + button, function() { - if (http.readyState === 4) { - if (http.status === 409) { - ui.error("Performing another ATX operation for other client.<br>Please try again later"); - } else if (http.status !== 200) { - ui.error("Click error:<br>", http.responseText); - } - } - }, timeout); - } - }); - }; - - var __setButtonsBusy = function(busy) { - $("atx-power-button").disabled = busy; - $("atx-power-button-long").disabled = busy; - $("atx-reset-button").disabled = busy; - }; - - __init__(); -} diff --git a/kvmd/web/js/hid.js b/kvmd/web/js/hid.js deleted file mode 100644 index ca535157..00000000 --- a/kvmd/web/js/hid.js +++ /dev/null @@ -1,186 +0,0 @@ -function Hid() { - var self = this; - - /********************************************************************************/ - - var __ws = null; - - var __chars_to_codes = {}; - var __codes_delay = 50; - - var __keyboard = new Keyboard(); - var __mouse = new Mouse(); - - var __init__ = function() { - var __hidden_attr = null; - var __visibility_change_attr = null; - - if (typeof document.hidden !== "undefined") { - __hidden_attr = "hidden"; - __visibility_change_attr = "visibilitychange"; - } else if (typeof document.webkitHidden !== "undefined") { - __hidden_attr = "webkitHidden"; - __visibility_change_attr = "webkitvisibilitychange"; - } else if (typeof document.mozHidden !== "undefined") { - __hidden_attr = "mozHidden"; - __visibility_change_attr = "mozvisibilitychange"; - } - - if (__visibility_change_attr) { - document.addEventListener( - __visibility_change_attr, - function() { - if (document[__hidden_attr]) { - __releaseAll(); - } - }, - false - ); - } - - window.onpagehide = __releaseAll; - window.onblur = __releaseAll; - - if (window.navigator.clipboard && window.navigator.clipboard.readText) { - __chars_to_codes = __buildCharsToCodes(); - tools.setOnClick($("pak-button"), __pasteAsKeysFromClipboard); - } else { - $("pak-button").title = $("pak-led").title = "Your browser does not support the Clipboard API.\nUse Google Chrome or Chromium."; - } - - Array.prototype.forEach.call(document.querySelectorAll("[data-shortcut]"), function(el_shortcut) { - tools.setOnClick(el_shortcut, () => __emitShortcut(el_shortcut.getAttribute("data-shortcut").split(" "))); - }); - }; - - /********************************************************************************/ - - self.setSocket = function(ws) { - __ws = ws; - __keyboard.setSocket(ws); - __mouse.setSocket(ws); - $("pak-button").disabled = !(window.navigator.clipboard && window.navigator.clipboard.readText && ws); - }; - - var __releaseAll = function() { - __keyboard.releaseAll(); - }; - - var __emitShortcut = function(codes) { - return new Promise(function(resolve) { - tools.debug("Emitting keys:", codes); - - var raw_events = []; - [[codes, true], [codes.slice().reverse(), false]].forEach(function(op) { - var [op_codes, state] = op; - op_codes.forEach(function(code) { - raw_events.push({code: code, state: state}); - }); - }); - - var index = 0; - var iterate = () => setTimeout(function() { - __keyboard.fireEvent(raw_events[index].code, raw_events[index].state); - ++index; - if (index < raw_events.length) { - iterate(); - } else { - resolve(null); - } - }, __codes_delay); - iterate(); - }); - }; - - var __buildCharsToCodes = function() { - var chars_to_codes = { - "\n": ["Enter"], - "\t": ["Tab"], - " ": ["Space"], - "`": ["Backquote"], "~": ["ShiftLeft", "Backquote"], - "\\": ["Backslash"], "|": ["ShiftLeft", "Backslash"], - "[": ["BracketLeft"], "{": ["ShiftLeft", "BracketLeft"], - "]": ["BracketLeft"], "}": ["ShiftLeft", "BracketRight"], - ",": ["Comma"], "<": ["ShiftLeft", "Comma"], - ".": ["Period"], ">": ["ShiftLeft", "Period"], - "1": ["Digit1"], "!": ["ShiftLeft", "Digit1"], - "2": ["Digit2"], "@": ["ShiftLeft", "Digit2"], - "3": ["Digit3"], "#": ["ShiftLeft", "Digit3"], - "4": ["Digit4"], "$": ["ShiftLeft", "Digit4"], - "5": ["Digit5"], "%": ["ShiftLeft", "Digit5"], - "6": ["Digit6"], "^": ["ShiftLeft", "Digit6"], - "7": ["Digit7"], "&": ["ShiftLeft", "Digit7"], - "8": ["Digit8"], "*": ["ShiftLeft", "Digit8"], - "9": ["Digit9"], "(": ["ShiftLeft", "Digit9"], - "0": ["Digit0"], ")": ["ShiftLeft", "Digit0"], - "-": ["Minus"], "_": ["ShiftLeft", "Minus"], - "'": ["Quote"], "\"": ["ShiftLeft", "Quote"], - ";": ["Semicolon"], ":": ["ShiftLeft", "Semicolon"], - "/": ["Slash"], "?": ["ShiftLeft", "Slash"], - "=": ["Equal"], "+": ["ShiftLeft", "Equal"], - }; - - for (var ch = "a".charCodeAt(0); ch <= "z".charCodeAt(0); ++ch) { - var low = String.fromCharCode(ch); - var up = low.toUpperCase(); - var code = "Key" + up; - chars_to_codes[low] = [code]; - chars_to_codes[up] = ["ShiftLeft", code]; - } - - return chars_to_codes; - }; - - var __pasteAsKeysFromClipboard = function() { - window.navigator.clipboard.readText().then(__pasteAsKeys); - }; - - var __pasteAsKeys = function(text) { - text = text.replace(/[^\x00-\x7F]/g, ""); // eslint-disable-line no-control-regex - if (text) { - var clipboard_codes = []; - var codes_count = 0; - [...text].forEach(function(ch) { - var codes = __chars_to_codes[ch]; - if (codes) { - codes_count += codes.length; - clipboard_codes.push(codes); - } - }); - - var confirm_msg = ( - "You are going to automatically type " + codes_count - + " characters from the system clipboard." - + " It will take " + (__codes_delay * codes_count * 2 / 1000) + " seconds.<br>" - + "<br>Are you sure you want to continue?<br>" - ); - - ui.confirm(confirm_msg).then(function(ok) { - if (ok) { - $("pak-button").disabled = true; - $("pak-led").className = "led-pak-typing"; - $("pak-led").title = "Autotyping..."; - - tools.debug("Paste-as-keys:", text); - - var index = 0; - var iterate = function() { - __emitShortcut(clipboard_codes[index]).then(function() { - ++index; - if (index < clipboard_codes.length && __ws) { - iterate(); - } else { - $("pak-button").disabled = false; - $("pak-led").className = "led-off"; - $("pak-led").title = ""; - } - }); - }; - iterate(); - } - }); - } - }; - - __init__(); -} diff --git a/kvmd/web/js/keyboard.js b/kvmd/web/js/keyboard.js deleted file mode 100644 index b8c4797b..00000000 --- a/kvmd/web/js/keyboard.js +++ /dev/null @@ -1,187 +0,0 @@ -function Keyboard() { - var self = this; - - /********************************************************************************/ - - var __ws = null; - - var __keys = [].slice.call(document.querySelectorAll("div#keyboard-desktop div.keyboard-block div.keyboard-row div.key")); - var __modifiers = [].slice.call(document.querySelectorAll("div#keyboard-desktop div.keyboard-block div.keyboard-row div.modifier")); - - var __mac_cmd_hook = (( - window.navigator.oscpu - || window.navigator.platform - || window.navigator.appVersion - || "Unknown" - ).indexOf("Mac") !== -1); - - var __init__ = function() { - $("hid-keyboard-led").title = "Keyboard free"; - - $("keyboard-window").onkeydown = (event) => __keyboardHandler(event, true); - $("keyboard-window").onkeyup = (event) => __keyboardHandler(event, false); - $("keyboard-window").onfocus = __updateLeds; - $("keyboard-window").onblur = __updateLeds; - - $("stream-window").onkeydown = (event) => __keyboardHandler(event, true); - $("stream-window").onkeyup = (event) => __keyboardHandler(event, false); - $("stream-window").onfocus = __updateLeds; - $("stream-window").onblur = __updateLeds; - - Array.prototype.forEach.call($$("key"), function(el_key) { - tools.setOnDown(el_key, () => __clickHandler(el_key, true)); - tools.setOnUp(el_key, () => __clickHandler(el_key, false)); - el_key.onmouseout = function() { - if (__isPressed(el_key)) { - __clickHandler(el_key, false); - } - }; - }); - - Array.prototype.forEach.call($$("modifier"), function(el_key) { - tools.setOnDown(el_key, () => __toggleModifierHandler(el_key)); - }); - - if (__mac_cmd_hook) { - tools.info("Keyboard: enabled Mac-CMD-Hook"); - } - }; - - /********************************************************************************/ - - self.setSocket = function(ws) { - if (ws !== __ws) { - self.releaseAll(); - __ws = ws; - } - __updateLeds(); - }; - - self.releaseAll = function() { - __keys.concat(__modifiers).forEach(function(el_key) { - if (__isActive(el_key)) { - self.fireEvent(el_key.getAttribute("data-key"), false); - } - }); - }; - - self.fireEvent = function(code, state) { - __keyboardHandler({code: code}, state); - }; - - var __updateLeds = function() { - if (__ws && (document.activeElement === $("stream-window") || document.activeElement === $("keyboard-window"))) { - $("hid-keyboard-led").className = "led-on"; - $("hid-keyboard-led").title = "Keyboard captured"; - } else { - $("hid-keyboard-led").className = "led-off"; - $("hid-keyboard-led").title = "Keyboard free"; - } - }; - - var __keyboardHandler = function(event, state) { - if (event.preventDefault) { - event.preventDefault(); - } - var el_key = document.querySelector("[data-key='" + event.code + "']"); - if (el_key && !event.repeat) { - __commonHandler(el_key, state, "pressed"); - if (__mac_cmd_hook) { - // https://bugs.chromium.org/p/chromium/issues/detail?id=28089 - // https://bugzilla.mozilla.org/show_bug.cgi?id=1299553 - if ((event.code === "MetaLeft" || event.code === "MetaRight") && !state) { - __keys.forEach(function(el_key) { - if (__isActive(el_key)) { - self.fireEvent(el_key.getAttribute("data-key"), false); - } - }); - } - } - __unholdModifiers(); - } - }; - - var __clickHandler = function(el_key, state) { - __commonHandler(el_key, state, "pressed"); - __unholdModifiers(); - }; - - var __toggleModifierHandler = function(el_key) { - __commonHandler(el_key, !__isActive(el_key), "holded"); - }; - - var __unholdModifiers = function() { - __modifiers.forEach(function(el_key) { - if (__isHolded(el_key)) { - __deactivate(el_key); - __sendKey(el_key, false); - } - }); - }; - - var __commonHandler = function(el_key, state, cls) { - if (state && !__isActive(el_key)) { - __deactivate(el_key); - __activate(el_key, cls); - __sendKey(el_key, true); - } else { - __deactivate(el_key); - __sendKey(el_key, false); - } - }; - - var __isPressed = function(el_key) { - var is_pressed = false; - Array.prototype.forEach.call(__resolveKeys(el_key), function(el_key) { - is_pressed = (is_pressed || el_key.classList.contains("pressed")); - }); - return is_pressed; - }; - - var __isHolded = function(el_key) { - var is_holded = false; - Array.prototype.forEach.call(__resolveKeys(el_key), function(el_key) { - is_holded = (is_holded || el_key.classList.contains("holded")); - }); - return is_holded; - }; - - var __isActive = function(el_key) { - var is_active = false; - Array.prototype.forEach.call(__resolveKeys(el_key), function(el_key) { - is_active = (is_active || el_key.classList.contains("pressed") || el_key.classList.contains("holded")); - }); - return is_active; - }; - - var __activate = function(el_key, cls) { - Array.prototype.forEach.call(__resolveKeys(el_key), function(el_key) { - el_key.classList.add(cls); - }); - }; - - var __deactivate = function(el_key) { - Array.prototype.forEach.call(__resolveKeys(el_key), function(el_key) { - el_key.classList.remove("pressed"); - el_key.classList.remove("holded"); - }); - }; - - var __resolveKeys = function(el_key) { - return document.querySelectorAll("[data-key='" + el_key.getAttribute("data-key") + "']"); - }; - - var __sendKey = function(el_key, state) { - var code = el_key.getAttribute("data-key"); - tools.debug("Key", (state ? "pressed:" : "released:"), code); - if (__ws) { - __ws.send(JSON.stringify({ - event_type: "key", - key: code, - state: state, - })); - } - }; - - __init__(); -} diff --git a/kvmd/web/js/main.js b/kvmd/web/js/main.js deleted file mode 100644 index 211e8525..00000000 --- a/kvmd/web/js/main.js +++ /dev/null @@ -1,16 +0,0 @@ -var ui; - -function main() { - if ( - !window.navigator - || window.navigator.userAgent.indexOf("MSIE ") > 0 - || window.navigator.userAgent.indexOf("Trident/") > 0 - || window.navigator.userAgent.indexOf("Edge/") > 0 - ) { - $("bad-browser-modal").style.visibility = "visible"; - } else { - ui = new Ui(); - new Session(new Atx(), new Hid(), new Msd()); - new Stream(); - } -} diff --git a/kvmd/web/js/mouse.js b/kvmd/web/js/mouse.js deleted file mode 100644 index e4038436..00000000 --- a/kvmd/web/js/mouse.js +++ /dev/null @@ -1,146 +0,0 @@ -function Mouse() { - var self = this; - - /********************************************************************************/ - - var __ws = null; - - var __current_pos = {x: 0, y:0}; - var __sent_pos = {x: 0, y:0}; - - var __stream_hovered = false; - - var __init__ = function() { - $("hid-mouse-led").title = "Mouse free"; - - $("stream-box").onmouseenter = __hoverStream; - $("stream-box").onmouseleave = __leaveStream; - $("stream-box").onmousedown = (event) => __buttonHandler(event, true); - $("stream-box").onmouseup = (event) => __buttonHandler(event, false); - $("stream-box").oncontextmenu = (event) => event.preventDefault(); - $("stream-box").onmousemove = __moveHandler; - $("stream-box").onwheel = __wheelHandler; - - $("stream-box").ontouchstart = (event) => __touchMoveHandler(event); - Array.prototype.forEach.call(document.querySelectorAll("[data-mouse-button]"), function(el_button) { - var button = el_button.getAttribute("data-mouse-button"); - tools.setOnDown(el_button, () => __sendButton(button, true)); - tools.setOnUp(el_button, () => __sendButton(button, false)); - }); - - setInterval(__sendMove, 100); - }; - - /********************************************************************************/ - - self.setSocket = function(ws) { - __ws = ws; - if (ws) { - $("stream-box").classList.add("stream-box-mouse-enabled"); - } else { - $("stream-box").classList.remove("stream-box-mouse-enabled"); - } - }; - - var __hoverStream = function() { - __stream_hovered = true; - __updateLeds(); - }; - - var __leaveStream = function() { - __stream_hovered = false; - __updateLeds(); - }; - - var __updateLeds = function() { - if (__ws && __stream_hovered) { - $("hid-mouse-led").className = "led-on"; - $("hid-mouse-led").title = "Mouse tracked"; - } else { - $("hid-mouse-led").className = "led-off"; - $("hid-mouse-led").title = "Mouse free"; - } - }; - - var __buttonHandler = function(event, state) { - // https://www.w3schools.com/jsref/event_button.asp - event.preventDefault(); - switch (event.button) { - case 0: __sendButton("left", state); break; - case 2: __sendButton("right", state); break; - } - }; - - var __touchMoveHandler = function(event) { - event.preventDefault(); - if (event.touches[0].target && event.touches[0].target.getBoundingClientRect) { - var rect = event.touches[0].target.getBoundingClientRect(); - __current_pos = { - x: Math.round(event.touches[0].clientX - rect.left), - y: Math.round(event.touches[0].clientY - rect.top), - }; - __sendMove(); - } - }; - - 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 __sendButton = function(button, state) { - tools.debug("Mouse button", (state ? "pressed:" : "released:"), button); - __sendMove(); - if (__ws) { - __ws.send(JSON.stringify({ - event_type: "mouse_button", - button: button, - state: state, - })); - } - }; - - var __sendMove = function() { - var pos = __current_pos; - if (pos.x !== __sent_pos.x || pos.y !== __sent_pos.y) { - var el_stream_image = $("stream-image"); - var to = { - x: __translate(pos.x, 0, el_stream_image.clientWidth, -32768, 32767), - y: __translate(pos.y, 0, el_stream_image.clientHeight, -32768, 32767), - }; - tools.debug("Mouse move:", to); - if (__ws) { - __ws.send(JSON.stringify({ - event_type: "mouse_move", - to: to, - })); - } - __sent_pos = pos; - } - }; - - var __translate = function(x, a, b, c, d) { - return Math.round((x - a) / (b - a) * (d - c) + c); - }; - - var __wheelHandler = function(event) { - // https://learn.javascript.ru/mousewheel - if (event.preventDefault) { - event.preventDefault(); - } - var delta = {x: event.deltaX, y: event.deltaY}; - tools.debug("Mouse wheel:", delta); - if (__ws) { - __ws.send(JSON.stringify({ - event_type: "mouse_wheel", - delta: delta, - })); - } - }; - - __init__(); -} diff --git a/kvmd/web/js/msd.js b/kvmd/web/js/msd.js deleted file mode 100644 index f90e4b05..00000000 --- a/kvmd/web/js/msd.js +++ /dev/null @@ -1,164 +0,0 @@ -function Msd() { - var self = this; - - /********************************************************************************/ - - var __state = null; - var __upload_http = null; - var __image_file = null; - - var __init__ = function() { - $("msd-led").title = "Unknown state"; - - $("msd-select-new-image-file").onchange = __selectNewImageFile; - tools.setOnClick($("msd-select-new-image-button"), () => $("msd-select-new-image-file").click()); - - tools.setOnClick($("msd-upload-new-image-button"), __clickUploadNewImageButton); - tools.setOnClick($("msd-abort-uploading-button"), __clickAbortUploadingButton); - - tools.setOnClick($("msd-switch-to-kvm-button"), () => __clickSwitchButton("kvm")); - tools.setOnClick($("msd-switch-to-server-button"), () => __clickSwitchButton("server")); - }; - - /********************************************************************************/ - - self.loadInitialState = function() { - var http = tools.makeRequest("GET", "/kvmd/msd", function() { - if (http.readyState === 4) { - if (http.status === 200) { - self.setState(JSON.parse(http.responseText).result); - } else { - setTimeout(self.loadInitialState, 1000); - } - } - }); - }; - - self.setState = function(state) { - __state = state; - __applyState(); - }; - - var __clickUploadNewImageButton = function() { - var form_data = new FormData(); - form_data.append("image_name", __image_file.name); - form_data.append("image_data", __image_file); - - __upload_http = new XMLHttpRequest(); - __upload_http.open("POST", "/kvmd/msd/write", true); - __upload_http.upload.timeout = 5000; - __upload_http.onreadystatechange = __uploadStateChange; - __upload_http.upload.onprogress = __uploadProgress; - __upload_http.send(form_data); - }; - - var __clickAbortUploadingButton = function() { - __upload_http.onreadystatechange = null; - __upload_http.upload.onprogress = null; - __upload_http.abort(); - __upload_http = null; - $("msd-progress").setAttribute("data-label", "Aborted"); - $("msd-progress-value").style.width = "0%"; - }; - - var __clickSwitchButton = function(to) { - var http = tools.makeRequest("POST", "/kvmd/msd/connect?to=" + to, function() { - if (http.readyState === 4) { - if (http.status !== 200) { - ui.error("Switch error:<br>", http.responseText); - } - } - __applyState(); - }); - __applyState(); - $("msd-switch-to-" + to + "-button").disabled = true; - }; - - var __selectNewImageFile = function() { - var el_input = $("msd-select-new-image-file"); - var image_file = (el_input.files.length ? el_input.files[0] : null); - if (image_file && image_file.size > __state.info.size) { - ui.error("New image is too big for your Mass Storage Device.<br>Maximum:", __formatSize(__state.info.size)); - el_input.value = ""; - image_file = null; - } - __image_file = image_file; - __applyState(); - }; - - var __applyState = function() { - if (__state.connected_to === "server") { - $("msd-another-another-user-uploads").style.display = "none"; - $("msd-led").className = "led-on"; - $("msd-status").innerHTML = $("msd-led").title = "Connected to Server"; - $("msd-another-another-user-uploads").style.display = "none"; - } else if (__state.busy) { - if (!__upload_http) { - $("msd-another-another-user-uploads").style.display = "block"; - } - $("msd-led").className = "led-msd-writing"; - $("msd-status").innerHTML = $("msd-led").title = "Uploading new image"; - } else { - $("msd-another-another-user-uploads").style.display = "none"; - $("msd-led").className = "led-off"; - if (__state.in_operate) { - $("msd-status").innerHTML = $("msd-led").title = "Connected to KVM"; - } else { - $("msd-status").innerHTML = $("msd-led").title = "Unavailable"; - } - } - - $("msd-not-in-operate").style.display = (__state.in_operate ? "none" : "block"); - $("msd-current-image-broken").style.display = ( - __state.in_operate && __state.info.image && - !__state.info.image.complete && !__state.busy ? "block" : "none" - ); - - $("msd-current-image-name").innerHTML = (__state.in_operate && __state.info.image ? __state.info.image.name : "None"); - $("msd-current-image-size").innerHTML = (__state.in_operate && __state.info.image ? __formatSize(__state.info.image.size) : "None"); - $("msd-storage-size").innerHTML = (__state.in_operate ? __formatSize(__state.info.size) : "Unavailable"); - - $("msd-switch-to-kvm-button").disabled = (!__state.in_operate || __state.connected_to === "kvm" || __state.busy); - $("msd-switch-to-server-button").disabled = (!__state.in_operate || __state.connected_to === "server" || __state.busy); - $("msd-select-new-image-button").disabled = (!__state.in_operate || __state.connected_to !== "kvm" || __state.busy || __upload_http); - $("msd-upload-new-image-button").disabled = (!__state.in_operate || __state.connected_to !== "kvm" || __state.busy || !__image_file); - $("msd-abort-uploading-button").disabled = (!__state.in_operate || !__upload_http); - - $("msd-new-image").style.display = (__image_file ? "block" : "none"); - $("msd-progress").setAttribute("data-label", "Waiting for upload ..."); - $("msd-progress-value").style.width = "0%"; - $("msd-new-image-name").innerHTML = (__image_file ? __image_file.name : ""); - $("msd-new-image-size").innerHTML = (__image_file ? __formatSize(__image_file.size) : ""); - }; - - var __formatSize = function(size) { - if (size > 0) { - var index = Math.floor( Math.log(size) / Math.log(1024) ); - return (size / Math.pow(1024, index)).toFixed(2) * 1 + " " + ["B", "kB", "MB", "GB", "TB"][index]; - } else { - return 0; - } - }; - - var __uploadStateChange = function() { - if (__upload_http.readyState === 4) { - if (__upload_http.status !== 200) { - ui.error("Can't upload image to the Mass Storage Device:<br>", __upload_http.responseText); - } - $("msd-select-new-image-file").value = ""; - __image_file = null; - __upload_http = null; - __applyState(); - } - }; - - var __uploadProgress = function(event) { - if(event.lengthComputable) { - var percent = Math.round((event.loaded * 100) / event.total); - $("msd-progress").setAttribute("data-label", percent + "%"); - $("msd-progress-value").style.width = percent + "%"; - } - }; - - __init__(); -} diff --git a/kvmd/web/js/session.js b/kvmd/web/js/session.js deleted file mode 100644 index 3169c8c1..00000000 --- a/kvmd/web/js/session.js +++ /dev/null @@ -1,121 +0,0 @@ -function Session(atx, hid, msd) { - // var self = this; - - /********************************************************************************/ - - var __ws = null; - - var __ping_timer = null; - var __missed_heartbeats = 0; - - var __init__ = function() { - $("link-led").title = "Not connected yet..."; - __loadKvmdVersion(); - __startPoller(); - }; - - /********************************************************************************/ - - var __loadKvmdVersion = function() { - var http = tools.makeRequest("GET", "/kvmd/info", function() { - if (http.readyState === 4) { - if (http.status === 200) { - var version = JSON.parse(http.responseText).result.version; - $("kvmd-version").innerHTML = "kvmd " + version.kvmd; - $("about-version-kvmd").innerHTML = version.kvmd; - $("about-version-python").innerHTML = version.python; - $("about-version-platform").innerHTML = version.platform; - } else { - setTimeout(__loadKvmdVersion, 1000); - } - } - }); - }; - - var __startPoller = function() { - $("link-led").className = "led-link-connecting"; - $("link-led").title = "Connecting..."; - var http = tools.makeRequest("GET", "/wsauth", function() { - if (http.readyState === 4) { - if (http.status === 200) { - __ws = new WebSocket((location.protocol == "https:" ? "wss" : "ws") + "://" + location.host + "/kvmd/ws"); - __ws.onopen = __wsOpenHandler; - __ws.onmessage = __wsMessageHandler; - __ws.onerror = __wsErrorHandler; - __ws.onclose = __wsCloseHandler; - } else { - __wsCloseHandler(null); - } - } - }); - }; - - var __wsOpenHandler = function(event) { - $("link-led").className = "led-on"; - $("link-led").title = "Connected"; - tools.debug("WebSocket opened:", event); - atx.loadInitialState(); - msd.loadInitialState(); - hid.setSocket(__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.setState(event.msg.event_attrs); - } else if (event.msg.event === "msd_state") { - msd.setState(event.msg.event_attrs); - } - } - }; - - var __wsErrorHandler = function(event) { - tools.error("WebSocket error:", event); - if (__ws) { - __ws.onclose = null; - __ws.close(); - __wsCloseHandler(null); - } - }; - - var __wsCloseHandler = function(event) { - $("link-led").className = "led-off"; - tools.debug("WebSocket closed:", event); - if (__ping_timer) { - clearInterval(__ping_timer); - __ping_timer = null; - } - hid.setSocket(null); - atx.clearState(); - __ws = null; - setTimeout(function() { - $("link-led").className = "led-link-connecting"; - setTimeout(__startPoller, 500); - }, 500); - }; - - var __pingServer = function() { - 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); - if (__ws) { - __ws.onclose = null; - __ws.close(); - __wsCloseHandler(null); - } - } - }; - - __init__(); -} diff --git a/kvmd/web/js/stream.js b/kvmd/web/js/stream.js deleted file mode 100644 index af3e45e9..00000000 --- a/kvmd/web/js/stream.js +++ /dev/null @@ -1,119 +0,0 @@ -function Stream() { - // var self = this; - - /********************************************************************************/ - - var __prev_state = false; - - var __quality = 80; - - var __normal_size = {width: 640, height: 480}; - var __size_factor = 1; - - var __init__ = function() { - $("stream-led").title = "Stream inactive"; - - var quality = 10; - for (; quality <= 100; quality += 10) { - $("stream-quality-select").innerHTML += "<option value=\"" + quality + "\">" + quality + "%</option>"; - } - - tools.setOnClick($("stream-reset-button"), __clickResetButton); - $("stream-quality-select").onchange = __changeQuality; - $("stream-size-slider").oninput = __resize; - $("stream-size-slider").onchange = __resize; - - __startPoller(); - }; - - /********************************************************************************/ - - // XXX: In current implementation we don't need this event because Stream() has own state poller - - var __startPoller = function() { - var http = tools.makeRequest("GET", "/streamer/ping", function() { - if (http.readyState === 4) { - var response = (http.status === 200 ? JSON.parse(http.responseText) : null); - if (http.status !== 200 || !response.stream.online) { - tools.info("Refreshing stream ..."); - __prev_state = false; - $("stream-image").className = "stream-image-inactive"; - $("stream-box").classList.add("stream-box-inactive"); - $("stream-led").className = "led-off"; - $("stream-led").title = "Stream inactive"; - $("stream-reset-button").disabled = true; - $("stream-quality-select").disabled = true; - } else if (http.status === 200 && !__prev_state) { - __normal_size = response.stream.resolution; - __refreshImage(); - __prev_state = true; - $("stream-image").className = "stream-image-active"; - $("stream-box").classList.remove("stream-box-inactive"); - $("stream-led").className = "led-on"; - $("stream-led").title = "Stream is active"; - $("stream-reset-button").disabled = false; - $("stream-quality-select").disabled = false; - } - } - }); - setTimeout(__startPoller, 1500); - }; - - var __clickResetButton = function() { - $("stream-reset-button").disabled = true; - var http = tools.makeRequest("POST", "/kvmd/streamer/reset", function() { - if (http.readyState === 4) { - if (http.status !== 200) { - ui.error("Can't reset stream:<br>", http.responseText); - } - } - }); - }; - - var __changeQuality = function() { - var quality = parseInt($("stream-quality-select").value); - if (__quality != quality) { - $("stream-quality-select").disabled = true; - var http = tools.makeRequest("POST", "/kvmd/streamer/set_params?quality=" + quality, function() { - if (http.readyState === 4) { - if (http.status !== 200) { - ui.error("Can't configure stream:<br>", http.responseText); - } - } - }); - } - }; - - var __resize = function() { - var percent = $("stream-size-slider").value; - $("stream-size-value").innerHTML = percent + "%"; - __size_factor = percent / 100; - __applySizeFactor(); - }; - - var __applySizeFactor = function() { - var el_stream_image = $("stream-image"); - el_stream_image.style.width = __normal_size.width * __size_factor + "px"; - el_stream_image.style.height = __normal_size.height * __size_factor + "px"; - ui.showWindow($("stream-window"), false); - }; - - var __refreshImage = function() { - var http = tools.makeRequest("GET", "/kvmd/streamer", function() { - if (http.readyState === 4 && http.status === 200) { - var result = JSON.parse(http.responseText).result; - - if (__quality != result.quality) { - tools.info("Quality changed:", result.quality); - document.querySelector("#stream-quality-select [value=\"" + result.quality + "\"]").selected = true; - __quality = result.quality; - } - - __applySizeFactor(); - $("stream-image").src = "/streamer/stream?t=" + new Date().getTime(); - } - }); - }; - - __init__(); -} diff --git a/kvmd/web/js/tools.js b/kvmd/web/js/tools.js deleted file mode 100644 index 76f27b7d..00000000 --- a/kvmd/web/js/tools.js +++ /dev/null @@ -1,43 +0,0 @@ -var tools = new function() { - var __debug = (new URL(window.location.href)).searchParams.get("debug"); - - this.makeRequest = function(method, url, callback, timeout=null) { - var http = new XMLHttpRequest(); - http.open(method, url, true); - http.onreadystatechange = callback; - http.timeout = (timeout ? timeout : 5000); - http.send(); - return http; - }; - - this.setOnClick = function(el, callback) { - el.onclick = el.ontouchend = function(event) { - event.preventDefault(); - callback(); - }; - }; - this.setOnDown = function(el, callback) { - el.onmousedown = el.ontouchstart = function(event) { - event.preventDefault(); - callback(); - }; - }; - this.setOnUp = function(el, callback) { - el.onmouseup = el.ontouchend = function(event) { - event.preventDefault(); - callback(); - }; - }; - - this.debug = function(...args) { - if (__debug) { - console.log("LOG/DEBUG", ...args); // eslint-disable-line no-console - } - }; - - this.info = (...args) => console.log("LOG/INFO", ...args); // eslint-disable-line no-console - this.error = (...args) => console.error("LOG/ERROR", ...args); // eslint-disable-line no-console -}; - -var $ = (id) => document.getElementById(id); -var $$ = (cls) => document.getElementsByClassName(cls); diff --git a/kvmd/web/js/ui.js b/kvmd/web/js/ui.js deleted file mode 100644 index d04184c1..00000000 --- a/kvmd/web/js/ui.js +++ /dev/null @@ -1,319 +0,0 @@ -function Ui() { - var self = this; - - /********************************************************************************/ - - var __top_z_index = 0; - var __windows = []; - var __ctl_items = []; - - var __init__ = function() { - Array.prototype.forEach.call(document.querySelectorAll("button"), function(el_button) { - // XXX: Workaround for iOS Safari: - // https://stackoverflow.com/questions/3885018/active-pseudo-class-doesnt-work-in-mobile-safari - el_button.ontouchstart = function() {}; - }); - - Array.prototype.forEach.call($$("ctl-item"), function(el_item) { - tools.setOnClick(el_item, () => __toggleMenu(el_item)); - __ctl_items.push(el_item); - }); - - Array.prototype.forEach.call($$("window"), function(el_window) { - __makeWindowMovable(el_window); - __windows.push(el_window); - - var el_button = el_window.querySelector(".window-header .window-button-close"); - if (el_button) { - tools.setOnClick(el_button, function() { - el_window.style.visibility = "hidden"; - __raiseLastWindow(); - }); - } - }); - - window.onmouseup = __globalMouseButtonHandler; - window.ontouchend = __globalMouseButtonHandler; - - window.addEventListener("resize", () => __organizeWindowsOnResize(false)); - window.addEventListener("orientationchange", () => __organizeWindowsOnResize(true)); - - tools.setOnClick($("show-about-button"), () => self.showWindow($("about-window"))); - tools.setOnClick($("show-keyboard-button"), () => self.showWindow($("keyboard-window"))); - tools.setOnClick($("show-stream-button"), () => self.showWindow($("stream-window"))); - - self.showWindow($("stream-window")); - }; - - /********************************************************************************/ - - self.error = (...args) => __modalDialog("Error", args.join(" "), true, false); - self.confirm = (...args) => __modalDialog("Question", args.join(" "), true, true); - - var __modalDialog = function(header, text, ok, cancel) { - var el_modal = document.createElement("div"); - el_modal.className = "modal"; - el_modal.style.visibility = "visible"; - - var el_window = document.createElement("div"); - el_window.className = "modal-window"; - el_window.setAttribute("tabindex", "-1"); - el_modal.appendChild(el_window); - - var el_header = document.createElement("div"); - el_header.className = "modal-header"; - el_header.innerHTML = header; - el_window.appendChild(el_header); - - var el_content = document.createElement("div"); - el_content.className = "modal-content"; - el_content.innerHTML = text; - el_window.appendChild(el_content); - - var promise = null; - if (ok || cancel) { - promise = new Promise(function(resolve) { - var el_buttons = document.createElement("div"); - el_buttons.className = "modal-buttons"; - el_window.appendChild(el_buttons); - - function close (retval) { - el_modal.outerHTML = ""; - var index = __windows.indexOf(el_modal); - if (index !== -1) { - __windows.splice(index, 1); - } - __raiseLastWindow(); - resolve(retval); - } - - if (cancel) { - var el_cancel_button = document.createElement("button"); - el_cancel_button.innerHTML = "Cancel"; - tools.setOnClick(el_cancel_button, () => close(false)); - el_buttons.appendChild(el_cancel_button); - } - if (ok) { - var el_ok_button = document.createElement("button"); - el_ok_button.innerHTML = "OK"; - tools.setOnClick(el_ok_button, () => close(true)); - el_buttons.appendChild(el_ok_button); - } - if (ok && cancel) { - el_ok_button.className = "row50"; - el_cancel_button.className = "row50"; - } - - el_window.onkeyup = function(event) { - event.preventDefault(); - if (ok && event.code === "Enter") { - el_ok_button.click(); - } else if (cancel && event.code === "Escape") { - el_cancel_button.click(); - } - }; - }); - } - - __windows.push(el_modal); - document.body.appendChild(el_modal); - __raiseWindow(el_modal); - - return promise; - }; - - self.showWindow = function(el_window, raise=true) { - if (!__isWindowOnPage(el_window) || el_window.hasAttribute("data-centered")) { - var view = __getViewGeometry(); - var rect = el_window.getBoundingClientRect(); - el_window.style.top = Math.max($("ctl").clientHeight, Math.round((view.bottom - rect.height) / 2)) + "px"; - el_window.style.left = Math.round((view.right - rect.width) / 2) + "px"; - el_window.setAttribute("data-centered", ""); - } - el_window.style.visibility = "visible"; - if (raise) { - __raiseWindow(el_window); - } - }; - - var __isWindowOnPage = function(el_window) { - var view = __getViewGeometry(); - var rect = el_window.getBoundingClientRect(); - - return ( - (rect.bottom - el_window.clientHeight / 1.5) <= view.bottom - && rect.top >= view.top - && (rect.left + el_window.clientWidth / 1.5) >= view.left - && (rect.right - el_window.clientWidth / 1.5) <= view.right - ); - }; - - var __getViewGeometry = function() { - return { - top: $("ctl").clientHeight, - bottom: Math.max(document.documentElement.clientHeight, window.innerHeight || 0), - left: 0, - right: Math.max(document.documentElement.clientWidth, window.innerWidth || 0), - }; - }; - - var __toggleMenu = function(el_a) { - var all_hidden = true; - - __ctl_items.forEach(function(el_item) { - var el_menu = el_item.parentElement.querySelector(".ctl-dropdown-content"); - if (el_item === el_a && window.getComputedStyle(el_menu, null).visibility === "hidden") { - el_item.focus(); - el_item.classList.add("ctl-item-selected"); - el_menu.style.visibility = "visible"; - all_hidden &= false; - } else { - el_item.classList.remove("ctl-item-selected"); - el_menu.style.visibility = "hidden"; - } - }); - - if (all_hidden) { - document.onkeyup = null; - __raiseLastWindow(); - } else { - document.onkeyup = function(event) { - if (event.code === "Escape") { - event.preventDefault(); - __closeAllMenues(); - __raiseLastWindow(); - } - }; - } - }; - - var __closeAllMenues = function() { - document.onkeyup = null; - __ctl_items.forEach(function(el_item) { - var el_menu = el_item.parentElement.querySelector(".ctl-dropdown-content"); - el_item.classList.remove("ctl-item-selected"); - el_menu.style.visibility = "hidden"; - }); - }; - - var __globalMouseButtonHandler = function(event) { - if (!event.target.matches(".ctl-item")) { - for (var el_item = event.target; el_item && el_item !== document; el_item = el_item.parentNode) { - if (el_item.hasAttribute("data-force-hide-menu")) { - break; - } else if (el_item.hasAttribute("data-dont-hide-menu")) { - return; - } - } - __closeAllMenues(); - __raiseLastWindow(); - } - }; - - var __organizeWindowsOnResize = function(orientation) { - var view = __getViewGeometry(); - Array.prototype.forEach.call($$("window"), function(el_window) { - if (el_window.style.visibility === "visible" && (orientation || el_window.hasAttribute("data-centered"))) { - var rect = el_window.getBoundingClientRect(); - el_window.style.top = Math.max($("ctl").clientHeight, Math.round((view.bottom - rect.height) / 2)) + "px"; - el_window.style.left = Math.round((view.right - rect.width) / 2) + "px"; - el_window.setAttribute("data-centered", ""); - } - }); - }; - - var __makeWindowMovable = function(el_window) { - var el_header = el_window.querySelector(".window-header"); - var el_grab = el_window.querySelector(".window-header .window-grab"); - - var prev_pos = {x: 0, y: 0}; - - function startMoving(event) { - __closeAllMenues(); - __raiseWindow(el_window); - event = (event || window.event); - event.preventDefault(); - - if (!event.touches || event.touches.length === 1) { - el_header.classList.add("window-header-grabbed"); - - prev_pos = getEventPosition(event); - - document.onmousemove = doMoving; - document.onmouseup = stopMoving; - - document.ontouchmove = doMoving; - document.ontouchend = stopMoving; - } - } - - function doMoving(event) { - el_window.removeAttribute("data-centered"); - - event = (event || window.event); - event.preventDefault(); - - var event_pos = getEventPosition(event); - var x = prev_pos.x - event_pos.x; - var y = prev_pos.y - event_pos.y; - - el_window.style.top = (el_window.offsetTop - y) + "px"; - el_window.style.left = (el_window.offsetLeft - x) + "px"; - - prev_pos = event_pos; - } - - function stopMoving() { - el_header.classList.remove("window-header-grabbed"); - - document.onmousemove = null; - document.onmouseup = null; - - document.ontouchmove = null; - document.ontouchend = null; - } - - function getEventPosition(event) { - if (event.touches) { - return {x: event.touches[0].clientX, y: event.touches[0].clientY}; - } else { - return {x: event.clientX, y: event.clientY}; - } - } - - el_window.setAttribute("data-centered", ""); - tools.setOnClick(el_window, () => __raiseWindow(el_window)); - - el_grab.onmousedown = startMoving; - el_grab.ontouchstart = startMoving; - }; - - var __raiseLastWindow = function() { - var last_el_window = null; - var max_z_index = 0; - __windows.forEach(function(el_window) { - var z_index = parseInt(window.getComputedStyle(el_window, null).zIndex) || 0; - if (max_z_index < z_index && window.getComputedStyle(el_window, null).visibility !== "hidden") { - last_el_window = el_window; - max_z_index = z_index; - } - }); - __raiseWindow(last_el_window); - }; - - var __raiseWindow = function(el_window) { - var el_to_focus = (el_window.className === "modal" ? el_window.querySelector(".modal-window") : el_window); - if (document.activeElement !== el_to_focus) { - el_to_focus.focus(); - tools.debug("Focused window:", el_window); - if (el_window.className !== "modal" && parseInt(el_window.style.zIndex) !== __top_z_index) { - var z_index = __top_z_index + 1; - el_window.style.zIndex = z_index; - __top_z_index = z_index; - tools.debug("Raised window:", el_window); - } - } - }; - - __init__(); -} |