diff --git a/www/js/app.js b/www/js/app.js index 52522e22..e3d16181 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -58,35 +58,44 @@ function browser_is(bname) { window.onload = () => { //to check if javascript is disabled like in android preview - displayNone('loadingmsg'); - console.log('Connect to board'); + displayNone("loadingmsg"); + console.log("Connect to board"); - let connectLoaded = false; - let controlsLoaded = false; - let navbarLoaded = false; + // These are all falsey, indicating nothing has been loaded + let connectDlg = ""; + let controlsPanel = ""; + let navbarLoaded = ""; + + let failSafe = 10; let startUpInt = setInterval(() => { // Check for various key HTML panels and load them up - if (!connectLoaded && id("connectdlg.html")) { + if (!connectDlg && id("connectdlg.html")) { + connectDlg = "loading"; connectdlg(); - connectLoaded = true; + connectDlg = "loaded"; } - if (!controlsLoaded && id("controlspanel.html")) { + if (!controlsPanel && id("controlPanel")) { + controlsPanel = "loading"; ControlsPanel(); - controlsLoaded = true; + controlsPanel = "loaded"; } if (!navbarLoaded && id("navbar")) { + navbarLoaded = "loading"; navbar(); tabletInit(); - navbarLoaded = true; + navbarLoaded = "loaded"; } - if (connectLoaded && controlsLoaded && navbarLoaded) { + if ((connectDlg && controlsPanel && navbarLoaded) || failSafe <= 0) { clearInterval(startUpInt); startUpInt = null; } + + // Ensure that we always break out of this + failSafe--; }, 500); } @@ -195,7 +204,9 @@ function Set_page_title(page_title) { function initUI() { console.log('Init UI'); - if (ESP3D_authentication) connectdlg(false); + if (ESP3D_authentication) { + connectdlg(false); + } AddCmd(display_boot_progress); //initial check if (typeof target_firmware === 'undefined' || typeof web_ui_version === 'undefined' || typeof direct_sd === 'undefined') @@ -238,7 +249,7 @@ function initUI_3() { console.log('Get macros'); init_controls_panel(); init_grbl_panel(); - console.log('Get preferences') + console.log('Get preferences'); getpreferenceslist(); initUI_4(); } @@ -265,7 +276,7 @@ function initUI_4() { } function show_main_UI() { - displayUndoNone('main_ui') + displayUndoNone('main_ui'); } // var socket_response = '' diff --git a/www/js/config.js b/www/js/config.js index 85b35b1d..b745adb0 100644 --- a/www/js/config.js +++ b/www/js/config.js @@ -226,10 +226,7 @@ function get_config_value(sline) { return tline2.length > 1 ? tline2[1] : "???"; } -function get_config_help(sline) { - if (is_override_config) return ""; - return inline_help(get_config_label(sline)) -} +const get_config_help = (sline) => (is_override_config) ? "" : inline_help(get_config_label(sline)); function get_config_command(sline) { return get_config_label(sline) + "="; @@ -237,9 +234,8 @@ function get_config_command(sline) { function is_config_commented(sline) { var line = sline.trim(); - if (line.length == 0) return false; - if (is_override_config) return line.startsWith(";"); - return false; + if (!line.length) return false; + return (is_override_config) ? line.startsWith(";") : false; } function config_revert_to_default(index, is_override) { diff --git a/www/js/controls.js b/www/js/controls.js index 94e2036c..5a2b962f 100644 --- a/www/js/controls.js +++ b/www/js/controls.js @@ -1,287 +1,315 @@ -var interval_position = -1; +let interval_position = -1; var control_macrolist = []; +/** Set up the macro list for the Controls Panel */ +const init_controls_panel = () => { + loadmacrolist(); +}; -function init_controls_panel() { - loadmacrolist(); -} +/** Set up the event handlers for the Controls Panel */ +const ControlsPanel = () => { + id("autocheck_position").addEventListener("click", (event) => on_autocheck_position()); + id("controlpanel_interval_positions").addEventListener("change", (event) => onPosIntervalChange()); + + id("zero_xyz_btn").addEventListener("click", (event) => SendZerocommand(grblzerocmd)); + id("zero_x_btn").addEventListener("click", (event) => SendZerocommand("X0")); + id("zero_y_btn").addEventListener("click", (event) => SendZerocommand("Y0")); + id("zero_z_btn").addEventListener("click", (event) => SendZerocommand("Z0")); + id("zero_a_btn").addEventListener("click", (event) => SendZerocommand("A0")); + id("zero_b_btn").addEventListener("click", (event) => SendZerocommand("B0")); + id("zero_c_btn").addEventListener("click", (event) => SendZerocommand("C0")); + + id("controlpanel_xy_feedrate").addEventListener("change", (event) => onXYvelocityChange()); + id("controlpanel_z_feedrate").addEventListener("change", (event) => onZvelocityChange()); + + id("motor_off_control").addEventListener("click", (event) => control_motorsOff()); +}; function hideAxiscontrols() { - displayNone('JogBar'); - displayNone('HomeZ'); - displayBlock('CornerZ'); - displayNone('control_z_position_display'); - displayNone('control_zm_position_row'); - displayNone('z_velocity_display'); + displayNone("JogBar"); + displayNone("HomeZ"); + displayBlock("CornerZ"); + displayNone("control_z_position_display"); + displayNone("control_zm_position_row"); + displayNone("z_velocity_display"); } function showAxiscontrols() { - displayNone('CornerZ'); - displayBlock('JogBar'); - displayBlock('HomeZ'); - displayBlock('control_z_position_display'); - displayTable('control_zm_position_row'); - displayInline('z_velocity_display'); - + displayNone("CornerZ"); + displayBlock("JogBar"); + displayBlock("HomeZ"); + displayBlock("control_z_position_display"); + displayTable("control_zm_position_row"); + displayInline("z_velocity_display"); } function loadmacrolist() { - control_macrolist = []; - var url = "/macrocfg.json"; - SendGetHttp(url, processMacroGetSuccess, processMacroGetFailed); + control_macrolist = []; + var url = "/macrocfg.json"; + SendGetHttp(url, processMacroGetSuccess, processMacroGetFailed); } function Macro_build_list(response_text) { - var response = []; - try { - if (response_text.length != 0) { - response = JSON.parse(response_text); - } - } catch (e) { - console.error("Parsing error:", e); - } - for (var i = 0; i < 9; i++) { - var entry; - if ((response.length != 0) && (typeof(response[i].name) !== 'undefined' && typeof(response[i].glyph) !== 'undefined' && typeof(response[i].filename) !== 'undefined' && typeof(response[i].target) !== 'undefined' && typeof(response[i].class) !== 'undefined' && typeof(response[i].index) !== 'undefined')) { - entry = { - name: response[i].name, - glyph: response[i].glyph, - filename: response[i].filename, - target: response[i].target, - class: response[i].class, - index: response[i].index - }; - } else { - entry = { - name: '', - glyph: '', - filename: '', - target: '', - class: '', - index: i - }; - } - control_macrolist.push(entry); - } - control_build_macro_ui(); + var response = []; + try { + if (response_text.length != 0) { + response = JSON.parse(response_text); + } + } catch (e) { + console.error("Parsing error:", e); + } + for (var i = 0; i < 9; i++) { + var entry; + if ( + response.length !== 0 && + typeof response[i].name !== "undefined" && + typeof response[i].glyph !== "undefined" && + typeof response[i].filename !== "undefined" && + typeof response[i].target !== "undefined" && + typeof response[i].class !== "undefined" && + typeof response[i].index !== "undefined" + ) { + entry = { + name: response[i].name, + glyph: response[i].glyph, + filename: response[i].filename, + target: response[i].target, + class: response[i].class, + index: response[i].index + }; + } else { + entry = { + name: "", + glyph: "", + filename: "", + target: "", + class: "", + index: i + }; + } + control_macrolist.push(entry); + } + control_build_macro_ui(); } -function processMacroGetSuccess(response) { - if (response.indexOf("") == -1) Macro_build_list(response); - else Macro_build_list(""); -} +const processMacroGetSuccess = (response) => Macro_build_list(response.indexOf("") == -1 ? response : ""); function processMacroGetFailed(error_code, response) { - conErr(error_code, response); - Macro_build_list(""); + conErr(error_code, response); + Macro_build_list(""); } function on_autocheck_position(use_value) { - if (typeof(use_value) !== 'undefined') id('autocheck_position').checked = use_value; - if (id('autocheck_position').checked) { - var interval = parseInt(id('posInterval_check').value); - if (!isNaN(interval) && interval > 0 && interval < 100) { - if (interval_position != -1) clearInterval(interval_position); - interval_position = setInterval(function() { - get_Position() - }, interval * 1000); - } else { - id('autocheck_position').checked = false; - id('posInterval_check').value = 0; - if (interval_position != -1) clearInterval(interval_position); - interval_position = -1; - } - } else { - if (interval_position != -1) clearInterval(interval_position); - interval_position = -1; - } + if (typeof (use_value) !== 'undefined') { + id('autocheck_position').checked = use_value; + } + if (id('autocheck_position').checked) { + var interval = parseInt(id('controlpanel_interval_positions').value); + if (!Number.isNaN(interval) && interval > 0 && interval < 100) { + if (interval_position != -1) { + clearInterval(interval_position); + } + interval_position = setInterval(function () { get_Position() }, interval * 1000); + } else { + id('autocheck_position').checked = false; + id('controlpanel_interval_positions').value = 0; + if (interval_position != -1) { + clearInterval(interval_position); + } + interval_position = -1; + } + } else { + if (interval_position != -1) { + clearInterval(interval_position); + } + interval_position = -1; + } } function onPosIntervalChange() { - var interval = parseInt(id('posInterval_check').value); - if (!isNaN(interval) && interval > 0 && interval < 100) { - on_autocheck_position(); - } else { - id('autocheck_position').checked = false; - id('posInterval_check').value = 0; - if (interval != 0) alertdlg(translate_text_item("Out of range"), translate_text_item("Value of auto-check must be between 0s and 99s !!")); - on_autocheck_position(); - } + var interval = parseInt(id('controlpanel_interval_positions').value); + if (!Number.isNaN(interval) && interval > 0 && interval < 100) { + on_autocheck_position(); + } else { + id('autocheck_position').checked = false; + id('controlpanel_interval_positions').value = 0; + if (interval != 0) { + alertdlg(translate_text_item("Out of range"), translate_text_item("Value of auto-check must be between 0s and 99s !!")); + } + on_autocheck_position(); + } } -function get_Position() { - SendPrinterCommand("?", false, null, null, 114, 1); -} +const get_Position = () => SendPrinterCommand("?", false, null, null, 114, 1); function Control_get_position_value(label, result_data) { - var result = ""; - var pos1 = result_data.indexOf(label, 0); - if (pos1 > -1) { - pos1 += label.length; - var pos2 = result_data.indexOf(" ", pos1); - if (pos2 > -1) { - result = result_data.substring(pos1, pos2); - } else result = result_data.substring(pos1); - } - return result.trim(); + var result = ""; + var pos1 = result_data.indexOf(label, 0); + if (pos1 > -1) { + pos1 += label.length; + var pos2 = result_data.indexOf(" ", pos1); + if (pos2 > -1) { + result = result_data.substring(pos1, pos2); + } else result = result_data.substring(pos1); + } + return result.trim(); } function process_Position(response) { - grblProcessStatus(response); + grblProcessStatus(response); } function control_motorsOff() { - SendPrinterCommand("$Motors/Disable", true); + SendPrinterCommand("$Motors/Disable", true); } function SendHomecommand(cmd) { - if (id('lock_UI').checked) return; - switch (cmd) { - case 'G28': - cmd = '$H'; - break; - case 'G28 X0': - cmd = '$HX'; - break; - case 'G28 Y0': - cmd = '$HY'; - break; - - case 'G28 Z0': - if (grblaxis > 3) { - cmd = '$H' + id('control_select_axis').value; - } else cmd = '$HZ'; - break; - default: - cmd = '$H'; - break; - } - - SendPrinterCommand(cmd, true, get_Position); + if (id('lock_UI').checked) { + return; + } + switch (cmd) { + case 'G28': cmd = '$H'; break; + case 'G28 X0': cmd = '$HX'; break; + case 'G28 Y0': cmd = '$HY'; break; + case 'G28 Z0': cmd = (grblaxis > 3) ? `$H${id("control_select_axis").value}` : '$HZ'; break; + default: cmd = '$H'; break; + } + + SendPrinterCommand(cmd, true, get_Position); } function SendZerocommand(cmd) { - var command = "G10 L20 P0 " + cmd; - SendPrinterCommand(command, true, get_Position); + const command = `G10 L20 P0 ${cmd}`; + SendPrinterCommand(command, true, get_Position); +} + +const buildFeedRateValueDef = (axis) => { + return { + "valueType": "float", + "units": "mm/min", + "label": axis.startsWith("Z") ? "Z axis feedrate" : "XY axis feedrate", + "min": 0.00001, + "defValue": 1, + }; } function JogFeedrate(axis) { - const controlName = axis.startsWith("Z") ? "control_z_velocity" : "control_xy_velocity"; - const feedrateValue = Number.parseInt(id(controlName).value); - if (feedrateValue < 1 || Number.isNaN(feedrateValue) || (feedrateValue === null)) { - alertdlg(translate_text_item("Out of range"), translate_text_item("Feedrate value must be at least 1 mm/min!")); - return 1; - } - return feedrateValue; + const controlName = axis.startsWith("Z") ? "controlpanel_z_feedrate" : "controlpanel_xy_feedrate"; + const valueDef = buildFeedRateValueDef(axis); + const feedrateValue = id(controlName).value; + const errorList = valueIsFloat(feedrateValue, valueDef); + if (errorList.length) { + // error text was "Feedrate value must be at least 1 mm/min!" + alertdlg(translate_text_item("Out of range"), errorList.join("\n")); + return valueDef.defValue; + } + return Number.parseFloat(feedrateValue); } +/** This is extensively used in the jog dial SVGs */ function SendJogcommand(cmd, feedrate) { - if (id('lock_UI').checked) return; - var feedratevalue = ""; - var command = ""; - if (feedrate == "XYfeedrate") { - feedratevalue = parseInt(id('control_xy_velocity').value); - if (feedratevalue < 1 || isNaN(feedratevalue) || (feedratevalue === null)) { - alertdlg(translate_text_item("Out of range"), translate_text_item("XY Feedrate value must be at least 1 mm/min!")); - id('control_xy_velocity').value = preferenceslist[0].xy_feedrate; - return; - } - } else { - feedratevalue = parseInt(id('control_z_velocity').value); - if (feedratevalue < 1 || isNaN(feedratevalue) || (feedratevalue === null)) { - var letter = "Z"; - if (grblaxis > 3) letter = "Axis"; - alertdlg(translate_text_item("Out of range"), translate_text_item( letter +" Feedrate value must be at least 1 mm/min!")); - id('control_z_velocity').value = preferenceslist[0].z_feedrate; - return; - } - } - if(grblaxis > 3){ - var letter = id('control_select_axis').value; - cmd = cmd.replace("Z", letter); - } - command = "$J=G91 G21 F" + feedratevalue + " " + cmd; - console.log(command); - SendPrinterCommand(command, true, get_Position); + if (getChecked("lock_UI") !== "false") { + return; + } + + const controlName = feedrate.startsWith("Z") ? "controlpanel_z_feedrate" : "controlpanel_xy_feedrate"; + const prefName = feedrate.startsWith("Z") ? "z_feedrate" : "xy_feedrate"; + const valueDef = buildFeedRateValueDef(feedrate); + + let letter = "Z"; + let cmd = ""; + if (grblaxis > 3) { + letter = "Axis"; + valueDef.label = valueDef.label.replace("Z axis", letter); + cmd = cmd.replace("Z", id("control_select_axis").value); + } + + const feedrateValue = id(controlName).value; + const errorList = valueIsFloat(feedrateValue, valueDef); + + if (errorList.length) { + // error text was "(something) Feedrate value must be at least 1 mm/min!" + alertdlg(translate_text_item("Out of range"), errorList.join("\n")); + id(controlName).value = feedrate.startsWith("Z") ? preferenceslist[0].z_feedrate : preferenceslist[0].xy_feedrate ; + return; + } + + let command = `$J=G91 G21 F${feedrateValue} ${cmd}`; + console.log(command); + SendPrinterCommand(command, true, get_Position); } function onXYvelocityChange() { - var feedratevalue = parseInt(id('control_xy_velocity').value); - if (feedratevalue < 1 || feedratevalue > 9999 || isNaN(feedratevalue) || (feedratevalue === null)) { - //we could display error but we do not - } + var feedratevalue = parseFloat(id('control_xy_velocity').value); + if (feedratevalue < 1 || feedratevalue > 9999 || Number.isNaN(feedratevalue) || (feedratevalue === null)) { + //we could display error but we do not + } } function onZvelocityChange() { - var feedratevalue = parseInt(id('control_z_velocity').value); - if (feedratevalue < 1 || feedratevalue > 999 || isNaN(feedratevalue) || (feedratevalue === null)) { - //we could display error but we do not - } + var feedratevalue = parseFloat(id('control_z_velocity').value); + if (feedratevalue < 1 || feedratevalue > 999 || Number.isNaN(feedratevalue) || (feedratevalue === null)) { + //we could display error but we do not + } } function processMacroSave(answer) { - if (answer == "ok") { - //console.log("now rebuild list"); - control_build_macro_ui(); - } + if (answer == "ok") { + //console.log("now rebuild list"); + control_build_macro_ui(); + } } -function control_build_macro_button(index) { - var content = ""; - var entry = control_macrolist[index]; - content += ""; - - return content; +function control_build_macro_button(index, entry) { + const noGlyph = entry.glyph.length === 0; + const btnStyle = noGlyph ? " style='display:none'" : ""; + const entryIcon = get_icon_svg(noGlyph ? "star" : entry.glyph); + + let content = `"; + + return content; } function control_build_macro_ui() { - var content = "
"; - content += "Manage macros" - content += ""; - content += "
"; - for (var i = 0; i < 9; i++) { - content += control_build_macro_button(i); - } - id('Macro_list').innerHTML = content; + const actions = []; + + var content = "
"; + content += "Manage macros" + content += ""; + content += "
"; + for (var i = 0; i < 9; i++) { + const entry = control_macrolist[i]; + content += control_build_macro_button(i, entry); + actions.push({ id: `control_macro_${i}`, type: "click", method: (event) => macro_command(entry.target, entry.filename) }); + } + id("Macro_list").innerHTML = content; + actions.forEach((action) => { + id(action.id).addEventListener(action.type, (event) => action.method); + }); } function macro_command(target, filename) { - var cmd = "" - if (target == "ESP") { - cmd = "$LocalFS/Run=" + filename; - } else if (target == "SD") { - files_print_filename(filename); - } else if (target == "URI") { - window.open(filename); - } else return; - //console.log(cmd); - SendPrinterCommand(cmd); + switch (target) { + case "ESP": SendPrinterCommand(`$LocalFS/Run=${filename}`); break; + case "SD": files_print_filename(filename); break; + case "URI": window.open(filename); break; + default: break; // do nothing + } } diff --git a/www/js/grblpanel.js b/www/js/grblpanel.js index 252ece0c..65b1fe1b 100644 --- a/www/js/grblpanel.js +++ b/www/js/grblpanel.js @@ -30,8 +30,8 @@ const grblpanel = () => { id("grblpanel_flood").addEventListener("click", (event) => SendRealtimeCmd(0xa0)); id("grblpanel_mist").addEventListener("click", (event) => SendRealtimeCmd(0xa1)); - id("grblspindle_fwd").addEventListener("click", (event) => SendPrinterCommand(`M3 S${common.spindleTabSpindleSpeed}`, false, null, null, 1, 1,)); - id("grblspindle_rew").addEventListener("click", (event) => SendPrinterCommand(`M4 S${common.spindleTabSpindleSpeed}`, false, null, null, 1, 1,)); + id("grblspindle_fwd").addEventListener("click", (event) => SendPrinterCommand(`M3 S${spindleTabSpindleSpeed}`, false, null, null, 1, 1,)); + id("grblspindle_rew").addEventListener("click", (event) => SendPrinterCommand(`M4 S${spindleTabSpindleSpeed}`, false, null, null, 1, 1,)); id("grblspindle_off").addEventListener("click", (event) => SendPrinterCommand("M5 S0", false, null, null, 1, 1)); id("grblspindle_rpm").addEventListener("change", (event) => setSpindleSpeed(event.value)); id("grblspindle_rpm").addEventListener("keyup", (event) => setSpindleSpeed(event.value)); diff --git a/www/js/http.js b/www/js/http.js index a982839c..410bb898 100644 --- a/www/js/http.js +++ b/www/js/http.js @@ -80,8 +80,7 @@ function AddCmd(cmd_fn, id) { http_errorfn(999, translate_text_item("Server not responding")); return; } - var cmd_id = 0; - if (typeof id != 'undefined') cmd_id = id; + const cmd_id = (typeof id !== 'undefined') ? id : 0; //console.log("adding command"); var cmd = { cmd: cmd_fn, diff --git a/www/js/preferencesdlg.js b/www/js/preferencesdlg.js index b7487fd9..cfd56166 100644 --- a/www/js/preferencesdlg.js +++ b/www/js/preferencesdlg.js @@ -289,13 +289,13 @@ function applypreferenceslist() { } id('preferences_pos_Interval_check').value = Number.parseInt(preferenceslist[0].interval_positions); - id('preferences_control_xy_velocity').value = Number.parseInt(preferenceslist[0].xy_feedrate); - id('preferences_control_z_velocity').value = Number.parseInt(preferenceslist[0].z_feedrate); + id('preferences_control_xy_velocity').value = Number.parseFloat(preferenceslist[0].xy_feedrate); + id('preferences_control_z_velocity').value = Number.parseFloat(preferenceslist[0].z_feedrate); - if (grblaxis > 2) axis_Z_feedrate = Number.parseInt(preferenceslist[0].z_feedrate); - if (grblaxis > 3) axis_A_feedrate = Number.parseInt(preferenceslist[0].a_feedrate); - if (grblaxis > 4) axis_B_feedrate = Number.parseInt(preferenceslist[0].b_feedrate); - if (grblaxis > 5) axis_C_feedrate = Number.parseInt(preferenceslist[0].c_feedrate); + if (grblaxis > 2) axis_Z_feedrate = Number.parseFloat(preferenceslist[0].z_feedrate); + if (grblaxis > 3) axis_A_feedrate = Number.parseFloat(preferenceslist[0].a_feedrate); + if (grblaxis > 4) axis_B_feedrate = Number.parseFloat(preferenceslist[0].b_feedrate); + if (grblaxis > 5) axis_C_feedrate = Number.parseFloat(preferenceslist[0].c_feedrate); if (grblaxis > 3) { const letter = id('control_select_axis').value; @@ -316,7 +316,7 @@ function applypreferenceslist() { } id('preferences_probemaxtravel').value = Number.parseFloat(preferenceslist[0].probemaxtravel); - id('preferences_probefeedrate').value = Number.parseInt(preferenceslist[0].probefeedrate); + id('preferences_probefeedrate').value = Number.parseFloat(preferenceslist[0].probefeedrate); id('preferences_proberetract').value = Number.parseFloat(preferenceslist[0].proberetract); id('preferences_probetouchplatethickness').value = Number.parseFloat(preferenceslist[0].probetouchplatethickness); build_file_filter_list(preferenceslist[0].f_filters); @@ -405,31 +405,31 @@ function build_dlg_preferences_list() { } else id('preferences_status_Interval_check').value = Number.parseInt(default_preferenceslist[0].interval_status); //xy feedrate if (typeof (preferenceslist[0].xy_feedrate) !== 'undefined') { - id('preferences_control_xy_velocity').value = Number.parseInt(preferenceslist[0].xy_feedrate); - } else id('preferences_control_xy_velocity').value = Number.parseInt(default_preferenceslist[0].xy_feedrate); + id('preferences_control_xy_velocity').value = Number.parseFloat(preferenceslist[0].xy_feedrate); + } else id('preferences_control_xy_velocity').value = Number.parseFloat(default_preferenceslist[0].xy_feedrate); if (grblaxis > 2) { //z feedrate if (typeof (preferenceslist[0].z_feedrate) !== 'undefined') { - id('preferences_control_z_velocity').value = Number.parseInt(preferenceslist[0].z_feedrate); - } else id('preferences_control_z_velocity').value = Number.parseInt(default_preferenceslist[0].z_feedrate); + id('preferences_control_z_velocity').value = Number.parseFloat(preferenceslist[0].z_feedrate); + } else id('preferences_control_z_velocity').value = Number.parseFloat(default_preferenceslist[0].z_feedrate); } if (grblaxis > 3) { //a feedrate if (typeof (preferenceslist[0].a_feedrate) !== 'undefined') { - id('preferences_control_a_velocity').value = Number.parseInt(preferenceslist[0].a_feedrate); - } else id('preferences_control_a_velocity').value = Number.parseInt(default_preferenceslist[0].a_feedrate); + id('preferences_control_a_velocity').value = Number.parseFloat(preferenceslist[0].a_feedrate); + } else id('preferences_control_a_velocity').value = Number.parseFloat(default_preferenceslist[0].a_feedrate); } if (grblaxis > 4) { //b feedrate if (typeof (preferenceslist[0].b_feedrate) !== 'undefined') { - id('preferences_control_b_velocity').value = Number.parseInt(preferenceslist[0].b_feedrate); - } else id('preferences_control_b_velocity').value = Number.parseInt(default_preferenceslist[0].b_feedrate); + id('preferences_control_b_velocity').value = Number.parseFloat(preferenceslist[0].b_feedrate); + } else id('preferences_control_b_velocity').value = Number.parseFloat(default_preferenceslist[0].b_feedrate); } if (grblaxis > 5) { //c feedrate if (typeof (preferenceslist[0].c_feedrate) !== 'undefined') { - id('preferences_control_c_velocity').value = Number.parseInt(preferenceslist[0].c_feedrate); - } else id('preferences_control_c_velocity').value = Number.parseInt(default_preferenceslist[0].c_feedrate); + id('preferences_control_c_velocity').value = Number.parseFloat(preferenceslist[0].c_feedrate); + } else id('preferences_control_c_velocity').value = Number.parseFloat(default_preferenceslist[0].c_feedrate); } //probemaxtravel @@ -440,8 +440,8 @@ function build_dlg_preferences_list() { } //probefeedrate if ((typeof (preferenceslist[0].probefeedrate) !== 'undefined') && (preferenceslist[0].probefeedrate.length !== 0)) { - id('preferences_probefeedrate').value = Number.parseInt(preferenceslist[0].probefeedrate); - } else id('preferences_probefeedrate').value = Number.parseInt(default_preferenceslist[0].probefeedrate); + id('preferences_probefeedrate').value = Number.parseFloat(preferenceslist[0].probefeedrate); + } else id('preferences_probefeedrate').value = Number.parseFloat(default_preferenceslist[0].probefeedrate); //proberetract if ((typeof (preferenceslist[0].proberetract) !== 'undefined') && (preferenceslist[0].proberetract.length !== 0)) { id('preferences_proberetract').value = Number.parseFloat(preferenceslist[0].proberetract); @@ -544,22 +544,22 @@ function closePreferencesDialog() { //interval status if (id('preferences_status_Interval_check').value !== Number.parseInt(preferenceslist[0].interval_status)) modified = true; //xy feedrate - if (id('preferences_control_xy_velocity').value !== Number.parseInt(preferenceslist[0].xy_feedrate)) modified = true; + if (id('preferences_control_xy_velocity').value !== Number.parseFloat(preferenceslist[0].xy_feedrate)) modified = true; if (grblaxis > 2) { //z feedrate - if (id('preferences_control_z_velocity').value !== Number.parseInt(preferenceslist[0].z_feedrate)) modified = true; + if (id('preferences_control_z_velocity').value !== Number.parseFloat(preferenceslist[0].z_feedrate)) modified = true; } if (grblaxis > 3) { //a feedrate - if (id('preferences_control_a_velocity').value !== Number.parseInt(preferenceslist[0].a_feedrate)) modified = true; + if (id('preferences_control_a_velocity').value !== Number.parseFloat(preferenceslist[0].a_feedrate)) modified = true; } if (grblaxis > 4) { //b feedrate - if (id('preferences_control_b_velocity').value !== Number.parseInt(preferenceslist[0].b_feedrate)) modified = true; + if (id('preferences_control_b_velocity').value !== Number.parseFloat(preferenceslist[0].b_feedrate)) modified = true; } if (grblaxis > 5) { //c feedrate - if (id('preferences_control_c_velocity').value !== Number.parseInt(preferenceslist[0].c_feedrate)) modified = true; + if (id('preferences_control_c_velocity').value !== Number.parseFloat(preferenceslist[0].c_feedrate)) modified = true; } } //autoscroll @@ -571,7 +571,7 @@ function closePreferencesDialog() { //probemaxtravel if (id('preferences_probemaxtravel').value !== Number.parseFloat(preferenceslist[0].probemaxtravel)) modified = true; //probefeedrate - if (id('preferences_probefeedrate').value !== Number.parseInt(preferenceslist[0].probefeedrate)) modified = true; + if (id('preferences_probefeedrate').value !== Number.parseFloat(preferenceslist[0].probefeedrate)) modified = true; //proberetract if (id('preferences_proberetract').value !== Number.parseFloat(preferenceslist[0].proberetract)) modified = true; //probetouchplatethickness @@ -725,51 +725,51 @@ function Checkvalues(id_2_check) { } break; case "preferences_control_xy_velocity": - value = Number.parseInt(id(id_2_check).value); - if (!(!Number.isNaN(value) && value >= 1)) { - error_message = translate_text_item("XY Feedrate value must be at least 1 mm/min!"); + value = Number.parseFloat(id(id_2_check).value); + if (!(!Number.isNaN(value) && value >= 0.00001)) { + error_message = translate_text_item("XY Feedrate value must be at least 0.00001 mm/min!"); status = false; } break; case "preferences_control_z_velocity": - value = Number.parseInt(id(id_2_check).value); - if (!(!Number.isNaN(value) && value >= 1)) { - error_message = translate_text_item("Z Feedrate value must be at least 1 mm/min!"); + value = Number.parseFloat(id(id_2_check).value); + if (!(!Number.isNaN(value) && value >= 0.00001)) { + error_message = translate_text_item("Z Feedrate value must be at least 0.00001 mm/min!"); status = false; } break; case "preferences_control_a_velocity": case "preferences_control_b_velocity": case "preferences_control_c_velocity": - value = Number.parseInt(id(id_2_check).value); - if (!(!Number.isNaN(value) && value >= 1)) { - error_message = translate_text_item("Axis Feedrate value must be at least 1 mm/min!"); + value = Number.parseFloat(id(id_2_check).value); + if (!(!Number.isNaN(value) && value >= 0.00001)) { + error_message = translate_text_item("Axis Feedrate value must be at least 0.00001 mm/min!"); status = false; } break; case "preferences_probefeedrate": - value = Number.parseInt(id(id_2_check).value); - if (!(!Number.isNaN(value) && value >= 1 && value <= 9999)) { - error_message = translate_text_item("Value of probe feedrate must be between 1 mm/min and 9999 mm/min !"); + value = Number.parseFloat(id(id_2_check).value); + if (!(!Number.isNaN(value) && value >= 0.00001 && value <= 9999)) { + error_message = translate_text_item("Value of probe feedrate must be between 0.00001 mm/min and 9999 mm/min !"); status = false; } break; case "preferences_probemaxtravel": - value = Number.parseInt(id(id_2_check).value); - if (!(!Number.isNaN(value) && value >= 1 && value <= 9999)) { - error_message = translate_text_item("Value of maximum probe travel must be between 1 mm and 9999 mm !"); + value = Number.parseFloat(id(id_2_check).value); + if (!(!Number.isNaN(value) && value >= 0.00001 && value <= 9999)) { + error_message = translate_text_item("Value of maximum probe travel must be between 0.00001 mm and 9999 mm !"); status = false; } break; case "preferences_proberetract": - value = Number.parseInt(id(id_2_check).value); + value = Number.parseFloat(id(id_2_check).value); if (!(!Number.isNaN(value) && value >= 0 && value <= 9999)) { error_message = translate_text_item("Value of probe retract must be between 0 mm and 9999 mm !"); status = false; } break; case "preferences_probetouchplatethickness": - value = Number.parseInt(id(id_2_check).value); + value = Number.parseFloat(id(id_2_check).value); if (!(!Number.isNaN(value) && value >= 0 && value <= 9999)) { error_message = translate_text_item("Value of probe touch plate thickness must be between 0 mm and 9999 mm !"); status = false; diff --git a/www/js/scanwifidlg.js b/www/js/scanwifidlg.js index aacdd869..3e832717 100644 --- a/www/js/scanwifidlg.js +++ b/www/js/scanwifidlg.js @@ -83,9 +83,9 @@ function process_scanWifi_answer(response_text) { } setHTML("AP_scan_data", content); - for(const action in actions) { + actions.forEach((action) => { id(action.id).addEventListener(action.type, (event) => action.method); - }; + }); return result; } diff --git a/www/js/utilValidation.js b/www/js/utilValidation.js new file mode 100644 index 00000000..95123a4e --- /dev/null +++ b/www/js/utilValidation.js @@ -0,0 +1,110 @@ +// For all of the following `valueDef` is the following structure +/* +{ + "defValue" - (optional) the default value + "valueType" - (required) the value type, one of "int", "float", "bool", "text", "enctext", "select", "panel" + "units" - (optinal) a very short name/description of the relevant units for the value + "label" - (required) The correct name/title/label of the value + "inpClass" - (optional) A boostrap class for the values presentation + "min" - (optional) A minimum (inclusive) for the value + "max" - (optional) A maximum (inclusive) for the value +}, +*/ + +/** Test the supplied numeric value against any defined `min` test (inclusive), + * success is an empty string, + * failure is an error message */ +const valueMinTest = (value, valueDef) => { + return "min" in valueDef && value < valueDef.min + ? `'${valueDef.label}' ${translate_text_item("must be greater than or equal to")} ${valueDef.min}` + : ""; +}; + +/** Test the supplied numeric value against any defined `max` test (inclusive), + * success is an empty string, + * failure is an error message */ +const valueMaxTest = (value, valueDef) => { + return "max" in valueDef && value > valueDef.max + ? `'${valueDef.label}' ${translate_text_item("must be less than or equal to")} ${valueDef.max}` + : ""; +}; + +/** Test whether a value is an integer, and optionally within a certain range, + * success is an empty array, + * failure is an array of one or more error messages */ +const valueIsInt = (value, valueDef) => { + const errorList = []; + const vInt = Number.parseInt(value); + if (Number.isNaN(vInt)) { + errorList.push(`'${valueDef.label}' ${translate_text_item("must be an integer")}`); + } else { + errorList.push(valueMinTest(vInt, valueDef)); + errorList.push(valueMaxTest(vInt, valueDef)); + } + return errorList.filter((err) => err); +} + +/** Test whether a value is an float, and optionally within a certain range, + * success is an empty array, + * failure is an array of one or more error messages */ +const valueIsFloat = (value, valueDef) => { + const errorList = []; + const vFloat = Number.parseFloat(value); + if (Number.isNaN(vFloat)) { + errorList.push(`'${valueDef.label}' ${translate_text_item("must be a float")}`); + } else { + errorList.push(valueMinTest(vFloat, valueDef)); + errorList.push(valueMaxTest(vFloat, valueDef)); + } + return errorList.filter((err) => err); +} + +/** Test whether a value is a boolean, or text that says 'true' or 'false', + * NOTE: This does NOT specifically test if a value is truthy or falsey + * success is an empty array, + * failure is an array of one error messages */ +const valueIsBool = (value, valueDef) => { + return (typeof value === "boolean" || (typeof value === "string" && ["true", "false"].includes(value.toLocaleLowerCase()))) + ? [] + : `'${valueDef.label}' ${translate_text_item("must be a boolean, or 'true' or 'false'")}`; +} + +/** Test whether a value is text, + * success is an empty array, + * failure is an array of one error messages */ +const valueIsText = (value, valueDef) => { + return (typeof value === "string") + ? [] + : `'${valueDef.label}' ${translate_text_item("must be a string")}`; +} + +/** Checks a supplied value against the supplied valueDef, + * success is an empty array, + * failure is an array of one or more error messages */ +const checkValue = (value, valueDef, errorList = []) => { + switch (valueDef.valueType) { + case "int": errorList.push(valueIsInt(value, valueDef)); break; + case "float": errorList.push(valueIsFloat(value, valueDef)); break; + case "panel": + case "bool": + // These are both boolean values + errorList.push(valueIsBool(value, valueDef)); + break; + case "enctext": + case "text": + // These are both text string + errorList.push(valueIsText(value, valueDef)); + break; + case "select": + // This is effectively an enum - no specific test for this yet + break; + default: + const valueDefError = `'${valueDef.label}' ${translate_text_item("is an unknown value type")} '${valueDef.valueType}'`; + console.error(`${valueDefError}: ${JSON.stringify(value)}`); + errorList.push(valueDefError); + break; + } + return errorList.filter((err) => err); +} + +// export { checkValue, valueIsFloat }; diff --git a/www/sub/controlspanel.html b/www/sub/controlspanel.html index 528bee5f..643176af 100644 --- a/www/sub/controlspanel.html +++ b/www/sub/controlspanel.html @@ -12,8 +12,7 @@    @@ -22,8 +21,8 @@ @@ -47,22 +46,20 @@
- +

-
+
- + sec
@@ -75,9 +72,10 @@
- + - X:  + + X:  +
- Xm:  + + Xm:  +
@@ -89,13 +87,12 @@ @@ -108,9 +105,10 @@
- + - Y:  + + Y:  +
- Ym:  + + Ym:  +
@@ -118,12 +116,11 @@ -
+
@@ -151,18 +148,18 @@
-
-
+
+
- +
- Zm: + Zm: 
@@ -175,9 +172,10 @@
- + - Aw:  + + Aw:  +
- Am:  + + Am:  +
@@ -185,17 +183,17 @@
-
+
@@ -208,9 +206,10 @@
- + - Bw:  + + Bw:  +
- Bm:  + + Bm:  +
@@ -222,13 +221,13 @@ @@ -241,7 +240,8 @@
- + Cw:  + id="control_c_position">  +
Cm:  + id="control_cm_position">  +
@@ -262,8 +262,7 @@ - + mm/min @@ -273,23 +272,21 @@ -
- Z: + Z: + - + mm/min
  - +
\ No newline at end of file