mirror of
https://github.com/xoseperez/espurna.git
synced 2026-03-08 09:17:06 +01:00
webui(debug): local cmdoutput instance & dev log output
avoid awkward `... | null` for the console text elem member var update handlers to also clear up oldest lines when pushing new ones
This commit is contained in:
@@ -2,9 +2,13 @@ import { send, sendAction } from './connection.mjs';
|
||||
import { variableListeners } from './settings.mjs';
|
||||
|
||||
class CmdOutputBase {
|
||||
constructor() {
|
||||
/** @type {HTMLTextAreaElement | null} */
|
||||
this.elem = null;
|
||||
/** @param {HTMLTextAreaElement} elem */
|
||||
constructor(elem) {
|
||||
/** @type {HTMLTextAreaElement} */
|
||||
this.elem = elem;
|
||||
|
||||
/** @type {number} */
|
||||
this.childrenMax = 4096;
|
||||
|
||||
/** @type {number} */
|
||||
this.lastScrollHeight = 0;
|
||||
@@ -14,14 +18,13 @@ class CmdOutputBase {
|
||||
|
||||
/** @type {boolean} */
|
||||
this.followScroll = true;
|
||||
|
||||
this.attach();
|
||||
}
|
||||
|
||||
/** @param {HTMLTextAreaElement} elem */
|
||||
attach(elem) {
|
||||
this.elem = elem;
|
||||
|
||||
this.lastScrollHeight = elem.scrollHeight;
|
||||
this.lastScrollTop = elem.scrollTop;
|
||||
attach() {
|
||||
this.lastScrollHeight = this.elem.scrollHeight;
|
||||
this.lastScrollTop = this.elem.scrollTop;
|
||||
|
||||
this.elem.addEventListener("scroll", () => {
|
||||
if (!this.elem) {
|
||||
@@ -62,58 +65,64 @@ class CmdOutputBase {
|
||||
this.followScroll = true;
|
||||
}
|
||||
|
||||
clearFirst() {
|
||||
while ((this.elem.childNodes.length > this.childrenMax) && this.elem.firstChild) {
|
||||
this.elem.removeChild(this.elem.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {string} line */
|
||||
push(line) {
|
||||
this?.elem?.appendChild(new Text(line));
|
||||
this.elem.appendChild(new Text(line));
|
||||
this.clearFirst();
|
||||
}
|
||||
|
||||
/** @param {string} line */
|
||||
pushAndFollow(line) {
|
||||
this?.elem?.appendChild(new Text(`${line}\n`));
|
||||
this.followScroll = true
|
||||
this.elem.appendChild(new Text(`${line}\n`));
|
||||
this.followScroll = true;
|
||||
this.clearFirst();
|
||||
this.follow();
|
||||
}
|
||||
|
||||
/** @param {string[]} lines */
|
||||
pushLines(lines) {
|
||||
for (const line of lines) {
|
||||
this.push(line);
|
||||
}
|
||||
|
||||
this.follow();
|
||||
}
|
||||
}
|
||||
|
||||
const CmdOutput = new CmdOutputBase();
|
||||
|
||||
/**
|
||||
* @returns {import('./settings.mjs').KeyValueListeners}
|
||||
* @param {CmdOutputBase} output
|
||||
*/
|
||||
function listeners() {
|
||||
return {
|
||||
"log": (_, value) => {
|
||||
send("{}");
|
||||
function onFormSubmit(output) {
|
||||
/**
|
||||
* @param {Event} event
|
||||
*/
|
||||
return function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
for (const message of value) {
|
||||
CmdOutput.push(message);
|
||||
}
|
||||
if (!(event.target instanceof HTMLFormElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CmdOutput.follow();
|
||||
},
|
||||
const cmd = event.target.elements
|
||||
.namedItem("cmd");
|
||||
if (!(cmd instanceof HTMLInputElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const value = cmd.value;
|
||||
cmd.value = "";
|
||||
|
||||
output.pushAndFollow(value);
|
||||
sendAction("cmd", {"line": `${value}\n`});
|
||||
};
|
||||
}
|
||||
|
||||
/** @param {Event} event */
|
||||
function onFormSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
if (!(event.target instanceof HTMLFormElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cmd = event.target.elements
|
||||
.namedItem("cmd");
|
||||
if (!(cmd instanceof HTMLInputElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const value = cmd.value;
|
||||
cmd.value = "";
|
||||
|
||||
CmdOutput.pushAndFollow(value);
|
||||
sendAction("cmd", {"line": `${value}\n`});
|
||||
}
|
||||
|
||||
/**
|
||||
* While the settings are grouped using forms, actual submit is useless here
|
||||
* b/c the data is intended to be sent with the websocket connection and never through some http endpoint
|
||||
@@ -126,23 +135,30 @@ function disableFormSubmit(event) {
|
||||
}
|
||||
|
||||
export function init() {
|
||||
variableListeners(listeners());
|
||||
|
||||
const output = document.getElementById("cmd-output");
|
||||
if (output instanceof HTMLTextAreaElement) {
|
||||
CmdOutput.attach(output);
|
||||
const elem = document.getElementById("cmd-output");
|
||||
if (!(elem instanceof HTMLTextAreaElement)) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.forms.namedItem("form-debug")
|
||||
?.addEventListener("submit", onFormSubmit);
|
||||
document.querySelectorAll("form:not([name='form-debug'])")
|
||||
.forEach((form) => {
|
||||
form.addEventListener("submit", disableFormSubmit);
|
||||
});
|
||||
const output = new CmdOutputBase(elem);
|
||||
|
||||
variableListeners({
|
||||
"log": (_, value) => {
|
||||
send("{}");
|
||||
output.pushLines(value);
|
||||
},
|
||||
});
|
||||
|
||||
document.querySelector(".button-dbg-clear")
|
||||
?.addEventListener("click", (event) => {
|
||||
event.preventDefault();
|
||||
CmdOutput.clear();
|
||||
output.clear();
|
||||
});
|
||||
|
||||
document.forms.namedItem("form-debug")
|
||||
?.addEventListener("submit", onFormSubmit(output));
|
||||
document.querySelectorAll("form:not([name='form-debug'])")
|
||||
.forEach((form) => {
|
||||
form.addEventListener("submit", disableFormSubmit);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user