e3bf2345348955e44ee5d7d5be325162f0b4475f
chmalee
  Tue Aug 29 09:24:13 2023 -0700
Fix notification box setup for udcTimeout messages, refs #32045

diff --git src/hg/js/utils.js src/hg/js/utils.js
index bc29d86..1afeead 100644
--- src/hg/js/utils.js
+++ src/hg/js/utils.js
@@ -787,75 +787,89 @@
 if (ix < 0)
     return "";
 content = content.substring(ix+sectionBegin.length);
 ix = content.indexOf(sectionEnd);
 if (ix < 0)
     return "";
 content = content.substring(0,ix);
 if (debug)
     alert('page nonce='+content);
 return content;
 }
 
 function notifBoxShow(cgiName, keyName) {
     /* move the notification bar div under '#TrackHeaderForm' */
     let lsKey = cgiName + "_" + keyName;
+    if (localStorage.getItem(lsKey))
+        return;
     var notifEl = document.getElementById(lsKey + "notifBox");
+    if (!notifEl) {
+        // missing call to setup function (ie generated server side like a udcTimeout message)
+        notifBoxSetup(cgiName, keyName);
+    }
     // TODO: make a generic element for positioning this
     var parentEl = document.getElementById('TrackHeaderForm');
     if (parentEl) {
         parentEl.appendChild(notifEl);
         notifEl.style.display = 'block';
     }
 }
 
 function notifBoxSetup(cgiName, keyName, msg) {
 /* Create a notification box if one hasn't been created, and
  * add msg to the list of shown notifications.
  * cgiName.keyName will be saved to localStorage in order to show
  * or hide this notification.
  * Must call notifBoxShow() in order to display the notification */
     lsKey = cgiName + "_" + keyName;
+    if (localStorage.getItem(lsKey))
+        return;
+    let alreadyPresent = false;
     let notifBox = document.getElementById(lsKey+"notifBox");
     if (notifBox) {
+        alreadyPreset = true;
+        if (msg) {
             notifBox.innerHTML += "<br>" + msg;
+        }
     } else {
-        let newDiv = document.createElement("div");
-        newDiv.className = "notifBox";
-        newDiv.style.display = "none";
-        newDiv.style.width = "90%";
-        newDiv.style.marginLeft = "100px";
-        newDiv.id = lsKey+"notifBox";
+        notifBox = document.createElement("div");
+        notifBox.className = "notifBox";
+        notifBox.style.display = "none";
+        notifBox.style.width = "90%";
+        notifBox.style.marginLeft = "100px";
+        notifBox.id = lsKey+"notifBox";
         if (msg) {
-            newDiv.innerHTML = msg;
+            notifBox.innerHTML = msg;
+        }
     }
-        newDiv.innerHTML += "<div style='text-align:center'>"+
+    notifBox.innerHTML += "<div style='text-align:center'>"+
         "<button id='" + lsKey + "notifyHide'>Close</button>&nbsp;"+
         "<button id='" + lsKey + "notifyHideForever'>Don't show again</button>"+
         "</div>";
-        document.body.appendChild(newDiv);
+    if (!alreadyPresent) {
+        document.body.appendChild(notifBox);
+    }
     $("#"+lsKey+"notifyHide").click({"id":lsKey}, function() {
         let key = arguments[0].data.id;
         $("#"+key+"notifBox").remove();
     });
     $("#"+lsKey+"notifyHideForever").click({"id": lsKey}, function() {
         let key = arguments[0].data.id;
         $("#"+key+"notifBox").remove();
         localStorage.setItem(key, "1");
     });
 }
-}
 
 function warnBoxJsSetup()
 {   // Sets up warnBox if not already established.  This is duplicated from htmshell.c
     var html = "";
     html += "<center>";
     html += "<div id='warnBox' style='display:none;'>";
     html += "<CENTER><B id='warnHead'></B></CENTER>";
     html += "<UL id='warnList'></UL>";
     html += "<CENTER><button id='warnOK'></button></CENTER>";
     html += "</div></center>";
 
 
     // GALT TODO either add nonce or move the showWarnBox and hideWarnBox to some universal javascript 
     //   file that is always included. Or consider if we can just dynamically define the functions
     //   right here inside this function?  maybe prepend function names with "window." to (re)define the global functions.