intermediate: prepare for js api
This commit is contained in:
parent
09b583ebd6
commit
f6e3fa369f
Binary file not shown.
Binary file not shown.
|
@ -18,6 +18,8 @@ OWN_FILE="extra_script.py"
|
||||||
GEN_DIR='lib/generated'
|
GEN_DIR='lib/generated'
|
||||||
CFG_FILE='web/config.json'
|
CFG_FILE='web/config.json'
|
||||||
XDR_FILE='web/xdrconfig.json'
|
XDR_FILE='web/xdrconfig.json'
|
||||||
|
INDEXJS="index.js"
|
||||||
|
INDEXCSS="index.css"
|
||||||
CFG_INCLUDE='GwConfigDefinitions.h'
|
CFG_INCLUDE='GwConfigDefinitions.h'
|
||||||
CFG_INCLUDE_IMPL='GwConfigDefImpl.h'
|
CFG_INCLUDE_IMPL='GwConfigDefImpl.h'
|
||||||
XDR_INCLUDE='GwXdrTypeMappings.h'
|
XDR_INCLUDE='GwXdrTypeMappings.h'
|
||||||
|
@ -66,6 +68,7 @@ def isCurrent(infile,outfile):
|
||||||
def compressFile(inFile,outfile):
|
def compressFile(inFile,outfile):
|
||||||
if isCurrent(inFile,outfile):
|
if isCurrent(inFile,outfile):
|
||||||
return
|
return
|
||||||
|
print("compressing %s"%inFile)
|
||||||
with open(inFile, 'rb') as f_in:
|
with open(inFile, 'rb') as f_in:
|
||||||
with gzip.open(outfile, 'wb') as f_out:
|
with gzip.open(outfile, 'wb') as f_out:
|
||||||
shutil.copyfileobj(f_in, f_out)
|
shutil.copyfileobj(f_in, f_out)
|
||||||
|
@ -372,6 +375,16 @@ def getLibs():
|
||||||
rt.append(e)
|
rt.append(e)
|
||||||
return rt
|
return rt
|
||||||
|
|
||||||
|
def joinFiles(target,pattern,dirlist):
|
||||||
|
with gzip.open(target,"wb") as oh:
|
||||||
|
for dir in dirlist:
|
||||||
|
fn=os.path.join(dir,pattern)
|
||||||
|
if os.path.exists(fn):
|
||||||
|
print("adding %s to %s"%(fn,target))
|
||||||
|
with open(fn,"rb") as rh:
|
||||||
|
shutil.copyfileobj(rh,oh)
|
||||||
|
|
||||||
|
|
||||||
OWNLIBS=getLibs()+["FS","WiFi"]
|
OWNLIBS=getLibs()+["FS","WiFi"]
|
||||||
GLOBAL_INCLUDES=[]
|
GLOBAL_INCLUDES=[]
|
||||||
|
|
||||||
|
@ -440,6 +453,8 @@ def prebuild(env):
|
||||||
compressFile(mergedConfig,mergedConfig+".gz")
|
compressFile(mergedConfig,mergedConfig+".gz")
|
||||||
generateCfg(mergedConfig,os.path.join(outPath(),CFG_INCLUDE),False)
|
generateCfg(mergedConfig,os.path.join(outPath(),CFG_INCLUDE),False)
|
||||||
generateCfg(mergedConfig,os.path.join(outPath(),CFG_INCLUDE_IMPL),True)
|
generateCfg(mergedConfig,os.path.join(outPath(),CFG_INCLUDE_IMPL),True)
|
||||||
|
joinFiles(os.path.join(outPath(),INDEXJS+".gz"),INDEXJS,["web"]+userTaskDirs)
|
||||||
|
joinFiles(os.path.join(outPath(),INDEXCSS+".gz"),INDEXCSS,["web"]+userTaskDirs)
|
||||||
embedded=getEmbeddedFiles(env)
|
embedded=getEmbeddedFiles(env)
|
||||||
filedefs=[]
|
filedefs=[]
|
||||||
for ef in embedded:
|
for ef in embedded:
|
||||||
|
@ -453,7 +468,6 @@ def prebuild(env):
|
||||||
filedefs.append((pureName,usname,ct))
|
filedefs.append((pureName,usname,ct))
|
||||||
inFile=os.path.join(basePath(),"web",pureName)
|
inFile=os.path.join(basePath(),"web",pureName)
|
||||||
if os.path.exists(inFile):
|
if os.path.exists(inFile):
|
||||||
print("compressing %s"%inFile)
|
|
||||||
compressFile(inFile,ef)
|
compressFile(inFile,ef)
|
||||||
else:
|
else:
|
||||||
print("#WARNING: infile %s for %s not found"%(inFile,ef))
|
print("#WARNING: infile %s for %s not found"%(inFile,ef))
|
||||||
|
|
|
@ -351,7 +351,7 @@
|
||||||
"check": "checkMinMax",
|
"check": "checkMinMax",
|
||||||
"min": -1,
|
"min": -1,
|
||||||
"max": 256,
|
"max": 256,
|
||||||
"description": "the temp instance of PGN 130312 used for water temperature, use -1 for none, 256 for any",
|
"description": "the temp instance of PGN 130312 used for water temperature (0...255), use -1 for none, 256 for any",
|
||||||
"default": "256",
|
"default": "256",
|
||||||
"category":"converter"
|
"category":"converter"
|
||||||
},
|
},
|
||||||
|
|
|
@ -341,3 +341,6 @@ body {
|
||||||
.error{
|
.error{
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
.changed input.error{
|
||||||
|
color: red;
|
||||||
|
}
|
73
web/index.js
73
web/index.js
|
@ -1,3 +1,4 @@
|
||||||
|
(function () {
|
||||||
let self = this;
|
let self = this;
|
||||||
let lastUpdate = (new Date()).getTime();
|
let lastUpdate = (new Date()).getTime();
|
||||||
let reloadConfig = false;
|
let reloadConfig = false;
|
||||||
|
@ -5,6 +6,7 @@ let needAdminPass=true;
|
||||||
let lastSalt = "";
|
let lastSalt = "";
|
||||||
let channelList = {};
|
let channelList = {};
|
||||||
let minUser = 200;
|
let minUser = 200;
|
||||||
|
let listeners = [];
|
||||||
function addEl(type, clazz, parent, text) {
|
function addEl(type, clazz, parent, text) {
|
||||||
let el = document.createElement(type);
|
let el = document.createElement(type);
|
||||||
if (clazz) {
|
if (clazz) {
|
||||||
|
@ -238,6 +240,7 @@ function checkXDR(v,allValues){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let loggedChecks={};
|
||||||
function getAllConfigs(omitPass) {
|
function getAllConfigs(omitPass) {
|
||||||
let values = document.querySelectorAll('.configForm select , .configForm input');
|
let values = document.querySelectorAll('.configForm select , .configForm input');
|
||||||
let allValues = {};
|
let allValues = {};
|
||||||
|
@ -253,12 +256,23 @@ function getAllConfigs(omitPass) {
|
||||||
}
|
}
|
||||||
let check = v.getAttribute('data-check');
|
let check = v.getAttribute('data-check');
|
||||||
if (check) {
|
if (check) {
|
||||||
if (typeof (self[check]) === 'function') {
|
let checkFunction;
|
||||||
let res = self[check](v.value, allValues, getConfigDefition(name));
|
try{
|
||||||
|
checkFunction=eval(check);
|
||||||
|
}catch(e){}
|
||||||
|
if (typeof (checkFunction) === 'function') {
|
||||||
|
if (! loggedChecks[check]){
|
||||||
|
loggedChecks[check]=true;
|
||||||
|
console.log("check:"+check);
|
||||||
|
}
|
||||||
|
let res = checkFunction(v.value, allValues, getConfigDefition(name));
|
||||||
if (res) {
|
if (res) {
|
||||||
let value = v.value;
|
let value = v.value;
|
||||||
if (v.type === 'password') value = "******";
|
if (v.type === 'password') value = "******";
|
||||||
alert("invalid config for " + v.getAttribute('name') + "(" + value + "):\n" + res);
|
let label = v.getAttribute('data-label');
|
||||||
|
if (!label) label = v.getAttribute('name');
|
||||||
|
v.classList.add("error");
|
||||||
|
alert("invalid config for " + label + "(" + value + "):\n" + res);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -408,6 +422,7 @@ function hideOverlay() {
|
||||||
el.textContent = '';
|
el.textContent = '';
|
||||||
}
|
}
|
||||||
function checkChange(el, row, name) {
|
function checkChange(el, row, name) {
|
||||||
|
el.classList.remove("error");
|
||||||
let loaded = el.getAttribute('data-loaded');
|
let loaded = el.getAttribute('data-loaded');
|
||||||
if (loaded !== undefined) {
|
if (loaded !== undefined) {
|
||||||
if (loaded != el.value) {
|
if (loaded != el.value) {
|
||||||
|
@ -505,11 +520,13 @@ function createCalSetInput(configItem,frame,clazz){
|
||||||
window.clearInterval(caliv);
|
window.clearInterval(caliv);
|
||||||
}
|
}
|
||||||
}, 200);
|
}, 200);
|
||||||
showOverlay(cs,false,[{label:'Set',click:()=>{
|
showOverlay(cs, false, [{
|
||||||
|
label: 'Set', click: () => {
|
||||||
el.value = vel.textContent;
|
el.value = vel.textContent;
|
||||||
let cev = new Event('change');
|
let cev = new Event('change');
|
||||||
el.dispatchEvent(cev);
|
el.dispatchEvent(cev);
|
||||||
}}]);
|
}
|
||||||
|
}]);
|
||||||
})
|
})
|
||||||
el.setAttribute('name', configItem.name)
|
el.setAttribute('name', configItem.name)
|
||||||
return el;
|
return el;
|
||||||
|
@ -554,11 +571,13 @@ function createCalValInput(configItem,frame,clazz){
|
||||||
window.clearInterval(caliv);
|
window.clearInterval(caliv);
|
||||||
}
|
}
|
||||||
}, 200);
|
}, 200);
|
||||||
showOverlay(cs,false,[{label:'Set',click:()=>{
|
showOverlay(cs, false, [{
|
||||||
|
label: 'Set', click: () => {
|
||||||
el.value = vinp.value;
|
el.value = vinp.value;
|
||||||
let cev = new Event('change');
|
let cev = new Event('change');
|
||||||
el.dispatchEvent(cev);
|
el.dispatchEvent(cev);
|
||||||
}}]);
|
}
|
||||||
|
}]);
|
||||||
})
|
})
|
||||||
el.setAttribute('name', configItem.name)
|
el.setAttribute('name', configItem.name)
|
||||||
return el;
|
return el;
|
||||||
|
@ -1140,7 +1159,7 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
|
||||||
configDefinitions = defs;
|
configDefinitions = defs;
|
||||||
let currentCategoryPopulated = true;
|
let currentCategoryPopulated = true;
|
||||||
defs.forEach(function (item) {
|
defs.forEach(function (item) {
|
||||||
if (!item.type) return;
|
if (!item.type || item.category === undefined) return;
|
||||||
if (item.category.match(/^xdr/)) {
|
if (item.category.match(/^xdr/)) {
|
||||||
if (!includeXdr) return;
|
if (!includeXdr) return;
|
||||||
}
|
}
|
||||||
|
@ -1228,6 +1247,7 @@ function createConfigDefinitions(parent, capabilities, defs,includeXdr) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (item.check) valueEl.setAttribute('data-check', item.check);
|
if (item.check) valueEl.setAttribute('data-check', item.check);
|
||||||
|
valueEl.setAttribute('data-label', label);
|
||||||
let btContainer = addEl('div', 'buttonContainer', row);
|
let btContainer = addEl('div', 'buttonContainer', row);
|
||||||
if (!readOnly) {
|
if (!readOnly) {
|
||||||
let bt = addEl('button', 'defaultButton', btContainer, 'X');
|
let bt = addEl('button', 'defaultButton', btContainer, 'X');
|
||||||
|
@ -1265,6 +1285,12 @@ function loadConfigDefinitions() {
|
||||||
let el = document.getElementById('helpButton');
|
let el = document.getElementById('helpButton');
|
||||||
if (el) el.setAttribute('data-url', capabilities.HELP_URL);
|
if (el) el.setAttribute('data-url', capabilities.HELP_URL);
|
||||||
}
|
}
|
||||||
|
try{
|
||||||
|
Object.freeze(capabilities);
|
||||||
|
callListeners(api.EVENTS.capabilities,capabilities);
|
||||||
|
}catch (e){
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
getJson("config.json")
|
getJson("config.json")
|
||||||
.then(function (defs) {
|
.then(function (defs) {
|
||||||
getJson("xdrconfig.json")
|
getJson("xdrconfig.json")
|
||||||
|
@ -1861,6 +1887,26 @@ function checkImageFile(file){
|
||||||
reader.readAsArrayBuffer(slice);
|
reader.readAsArrayBuffer(slice);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
const api= {
|
||||||
|
registerListener: function (callback) {
|
||||||
|
listeners.push(callback);
|
||||||
|
},
|
||||||
|
addEl: addEl,
|
||||||
|
forEl: forEl,
|
||||||
|
closestParent: closestParent,
|
||||||
|
EVENTS: {
|
||||||
|
init: 0,
|
||||||
|
capabilities: 1, //called when capabilities are loaded
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function callListeners(event,data){
|
||||||
|
listeners.forEach((listener)=>{
|
||||||
|
if (typeof(listener) === 'function'){
|
||||||
|
listener(event,data);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
window.esp32nmea = api;
|
||||||
window.setInterval(update, 1000);
|
window.setInterval(update, 1000);
|
||||||
window.setInterval(function () {
|
window.setInterval(function () {
|
||||||
let dp = document.getElementById('dashboardPage');
|
let dp = document.getElementById('dashboardPage');
|
||||||
|
@ -1873,7 +1919,14 @@ window.addEventListener('load', function () {
|
||||||
let buttons = document.querySelectorAll('button');
|
let buttons = document.querySelectorAll('button');
|
||||||
for (let i = 0; i < buttons.length; i++) {
|
for (let i = 0; i < buttons.length; i++) {
|
||||||
let be = buttons[i];
|
let be = buttons[i];
|
||||||
be.onclick = window[be.id]; //assume a function with the button id
|
let buttonFunction=eval(be.id);
|
||||||
|
if (typeof(buttonFunction) === 'function'){
|
||||||
|
be.onclick = buttonFunction; //assume a function with the button id
|
||||||
|
console.log("button: "+be.id);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
console.log("no handler for button "+be.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
forEl('.showMsgDetails', function (cd) {
|
forEl('.showMsgDetails', function (cd) {
|
||||||
cd.addEventListener('change', function (ev) {
|
cd.addEventListener('change', function (ev) {
|
||||||
|
@ -1930,4 +1983,6 @@ window.addEventListener('load', function () {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
callListeners(api.EVENTS.init);
|
||||||
});
|
});
|
||||||
|
}());
|
Loading…
Reference in New Issue