diff options
-rw-r--r-- | web/css/menu.css | 9 | ||||
-rw-r--r-- | web/css/vars.css | 4 | ||||
-rw-r--r-- | web/js/kvm/atx.js | 6 | ||||
-rw-r--r-- | web/js/kvm/hid.js | 14 | ||||
-rw-r--r-- | web/js/kvm/keyboard.js | 14 | ||||
-rw-r--r-- | web/js/kvm/msd.js | 14 | ||||
-rw-r--r-- | web/js/kvm/stream.js | 16 | ||||
-rw-r--r-- | web/js/ui.js | 166 | ||||
-rw-r--r-- | web/kvm/index.html | 10 |
9 files changed, 143 insertions, 110 deletions
diff --git a/web/css/menu.css b/web/css/menu.css index 6fa28e44..5ececb32 100644 --- a/web/css/menu.css +++ b/web/css/menu.css @@ -71,10 +71,11 @@ ul#menu li a.menu-item-selected { ul#menu li div.menu-item-content { visibility: hidden; + outline: none; overflow: hidden; white-space: nowrap; - border: var(--border-intensive-2px); - border-top: var(--border-control-thin); + border: var(--border-menu-item-content-default-2px); + border-top: var(--border-menu-item-content-top-thin); border-radius: 0 0 8px 8px; position: absolute; background-color: var(--cs-menu-default-bg); @@ -82,6 +83,10 @@ ul#menu li div.menu-item-content { box-shadow: var(--shadow-big); z-index: 2147483645; } +ul#menu li div.menu-item-content-active { + border: var(--border-menu-item-content-active-2px) !important; + border-top: var(--border-menu-item-content-top-thin) !important; +} ul#menu li div.menu-item-content-buttons { background-color: var(--cs-control-default-bg); diff --git a/web/css/vars.css b/web/css/vars.css index 8f5c6d52..57e71c0f 100644 --- a/web/css/vars.css +++ b/web/css/vars.css @@ -56,4 +56,8 @@ --border-key-thin: thin solid #202225; --border-intensive-2px: 2px solid #5b90bb; --border-intensive-thin: thin solid #5b90bb; + + --border-menu-item-content-default-2px: 2px solid black; + --border-menu-item-content-active-2px: 2px solid #5b90bb; + --border-menu-item-content-top-thin: thin solid #17191d; } diff --git a/web/js/kvm/atx.js b/web/js/kvm/atx.js index d637c742..9ef0c063 100644 --- a/web/js/kvm/atx.js +++ b/web/js/kvm/atx.js @@ -18,9 +18,9 @@ function Atx() { $("atx-power-led").className = (state.leds.power ? "led-green" : "led-gray"); $("atx-hdd-led").className = (state.leds.hdd ? "led-red" : "led-gray"); - $("atx-power-button").disabled = state.busy; - $("atx-power-button-long").disabled = state.busy; - $("atx-reset-button").disabled = state.busy; + ui.switchDisabled($("atx-power-button"), state.busy); + ui.switchDisabled($("atx-power-button-long"), state.busy); + ui.switchDisabled($("atx-reset-button"), state.busy); }; self.clearState = function() { diff --git a/web/js/kvm/hid.js b/web/js/kvm/hid.js index e7877484..c837b809 100644 --- a/web/js/kvm/hid.js +++ b/web/js/kvm/hid.js @@ -54,9 +54,9 @@ function Hid() { /********************************************************************************/ self.setSocket = function(ws) { - $("hid-pak-text").disabled = !ws; - $("hid-pak-button").disabled = !ws; - $("hid-reset-button").disabled = !ws; + ui.switchDisabled($("hid-pak-text"), !ws); + ui.switchDisabled($("hid-pak-button"), !ws); + ui.switchDisabled($("hid-reset-button"), !ws); __ws = ws; __keyboard.setSocket(ws); __mouse.setSocket(ws); @@ -154,8 +154,8 @@ function Hid() { ui.confirm(confirm_msg).then(function(ok) { if (ok) { - $("hid-pak-text").disabled = true; - $("hid-pak-button").disabled = true; + ui.switchDisabled($("hid-pak-text"), true); + ui.switchDisabled($("hid-pak-button"), true); $("hid-pak-led").className = "led-yellow-rotating-fast"; $("hid-pak-led").title = "Autotyping..."; @@ -169,8 +169,8 @@ function Hid() { iterate(); } else { $("hid-pak-text").value = ""; - $("hid-pak-text").disabled = false; - $("hid-pak-button").disabled = false; + ui.switchDisabled($("hid-pak-text"), false); + ui.switchDisabled($("hid-pak-button"), false); $("hid-pak-led").className = "led-gray"; $("hid-pak-led").title = ""; } diff --git a/web/js/kvm/keyboard.js b/web/js/kvm/keyboard.js index 273038fa..3c821406 100644 --- a/web/js/kvm/keyboard.js +++ b/web/js/kvm/keyboard.js @@ -21,9 +21,8 @@ function Keyboard() { $("stream-window").onfocus = __updateLeds; $("stream-window").onblur = __updateLeds; - window.addEventListener("focus", __updateLeds); - window.addEventListener("pagehide", __updateLeds); - window.addEventListener("blur", __updateLeds); + window.addEventListener("focusin", __updateLeds); + window.addEventListener("focusout", __updateLeds); Array.prototype.forEach.call($$("key"), function(el_key) { tools.setOnDown(el_key, () => __clickHandler(el_key, true)); @@ -67,14 +66,9 @@ function Keyboard() { }; var __updateLeds = function() { - tools.info("Update leds"); + tools.debug("Keyboard: update leds"); if ( - __ws - && ( - document.activeElement === $("stream-window") - || document.activeElement === $("keyboard-window") - ) - && ( + __ws && ( $("stream-window").classList.contains("window-active") || $("keyboard-window").classList.contains("window-active") ) diff --git a/web/js/kvm/msd.js b/web/js/kvm/msd.js index 057dec5b..4ce5d464 100644 --- a/web/js/kvm/msd.js +++ b/web/js/kvm/msd.js @@ -61,7 +61,7 @@ function Msd() { __applyState(); }); __applyState(); - $(`msd-switch-to-${to}-button`).disabled = true; + ui.switchDisabled($(`msd-switch-to-${to}-button`), true); }; var __selectNewImageFile = function() { @@ -120,12 +120,12 @@ function Msd() { $("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-reset-button").disabled = (!__state.in_operate || __upload_http); + ui.switchDisabled($("msd-switch-to-kvm-button"), (!__state.in_operate || __state.connected_to === "kvm" || __state.busy)); + ui.switchDisabled($("msd-switch-to-server-button"), (!__state.in_operate || __state.connected_to === "server" || __state.busy)); + ui.switchDisabled($("msd-select-new-image-button"), (!__state.in_operate || __state.connected_to !== "kvm" || __state.busy || __upload_http)); + ui.switchDisabled($("msd-upload-new-image-button"), (!__state.in_operate || __state.connected_to !== "kvm" || __state.busy || !__image_file)); + ui.switchDisabled($("msd-abort-uploading-button"), (!__state.in_operate || !__upload_http)); + ui.switchDisabled($("msd-reset-button"), (!__state.in_operate || __upload_http)); $("msd-new-image").style.display = (__image_file ? "block" : "none"); $("msd-progress").setAttribute("data-label", "Waiting for upload ..."); diff --git a/web/js/kvm/stream.js b/web/js/kvm/stream.js index 4efaefed..52e01fc4 100644 --- a/web/js/kvm/stream.js +++ b/web/js/kvm/stream.js @@ -49,7 +49,7 @@ function Streamer() { } if (!$("stream-quality-slider").activated) { - $("stream-quality-slider").disabled = false; + ui.switchDisabled($("stream-quality-slider"), false); if ($("stream-quality-slider").value !== source.quality) { $("stream-quality-slider").value = source.quality; __updateQualityValue(source.quality); @@ -57,7 +57,7 @@ function Streamer() { } if (!$("stream-desired-fps-slider").activated) { - $("stream-desired-fps-slider").disabled = false; + ui.switchDisabled($("stream-desired-fps-slider"), false); if ($("stream-desired-fps-slider").value !== source.desired_fps) { $("stream-desired-fps-slider").value = source.desired_fps; __updateDesiredFpsValue(source.desired_fps); @@ -101,8 +101,8 @@ function Streamer() { $("stream-box").classList.remove("stream-box-inactive"); $("stream-led").className = "led-green"; $("stream-led").title = "Stream is active"; - $("stream-screenshot-button").disabled = false; - $("stream-reset-button").disabled = false; + ui.switchDisabled($("stream-screenshot-button"), false); + ui.switchDisabled($("stream-reset-button"), false); tools.info("Stream: acquired"); __prev = true; } @@ -121,10 +121,10 @@ function Streamer() { $("stream-box").classList.add("stream-box-inactive"); $("stream-led").className = "led-gray"; $("stream-led").title = "Stream inactive"; - $("stream-screenshot-button").disabled = true; - $("stream-reset-button").disabled = true; - $("stream-quality-slider").disabled = true; - $("stream-desired-fps-slider").disabled = true; + ui.switchDisabled($("stream-screenshot-button"), true); + ui.switchDisabled($("stream-reset-button"), true); + ui.switchDisabled($("stream-quality-slider"), true); + ui.switchDisabled($("stream-desired-fps-slider"), true); __client_key = tools.makeId(); __client_id = ""; diff --git a/web/js/ui.js b/web/js/ui.js index e3877191..efbb1a6c 100644 --- a/web/js/ui.js +++ b/web/js/ui.js @@ -15,11 +15,13 @@ function Ui() { }); Array.prototype.forEach.call($$("menu-item"), function(el_item) { + el_item.parentElement.querySelector(".menu-item-content").setAttribute("tabindex", "-1"); tools.setOnClick(el_item, () => __toggleMenu(el_item)); __menu_items.push(el_item); }); Array.prototype.forEach.call($$("window"), function(el_window) { + el_window.setAttribute("tabindex", "-1"); __makeWindowMovable(el_window); __windows.push(el_window); @@ -39,11 +41,9 @@ function Ui() { window.onmouseup = __globalMouseButtonHandler; window.ontouchend = __globalMouseButtonHandler; - window.addEventListener("focus", () => __activateLastWindow()); - window.addEventListener("pagehide", () => __deactivateAllWindows()); - window.addEventListener("pagehide", __closeAllMenues); - window.addEventListener("blur", () => __deactivateAllWindows()); - window.addEventListener("blur", __closeAllMenues); + window.addEventListener("focusin", __focusIn); + window.addEventListener("focusout", __focusOut); + window.addEventListener("resize", () => __organizeWindowsOnResize(false)); window.addEventListener("orientationchange", () => __organizeWindowsOnResize(true)); }; @@ -126,6 +126,20 @@ function Ui() { return promise; }; + self.switchDisabled = function(el, disabled) { + if (disabled && document.activeElement === el) { + var el_to_focus = ( + el.closest(".modal-window") + || el.closest(".window") + || el.closest(".menu-item-content") + ); + if (el_to_focus) { + el_to_focus.focus(); + } + } + el.disabled = disabled; + }; + self.showWindow = function(el_window, activate=true, center=false) { if (!__isWindowOnPage(el_window) || el_window.hasAttribute("data-centered") || center) { var view = self.getViewGeometry(); @@ -169,10 +183,9 @@ function Ui() { __menu_items.forEach(function(el_item) { var el_menu = el_item.parentElement.querySelector(".menu-item-content"); if (el_item === el_a && window.getComputedStyle(el_menu, null).visibility === "hidden") { - __deactivateAllWindows(); - el_item.focus(); el_item.classList.add("menu-item-selected"); el_menu.style.visibility = "visible"; + el_menu.focus(); all_hidden &= false; } else { el_item.classList.remove("menu-item-selected"); @@ -203,6 +216,30 @@ function Ui() { }); }; + var __focusIn = function(event) { + var el_parent; + if ((el_parent = event.target.closest(".modal-window")) !== null) { + el_parent.classList.add("window-active"); + } else if ((el_parent = event.target.closest(".window")) !== null) { + el_parent.classList.add("window-active"); + } else if ((el_parent = event.target.closest(".menu-item-content")) !== null) { + el_parent.classList.add("menu-item-content-active"); + } + tools.debug("Focus in:", el_parent); + }; + + var __focusOut = function(event) { + var el_parent; + if ((el_parent = event.target.closest(".modal-window")) !== null) { + el_parent.classList.remove("window-active"); + } else if ((el_parent = event.target.closest(".window")) !== null) { + el_parent.classList.remove("window-active"); + } else if ((el_parent = event.target.closest(".menu-item-content")) !== null) { + el_parent.classList.remove("menu-item-content-active"); + } + tools.debug("Focus out:", el_parent); + }; + var __globalMouseButtonHandler = function(event) { if (!event.target.matches(".menu-item")) { for (var el_item = event.target; el_item && el_item !== document; el_item = el_item.parentNode) { @@ -231,6 +268,59 @@ function Ui() { }); }; + var __activateLastWindow = function(el_except_window=null) { + var el_last_window = null; + + if (document.activeElement) { + el_last_window = (document.activeElement.closest(".modal-window") || document.activeElement.closest(".window")); + } + + if (!el_last_window || el_last_window === el_except_window) { + var max_z_index = 0; + + __windows.forEach(function(el_window) { + var z_index = parseInt(window.getComputedStyle(el_window, null).zIndex) || 0; + var visibility = window.getComputedStyle(el_window, null).visibility; + + if (max_z_index < z_index && visibility !== "hidden" && el_window !== el_except_window) { + el_last_window = el_window; + max_z_index = z_index; + } + }); + } + + if (el_last_window) { + tools.debug("Activating last window:", el_last_window); + __activateWindow(el_last_window); + } + }; + + var __activateWindow = function(el_window) { + if (window.getComputedStyle(el_window, null).visibility !== "hidden") { + var el_to_focus; + var el_window_contains_focus; + + if (el_window.className === "modal") { + el_to_focus = el_window.querySelector(".modal-window"); + el_window_contains_focus = (document.activeElement && document.activeElement.closest(".modal-window")); + } else { // .window + el_to_focus = el_window; + el_window_contains_focus = (document.activeElement && document.activeElement.closest(".window")); + } + + if (el_window.className !== "modal" && parseInt(el_window.style.zIndex) !== __top_z_index) { + __top_z_index += 1; + el_window.style.zIndex = __top_z_index; + tools.debug("UI: activated window:", el_window); + } + + if (el_window !== el_window_contains_focus) { + el_to_focus.focus(); + tools.debug("UI: focused window:", el_window); + } + } + }; + var __makeWindowMovable = function(el_window) { var el_header = el_window.querySelector(".window-header"); var el_grab = el_window.querySelector(".window-header .window-grab"); @@ -297,67 +387,5 @@ function Ui() { el_grab.ontouchstart = startMoving; }; - var __activateLastWindow = function(el_except=null) { - var el_last_window = null; - - if (document.activeElement) { - el_last_window = (document.activeElement.closest(".modal-window") || document.activeElement.closest(".window")); - } - - if (!el_last_window || el_last_window === el_except) { - var max_z_index = 0; - __windows.forEach(function(el_window) { - var z_index = parseInt(window.getComputedStyle(el_window, null).zIndex) || 0; - var visibility = window.getComputedStyle(el_window, null).visibility; - if (max_z_index < z_index && visibility !== "hidden" && el_window !== el_except) { - el_last_window = el_window; - max_z_index = z_index; - } - }); - } - - if (el_last_window) { - tools.info("Activating last window:", el_last_window); - __activateWindow(el_last_window); - } - }; - - var __activateWindow = function(el_window) { - if (window.getComputedStyle(el_window, null).visibility !== "hidden") { - var el_to_focus; - var el_window_contains_focus; - - if (el_window.className === "modal") { - el_to_focus = el_window.querySelector(".modal-window"); - el_window_contains_focus = (document.activeElement && document.activeElement.closest(".modal-window")); - } else { // .window - el_to_focus = el_window; - el_window_contains_focus = (document.activeElement && document.activeElement.closest(".window")); - } - - __deactivateAllWindows(el_to_focus); - el_to_focus.classList.add("window-active"); - - if (el_window.className !== "modal" && parseInt(el_window.style.zIndex) !== __top_z_index) { - __top_z_index += 1; - el_window.style.zIndex = __top_z_index; - tools.debug("UI: activated window:", el_window); - } - - if (el_window !== el_window_contains_focus) { - el_to_focus.focus(); - tools.debug("UI: focused window:", el_window); - } - } - }; - - var __deactivateAllWindows = function(el_except=null) { - __windows.forEach(function(el_window) { - if (el_window !== el_except) { - el_window.classList.remove("window-active"); - } - }); - }; - __init__(); } diff --git a/web/kvm/index.html b/web/kvm/index.html index bae173cd..6b67cfff 100644 --- a/web/kvm/index.html +++ b/web/kvm/index.html @@ -276,8 +276,10 @@ </li> </ul> - <div id="stream-window" class="window" style="z-index: 1" tabindex="0"> - <div id="stream-window-header" class="window-header"><div class="window-grab">Stream</div></div> + <div id="stream-window" class="window" style="z-index: 1"> + <div id="stream-window-header" class="window-header"> + <div class="window-grab">Stream</div> + </div> <div id="stream-info"></div> <div id="stream-box" class="stream-box-inactive"> <img id="stream-image" class="stream-image-inactive" src="../png/blank-stream.png" /> @@ -288,7 +290,7 @@ </div> </div> - <div id="keyboard-window" class="window" tabindex="0"> + <div id="keyboard-window" class="window"> <div id="keyboard-window-header" class="window-header"> <div class="window-grab">Virtual Keyboard</div> <button class="window-button-close">×</button> @@ -523,7 +525,7 @@ </div> </div> - <div id="about-window" class="window" tabindex="0"> + <div id="about-window" class="window"> <div class="window-header"> <div class="window-grab">About</div> <button class="window-button-close">×</button> |