webui: expected emon app keys leaking into settings

disable on-change listener for webui-only inputs
also assuming input[readonly]s never needs to be commited
This commit is contained in:
Maxim Prokhorov
2024-08-09 14:25:06 +03:00
parent c4c31fc5f0
commit 29787143bf
4 changed files with 48 additions and 11 deletions

View File

@@ -12,6 +12,7 @@ import {
prepareEnumerableTarget,
resetGroupElement,
setChangedElement,
setIgnoredElement,
setOriginalFromValue,
setSelectValue,
variableListeners,
@@ -428,6 +429,7 @@ function initMagnitudesExpected(id) {
expected.name += info.key;
expected.id = expected.name;
expected.dataset["id"] = info.id.toString();
setIgnoredElement(expected);
const [message] = /** @type {NodeListOf<HTMLSpanElement>} */
(template.querySelectorAll(`span.emon-expected-${info.prefix}`));

View File

@@ -54,7 +54,7 @@ export function resetChangedElement(elem) {
* @param {HTMLElement} elem
*/
function resetGroupPending(elem) {
elem.dataset["settingsGroupPending"] = "";
delete elem.dataset["settingsGroupPending"];
}
// Right now, group additions happen from:
@@ -137,16 +137,34 @@ export function resetGroupElement(elem) {
/**
* @param {HTMLElement} elem
* @returns {boolean}
*/
export function isGroupElement(elem) {
return elem.dataset[SETTINGS_GROUP_ELEMENT] !== undefined;
}
const SETTINGS_IGNORED_ELEMENT = "settingsIgnore";
/**
* @param {HTMLElement} elem
*/
function isIgnoredElement(elem) {
return elem.dataset["settingsIgnore"] !== undefined;
export function setIgnoredElement(elem) {
elem.dataset[SETTINGS_IGNORED_ELEMENT] = "true";
}
/**
* @param {HTMLElement} elem
*/
export function resetIgnoredElement(elem) {
delete elem.dataset[SETTINGS_IGNORED_ELEMENT];
}
/**
* @param {HTMLElement} elem
* @returns {boolean}
*/
export function isIgnoredElement(elem) {
return elem.dataset[SETTINGS_IGNORED_ELEMENT] !== undefined;
}
/**
@@ -432,6 +450,22 @@ function groupSettingsCleanup(container, keys) {
* @typedef {{[k: string]: DataValue}} SetRequest
*/
/**
* @param {string | number |boolean} value
* @returns {DataValue}
*/
function maybeAdjustDataValue(value) {
if (typeof value === "boolean") {
return value ? 1 : 0;
}
if (typeof value === "number" && isNaN(value)) {
return "nan";
}
return value;
}
/**
* specific 'key' string to remove from the device settings storage
* @typedef {string} DelRequest
@@ -478,6 +512,10 @@ export function getData(forms, {cleanup = true, assumeChanged = false} = {}) {
continue;
}
if (elem instanceof HTMLInputElement && elem.readOnly) {
continue;
}
const name = elem.dataset["settingsRealName"] || elem.name;
if (!name) {
continue;
@@ -506,11 +544,8 @@ export function getData(forms, {cleanup = true, assumeChanged = false} = {}) {
const data_name = group_element
? group_name : name;
// TODO small value optimization, so booleans always take 1 byte in the resulting json
const data_value = (typeof value === "boolean")
? (value ? 1 : 0) : value;
data[data_name] = data_value;
// fixing outgoing data, when it is necessary
data[data_name] = maybeAdjustDataValue(value);
}
}
}

View File

@@ -28,7 +28,7 @@
</div>
<div class="pure-control-group">
<label>Expected value</label>
<input name="expected:" type="text" class="emon-expected-input">
<input name="expected:" type="text" class="emon-expected-input" data-action="none">
<span class="pure-form-message-inline hidden emon-expected-pwrP">
In Watts (W). Calibrate your sensor connecting a pure resistive load (like a bulb) and enter here its nominal power or use a multimeter.
</span>

View File

@@ -1,4 +1,4 @@
import { isChangedElement, getElements } from './settings.mjs';
import { isChangedElement, isIgnoredElement, getElements } from './settings.mjs';
import { showPanel } from './core.mjs';
import {
formPassPair,
@@ -126,7 +126,7 @@ export function validateFormsPasswords(forms, {strict = true, assumeChanged = fa
export function validateFormsReportValidity(forms) {
const elems = forms
.flatMap((form) => getElements(form))
.filter(isChangedElement)
.filter((x) => isChangedElement(x) && !isIgnoredElement(x))
if (!elems.length) {
return false;