6.5.0.14 Webserver HTML/Javascript changes

6.5.0.14 20190602
 * Change webserver HTML input, button, textarea, and select name based on id
 * Fix webserver multiple Javascript window.onload functionality
This commit is contained in:
Theo Arends 2019-06-02 16:44:02 +02:00
parent bb3fb7c4d6
commit ffd36e0b2d
5 changed files with 62 additions and 31 deletions

View File

@ -1,4 +1,8 @@
/* 6.5.0.13 20190527 /* 6.5.0.14 20190602
* Change webserver HTML input, button, textarea, and select name based on id
* Fix webserver multiple Javascript window.onload functionality
*
* 6.5.0.13 20190527
* Add command SetOption38 6..255 to set IRReceive protocol detection sensitivity mimizing UNKNOWN protocols (#5853) * Add command SetOption38 6..255 to set IRReceive protocol detection sensitivity mimizing UNKNOWN protocols (#5853)
* Fix missing white channel for WS2812 (#5869) * Fix missing white channel for WS2812 (#5869)
* Add reset of Energy values when connection to sensor is lost for over 4 seconds (#5874, #5881) * Add reset of Energy values when connection to sensor is lost for over 4 seconds (#5874, #5881)

View File

@ -20,6 +20,6 @@
#ifndef _SONOFF_VERSION_H_ #ifndef _SONOFF_VERSION_H_
#define _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_
const uint32_t VERSION = 0x0605000D; const uint32_t VERSION = 0x0605000E;
#endif // _SONOFF_VERSION_H_ #endif // _SONOFF_VERSION_H_

View File

@ -58,13 +58,24 @@ const char HTTP_HEAD[] PROGMEM =
"function eb(s){" "function eb(s){"
"return document.getElementById(s);" // Save code space "return document.getElementById(s);" // Save code space
"}" "}"
"function qs(s){" // Alias to save code space "function qs(s){" // Alias to save code space
"return document.querySelector(s);" "return document.querySelector(s);"
"}" "}"
"function idn(){"
"var t=0,i=document.querySelectorAll('input,button,textarea,select'); while(i.length>=t){ if(i[t]) {i[t]['name']=(i[t].hasAttribute('id')&&(!i[t].hasAttribute('name')))?i[t]['id']:i[t]['name'];}t++;}" // https://www.htmlgoodies.com/beyond/javascript/article.php/3724571/Using-Multiple-JavaScript-Onload-Functions.htm
"}" "function wl(f){" // Execute multiple window.onload
"window.onload=idn;idn();"; "var o=window.onload;"
"if(typeof window.onload!='function'){"
"window.onload=f;"
"}else{"
"window.onload=function(){"
"if(o){"
"o();"
"}"
"f();"
"}"
"}"
"}";
const char HTTP_SCRIPT_COUNTER[] PROGMEM = const char HTTP_SCRIPT_COUNTER[] PROGMEM =
"var cn=180;" // seconds "var cn=180;" // seconds
@ -75,7 +86,7 @@ const char HTTP_SCRIPT_COUNTER[] PROGMEM =
"setTimeout(u,1000);" "setTimeout(u,1000);"
"}" "}"
"}" "}"
"window.onload=u;"; "wl(u);";
const char HTTP_SCRIPT_ROOT[] PROGMEM = const char HTTP_SCRIPT_ROOT[] PROGMEM =
"function la(p){" "function la(p){"
@ -102,7 +113,7 @@ const char HTTP_SCRIPT_ROOT[] PROGMEM =
"function lc(p){" "function lc(p){"
"la('&t='+p);" // &t related to WebGetArg("t", tmp, sizeof(tmp)); "la('&t='+p);" // &t related to WebGetArg("t", tmp, sizeof(tmp));
"}" "}"
"window.onload=la();"; "wl(la);";
const char HTTP_SCRIPT_WIFI[] PROGMEM = const char HTTP_SCRIPT_WIFI[] PROGMEM =
"function c(l){" "function c(l){"
@ -152,7 +163,7 @@ const char HTTP_SCRIPT_CONSOL[] PROGMEM =
"lt=setTimeout(l,%d);" "lt=setTimeout(l,%d);"
"return false;" "return false;"
"}" "}"
"window.onload=l;"; "wl(l);";
const char HTTP_MODULE_TEMPLATE_REPLACE[] PROGMEM = const char HTTP_MODULE_TEMPLATE_REPLACE[] PROGMEM =
"}2%d'>%s (%d}3"; // }2 and }3 are used in below os.replace "}2%d'>%s (%d}3"; // }2 and }3 are used in below os.replace
@ -218,7 +229,10 @@ const char HTTP_SCRIPT_TEMPLATE[] PROGMEM =
"sk(17,99);" // 17 = WEMOS "sk(17,99);" // 17 = WEMOS
"st(" STR(USER_MODULE) ");" "st(" STR(USER_MODULE) ");"
"}" "}"
"window.onload=ld('tp?m=1',x2);"; // ?m related to WebServer->hasArg("m") "function sl(){"
"ld('tp?m=1',x2);" // ?m related to WebServer->hasArg("m")
"}"
"wl(sl);";
const char HTTP_SCRIPT_MODULE1[] PROGMEM = const char HTTP_SCRIPT_MODULE1[] PROGMEM =
"function x1(a){" // Module Type "function x1(a){" // Module Type
@ -240,7 +254,7 @@ const char HTTP_SCRIPT_MODULE2[] PROGMEM =
"ld('md?a=1',x3);" // ?a related to WebServer->hasArg("a") "ld('md?a=1',x3);" // ?a related to WebServer->hasArg("a")
"}" "}"
"}" "}"
"window.onload=sl;"; "wl(sl);";
const char HTTP_SCRIPT_INFO_BEGIN[] PROGMEM = const char HTTP_SCRIPT_INFO_BEGIN[] PROGMEM =
"function i(){" "function i(){"
@ -250,11 +264,22 @@ const char HTTP_SCRIPT_INFO_END[] PROGMEM =
"s=o.replace(/}1/g,\"</td></tr><tr><th>\").replace(/}2/g,\"</th><td>\");" "s=o.replace(/}1/g,\"</td></tr><tr><th>\").replace(/}2/g,\"</th><td>\");"
"eb('i').innerHTML=s;" "eb('i').innerHTML=s;"
"}" "}"
"window.onload=i;"; "wl(i);";
const char HTTP_HEAD_LAST_SCRIPT[] PROGMEM =
"function id(){" // Add label name='' based on provided id=''
"var t=0,i=document.querySelectorAll('input,button,textarea,select');"
"while(i.length>=t){"
"if(i[t]){"
"i[t]['name']=(i[t].hasAttribute('id')&&(!i[t].hasAttribute('name')))?i[t]['id']:i[t]['name'];"
"}"
"t++;"
"}"
"}"
"wl(id);" // Add name='' to any id='' in input,button,textarea,select
"</script>";
const char HTTP_HEAD_STYLE1[] PROGMEM = const char HTTP_HEAD_STYLE1[] PROGMEM =
"</script>"
"<style>" "<style>"
"div,fieldset,input,select{padding:5px;font-size:1em;}" "div,fieldset,input,select{padding:5px;font-size:1em;}"
"fieldset{background:#%06x;}" // COLOR_FORM, Also update HTTP_TIMER_STYLE "fieldset{background:#%06x;}" // COLOR_FORM, Also update HTTP_TIMER_STYLE
@ -322,7 +347,7 @@ const char HTTP_FORM_TEMPLATE_FLAG[] PROGMEM =
const char HTTP_FORM_MODULE[] PROGMEM = const char HTTP_FORM_MODULE[] PROGMEM =
"<fieldset><legend><b>&nbsp;" D_MODULE_PARAMETERS "&nbsp;</b></legend>" "<fieldset><legend><b>&nbsp;" D_MODULE_PARAMETERS "&nbsp;</b></legend>"
"<form method='get' action='md'>" "<form method='get' action='md'>"
"<p></p><b>" D_MODULE_TYPE "</b> (%s)<br><select id='g99' name='g99'></select><br>" "<p></p><b>" D_MODULE_TYPE "</b> (%s)<br><select id='g99'></select><br>"
"<br><table>"; "<br><table>";
const char HTTP_FORM_WIFI[] PROGMEM = const char HTTP_FORM_WIFI[] PROGMEM =
@ -725,6 +750,8 @@ void WSContentSendStyle_P(const char* formatP, ...)
WSContentSend_P(HTTP_SCRIPT_COUNTER); WSContentSend_P(HTTP_SCRIPT_COUNTER);
} }
} }
WSContentSend_P(HTTP_HEAD_LAST_SCRIPT);
WSContentSend_P(HTTP_HEAD_STYLE1, WebColor(COL_FORM), WebColor(COL_INPUT), WebColor(COL_INPUT_TEXT), WebColor(COL_INPUT), WebColor(COL_INPUT_TEXT), WebColor(COL_CONSOLE), WebColor(COL_CONSOLE_TEXT), WebColor(COL_BACKGROUND)); WSContentSend_P(HTTP_HEAD_STYLE1, WebColor(COL_FORM), WebColor(COL_INPUT), WebColor(COL_INPUT_TEXT), WebColor(COL_INPUT), WebColor(COL_INPUT_TEXT), WebColor(COL_CONSOLE), WebColor(COL_CONSOLE_TEXT), WebColor(COL_BACKGROUND));
WSContentSend_P(HTTP_HEAD_STYLE2, WebColor(COL_BUTTON), WebColor(COL_BUTTON_TEXT), WebColor(COL_BUTTON_HOVER), WebColor(COL_BUTTON_RESET), WebColor(COL_BUTTON_RESET_HOVER), WebColor(COL_BUTTON_SAVE), WebColor(COL_BUTTON_SAVE_HOVER)); WSContentSend_P(HTTP_HEAD_STYLE2, WebColor(COL_BUTTON), WebColor(COL_BUTTON_TEXT), WebColor(COL_BUTTON_HOVER), WebColor(COL_BUTTON_RESET), WebColor(COL_BUTTON_RESET_HOVER), WebColor(COL_BUTTON_SAVE), WebColor(COL_BUTTON_SAVE_HOVER));
if (formatP != nullptr) { if (formatP != nullptr) {
@ -1126,8 +1153,8 @@ void HandleTemplateConfiguration(void)
WSContentSend_P(HTTP_TABLE100); WSContentSend_P(HTTP_TABLE100);
for (uint8_t i = 0; i < 17; i++) { for (uint8_t i = 0; i < 17; i++) {
if ((i < 6) || ((i > 8) && (i != 11))) { // Ignore flash pins GPIO06, 7, 8 and 11 if ((i < 6) || ((i > 8) && (i != 11))) { // Ignore flash pins GPIO06, 7, 8 and 11
WSContentSend_P(PSTR("<tr><td><b><font color='#%06x'>" D_GPIO "%d</font></b></td><td%s><select id='g%d' name='g%d'></select></td></tr>"), WSContentSend_P(PSTR("<tr><td><b><font color='#%06x'>" D_GPIO "%d</font></b></td><td%s><select id='g%d'></select></td></tr>"),
((9==i)||(10==i)) ? WebColor(COL_TEXT_WARNING) : WebColor(COL_TEXT), i, (0==i) ? " style='width:200px'" : "", i, i); ((9==i)||(10==i)) ? WebColor(COL_TEXT_WARNING) : WebColor(COL_TEXT), i, (0==i) ? " style='width:200px'" : "", i);
} }
} }
WSContentSend_P(PSTR("<tr><td><b><font color='#%06x'>" D_ADC "0</font></b></td><td><select id='g17'></select></td></tr>"), WebColor(COL_TEXT)); WSContentSend_P(PSTR("<tr><td><b><font color='#%06x'>" D_ADC "0</font></b></td><td><select id='g17'></select></td></tr>"), WebColor(COL_TEXT));
@ -1250,8 +1277,8 @@ void HandleModuleConfiguration(void)
snprintf_P(stemp, 3, PINS_WEMOS +i*2); snprintf_P(stemp, 3, PINS_WEMOS +i*2);
char sesp8285[40]; char sesp8285[40];
snprintf_P(sesp8285, sizeof(sesp8285), PSTR("<font color='#%06x'>ESP8285</font>"), WebColor(COL_TEXT_WARNING)); snprintf_P(sesp8285, sizeof(sesp8285), PSTR("<font color='#%06x'>ESP8285</font>"), WebColor(COL_TEXT_WARNING));
WSContentSend_P(PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:176px'><select id='g%d' name='g%d'></select></td></tr>"), WSContentSend_P(PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:176px'><select id='g%d'></select></td></tr>"),
(WEMOS==my_module_type)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :((9==i)||(10==i))? sesp8285 :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i); (WEMOS==my_module_type)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :((9==i)||(10==i))? sesp8285 :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i);
} }
} }
#ifndef USE_ADC_VCC #ifndef USE_ADC_VCC
@ -1470,7 +1497,7 @@ void HandleLoggingConfiguration(void)
WSContentSend_P(PSTR("<p><b>%s</b> (%s)<br><select id='l%d'>"), WSContentSend_P(PSTR("<p><b>%s</b> (%s)<br><select id='l%d'>"),
GetTextIndexed(stemp1, sizeof(stemp1), idx, kLoggingOptions), GetTextIndexed(stemp1, sizeof(stemp1), idx, kLoggingOptions),
GetTextIndexed(stemp2, sizeof(stemp2), dlevel[idx], kLoggingLevels), GetTextIndexed(stemp2, sizeof(stemp2), dlevel[idx], kLoggingLevels),
idx, idx); idx);
for (uint8_t i = LOG_LEVEL_NONE; i < LOG_LEVEL_ALL; i++) { for (uint8_t i = LOG_LEVEL_NONE; i < LOG_LEVEL_ALL; i++) {
WSContentSend_P(PSTR("<option%s value='%d'>%d %s</option>"), WSContentSend_P(PSTR("<option%s value='%d'>%d %s</option>"),
(i == llevel) ? " selected" : "", i, i, (i == llevel) ? " selected" : "", i, i,
@ -1535,10 +1562,10 @@ void HandleOtherConfiguration(void)
if (SONOFF_IFAN02 == my_module_type) { maxfn = 1; } if (SONOFF_IFAN02 == my_module_type) { maxfn = 1; }
for (uint8_t i = 0; i < maxfn; i++) { for (uint8_t i = 0; i < maxfn; i++) {
snprintf_P(stemp, sizeof(stemp), PSTR("%d"), i +1); snprintf_P(stemp, sizeof(stemp), PSTR("%d"), i +1);
WSContentSend_P(PSTR("<b>" D_FRIENDLY_NAME " %d</b> (" FRIENDLY_NAME "%s)<br><input id='a%d' name='a%d' placeholder='" FRIENDLY_NAME "%s' value='%s'><p></p>"), WSContentSend_P(PSTR("<b>" D_FRIENDLY_NAME " %d</b> (" FRIENDLY_NAME "%s)<br><input id='a%d' placeholder='" FRIENDLY_NAME "%s' value='%s'><p></p>"),
i +1, i +1,
(i) ? stemp : "", (i) ? stemp : "",
i, i, i,
(i) ? stemp : "", (i) ? stemp : "",
Settings.friendlyname[i]); Settings.friendlyname[i]);
} }

View File

@ -627,7 +627,7 @@ const char HTTP_TIMER_SCRIPT5[] PROGMEM =
"}" "}"
"eb('bt').innerHTML=s;" // Create tabs "eb('bt').innerHTML=s;" // Create tabs
"if(%d>0){" // Create Output and Action drop down boxes "if(%d>0){" // Create Output and Action drop down boxes
"eb('oa').innerHTML=\"<b>" D_TIMER_OUTPUT "</b>&nbsp;<span><select style='width:60px;' id='d1' name='d1'></select></span>&emsp;<b>" D_TIMER_ACTION "</b>&nbsp;<select style='width:99px;' id='p1' name='p1'></select>\";" "eb('oa').innerHTML=\"<b>" D_TIMER_OUTPUT "</b>&nbsp;<span><select style='width:60px;' id='d1'></select></span>&emsp;<b>" D_TIMER_ACTION "</b>&nbsp;<select style='width:99px;' id='p1'></select>\";"
"o=qs('#p1');ce('" D_OFF "',o);ce('" D_ON "',o);ce('" D_TOGGLE "',o);" // Create offset direction select options "o=qs('#p1');ce('" D_OFF "',o);ce('" D_ON "',o);ce('" D_TOGGLE "',o);" // Create offset direction select options
#if defined(USE_RULES) || defined(USE_SCRIPT) #if defined(USE_RULES) || defined(USE_SCRIPT)
"ce('" D_RULE "',o);" "ce('" D_RULE "',o);"
@ -646,11 +646,11 @@ const char HTTP_TIMER_SCRIPT6[] PROGMEM =
"o=qs('#mw');for(i=0;i<=15;i++){ce((i<10)?('0'+i):i,o);}" // Create window minutes select options "o=qs('#mw');for(i=0;i<=15;i++){ce((i<10)?('0'+i):i,o);}" // Create window minutes select options
"o=qs('#d1');for(i=0;i<%d;i++){ce(i+1,o);}" // Create outputs "o=qs('#d1');for(i=0;i<%d;i++){ce(i+1,o);}" // Create outputs
"var a='" D_DAY3LIST "';" "var a='" D_DAY3LIST "';"
"s='';for(i=0;i<7;i++){s+=\"<input id='w\"+i+\"' name='w\"+i+\"' type='checkbox'><b>\"+a.substring(i*3,(i*3)+3)+\"</b> \"}" "s='';for(i=0;i<7;i++){s+=\"<input id='w\"+i+\"' type='checkbox'><b>\"+a.substring(i*3,(i*3)+3)+\"</b> \"}"
"eb('ds').innerHTML=s;" // Create weekdays "eb('ds').innerHTML=s;" // Create weekdays
"eb('dP').click();" // Get the element with id='dP' and click on it "eb('dP').click();" // Get the element with id='dP' and click on it
"}" "}"
"window.onload=it;"; "wl(it);";
const char HTTP_TIMER_STYLE[] PROGMEM = const char HTTP_TIMER_STYLE[] PROGMEM =
".tl{float:left;border-radius:0;border:1px solid #%06x;padding:1px;width:6.25%%;}"; // COLOR_FORM, Border color needs to be the same as Fieldset background color from HTTP_HEAD_STYLE1 (transparent won't work) ".tl{float:left;border-radius:0;border:1px solid #%06x;padding:1px;width:6.25%%;}"; // COLOR_FORM, Border color needs to be the same as Fieldset background color from HTTP_HEAD_STYLE1 (transparent won't work)
const char HTTP_FORM_TIMER1[] PROGMEM = const char HTTP_FORM_TIMER1[] PROGMEM =

View File

@ -768,9 +768,9 @@ const char HTTP_FORM_KNX_OPT[] PROGMEM =
"<option value='%d'>%s</option>"; "<option value='%d'>%s</option>";
const char HTTP_FORM_KNX_GA[] PROGMEM = const char HTTP_FORM_KNX_GA[] PROGMEM =
"<input style='width:12%%;' type='number' id='%s' name='%s' min='0' max='31' value='0'> / " "<input style='width:12%%;' type='number' id='%s' min='0' max='31' value='0'> / "
"<input style='width:12%%;' type='number' id='%s' name='%s' min='0' max='7' value='0'> / " "<input style='width:12%%;' type='number' id='%s' min='0' max='7' value='0'> / "
"<input style='width:12%%;' type='number' id='%s' name='%s' min='0' max='255' value='0'> "; "<input style='width:12%%;' type='number' id='%s' min='0' max='255' value='0'> ";
const char HTTP_FORM_KNX_ADD_BTN[] PROGMEM = const char HTTP_FORM_KNX_ADD_BTN[] PROGMEM =
"<button type='submit' onclick='%s()' %s name='btn_add' value='%d' style='width:18%%;'>" D_ADD "</button><br><br>" "<button type='submit' onclick='%s()' %s name='btn_add' value='%d' style='width:18%%;'>" D_ADD "</button><br><br>"
@ -895,7 +895,7 @@ void HandleKNXConfiguration(void)
} }
} }
WSContentSend_P(PSTR("</select> -> ")); WSContentSend_P(PSTR("</select> -> "));
WSContentSend_P(HTTP_FORM_KNX_GA, "GA_FNUM", "GA_FNUM", "GA_AREA", "GA_AREA", "GA_FDEF", "GA_FDEF"); WSContentSend_P(HTTP_FORM_KNX_GA, "GA_FNUM", "GA_AREA", "GA_FDEF");
WSContentSend_P(HTTP_FORM_KNX_ADD_BTN, "GAwarning", (Settings.knx_GA_registered < MAX_KNX_GA) ? "" : "disabled", 1); WSContentSend_P(HTTP_FORM_KNX_ADD_BTN, "GAwarning", (Settings.knx_GA_registered < MAX_KNX_GA) ? "" : "disabled", 1);
for (uint8_t i = 0; i < Settings.knx_GA_registered ; ++i) for (uint8_t i = 0; i < Settings.knx_GA_registered ; ++i)
{ {
@ -907,7 +907,7 @@ void HandleKNXConfiguration(void)
} }
WSContentSend_P(HTTP_FORM_KNX3); WSContentSend_P(HTTP_FORM_KNX3);
WSContentSend_P(HTTP_FORM_KNX_GA, "CB_FNUM", "CB_FNUM", "CB_AREA", "CB_AREA", "CB_FDEF", "CB_FDEF"); WSContentSend_P(HTTP_FORM_KNX_GA, "CB_FNUM", "CB_AREA", "CB_FDEF");
WSContentSend_P(HTTP_FORM_KNX4); WSContentSend_P(HTTP_FORM_KNX4);
uint8_t j; uint8_t j;