';
- for(var i2 = 0; i2 < myMenu[i].tabs.length; i2++){
- if(myMenu[i].tabs[i2].tabName == '__HIDE__'){
- continue;
- }
- var tabname = myMenu[i].tabs[i2].tabName;
- var taburl = myMenu[i].tabs[i2].url;
- if(tabname == '__INHERIT__'){
- tabname = taburl.split('.')[0];
- }
- if(taburl.indexOf('redirect.htm') != -1){
- taburl = '/ext/shared-jy/redirect.htm';
- }
- sitemapstring += '
';
- }
- document.getElementsByClassName(myMenu[i].index)[0].parentElement.parentElement.parentElement.parentElement.parentElement.innerHTML += sitemapstring;
- document.getElementsByClassName(myMenu[i].index)[0].parentElement.parentElement.parentElement.parentElement.parentElement.classList.add('dropdown');
- }
-}
-
function GenerateSiteMap(showurls)
{
myMenu = [];
@@ -898,16 +871,57 @@ function GenerateSiteMap(showurls)
return sitemapstring;
}
GenerateSiteMap(false);
+/*END:SCMERLIN_SITEMAP*/
+EOF
+}
+
+##------------------------------------------##
+## Modified by ExtremeFiretop [2026-Mar-03] ##
+##------------------------------------------##
+AppendTo_statejs_Dropdowns_3004_()
+{
+ cat << 'EOF'
+/*BEGIN:SCMERLIN_DROPDOWNS*/
+function AddDropdowns()
+{
+ if (myMenu.length == 0)
+ {
+ setTimeout(AddDropdowns,1000);
+ return;
+ }
+ for (var i = 0; i < myMenu.length; i++)
+ {
+ var sitemapstring = '
';
+ for(var i2 = 0; i2 < myMenu[i].tabs.length; i2++){
+ if(myMenu[i].tabs[i2].tabName == '__HIDE__'){
+ continue;
+ }
+ var tabname = myMenu[i].tabs[i2].tabName;
+ var taburl = myMenu[i].tabs[i2].url;
+ if(tabname == '__INHERIT__'){
+ tabname = taburl.split('.')[0];
+ }
+ if(taburl.indexOf('redirect.htm') != -1){
+ taburl = '/ext/shared-jy/redirect.htm';
+ }
+ sitemapstring += '
'+tabname+'';
+ }
+ document.getElementsByClassName(myMenu[i].index)[0].parentElement.parentElement.parentElement.parentElement.parentElement.innerHTML += sitemapstring;
+ document.getElementsByClassName(myMenu[i].index)[0].parentElement.parentElement.parentElement.parentElement.parentElement.classList.add('dropdown');
+ }
+}
AddDropdowns();
+/*END:SCMERLIN_DROPDOWNS*/
EOF
}
-##---------------------------------------##
-## Added by ExtremeFiretop [2025-May-15] ##
-##---------------------------------------##
-AppendTo_statejs_3006_()
+##------------------------------------------##
+## Modified by ExtremeFiretop [2026-Mar-03] ##
+##------------------------------------------##
+AppendTo_statejs_Sitemap_3006_()
{
- cat << 'EOF'
+ cat << 'EOF'
+/*BEGIN:SCMERLIN_SITEMAP*/
function GenerateSiteMap(showurls)
{
myMenu = [];
@@ -973,6 +987,17 @@ function GenerateSiteMap(showurls)
}
return sitemapstring;
}
+/*END:SCMERLIN_SITEMAP*/
+EOF
+}
+
+##------------------------------------------##
+## Modified by ExtremeFiretop [2026-Mar-03] ##
+##------------------------------------------##
+AppendTo_statejs_Dropdowns_3006_()
+{
+ cat << 'EOF'
+/*BEGIN:SCMERLIN_DROPDOWNS*/
(function(){
if (window._stateEnhancedInjected) return;
window._stateEnhancedInjected = true;
@@ -1106,56 +1131,267 @@ function GenerateSiteMap(showurls)
injectDropdowns();
});
})();
+/*END:SCMERLIN_DROPDOWNS*/
EOF
}
+AppendTo_statejs_3004_()
+{
+ AppendTo_statejs_Sitemap_3004_
+ if [ -f "$WEBUI_MODS_FILE" ]; then
+ AppendTo_statejs_Dropdowns_3004_
+ fi
+}
+
+AppendTo_statejs_3006_()
+{
+ AppendTo_statejs_Sitemap_3006_
+ if [ -f "$WEBUI_MODS_FILE" ]; then
+ AppendTo_statejs_Dropdowns_3006_
+ fi
+}
+
##----------------------------------------##
-## Modified by Martinski W. [2025-May-17] ##
+## Added by ExtremeFiretop [2026-Mar-03] ##
##----------------------------------------##
+Patch_StateJS()
+{
+ local TMP_STATE_JS="/tmp/state.js"
+ local sitemapPage="NONE"
+
+ # Only makes sense on Merlin with /www/state.js present
+ [ -f /www/state.js ] || return 0
+
+ # Try to find the currently mounted Sitemap page (userXX.asp)
+ if [ -f "$TEMP_MENU_TREE" ]
+ then
+ sitemapPage="$(_Check_WebGUI_Page_Exists_ "$SCRIPT_DIR/sitemap.asp")"
+ fi
+
+ # Always rebuild from the real, unmounted state.js
+ umount /www/state.js 2>/dev/null
+ cp -f /www/state.js "$TMP_STATE_JS" 2>/dev/null || return 1
+
+ #
+ # If WebUI modifications are disabled, bind back a clean/stock state.js
+ # with NO scMerlin injections at all.
+ #
+ if [ ! -f "$WEBUI_MODS_FILE" ]
+ then
+ mount -o bind "$TMP_STATE_JS" /www/state.js
+ return 0
+ fi
+
+ # Inject Sitemap link into bottom bar if we know the page
+ if echo "$sitemapPage" | grep -qE "^user[0-9]+\.asp$"
+ then
+ sed -i \
+ 's~
~ | Sitemap<\/a>\ \|\ ~' \
+ "$TMP_STATE_JS"
+ fi
+
+ # Append scMerlin injected blocks
+ {
+ echo '/*BEGIN:SCMERLIN_INJECT*/'
+ if [ "$fwInstalledBaseVers" = "3004" ]
+ then
+ AppendTo_statejs_Sitemap_3004_
+ AppendTo_statejs_Dropdowns_3004_
+ else
+ # Default to 3006 behavior
+ AppendTo_statejs_Sitemap_3006_
+ AppendTo_statejs_Dropdowns_3006_
+ fi
+ echo '/*END:SCMERLIN_INJECT*/'
+ } >> "$TMP_STATE_JS"
+
+ # Re-bind into WebUI
+ mount -o bind "$TMP_STATE_JS" /www/state.js
+ return 0
+}
+
+##---------------------------------------##
+## Added by ExtremeFiretop [2026-Mar-09] ##
+##---------------------------------------##
+Apply_WebUI_Modifications()
+{
+ case "$1" in
+ enable)
+ touch "$WEBUI_MODS_FILE"
+ Apply_WebUI_Modifications apply >/dev/null 2>&1
+ Mount_WebUI >/dev/null 2>&1
+ ;;
+ disable)
+ rm -f "$WEBUI_MODS_FILE"
+ Apply_WebUI_Modifications apply >/dev/null 2>&1
+ Mount_WebUI >/dev/null 2>&1
+ ;;
+ apply)
+ local keepAddonsCss=false
+
+ # Always work from a writable temp copy if one does not exist yet
+ if [ ! -f /tmp/index_style.css ]
+ then
+ umount /www/index_style.css 2>/dev/null
+ cp -fp /www/index_style.css /tmp/index_style.css \
+ 2>/dev/null || return 1
+ fi
+
+ # Strip scMerlin dropdown CSS unconditionally first
+ sed -i '/\.dropdown-content/d' /tmp/index_style.css
+ sed -i '/\.dropdown:hover[[:space:]]*\.dropdown-content/d' \
+ /tmp/index_style.css
+
+ # Decide whether .menu_Addons CSS should remain
+ if [ -f "$TEMP_MENU_TREE" ] && \
+ grep -qF 'index: "menu_Addons"' "$TEMP_MENU_TREE"
+ then
+ keepAddonsCss=true
+ fi
+
+ # If WebUI mods are disabled, do not re-add dropdown CSS
+ if [ ! -f "$WEBUI_MODS_FILE" ]
+ then
+ if "$keepAddonsCss" && \
+ grep -qF '.menu_Addons { background:' /tmp/index_style.css
+ then
+ umount /www/index_style.css 2>/dev/null
+ mount -o bind /tmp/index_style.css /www/index_style.css
+ else
+ rm -f /tmp/index_style.css 2>/dev/null
+ umount /www/index_style.css 2>/dev/null
+ fi
+ return 0
+ fi
+
+ # WebUI mods enabled: ensure Addons icon CSS exists if Addons menu exists
+ if "$keepAddonsCss" && \
+ ! grep -qF '.menu_Addons { background:' /tmp/index_style.css
+ then
+ echo ".menu_Addons { background: url(ext/shared-jy/addons.png); background-size: contain;}" \
+ >> /tmp/index_style.css
+ fi
+
+ # Re-add dropdown CSS
+ {
+ echo ".dropdown-content {top: 0px; left: 185px; "\
+"visibility: hidden; position: absolute; "\
+"background-color: #3a4042; min-width: 165px; "\
+"box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); "\
+"z-index: 1000;}"
+ echo ".dropdown-content a {padding: 6px 8px; "\
+"text-decoration: none; display: block; height: 100%; "\
+"min-height: 20px; max-height: 40px; font-weight: bold; "\
+"text-shadow: 1px 1px 0px black; "\
+"font-family: Verdana, MS UI Gothic, MS P Gothic, "\
+"Microsoft Yahei UI, sans-serif; font-size: 12px; "\
+"border: 1px solid #6B7071;}"
+ echo ".dropdown-content a:hover {background-color: #77a5c6;}"
+ echo ".dropdown:hover .dropdown-content {visibility: visible;}"
+ } >> /tmp/index_style.css
+
+ umount /www/index_style.css 2>/dev/null
+ mount -o bind /tmp/index_style.css /www/index_style.css
+ ;;
+ status)
+ if [ -f "$WEBUI_MODS_FILE" ]
+ then
+ echo "ENABLED"
+ else
+ echo "DISABLED"
+ fi
+ ;;
+ esac
+}
+
+##------------------------------------------##
+## Modified by ExtremeFiretop [2026-Mar-03] ##
+##------------------------------------------##
Upgrade_StateJS()
{
- local TMP_STATE_JS="/tmp/state.js"
- [ -f "$TMP_STATE_JS" ] || return 0
+ local TMP_STATE_JS="/tmp/state.js"
+ [ -f "$TMP_STATE_JS" ] || return 0
+
+ #
+ # Bootstrap/migrate dropdown preference:
+ # If state.js already contains dropdowns code but the marker file doesn't exist
+ # (older versions), create the marker so updates don't "start disabled".
+ #
+ if [ ! -f "$WEBUI_MODS_FILE" ]
+ then
+ if grep -qE '^[[:space:]]*window\._scmDropdownsEnabled[[:space:]]*=[[:space:]]*1' \
+ "$TMP_STATE_JS" 2>/dev/null || \
+ grep -qF 'BEGIN:SCMERLIN_DROPDOWNS' "$TMP_STATE_JS" 2>/dev/null || \
+ grep -qF 'function injectDropdowns()' "$TMP_STATE_JS" 2>/dev/null || \
+ grep -qF 'AddDropdowns();' "$TMP_STATE_JS" 2>/dev/null
+ then
+ touch "$WEBUI_MODS_FILE" 2>/dev/null
+ fi
+ fi
- if [ "$fwInstalledBaseVers" = "3006" ] && \
- grep -q '^var myMenu = \[\];$' "$TMP_STATE_JS"
- then
- umount /www/state.js 2>/dev/null
+ # If new split markers exist, just remove & re-append based on current state.
+ if grep -q 'BEGIN:SCMERLIN_SITEMAP' "$TMP_STATE_JS" 2>/dev/null || \
+ grep -q 'BEGIN:SCMERLIN_DROPDOWNS' "$TMP_STATE_JS" 2>/dev/null
+ then
+ umount /www/state.js 2>/dev/null
- # Remove previous code #
- sed -i '/^var myMenu = \[\];$/,/^AddDropdowns();$/d' "$TMP_STATE_JS"
+ sed -i '/\/\*BEGIN:SCMERLIN_SITEMAP\*\//,/\/\*END:SCMERLIN_SITEMAP\*\//d' \
+ "$TMP_STATE_JS"
+ sed -i '/\/\*BEGIN:SCMERLIN_DROPDOWNS\*\//,/\/\*END:SCMERLIN_DROPDOWNS\*\//d' \
+ "$TMP_STATE_JS"
- # Append new 3006 code #
- AppendTo_statejs_3006_ >> "$TMP_STATE_JS"
+ if [ "$fwInstalledBaseVers" = "3004" ]
+ then
+ AppendTo_statejs_3004_ >> "$TMP_STATE_JS"
+ else
+ AppendTo_statejs_3006_ >> "$TMP_STATE_JS"
+ fi
- mount -o bind /tmp/state.js /www/state.js
+ mount -o bind "$TMP_STATE_JS" /www/state.js
+ return 0
+ fi
- elif [ "$fwInstalledBaseVers" = "3006" ] && \
- ! grep -q 'write them straight to cache' "$TMP_STATE_JS"
- then
- umount /www/state.js 2>/dev/null
+ # ---- Legacy upgrade paths below ----
- # Remove old block starting at GenerateSiteMap() through EOF
- sed -i '/^function GenerateSiteMap(showurls)/,$d' "$TMP_STATE_JS"
+ if [ "$fwInstalledBaseVers" = "3006" ] && \
+ grep -q '^var myMenu = \[\];$' "$TMP_STATE_JS"
+ then
+ umount /www/state.js 2>/dev/null
- # Reinject the 3006 specific code
- AppendTo_statejs_3006_ >> "$TMP_STATE_JS"
+ # Remove previous code #
+ sed -i '/^var myMenu = \[\];$/,/^AddDropdowns();$/d' "$TMP_STATE_JS"
- mount -o bind /tmp/state.js /www/state.js
+ # Append new (split-aware) 3006 code #
+ AppendTo_statejs_3006_ >> "$TMP_STATE_JS"
- elif [ "$fwInstalledBaseVers" = "3004" ] && \
- grep -q 'function injectDropdowns()' "$TMP_STATE_JS"
- then
- umount /www/state.js 2>/dev/null
+ mount -o bind "$TMP_STATE_JS" /www/state.js
- # Remove the 3006 code #
- sed -i '/^function GenerateSiteMap(showurls)/,$d' "$TMP_STATE_JS"
+ elif [ "$fwInstalledBaseVers" = "3006" ] && \
+ ! grep -q 'write them straight to cache' "$TMP_STATE_JS"
+ then
+ umount /www/state.js 2>/dev/null
- # Append previous code #
- AppendTo_statejs_3004_ >> "$TMP_STATE_JS"
+ # Remove old block starting at GenerateSiteMap() through EOF
+ sed -i '/^function GenerateSiteMap(showurls)/,$d' "$TMP_STATE_JS"
- mount -o bind /tmp/state.js /www/state.js
- fi
+ # Reinject the 3006 specific code
+ AppendTo_statejs_3006_ >> "$TMP_STATE_JS"
+
+ mount -o bind "$TMP_STATE_JS" /www/state.js
+
+ elif [ "$fwInstalledBaseVers" = "3004" ] && \
+ grep -q 'function injectDropdowns()' "$TMP_STATE_JS"
+ then
+ umount /www/state.js 2>/dev/null
+
+ # Remove the 3006 code #
+ sed -i '/^function GenerateSiteMap(showurls)/,$d' "$TMP_STATE_JS"
+
+ # Append previous code #
+ AppendTo_statejs_3004_ >> "$TMP_STATE_JS"
+
+ mount -o bind "$TMP_STATE_JS" /www/state.js
+ fi
}
##------------------------------------------##
@@ -1445,6 +1681,7 @@ Create_Symlinks()
ln -s "$NTP_WATCHDOG_FILE" "$SCRIPT_WEB_DIR/watchdogenabled.htm" 2>/dev/null
ln -s "$NTP_READY_CHECK_CONF" "$SCRIPT_WEB_DIR/${NTP_READY_CHECK_FILE}.htm" 2>/dev/null
ln -s "$TAIL_TAINTED_FILE" "$SCRIPT_WEB_DIR/tailtaintdnsenabled.htm" 2>/dev/null
+ ln -s "$WEBUI_MODS_FILE" "$SCRIPT_WEB_DIR/webuimodsenabled.htm" 2>/dev/null
if [ ! -d "$SHARED_WEB_DIR" ]; then
ln -s "$SHARED_DIR" "$SHARED_WEB_DIR" 2>/dev/null
@@ -1677,94 +1914,118 @@ ${ENDIN_MenuAddOnsTag}" "$TEMP_MENU_TREE"
##----------------------------------------##
Mount_WebUI()
{
- realpage=""
+ local realpage="" sitemapMountedPage="NONE"
+ local restartHttpd=false sitemapAction=""
+
Print_Output true "Mounting WebUI tabs for $SCRIPT_NAME" "$PASS"
+
LOCKFILE=/tmp/addonwebui.lock
FD=386
eval exec "$FD>$LOCKFILE"
flock -x "$FD"
+
Get_WebUI_Page "$SCRIPT_DIR/scmerlin_www.asp"
if [ "$MyWebPage" = "NONE" ]
then
- Print_Output true "**ERROR** Unable to mount $SCRIPT_NAME WebUI page, exiting" "$CRIT"
+ Print_Output true \
+ "**ERROR** Unable to mount $SCRIPT_NAME WebUI page, exiting" \
+ "$CRIT"
flock -u "$FD"
return 1
fi
- cp -fp "$SCRIPT_DIR/scmerlin_www.asp" "$SCRIPT_WEBPAGE_DIR/$MyWebPage"
- echo "$SCRIPT_NAME" > "$SCRIPT_WEBPAGE_DIR/$(echo "$MyWebPage" | cut -f1 -d'.').title"
+
+ cp -fp "$SCRIPT_DIR/scmerlin_www.asp" \
+ "$SCRIPT_WEBPAGE_DIR/$MyWebPage"
+ echo "$SCRIPT_NAME" \
+ > "$SCRIPT_WEBPAGE_DIR/$(echo "$MyWebPage" | cut -f1 -d'.').title"
if [ "$(uname -o)" = "ASUSWRT-Merlin" ]
then
- if [ ! -f /tmp/index_style.css ]; then
+ if [ ! -f /tmp/index_style.css ]
+ then
cp -fp /www/index_style.css /tmp/
fi
- if ! grep -q '.menu_Addons' /tmp/index_style.css ; then
- echo ".menu_Addons { background: url(ext/shared-jy/addons.png); background-size: contain; }" >> /tmp/index_style.css
- fi
-
- if grep -q '.menu_Addons' /tmp/index_style.css && ! grep -q 'url(ext/shared-jy/addons.png); background-size: contain;' /tmp/index_style.css; then
- sed -i 's/addons.png);/addons.png); background-size: contain;/' /tmp/index_style.css
- fi
-
- if grep -q '.dropdown-content {display: block;}' /tmp/index_style.css ; then
- sed -i '/dropdown-content/d' /tmp/index_style.css
- fi
+ # Apply CSS/menu behavior based on saved setting
+ Apply_WebUI_Modifications apply
- if ! grep -q '.dropdown-content {visibility: visible;}' /tmp/index_style.css
+ if [ ! -f "$TEMP_MENU_TREE" ]
then
- {
- echo ".dropdown-content {top: 0px; left: 185px; visibility: hidden; position: absolute; background-color: #3a4042; min-width: 165px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1000;}"
- echo ".dropdown-content a {padding: 6px 8px; text-decoration: none; display: block; height: 100%; min-height: 20px; max-height: 40px; font-weight: bold; text-shadow: 1px 1px 0px black; font-family: Verdana, MS UI Gothic, MS P Gothic, Microsoft Yahei UI, sans-serif; font-size: 12px; border: 1px solid #6B7071;}"
- echo ".dropdown-content a:hover {background-color: #77a5c6;}"
- echo ".dropdown:hover .dropdown-content {visibility: visible;}"
- } >> /tmp/index_style.css
- fi
-
- umount /www/index_style.css 2>/dev/null
- mount -o bind /tmp/index_style.css /www/index_style.css
-
- if [ ! -f "$TEMP_MENU_TREE" ]; then
cp -fp /www/require/modules/menuTree.js "$TEMP_MENU_TREE"
fi
- sed -i "\\~$MyWebPage~d" "$TEMP_MENU_TREE"
+ # Always remove any existing scMerlin main page entry first
+ sed -i "\\~$MyWebPage~d" "$TEMP_MENU_TREE"
_CreateMenuAddOnsSection_
-
- sed -i "/url: \"javascript:var helpwindow=window.open('\/ext\/shared-jy\/redirect.htm'/i {url: \"$MyWebPage\", tabName: \"$SCRIPT_NAME\"}," "$TEMP_MENU_TREE"
+ sed -i \
+ "/url: \"javascript:var helpwindow=window.open('\/ext\/shared-jy\/redirect.htm'/i {url: \"$MyWebPage\", tabName: \"$SCRIPT_NAME\"}," \
+ "$TEMP_MENU_TREE"
realpage="$MyWebPage"
- if [ -f "$SCRIPT_DIR/sitemap.asp" ]
+ #
+ # Always clean up any previously-mounted Sitemap page and its menuTree
+ # entry first, so the current WUI toggle state fully controls it.
+ #
+ sitemapMountedPage="$(_Check_WebGUI_Page_Exists_ "$SCRIPT_DIR/sitemap.asp")"
+ if [ -n "$sitemapMountedPage" ] && \
+ [ "$sitemapMountedPage" != "NONE" ]
+ then
+ sed -i "\\~$sitemapMountedPage~d" "$TEMP_MENU_TREE"
+ rm -f "$SCRIPT_WEBPAGE_DIR/$sitemapMountedPage" 2>/dev/null
+ rm -f "$SCRIPT_WEBPAGE_DIR/$(echo "$sitemapMountedPage" | cut -f1 -d'.').title" \
+ 2>/dev/null
+ restartHttpd=true
+ sitemapAction="removed"
+ fi
+
+ #
+ # Only mount/add Sitemap when WebUI modifications are ENABLED.
+ #
+ if [ -f "$WEBUI_MODS_FILE" ] && [ -f "$SCRIPT_DIR/sitemap.asp" ]
then
Get_WebUI_Page "$SCRIPT_DIR/sitemap.asp"
if [ "$MyWebPage" = "NONE" ]
then
- Print_Output true "**ERROR** Unable to mount $SCRIPT_NAME Sitemap page, exiting" "$CRIT"
+ Print_Output true \
+ "**ERROR** Unable to mount $SCRIPT_NAME Sitemap page, exiting" \
+ "$CRIT"
flock -u "$FD"
return 1
fi
- cp -fp "$SCRIPT_DIR/sitemap.asp" "$SCRIPT_WEBPAGE_DIR/$MyWebPage"
- sed -i "\\~$MyWebPage~d" "$TEMP_MENU_TREE"
- sed -i "/url: \"javascript:var helpwindow=window.open('\/ext\/shared-jy\/redirect.htm'/a {url: \"$MyWebPage\", tabName: \"Sitemap\"}," "$TEMP_MENU_TREE"
-
- umount /www/state.js 2>/dev/null
- cp -f /www/state.js /tmp/
- sed -i 's~ | ~ | Sitemap<\/a>\ \|\ ~' /tmp/state.js
-
- # Append custom code to 'state.js' file #
- if [ "$fwInstalledBaseVers" = "3004" ]
- then AppendTo_statejs_3004_ >> /tmp/state.js
- else AppendTo_statejs_3006_ >> /tmp/state.js
- fi
- mount -o bind /tmp/state.js /www/state.js
+ cp -fp "$SCRIPT_DIR/sitemap.asp" \
+ "$SCRIPT_WEBPAGE_DIR/$MyWebPage"
+ echo "Sitemap" \
+ > "$SCRIPT_WEBPAGE_DIR/$(echo "$MyWebPage" | cut -f1 -d'.').title"
+ sed -i "\\~$MyWebPage~d" "$TEMP_MENU_TREE"
+ sed -i \
+ "/url: \"javascript:var helpwindow=window.open('\/ext\/shared-jy\/redirect.htm'/a {url: \"$MyWebPage\", tabName: \"Sitemap\"}," \
+ "$TEMP_MENU_TREE"
Print_Output true "Mounted Sitemap page as $MyWebPage" "$PASS"
+ restartHttpd=true
+ sitemapAction="added"
fi
umount /www/require/modules/menuTree.js 2>/dev/null
mount -o bind "$TEMP_MENU_TREE" /www/require/modules/menuTree.js
+
+ # state.js is now fully handled here
+ Patch_StateJS
+
+ if "$restartHttpd"
+ then
+ /sbin/service restart_httpd >/dev/null 2>&1
+ if [ "$sitemapAction" = "removed" ]
+ then
+ Print_Output true "Restarted httpd after removing Sitemap page" "$PASS"
+ elif [ "$sitemapAction" = "added" ]
+ then
+ Print_Output true "Restarted httpd after adding Sitemap page" "$PASS"
+ fi
+ fi
fi
+
flock -u "$FD"
Print_Output true "Mounted $SCRIPT_NAME WebUI page as $realpage" "$PASS"
}
@@ -3374,6 +3635,15 @@ _Menu_ToggleOptions_()
printf " ${GRNct}dns${CLRct}. Toggle dnsmasq tainted watchdog script\n"
printf " Currently: ${TAILTAINT_DNS_STATUS}\n\n"
+ if [ "$(Apply_WebUI_Modifications status)" = "ENABLED" ]
+ then
+ WEBUI_MODS_STATUS="${GRNct}ENABLED${CLRct}"
+ else
+ WEBUI_MODS_STATUS="${REDct}DISABLED${CLRct}"
+ fi
+ printf " ${GRNct}wui${CLRct}. Toggle WebUI modifications\n"
+ printf " Currently: ${WEBUI_MODS_STATUS}\n\n"
+
printf " ${GRNct}e${CLRct}. Return to Main Menu\n"
printf "\n${menuSepStr}\n\n"
@@ -3412,6 +3682,16 @@ _Menu_ToggleOptions_()
fi
break
;;
+ wui)
+ printf "\n"
+ WEBUI_MODS_STATUS="$(Apply_WebUI_Modifications status)"
+ if [ "$WEBUI_MODS_STATUS" = "ENABLED" ]
+ then Apply_WebUI_Modifications disable
+ elif [ "$WEBUI_MODS_STATUS" = "DISABLED" ]
+ then Apply_WebUI_Modifications enable
+ fi
+ break
+ ;;
e) exitMenu=true
break
;;
@@ -3579,6 +3859,7 @@ Menu_Install()
fi
Create_Dirs
+ touch "$WEBUI_MODS_FILE"
Create_Symlinks
Shortcut_Script create
Set_Version_Custom_Settings local "$SCRIPT_VERSION"
@@ -3717,7 +3998,9 @@ Menu_Uninstall()
eval exec "$FD>$LOCKFILE"
flock -x "$FD"
- local doResetWebGUI=false doResetStyle=false
+ local doResetWebGUI=false
+ local keepAddonsCss=false
+ local restartHttpd=false
if [ -f "$SCRIPT_DIR/sitemap.asp" ]
then
@@ -3727,40 +4010,74 @@ Menu_Uninstall()
[ -f "$TEMP_MENU_TREE" ]
then
doResetWebGUI=true
+ restartHttpd=true
sed -i "\\~$MyWebPage~d" "$TEMP_MENU_TREE"
rm -f "$SCRIPT_WEBPAGE_DIR/$MyWebPage"
+ rm -f "$SCRIPT_WEBPAGE_DIR/$(echo "$MyWebPage" | cut -f1 -d'.').title"
fi
fi
+
Get_WebUI_Page "$SCRIPT_DIR/scmerlin_www.asp"
if [ -n "$MyWebPage" ] && \
[ "$MyWebPage" != "NONE" ] && \
[ -f "$TEMP_MENU_TREE" ]
then
doResetWebGUI=true
+ restartHttpd=true
sed -i "\\~$MyWebPage~d" "$TEMP_MENU_TREE"
rm -f "$SCRIPT_WEBPAGE_DIR/$MyWebPage"
rm -f "$SCRIPT_WEBPAGE_DIR/$(echo "$MyWebPage" | cut -f1 -d'.').title"
fi
- _FindandRemoveMenuAddOnsSection_ && doResetStyle=true
+ _FindandRemoveMenuAddOnsSection_
+
+ if [ -f "$TEMP_MENU_TREE" ] && \
+ grep -qF 'index: "menu_Addons"' "$TEMP_MENU_TREE"
+ then
+ keepAddonsCss=true
+ fi
if "$doResetWebGUI"
then
umount /www/require/modules/menuTree.js 2>/dev/null
mount -o bind "$TEMP_MENU_TREE" /www/require/modules/menuTree.js
- if "$doResetStyle" && [ -f /tmp/index_style.css ] && \
+ fi
+
+ if [ -f /tmp/index_style.css ]
+ then
+ sed -i '/\.dropdown-content/d' /tmp/index_style.css
+ sed -i '/\.dropdown:hover[[:space:]]*\.dropdown-content/d' \
+ /tmp/index_style.css
+
+ if "$keepAddonsCss" && \
grep -qF '.menu_Addons { background:' /tmp/index_style.css
then
+ umount /www/index_style.css 2>/dev/null
+ mount -o bind /tmp/index_style.css /www/index_style.css
+ restartHttpd=true
+ else
rm -f /tmp/index_style.css
umount /www/index_style.css 2>/dev/null
+ restartHttpd=true
fi
- if [ -f /tmp/state.js ] && \
- grep -qE 'function GenerateSiteMap|function AddDropdowns' /tmp/state.js
- then
- rm -f /tmp/state.js
- umount /www/state.js 2>/dev/null
- fi
+ else
+ umount /www/index_style.css 2>/dev/null
fi
+
+ if [ -f /tmp/state.js ] && \
+ grep -qE 'function GenerateSiteMap|function AddDropdowns|function injectDropdowns|BEGIN:SCMERLIN_' /tmp/state.js
+ then
+ rm -f /tmp/state.js
+ umount /www/state.js 2>/dev/null
+ restartHttpd=true
+ fi
+
+ if "$restartHttpd"
+ then
+ /sbin/service restart_httpd >/dev/null 2>&1
+ Print_Output true "Restarted httpd after removing WebUI modifications" "$PASS"
+ fi
+
flock -u "$FD"
rm -rf "$SCRIPT_WEB_DIR" 2>/dev/null
@@ -4005,6 +4322,11 @@ case "$1" in
settingstate="$(echo "$3" | sed "s/${SCRIPT_NAME_LOWER}_DNSmasqWatchdog//")";
settingstate="$(echo "$settingstate" | tr 'A-Z' 'a-z')"
TailTaintDNSmasq "$settingstate"
+ elif echo "$3" | grep -qE "^${SCRIPT_NAME_LOWER}_WebUIMods"
+ then
+ settingstate="$(echo "$3" | sed "s/${SCRIPT_NAME_LOWER}_WebUIMods//")";
+ settingstate="$(echo "$settingstate" | tr 'A-Z' 'a-z')"
+ Apply_WebUI_Modifications "$settingstate"
elif echo "$3" | grep -qE "^${SCRIPT_NAME_LOWER}servicerestart"
then
rm -f "$SCRIPT_WEB_DIR/detect_service.js"
diff --git a/scmerlin_www.asp b/scmerlin_www.asp
index f55a307..d419917 100644
--- a/scmerlin_www.asp
+++ b/scmerlin_www.asp
@@ -118,6 +118,9 @@ function JFFS_GetUsageInfo()
/* Taken from firmware WebUI, Tools_SysInfo.asp */
function update_sysinfo(e)
{
+ if (window._scmPauseAjax)
+ return;
+
$.ajax({
url: '/ajax_sysinfo.asp',
dataType: 'script',
@@ -399,6 +402,9 @@ function lineForWan(idx, sysNow)
function update_wanuptime()
{
+ if (window._scmPauseAjax)
+ return;
+
// -------- fast local path (NVRAM) -------- //
if (!wu_useFallback)
{
@@ -485,14 +491,20 @@ function update_wanuptime()
/**----------------------------------------**/
function update_temperatures()
{
+ if (window._scmPauseAjax)
+ return;
+
$.ajax({
url: '/ajax_coretmp.asp',
dataType: 'script',
error: function(xhr){
- update_temperatures();
+ if (!window._scmPauseAjax)
+ setTimeout(update_temperatures, 3000);
},
success: function(response)
{
+ if (window._scmPauseAjax)
+ return;
code = '2.4 GHz: ' + GetTemperatureValue ('2.4GHz') + '';
if (band_5GHz_2_supported)
@@ -525,13 +537,14 @@ function update_temperatures()
code +=' - CPU: ' + parseInt(CPUTemp) +'°C';
}
document.getElementById('temp_td').innerHTML = code;
- setTimeout(update_temperatures, 3000);
+ if (!window._scmPauseAjax)
+ setTimeout(update_temperatures, 3000);
}
});
}
/* End firmware functions */
-var arrayproclistlines=[],sortnameproc="CPU%",sortdirproc="desc",arraycronjobs=[],sortnamecron="Name",sortdircron="asc",tmout=null;function SetCurrentPage(){document.form.next_page.value=window.location.pathname.substring(1),document.form.current_page.value=window.location.pathname.substring(1)}Chart.defaults.global.defaultFontColor="#CCC",Chart.Tooltip.positioners.cursor=function(e,t){return t};var srvnamelist=["dnsmasq","wan","httpd","wireless","vsftpd","samba","ddns","ntpd/chronyd"],srvdesclist=["DNS/DHCP Server","Internet Connection","Web Interface","WiFi","FTP Server","Samba","DDNS client","Timeserver"],srvnamevisiblelist=[!0,!1,!0,!1,!0,!1,!1,!0],sortedAddonPages=[];function initial(){SetCurrentPage(),LoadCustomSettings(),show_menu(),Draw_Chart_NoData("nvramUsage","Data loading..."),Draw_Chart_NoData("jffsUsage","Data loading..."),Draw_Chart_NoData("MemoryUsage","Data loading..."),Draw_Chart_NoData("SwapUsage","No swap file configured"),$("#sortTableCron").empty(),$("#sortTableCron").append(BuildSortTableHtmlNoData()),$("#sortTableProcesses").empty(),$("#sortTableProcesses").append(BuildSortTableHtmlNoData());let e="",t="";if(isWireGuard_Supported){e+=Build_WireGuardServer_Table(1),$("#table_config").after(e);for(var r=1;r<6;r++)t+=Build_WireGuardClient_Table(r);$("#table_config").after(t)}let s="";for(r=1;r<3;r++)s+=Build_OpenVPNServer_Table(r);$("#table_config").after(s);let a="";for(r=1;r<6;r++)a+=Build_OpenVPNClient_Table(r);$("#table_config").after(a);let n="";for(var i=0;i",'| ',"Data loading..."," | ","","",''}function BuildSortTableHtml(e){var t='';if("sortTableProcesses"==e){t+='',t+='',t+='',t+='',t+='',t+='',t+='',t+='',t+='',t+='",t+='';for(var r=0;r',t+="| "+arrayproclistlines[r].PID+" | ",t+=""+arrayproclistlines[r].PPID+" | ",t+=""+arrayproclistlines[r].USER+" | ",t+=""+arrayproclistlines[r].STAT+" | ",t+=""+arrayproclistlines[r].VSZ+" | ",t+=""+arrayproclistlines[r].VSZP+" | ",t+=""+arrayproclistlines[r].CPU+" | ",t+=""+arrayproclistlines[r].CPUP+" | ",t+=""+arrayproclistlines[r].COMMAND+" | ",t+=""}else if("sortTableCron"==e){t+='',t+='',t+='',t+='',t+='',t+='',t+='',t+='",t+='';for(r=0;r',t+=""+arraycronjobs[r].Name+" | ",t+=""+arraycronjobs[r].Min+" | ",t+=""+arraycronjobs[r].Hour+" | ",t+=""+arraycronjobs[r].DayM+" | ",t+=""+arraycronjobs[r].Month+" | ",t+=""+arraycronjobs[r].DayW+" | ",t+=""+arraycronjobs[r].Command+" | ",t+=""}return t+="",t+=" "}function Get_NTPWatchdogEnabled_File(){$.ajax({url:"/ext/scmerlin/watchdogenabled.htm",dataType:"text",error:function(e){document.form.scMerlin_NTPwatchdog.value="Disable",$("#scMerlin_NTPwatchdog_Status").text("Currently: DISABLED")},success:function(e){document.form.scMerlin_NTPwatchdog.value="Enable",$("#scMerlin_NTPwatchdog_Status").text("Currently: ENABLED")}})}function Save_NTPWatchdog(){document.form.action_script.value="start_scmerlin_NTPwatchdog"+document.form.scMerlin_NTPwatchdog.value,document.form.action_wait.value=4,$("#auto_refresh").prop("checked",!1),null!=tmout&&clearTimeout(tmout),showLoading(),document.form.submit(),setTimeout(Get_NTPWatchdogEnabled_File,4e3)}function Get_DNSmasqWatchdogEnabled_File(){$.ajax({url:"/ext/scmerlin/tailtaintdnsenabled.htm",dataType:"text",error:function(e){document.form.scMerlin_DNSmasqWatchdog.value="Disable",$("#scMerlin_DNSmasqWatchdog_Status").text("Currently: DISABLED")},success:function(e){document.form.scMerlin_DNSmasqWatchdog.value="Enable",$("#scMerlin_DNSmasqWatchdog_Status").text("Currently: ENABLED")}})}function Save_DNSmasqWatchdog(){document.form.action_script.value="start_scmerlin_DNSmasqWatchdog"+document.form.scMerlin_DNSmasqWatchdog.value,document.form.action_wait.value=4,$("#auto_refresh").prop("checked",!1),null!=tmout&&clearTimeout(tmout),showLoading(),document.form.submit(),setTimeout(Get_DNSmasqWatchdogEnabled_File,4e3)}const WaitMsgPopupBox={waitCounter:0,waitMaxSecs:0,waitTimerOn:!1,waitTimerID:null,waitMsgBox:null,waitMsgTemp:"",waitMsgBoxID:"myWaitMsgPopupBoxID",CloseMsg:function(){this.waitTimerOn=!1,this.waitCounter=0,this.waitMaxSecs=0,this.waitMsgTemp="",null!=this.waitTimerID&&(clearTimeout(this.waitTimerID),this.waitTimerID=null),null!=this.waitMsgBox&&this.waitMsgBox.close()},StartMsg:function(e,t,r){this.waitTimerOn||(this.waitTimerOn=!0,this.waitCounter=0,this.waitMsgTemp="",this.waitMaxSecs=Math.round(t/1e3),this.ShowTimedMsg(e,r))},ShowTimedMsg:function(e,t){if(this.waitCounter>this.waitMaxSecs)return void this.CloseMsg();if(!this.waitTimerOn)return;this.waitMsgBox=document.getElementById(this.waitMsgBoxID),null==this.waitMsgBox&&(this.waitMsgBox=document.body.appendChild(document.createElement("dialog")),this.waitMsgBox.setAttribute("id",this.waitMsgBoxID));let r=this.waitCounter+1;0==this.waitCounter&&this.waitMsgBox.close(),t?t&&(this.waitMsgBox.innerText=e+` [${r}]`):(0==this.waitCounter?this.waitMsgTemp=e+"\n >":this.waitMsgTemp=this.waitMsgTemp+">",this.waitMsgBox.innerText=this.waitMsgTemp),0==this.waitCounter&&this.waitMsgBox.showModal(),this.waitCounter=r,this.waitTimerID=setTimeout((function(){WaitMsgPopupBox.ShowTimedMsg(e,t)}),1e3)},ShowMsg:function(e,t){this.waitMsgBox=document.getElementById(this.waitMsgBoxID),null==this.waitMsgBox&&(this.waitMsgBox=document.body.appendChild(document.createElement("dialog")),this.waitMsgBox.setAttribute("id",this.waitMsgBoxID)),this.waitMsgBox.close(),this.waitMsgBox.innerText=e,this.waitMsgBox.showModal(),setTimeout((function(){WaitMsgPopupBox.waitMsgBox.close()}),t)}},AlertMsgBox={alertMsgBox:null,alertMsgBoxID:"myAlertMsgPopupBoxID",BuildAlertBox:function(e){let t;const r=e.split("\n");t='';for(var s=0;s"+r[s]+"";return t+=' ',t},CloseAlert:function(){null!=this.alertMsgBox&&this.alertMsgBox.close()},ShowAlert:function(e){this.alertMsgBox=document.getElementById(this.alertMsgBoxID),null==this.alertMsgBox&&(this.alertMsgBox=document.body.appendChild(document.createElement("dialog")),this.alertMsgBox.setAttribute("id",this.alertMsgBoxID)),this.alertMsgBox.close(),this.alertMsgBox.innerHTML=this.BuildAlertBox(e),this.alertMsgBox.showModal()}};var theButtonBackStyle=null;function SetButtonGenState(e,t,r){t?(document.getElementById(e).disabled=!1,document.getElementById(e).title=r,null!=theButtonBackStyle&&(document.getElementById(e).style.background=theButtonBackStyle)):(0==document.getElementById(e).disabled&&(theButtonBackStyle=document.getElementById(e).style.background),document.getElementById(e).disabled=!0,document.getElementById(e).title=r,document.getElementById(e).style.background="grey")}function SetNTPReadyCheckButtonState(e,t){let r;r=e?NTPReadyCheck.buttonHintMsg:t,SetButtonGenState("btnSaveNTPcheck",e,r)}function Get_NTPReadyCheck_Option(){$.ajax({url:"/ext/scmerlin/NTP_Ready_Config.htm",dataType:"text",error:function(e){document.form.scMerlin_NTPcheck.value="Disable",NTPReadyCheck.prevOptionValue="DISABLED",WaitMsgPopupBox.CloseMsg(),SetNTPReadyCheckButtonState(!0,null),$("#scMerlin_NTPcheck_Status").text("Currently: DISABLED")},success:function(e){let t=e.split("\n");t=t.filter(Boolean);let r,s,a,n,i,o=t.length,l="";for(var c=0;c (a."+sortfield+".toLowerCase() > b."+sortfield+".toLowerCase()) ? 1 : ((b."+sortfield+".toLowerCase() > a."+sortfield+".toLowerCase()) ? -1 : 0));"),window[sortdir]="asc"):(eval(arrayid+" = "+arrayid+".sort((a,b) => (a."+sortfield+".toLowerCase() < b."+sortfield+".toLowerCase()) ? 1 : ((b."+sortfield+".toLowerCase() < a."+sortfield+".toLowerCase()) ? -1 : 0));"),window[sortdir]="desc"):"number"==sorttype&&(-1==sorttext.indexOf("↓")&&-1==sorttext.indexOf("↑")||-1!=sorttext.indexOf("↓")?(eval(arrayid+" = "+arrayid+".sort((a,b) => parseFloat(getNum(a."+sortfield+'.replace("m","000"))) - parseFloat(getNum(b.'+sortfield+'.replace("m","000"))));'),window[sortdir]="asc"):(eval(arrayid+" = "+arrayid+".sort((a,b) => parseFloat(getNum(b."+sortfield+'.replace("m","000"))) - parseFloat(getNum(a.'+sortfield+'.replace("m","000"))));'),window[sortdir]="desc")),$("#"+tableid).empty(),$("#"+tableid).append(BuildSortTableHtml(tableid)),$("#"+tableid).find(".sortable").each((function(e,t){t.innerHTML==window[sortname]&&("asc"==window[sortdir]?t.innerHTML=window[sortname]+" ↑":t.innerHTML=window[sortname]+" ↓")}))}function getNum(e){if(isNaN(e)){if("*"==e)return-10;if(-1!=e.indexOf("*/"))return-5;if(-1!=e.indexOf("/"))return e.split("/")[0];if("Sun"==e)return 0;if("Mon"==e)return 1;if("Tue"==e)return 2;if("Wed"==e)return 3;if("Thu"==e)return 4;if("Fri"==e)return 5;if("Sat"==e)return 6}return e}function ToggleRefresh(){1==$("#auto_refresh").prop("checked")?get_proclist_file():null!=tmout&&clearTimeout(tmout)}function BuildAddonPageTable(e,t,r){var s="";if(0==r&&(s+=' ',s+='"}return s}function BuildServiceTable(e,t,r,s){var a="";return 0==s&&(a+=' ',a+='"),a}function Build_OpenVPNClient_Table(theIndex){let vpnClientHTML="",vpnClientName="vpnclient"+theIndex,vpnClientDesc=eval("document.form.vpnc"+theIndex+"_desc").value;return 1==theIndex&&(vpnClientHTML+=' ',vpnClientHTML+='"),vpnClientHTML}function Build_OpenVPNServer_Table(e){let t="",r="vpnserver"+e;return 1==e&&(t+=' ',t+='"),t}function Build_WireGuardServer_Table(e){let t="",r="wgServer"+e;return 1==e&&(t+=' ',t+='"),t}function Build_WireGuardClient_Table(theIndex){let wgClientHTML="",wgClientName="wgClient"+theIndex,wgClientDesc=eval("document.form.wrgc"+theIndex+"_desc").value;return null!==wgClientDesc&&""!==wgClientDesc||(wgClientDesc="No description"),1==theIndex&&(wgClientHTML+=' ',wgClientHTML+='"),wgClientHTML}function round(e,t){return Number(Math.round(e+"e"+t)+"e-"+t)}function Draw_Chart_NoData(e,t){document.getElementById("canvasChart"+e).width="265",document.getElementById("canvasChart"+e).height="250",document.getElementById("canvasChart"+e).style.width="265px",document.getElementById("canvasChart"+e).style.height="250px";var r=document.getElementById("canvasChart"+e).getContext("2d");r.save(),r.textAlign="center",r.textBaseline="middle",r.font="normal normal bolder 22px Arial",r.fillStyle="white",r.fillText(t,135,125),r.restore()}function Draw_Chart(e){var t=[],r=[],s=[],a="",n="";"MemoryUsage"==e?(t=[1*mem_stats_arr[0]-1*mem_stats_arr[1]-1*mem_stats_arr[2]-1*mem_stats_arr[3],mem_stats_arr[1],mem_stats_arr[2],mem_stats_arr[3]],r=["Used","Free","Buffers","Cache"],s=["#5eaec0","#12cf80","#ceca09","#9d12c4"],a="Memory Usage",n="MB"):"SwapUsage"==e?(t=[mem_stats_arr[4],1*mem_stats_arr[5]-1*mem_stats_arr[4]],r=["Used","Free"],s=["#135fee","#1aa658"],a="Swap Usage",n="MB"):"nvramUsage"==e?(t=[round(mem_stats_arr[6]/1024,2).toFixed(2),round(1*nvramtotal-1*mem_stats_arr[6]/1024,2).toFixed(2)],r=["Used","Free"],s=["#5eaec0","#12cf80"],a="NVRAM Usage",n="KB"):"jffsUsage"==e&&(t=[jffs_Used,jffs_Free],r=["Used","Free"],s=["#135fee","#1aa658"],a="JFFS Usage",n="MB");var i=window["Chart"+e];null!=i&&i.destroy();var o=document.getElementById("canvasChart"+e).getContext("2d");i=new Chart(o,{type:"pie",options:{segmentShowStroke:!1,segmentStrokeColor:"#000",maintainAspectRatio:!1,animation:{duration:0},hover:{animationDuration:0},responsiveAnimationDuration:0,legend:{onClick:null,display:!0,position:"left",labels:{fontColor:"#ffffff"}},title:{display:!0,text:a,position:"top"},tooltips:{callbacks:{title:function(e,t){return t.labels[e[0].index]},label:function(e,t){return round(t.datasets[e.datasetIndex].data[e.index],2).toFixed(2)+" "+n}},mode:"point",position:"cursor",intersect:!0},scales:{xAxes:[{display:!1,gridLines:{display:!1},scaleLabel:{display:!1},ticks:{display:!1}}],yAxes:[{display:!1,gridLines:{display:!1},scaleLabel:{display:!1},ticks:{display:!1}}]}},data:{labels:r,datasets:[{data:t,borderWidth:1,backgroundColor:s,borderColor:"#000000"}]}}),window["Chart"+e]=i}
+var arrayproclistlines=[],sortnameproc="CPU%",sortdirproc="desc",arraycronjobs=[],sortnamecron="Name",sortdircron="asc",tmout=null;function SetCurrentPage(){document.form.next_page.value=window.location.pathname.substring(1),document.form.current_page.value=window.location.pathname.substring(1)}Chart.defaults.global.defaultFontColor="#CCC",Chart.Tooltip.positioners.cursor=function(e,t){return t};var srvnamelist=["dnsmasq","wan","httpd","wireless","vsftpd","samba","ddns","ntpd/chronyd"],srvdesclist=["DNS/DHCP Server","Internet Connection","Web Interface","WiFi","FTP Server","Samba","DDNS client","Timeserver"],srvnamevisiblelist=[!0,!1,!0,!1,!0,!1,!1,!0],sortedAddonPages=[];function initial(){SetCurrentPage(),LoadCustomSettings(),show_menu(),Draw_Chart_NoData("nvramUsage","Data loading..."),Draw_Chart_NoData("jffsUsage","Data loading..."),Draw_Chart_NoData("MemoryUsage","Data loading..."),Draw_Chart_NoData("SwapUsage","No swap file configured"),$("#sortTableCron").empty(),$("#sortTableCron").append(BuildSortTableHtmlNoData()),$("#sortTableProcesses").empty(),$("#sortTableProcesses").append(BuildSortTableHtmlNoData());let e="",t="";if(isWireGuard_Supported){e+=Build_WireGuardServer_Table(1),$("#table_config").after(e);for(var r=1;r<6;r++)t+=Build_WireGuardClient_Table(r);$("#table_config").after(t)}let s="";for(r=1;r<3;r++)s+=Build_OpenVPNServer_Table(r);$("#table_config").after(s);let a="";for(r=1;r<6;r++)a+=Build_OpenVPNClient_Table(r);$("#table_config").after(a);let n="";for(var i=0;i",'',"Data loading..."," | ","","",''}function BuildSortTableHtml(e){var t='';if("sortTableProcesses"==e){t+='',t+='',t+='',t+='',t+='',t+='',t+='',t+='',t+='',t+='",t+='';for(var r=0;r',t+="| "+arrayproclistlines[r].PID+" | ",t+=""+arrayproclistlines[r].PPID+" | ",t+=""+arrayproclistlines[r].USER+" | ",t+=""+arrayproclistlines[r].STAT+" | ",t+=""+arrayproclistlines[r].VSZ+" | ",t+=""+arrayproclistlines[r].VSZP+" | ",t+=""+arrayproclistlines[r].CPU+" | ",t+=""+arrayproclistlines[r].CPUP+" | ",t+=""+arrayproclistlines[r].COMMAND+" | ",t+=""}else if("sortTableCron"==e){t+='',t+='',t+='',t+='',t+='',t+='',t+='',t+='",t+='';for(r=0;r',t+=""+arraycronjobs[r].Name+" | ",t+=""+arraycronjobs[r].Min+" | ",t+=""+arraycronjobs[r].Hour+" | ",t+=""+arraycronjobs[r].DayM+" | ",t+=""+arraycronjobs[r].Month+" | ",t+=""+arraycronjobs[r].DayW+" | ",t+=""+arraycronjobs[r].Command+" | ",t+=""}return t+="",t+=" "}function Get_NTPWatchdogEnabled_File(){$.ajax({url:"/ext/scmerlin/watchdogenabled.htm",dataType:"text",error:function(e){document.form.scMerlin_NTPwatchdog.value="Disable",$("#scMerlin_NTPwatchdog_Status").text("Currently: DISABLED")},success:function(e){document.form.scMerlin_NTPwatchdog.value="Enable",$("#scMerlin_NTPwatchdog_Status").text("Currently: ENABLED")}})}function Save_NTPWatchdog(){document.form.action_script.value="start_scmerlin_NTPwatchdog"+document.form.scMerlin_NTPwatchdog.value,document.form.action_wait.value=4,$("#auto_refresh").prop("checked",!1),null!=tmout&&clearTimeout(tmout),showLoading(),document.form.submit(),setTimeout(Get_NTPWatchdogEnabled_File,4e3)}function Get_DNSmasqWatchdogEnabled_File(){$.ajax({url:"/ext/scmerlin/tailtaintdnsenabled.htm",dataType:"text",error:function(e){document.form.scMerlin_DNSmasqWatchdog.value="Disable",$("#scMerlin_DNSmasqWatchdog_Status").text("Currently: DISABLED")},success:function(e){document.form.scMerlin_DNSmasqWatchdog.value="Enable",$("#scMerlin_DNSmasqWatchdog_Status").text("Currently: ENABLED")}})}function Get_WebUIModsEnabled_File(){$.ajax({url:"/ext/scmerlin/webuimodsenabled.htm",dataType:"text",cache:false,error:function(){document.form.scMerlin_WebUIMods.value="Disable",$("#scMerlin_WebUIMods_Status").text("Currently: DISABLED")},success:function(){document.form.scMerlin_WebUIMods.value="Enable",$("#scMerlin_WebUIMods_Status").text("Currently: ENABLED")}})}function Save_WebUIMods(){$("#auto_refresh").prop("checked",false),null!=tmout&&clearTimeout(tmout),"undefined"!=typeof WaitMsgPopupBox&&WaitMsgPopupBox.CloseMsg(),window._scmPauseAjax=!0,document.form.action_script.value="start_scmerlin_WebUIMods"+document.form.scMerlin_WebUIMods.value,document.form.action_wait.value=8,showLoading(),document.form.submit()}function Save_DNSmasqWatchdog(){document.form.action_script.value="start_scmerlin_DNSmasqWatchdog"+document.form.scMerlin_DNSmasqWatchdog.value,document.form.action_wait.value=4,$("#auto_refresh").prop("checked",!1),null!=tmout&&clearTimeout(tmout),showLoading(),document.form.submit(),setTimeout(Get_DNSmasqWatchdogEnabled_File,4e3)}const WaitMsgPopupBox={waitCounter:0,waitMaxSecs:0,waitTimerOn:!1,waitTimerID:null,waitMsgBox:null,waitMsgTemp:"",waitMsgBoxID:"myWaitMsgPopupBoxID",CloseMsg:function(){this.waitTimerOn=!1,this.waitCounter=0,this.waitMaxSecs=0,this.waitMsgTemp="",null!=this.waitTimerID&&(clearTimeout(this.waitTimerID),this.waitTimerID=null),null!=this.waitMsgBox&&this.waitMsgBox.close()},StartMsg:function(e,t,r){this.waitTimerOn||(this.waitTimerOn=!0,this.waitCounter=0,this.waitMsgTemp="",this.waitMaxSecs=Math.round(t/1e3),this.ShowTimedMsg(e,r))},ShowTimedMsg:function(e,t){if(this.waitCounter>this.waitMaxSecs)return void this.CloseMsg();if(!this.waitTimerOn)return;this.waitMsgBox=document.getElementById(this.waitMsgBoxID),null==this.waitMsgBox&&(this.waitMsgBox=document.body.appendChild(document.createElement("dialog")),this.waitMsgBox.setAttribute("id",this.waitMsgBoxID));let r=this.waitCounter+1;0==this.waitCounter&&this.waitMsgBox.close(),t?t&&(this.waitMsgBox.innerText=e+` [${r}]`):(0==this.waitCounter?this.waitMsgTemp=e+"\n >":this.waitMsgTemp=this.waitMsgTemp+">",this.waitMsgBox.innerText=this.waitMsgTemp),0==this.waitCounter&&this.waitMsgBox.showModal(),this.waitCounter=r,this.waitTimerID=setTimeout((function(){WaitMsgPopupBox.ShowTimedMsg(e,t)}),1e3)},ShowMsg:function(e,t){this.waitMsgBox=document.getElementById(this.waitMsgBoxID),null==this.waitMsgBox&&(this.waitMsgBox=document.body.appendChild(document.createElement("dialog")),this.waitMsgBox.setAttribute("id",this.waitMsgBoxID)),this.waitMsgBox.close(),this.waitMsgBox.innerText=e,this.waitMsgBox.showModal(),setTimeout((function(){WaitMsgPopupBox.waitMsgBox.close()}),t)}},AlertMsgBox={alertMsgBox:null,alertMsgBoxID:"myAlertMsgPopupBoxID",BuildAlertBox:function(e){let t;const r=e.split("\n");t='';for(var s=0;s"+r[s]+"";return t+=' ',t},CloseAlert:function(){null!=this.alertMsgBox&&this.alertMsgBox.close()},ShowAlert:function(e){this.alertMsgBox=document.getElementById(this.alertMsgBoxID),null==this.alertMsgBox&&(this.alertMsgBox=document.body.appendChild(document.createElement("dialog")),this.alertMsgBox.setAttribute("id",this.alertMsgBoxID)),this.alertMsgBox.close(),this.alertMsgBox.innerHTML=this.BuildAlertBox(e),this.alertMsgBox.showModal()}};var theButtonBackStyle=null;function SetButtonGenState(e,t,r){t?(document.getElementById(e).disabled=!1,document.getElementById(e).title=r,null!=theButtonBackStyle&&(document.getElementById(e).style.background=theButtonBackStyle)):(0==document.getElementById(e).disabled&&(theButtonBackStyle=document.getElementById(e).style.background),document.getElementById(e).disabled=!0,document.getElementById(e).title=r,document.getElementById(e).style.background="grey")}function SetNTPReadyCheckButtonState(e,t){let r;r=e?NTPReadyCheck.buttonHintMsg:t,SetButtonGenState("btnSaveNTPcheck",e,r)}function Get_NTPReadyCheck_Option(){$.ajax({url:"/ext/scmerlin/NTP_Ready_Config.htm",dataType:"text",error:function(e){document.form.scMerlin_NTPcheck.value="Disable",NTPReadyCheck.prevOptionValue="DISABLED",WaitMsgPopupBox.CloseMsg(),SetNTPReadyCheckButtonState(!0,null),$("#scMerlin_NTPcheck_Status").text("Currently: DISABLED")},success:function(e){let t=e.split("\n");t=t.filter(Boolean);let r,s,a,n,i,o=t.length,l="";for(var c=0;c (a."+sortfield+".toLowerCase() > b."+sortfield+".toLowerCase()) ? 1 : ((b."+sortfield+".toLowerCase() > a."+sortfield+".toLowerCase()) ? -1 : 0));"),window[sortdir]="asc"):(eval(arrayid+" = "+arrayid+".sort((a,b) => (a."+sortfield+".toLowerCase() < b."+sortfield+".toLowerCase()) ? 1 : ((b."+sortfield+".toLowerCase() < a."+sortfield+".toLowerCase()) ? -1 : 0));"),window[sortdir]="desc"):"number"==sorttype&&(-1==sorttext.indexOf("↓")&&-1==sorttext.indexOf("↑")||-1!=sorttext.indexOf("↓")?(eval(arrayid+" = "+arrayid+".sort((a,b) => parseFloat(getNum(a."+sortfield+'.replace("m","000"))) - parseFloat(getNum(b.'+sortfield+'.replace("m","000"))));'),window[sortdir]="asc"):(eval(arrayid+" = "+arrayid+".sort((a,b) => parseFloat(getNum(b."+sortfield+'.replace("m","000"))) - parseFloat(getNum(a.'+sortfield+'.replace("m","000"))));'),window[sortdir]="desc")),$("#"+tableid).empty(),$("#"+tableid).append(BuildSortTableHtml(tableid)),$("#"+tableid).find(".sortable").each((function(e,t){t.innerHTML==window[sortname]&&("asc"==window[sortdir]?t.innerHTML=window[sortname]+" ↑":t.innerHTML=window[sortname]+" ↓")}))}function getNum(e){if(isNaN(e)){if("*"==e)return-10;if(-1!=e.indexOf("*/"))return-5;if(-1!=e.indexOf("/"))return e.split("/")[0];if("Sun"==e)return 0;if("Mon"==e)return 1;if("Tue"==e)return 2;if("Wed"==e)return 3;if("Thu"==e)return 4;if("Fri"==e)return 5;if("Sat"==e)return 6}return e}function ToggleRefresh(){1==$("#auto_refresh").prop("checked")?get_proclist_file():null!=tmout&&clearTimeout(tmout)}function BuildAddonPageTable(e,t,r){var s="";if(0==r&&(s+=' ',s+='"}return s}function BuildServiceTable(e,t,r,s){var a="";return 0==s&&(a+=' ',a+='"),a}function Build_OpenVPNClient_Table(theIndex){let vpnClientHTML="",vpnClientName="vpnclient"+theIndex,vpnClientDesc=eval("document.form.vpnc"+theIndex+"_desc").value;return 1==theIndex&&(vpnClientHTML+=' ',vpnClientHTML+='"),vpnClientHTML}function Build_OpenVPNServer_Table(e){let t="",r="vpnserver"+e;return 1==e&&(t+=' ',t+='"),t}function Build_WireGuardServer_Table(e){let t="",r="wgServer"+e;return 1==e&&(t+=' ',t+='"),t}function Build_WireGuardClient_Table(theIndex){let wgClientHTML="",wgClientName="wgClient"+theIndex,wgClientDesc=eval("document.form.wrgc"+theIndex+"_desc").value;return null!==wgClientDesc&&""!==wgClientDesc||(wgClientDesc="No description"),1==theIndex&&(wgClientHTML+=' ',wgClientHTML+='"),wgClientHTML}function round(e,t){return Number(Math.round(e+"e"+t)+"e-"+t)}function Draw_Chart_NoData(e,t){document.getElementById("canvasChart"+e).width="265",document.getElementById("canvasChart"+e).height="250",document.getElementById("canvasChart"+e).style.width="265px",document.getElementById("canvasChart"+e).style.height="250px";var r=document.getElementById("canvasChart"+e).getContext("2d");r.save(),r.textAlign="center",r.textBaseline="middle",r.font="normal normal bolder 22px Arial",r.fillStyle="white",r.fillText(t,135,125),r.restore()}function Draw_Chart(e){var t=[],r=[],s=[],a="",n="";"MemoryUsage"==e?(t=[1*mem_stats_arr[0]-1*mem_stats_arr[1]-1*mem_stats_arr[2]-1*mem_stats_arr[3],mem_stats_arr[1],mem_stats_arr[2],mem_stats_arr[3]],r=["Used","Free","Buffers","Cache"],s=["#5eaec0","#12cf80","#ceca09","#9d12c4"],a="Memory Usage",n="MB"):"SwapUsage"==e?(t=[mem_stats_arr[4],1*mem_stats_arr[5]-1*mem_stats_arr[4]],r=["Used","Free"],s=["#135fee","#1aa658"],a="Swap Usage",n="MB"):"nvramUsage"==e?(t=[round(mem_stats_arr[6]/1024,2).toFixed(2),round(1*nvramtotal-1*mem_stats_arr[6]/1024,2).toFixed(2)],r=["Used","Free"],s=["#5eaec0","#12cf80"],a="NVRAM Usage",n="KB"):"jffsUsage"==e&&(t=[jffs_Used,jffs_Free],r=["Used","Free"],s=["#135fee","#1aa658"],a="JFFS Usage",n="MB");var i=window["Chart"+e];null!=i&&i.destroy();var o=document.getElementById("canvasChart"+e).getContext("2d");i=new Chart(o,{type:"pie",options:{segmentShowStroke:!1,segmentStrokeColor:"#000",maintainAspectRatio:!1,animation:{duration:0},hover:{animationDuration:0},responsiveAnimationDuration:0,legend:{onClick:null,display:!0,position:"left",labels:{fontColor:"#ffffff"}},title:{display:!0,text:a,position:"top"},tooltips:{callbacks:{title:function(e,t){return t.labels[e[0].index]},label:function(e,t){return round(t.datasets[e.datasetIndex].data[e.index],2).toFixed(2)+" "+n}},mode:"point",position:"cursor",intersect:!0},scales:{xAxes:[{display:!1,gridLines:{display:!1},scaleLabel:{display:!1},ticks:{display:!1}}],yAxes:[{display:!1,gridLines:{display:!1},scaleLabel:{display:!1},ticks:{display:!1}}]}},data:{labels:r,datasets:[{data:t,borderWidth:1,backgroundColor:s,borderColor:"#000000"}]}}),window["Chart"+e]=i}
@@ -660,6 +673,25 @@ var arrayproclistlines=[],sortnameproc="CPU%",sortdirproc="desc",arraycronjobs=[
|
+
+
+
+Enable WebUI modifications
|
+
+Yes
+No
+
+
+
+
+ |
+
diff --git a/scmerlin_www.js b/scmerlin_www.js
index 074caef..727288a 100644
--- a/scmerlin_www.js
+++ b/scmerlin_www.js
@@ -88,6 +88,7 @@ function initial()
Get_NTPWatchdogEnabled_File();
Get_NTPReadyCheck_Option();
Get_DNSmasqWatchdogEnabled_File();
+ Get_WebUIModsEnabled_File();
update_temperatures();
update_wanuptime();
update_sysinfo();
@@ -377,6 +378,45 @@ function Get_DNSmasqWatchdogEnabled_File()
});
}
+function Get_WebUIModsEnabled_File()
+{
+ $.ajax({
+ url: "/ext/scmerlin/webuimodsenabled.htm",
+ dataType: "text",
+ cache: false,
+ error: function(){
+ document.form.scMerlin_WebUIMods.value = "Disable";
+ $("#scMerlin_WebUIMods_Status").text("Currently: DISABLED");
+ },
+ success: function(){
+ document.form.scMerlin_WebUIMods.value = "Enable";
+ $("#scMerlin_WebUIMods_Status").text("Currently: ENABLED");
+ }
+ });
+}
+
+function Save_WebUIMods()
+{
+ $("#auto_refresh").prop("checked", false);
+
+ if (tmout != null)
+ clearTimeout(tmout);
+
+ if (typeof WaitMsgPopupBox !== 'undefined')
+ WaitMsgPopupBox.CloseMsg();
+
+ /* stop/pause recurring AJAX refreshes while httpd is being restarted */
+ window._scmPauseAjax = true;
+
+ document.form.action_script.value =
+ "start_scmerlin_WebUIMods" +
+ document.form.scMerlin_WebUIMods.value;
+ document.form.action_wait.value = 8;
+
+ showLoading();
+ document.form.submit();
+}
+
/**-------------------------------------**/
/** Added by Martinski W. [2024-Apr-29] **/
/**-------------------------------------**/